# tests/fixtures/message_fixtures.py """ Messaging-related test fixtures. Note: Fixtures should NOT use db.expunge() as it breaks lazy loading. See tests/conftest.py for details on fixture best practices. """ from datetime import UTC import pytest from app.modules.messaging.models import ( Conversation, ConversationParticipant, ConversationType, Message, MessageAttachment, ParticipantType, ) @pytest.fixture def test_conversation_admin_store(db, test_admin, test_store_user, test_store): """Create a test conversation between admin and store user.""" conversation = Conversation( conversation_type=ConversationType.ADMIN_STORE, subject="Test Admin-Store Conversation", store_id=test_store.id, ) db.add(conversation) db.commit() db.refresh(conversation) # Add admin participant admin_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.ADMIN, participant_id=test_admin.id, ) db.add(admin_participant) # Add store participant store_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.STORE, participant_id=test_store_user.id, store_id=test_store.id, ) db.add(store_participant) db.commit() db.refresh(conversation) return conversation @pytest.fixture def test_conversation_store_customer(db, test_store_user, test_customer, test_store): """Create a test conversation between store and customer.""" conversation = Conversation( conversation_type=ConversationType.STORE_CUSTOMER, subject="Test Store-Customer Conversation", store_id=test_store.id, ) db.add(conversation) db.commit() db.refresh(conversation) # Add store participant store_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.STORE, participant_id=test_store_user.id, store_id=test_store.id, ) db.add(store_participant) # Add customer participant customer_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.CUSTOMER, participant_id=test_customer.id, ) db.add(customer_participant) db.commit() db.refresh(conversation) return conversation @pytest.fixture def test_conversation_admin_customer(db, test_admin, test_customer, test_store): """Create a test conversation between admin and customer.""" conversation = Conversation( conversation_type=ConversationType.ADMIN_CUSTOMER, subject="Test Admin-Customer Conversation", store_id=test_store.id, ) db.add(conversation) db.commit() db.refresh(conversation) # Add admin participant admin_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.ADMIN, participant_id=test_admin.id, ) db.add(admin_participant) # Add customer participant customer_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.CUSTOMER, participant_id=test_customer.id, ) db.add(customer_participant) db.commit() db.refresh(conversation) return conversation @pytest.fixture def test_message(db, test_conversation_admin_store, test_admin): """Create a test message in a conversation.""" message = Message( conversation_id=test_conversation_admin_store.id, sender_type=ParticipantType.ADMIN, sender_id=test_admin.id, content="This is a test message from admin.", ) db.add(message) # Update conversation stats test_conversation_admin_store.message_count = 1 test_conversation_admin_store.last_message_at = message.created_at db.commit() db.refresh(message) return message @pytest.fixture def test_message_with_attachment(db, test_conversation_admin_store, test_admin): """Create a test message with an attachment.""" message = Message( conversation_id=test_conversation_admin_store.id, sender_type=ParticipantType.ADMIN, sender_id=test_admin.id, content="This message has an attachment.", ) db.add(message) db.commit() db.refresh(message) attachment = MessageAttachment( message_id=message.id, filename="test_file_abc123.pdf", original_filename="test_document.pdf", file_path="/uploads/messages/2025/01/1/test_file_abc123.pdf", file_size=12345, mime_type="application/pdf", is_image=False, ) db.add(attachment) db.commit() db.refresh(message) return message @pytest.fixture def closed_conversation(db, test_admin, test_store_user, test_store): """Create a closed conversation.""" from datetime import datetime conversation = Conversation( conversation_type=ConversationType.ADMIN_STORE, subject="Closed Conversation", store_id=test_store.id, is_closed=True, closed_at=datetime.now(UTC), closed_by_type=ParticipantType.ADMIN, closed_by_id=test_admin.id, ) db.add(conversation) db.commit() db.refresh(conversation) # Add participants admin_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.ADMIN, participant_id=test_admin.id, ) db.add(admin_participant) store_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.STORE, participant_id=test_store_user.id, store_id=test_store.id, ) db.add(store_participant) db.commit() db.refresh(conversation) return conversation @pytest.fixture def multiple_conversations(db, test_admin, test_store_user, test_customer, test_store): """Create multiple conversations of different types.""" conversations = [] # Create 3 admin-store conversations for i in range(3): conv = Conversation( conversation_type=ConversationType.ADMIN_STORE, subject=f"Admin-Store Conversation {i+1}", store_id=test_store.id, ) db.add(conv) # noqa: PERF006 db.commit() db.refresh(conv) db.add( # noqa: PERF006 ConversationParticipant( conversation_id=conv.id, participant_type=ParticipantType.ADMIN, participant_id=test_admin.id, ) ) db.add( # noqa: PERF006 ConversationParticipant( conversation_id=conv.id, participant_type=ParticipantType.STORE, participant_id=test_store_user.id, store_id=test_store.id, ) ) conversations.append(conv) # Create 2 store-customer conversations for i in range(2): conv = Conversation( conversation_type=ConversationType.STORE_CUSTOMER, subject=f"Store-Customer Conversation {i+1}", store_id=test_store.id, ) db.add(conv) # noqa: PERF006 db.commit() db.refresh(conv) db.add( # noqa: PERF006 ConversationParticipant( conversation_id=conv.id, participant_type=ParticipantType.STORE, participant_id=test_store_user.id, store_id=test_store.id, ) ) db.add( # noqa: PERF006 ConversationParticipant( conversation_id=conv.id, participant_type=ParticipantType.CUSTOMER, participant_id=test_customer.id, ) ) conversations.append(conv) db.commit() # Refresh all for conv in conversations: db.refresh(conv) return conversations @pytest.fixture def store_api_conversation(db, test_admin, test_store_user, test_store_with_store_user): """Create a conversation for store API tests (uses store from store_user_headers).""" conversation = Conversation( conversation_type=ConversationType.ADMIN_STORE, subject="Store API Test Conversation", store_id=test_store_with_store_user.id, ) db.add(conversation) db.commit() db.refresh(conversation) # Add admin participant admin_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.ADMIN, participant_id=test_admin.id, ) db.add(admin_participant) # Add store participant (uses test_store_user which store_user_headers uses) store_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.STORE, participant_id=test_store_user.id, store_id=test_store_with_store_user.id, ) db.add(store_participant) db.commit() db.refresh(conversation) return conversation @pytest.fixture def store_api_closed_conversation(db, test_admin, test_store_user, test_store_with_store_user): """Create a closed conversation for store API tests.""" from datetime import datetime conversation = Conversation( conversation_type=ConversationType.ADMIN_STORE, subject="Store API Closed Conversation", store_id=test_store_with_store_user.id, is_closed=True, closed_at=datetime.now(UTC), closed_by_type=ParticipantType.ADMIN, closed_by_id=test_admin.id, ) db.add(conversation) db.commit() db.refresh(conversation) # Add participants admin_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.ADMIN, participant_id=test_admin.id, ) db.add(admin_participant) store_participant = ConversationParticipant( conversation_id=conversation.id, participant_type=ParticipantType.STORE, participant_id=test_store_user.id, store_id=test_store_with_store_user.id, ) db.add(store_participant) db.commit() db.refresh(conversation) return conversation