# tests/integration/api/v1/vendor/test_messages.py """ Integration tests for vendor messaging endpoints. Tests the /api/v1/vendor/messages/* endpoints. """ import pytest from models.database.message import ConversationType, ParticipantType @pytest.mark.integration @pytest.mark.api @pytest.mark.vendor class TestVendorMessagesListAPI: """Tests for vendor message list endpoints.""" def test_list_conversations_empty(self, client, vendor_user_headers): """Test listing conversations when none exist.""" response = client.get("/api/v1/vendor/messages", headers=vendor_user_headers) assert response.status_code == 200 data = response.json() assert "conversations" in data assert "total" in data assert "total_unread" in data assert data["total"] == 0 def test_list_conversations_requires_auth(self, client): """Test that listing requires authentication.""" response = client.get("/api/v1/vendor/messages") assert response.status_code == 401 def test_list_conversations_requires_vendor(self, client, admin_headers): """Test that admin cannot use vendor endpoint.""" response = client.get("/api/v1/vendor/messages", headers=admin_headers) # Admin doesn't have vendor context assert response.status_code == 403 def test_list_conversations_with_data( self, client, vendor_user_headers, vendor_api_conversation ): """Test listing conversations with existing data.""" response = client.get("/api/v1/vendor/messages", headers=vendor_user_headers) assert response.status_code == 200 data = response.json() assert data["total"] >= 1 def test_list_conversations_filter_by_type( self, client, vendor_user_headers, vendor_api_conversation ): """Test filtering conversations by type.""" response = client.get( "/api/v1/vendor/messages", params={"conversation_type": "admin_vendor"}, headers=vendor_user_headers, ) assert response.status_code == 200 data = response.json() for conv in data["conversations"]: assert conv["conversation_type"] == "admin_vendor" @pytest.mark.integration @pytest.mark.api @pytest.mark.vendor class TestVendorMessagesUnreadCountAPI: """Tests for unread count endpoint.""" def test_get_unread_count(self, client, vendor_user_headers): """Test getting unread count.""" response = client.get( "/api/v1/vendor/messages/unread-count", headers=vendor_user_headers ) assert response.status_code == 200 data = response.json() assert "total_unread" in data assert isinstance(data["total_unread"], int) @pytest.mark.integration @pytest.mark.api @pytest.mark.vendor class TestVendorMessagesRecipientsAPI: """Tests for recipients endpoint.""" def test_get_customer_recipients( self, client, vendor_user_headers, test_customer ): """Test getting customer recipients.""" response = client.get( "/api/v1/vendor/messages/recipients", params={"recipient_type": "customer"}, headers=vendor_user_headers, ) assert response.status_code == 200 data = response.json() assert "recipients" in data assert "total" in data def test_get_recipients_requires_type(self, client, vendor_user_headers): """Test that recipient_type is required.""" response = client.get( "/api/v1/vendor/messages/recipients", headers=vendor_user_headers ) assert response.status_code == 422 @pytest.mark.integration @pytest.mark.api @pytest.mark.vendor class TestVendorMessagesCreateAPI: """Tests for conversation creation.""" def test_create_conversation_vendor_customer( self, client, vendor_user_headers, test_customer, test_vendor ): """Test creating vendor-customer conversation.""" response = client.post( "/api/v1/vendor/messages", json={ "conversation_type": "vendor_customer", "subject": "Customer Support", "recipient_type": "customer", "recipient_id": test_customer.id, "vendor_id": test_vendor.id, "initial_message": "Hello customer!", }, headers=vendor_user_headers, ) assert response.status_code == 200 data = response.json() assert data["subject"] == "Customer Support" assert data["conversation_type"] == "vendor_customer" def test_create_conversation_admin_vendor_not_allowed( self, client, vendor_user_headers, test_admin, test_vendor ): """Test vendor cannot initiate admin_vendor conversation.""" response = client.post( "/api/v1/vendor/messages", json={ "conversation_type": "admin_vendor", "subject": "Question for Admin", "recipient_type": "admin", "recipient_id": test_admin.id, "vendor_id": test_vendor.id, }, headers=vendor_user_headers, ) assert response.status_code == 400 @pytest.mark.integration @pytest.mark.api @pytest.mark.vendor class TestVendorMessagesDetailAPI: """Tests for conversation detail.""" def test_get_conversation_detail( self, client, vendor_user_headers, vendor_api_conversation ): """Test getting conversation detail.""" response = client.get( f"/api/v1/vendor/messages/{vendor_api_conversation.id}", headers=vendor_user_headers, ) assert response.status_code == 200 data = response.json() assert data["id"] == vendor_api_conversation.id assert "participants" in data assert "messages" in data def test_get_conversation_not_found(self, client, vendor_user_headers): """Test getting nonexistent conversation.""" response = client.get( "/api/v1/vendor/messages/99999", headers=vendor_user_headers ) assert response.status_code == 404 @pytest.mark.integration @pytest.mark.api @pytest.mark.vendor class TestVendorMessagesSendAPI: """Tests for sending messages.""" def test_send_message( self, client, vendor_user_headers, vendor_api_conversation ): """Test sending a message.""" response = client.post( f"/api/v1/vendor/messages/{vendor_api_conversation.id}/messages", data={"content": "Reply from vendor"}, headers=vendor_user_headers, ) assert response.status_code == 200 data = response.json() assert data["content"] == "Reply from vendor" assert data["sender_type"] == "vendor" def test_send_message_to_closed( self, client, vendor_user_headers, vendor_api_closed_conversation ): """Test cannot send to closed conversation.""" response = client.post( f"/api/v1/vendor/messages/{vendor_api_closed_conversation.id}/messages", data={"content": "Test message"}, headers=vendor_user_headers, ) assert response.status_code == 400 @pytest.mark.integration @pytest.mark.api @pytest.mark.vendor class TestVendorMessagesActionsAPI: """Tests for conversation actions.""" def test_mark_read( self, client, vendor_user_headers, vendor_api_conversation ): """Test marking conversation as read.""" response = client.put( f"/api/v1/vendor/messages/{vendor_api_conversation.id}/read", headers=vendor_user_headers, ) assert response.status_code == 200 data = response.json() assert data["success"] is True assert data["unread_count"] == 0 def test_update_preferences( self, client, vendor_user_headers, vendor_api_conversation ): """Test updating notification preferences.""" response = client.put( f"/api/v1/vendor/messages/{vendor_api_conversation.id}/preferences", json={"email_notifications": True, "muted": False}, headers=vendor_user_headers, ) assert response.status_code == 200 data = response.json() assert data["success"] is True