- Refactor messaging API endpoints for admin, shop, and vendor - Add message-specific exceptions (ConversationNotFoundException, etc.) - Enhance messaging service with additional helper methods - Add comprehensive test fixtures for messaging - Add integration tests for admin and vendor messaging APIs - Add unit tests for messaging and attachment services 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
351 lines
10 KiB
Python
351 lines
10 KiB
Python
# 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.
|
|
"""
|
|
|
|
import pytest
|
|
|
|
from models.database.message import (
|
|
Conversation,
|
|
ConversationParticipant,
|
|
ConversationType,
|
|
Message,
|
|
MessageAttachment,
|
|
ParticipantType,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def test_conversation_admin_vendor(db, test_admin, test_vendor_user, test_vendor):
|
|
"""Create a test conversation between admin and vendor user."""
|
|
conversation = Conversation(
|
|
conversation_type=ConversationType.ADMIN_VENDOR,
|
|
subject="Test Admin-Vendor Conversation",
|
|
vendor_id=test_vendor.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 vendor participant
|
|
vendor_participant = ConversationParticipant(
|
|
conversation_id=conversation.id,
|
|
participant_type=ParticipantType.VENDOR,
|
|
participant_id=test_vendor_user.id,
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
db.add(vendor_participant)
|
|
|
|
db.commit()
|
|
db.refresh(conversation)
|
|
return conversation
|
|
|
|
|
|
@pytest.fixture
|
|
def test_conversation_vendor_customer(db, test_vendor_user, test_customer, test_vendor):
|
|
"""Create a test conversation between vendor and customer."""
|
|
conversation = Conversation(
|
|
conversation_type=ConversationType.VENDOR_CUSTOMER,
|
|
subject="Test Vendor-Customer Conversation",
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
db.add(conversation)
|
|
db.commit()
|
|
db.refresh(conversation)
|
|
|
|
# Add vendor participant
|
|
vendor_participant = ConversationParticipant(
|
|
conversation_id=conversation.id,
|
|
participant_type=ParticipantType.VENDOR,
|
|
participant_id=test_vendor_user.id,
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
db.add(vendor_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_vendor):
|
|
"""Create a test conversation between admin and customer."""
|
|
conversation = Conversation(
|
|
conversation_type=ConversationType.ADMIN_CUSTOMER,
|
|
subject="Test Admin-Customer Conversation",
|
|
vendor_id=test_vendor.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_vendor, test_admin):
|
|
"""Create a test message in a conversation."""
|
|
message = Message(
|
|
conversation_id=test_conversation_admin_vendor.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_vendor.message_count = 1
|
|
test_conversation_admin_vendor.last_message_at = message.created_at
|
|
|
|
db.commit()
|
|
db.refresh(message)
|
|
return message
|
|
|
|
|
|
@pytest.fixture
|
|
def test_message_with_attachment(db, test_conversation_admin_vendor, test_admin):
|
|
"""Create a test message with an attachment."""
|
|
message = Message(
|
|
conversation_id=test_conversation_admin_vendor.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_vendor_user, test_vendor):
|
|
"""Create a closed conversation."""
|
|
from datetime import datetime, timezone
|
|
|
|
conversation = Conversation(
|
|
conversation_type=ConversationType.ADMIN_VENDOR,
|
|
subject="Closed Conversation",
|
|
vendor_id=test_vendor.id,
|
|
is_closed=True,
|
|
closed_at=datetime.now(timezone.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)
|
|
|
|
vendor_participant = ConversationParticipant(
|
|
conversation_id=conversation.id,
|
|
participant_type=ParticipantType.VENDOR,
|
|
participant_id=test_vendor_user.id,
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
db.add(vendor_participant)
|
|
|
|
db.commit()
|
|
db.refresh(conversation)
|
|
return conversation
|
|
|
|
|
|
@pytest.fixture
|
|
def multiple_conversations(db, test_admin, test_vendor_user, test_customer, test_vendor):
|
|
"""Create multiple conversations of different types."""
|
|
conversations = []
|
|
|
|
# Create 3 admin-vendor conversations
|
|
for i in range(3):
|
|
conv = Conversation(
|
|
conversation_type=ConversationType.ADMIN_VENDOR,
|
|
subject=f"Admin-Vendor Conversation {i+1}",
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
db.add(conv)
|
|
db.commit()
|
|
db.refresh(conv)
|
|
|
|
db.add(
|
|
ConversationParticipant(
|
|
conversation_id=conv.id,
|
|
participant_type=ParticipantType.ADMIN,
|
|
participant_id=test_admin.id,
|
|
)
|
|
)
|
|
db.add(
|
|
ConversationParticipant(
|
|
conversation_id=conv.id,
|
|
participant_type=ParticipantType.VENDOR,
|
|
participant_id=test_vendor_user.id,
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
)
|
|
conversations.append(conv)
|
|
|
|
# Create 2 vendor-customer conversations
|
|
for i in range(2):
|
|
conv = Conversation(
|
|
conversation_type=ConversationType.VENDOR_CUSTOMER,
|
|
subject=f"Vendor-Customer Conversation {i+1}",
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
db.add(conv)
|
|
db.commit()
|
|
db.refresh(conv)
|
|
|
|
db.add(
|
|
ConversationParticipant(
|
|
conversation_id=conv.id,
|
|
participant_type=ParticipantType.VENDOR,
|
|
participant_id=test_vendor_user.id,
|
|
vendor_id=test_vendor.id,
|
|
)
|
|
)
|
|
db.add(
|
|
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 vendor_api_conversation(db, test_admin, test_vendor_user, test_vendor_with_vendor_user):
|
|
"""Create a conversation for vendor API tests (uses vendor from vendor_user_headers)."""
|
|
conversation = Conversation(
|
|
conversation_type=ConversationType.ADMIN_VENDOR,
|
|
subject="Vendor API Test Conversation",
|
|
vendor_id=test_vendor_with_vendor_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 vendor participant (uses test_vendor_user which vendor_user_headers uses)
|
|
vendor_participant = ConversationParticipant(
|
|
conversation_id=conversation.id,
|
|
participant_type=ParticipantType.VENDOR,
|
|
participant_id=test_vendor_user.id,
|
|
vendor_id=test_vendor_with_vendor_user.id,
|
|
)
|
|
db.add(vendor_participant)
|
|
|
|
db.commit()
|
|
db.refresh(conversation)
|
|
return conversation
|
|
|
|
|
|
@pytest.fixture
|
|
def vendor_api_closed_conversation(db, test_admin, test_vendor_user, test_vendor_with_vendor_user):
|
|
"""Create a closed conversation for vendor API tests."""
|
|
from datetime import datetime, timezone
|
|
|
|
conversation = Conversation(
|
|
conversation_type=ConversationType.ADMIN_VENDOR,
|
|
subject="Vendor API Closed Conversation",
|
|
vendor_id=test_vendor_with_vendor_user.id,
|
|
is_closed=True,
|
|
closed_at=datetime.now(timezone.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)
|
|
|
|
vendor_participant = ConversationParticipant(
|
|
conversation_id=conversation.id,
|
|
participant_type=ParticipantType.VENDOR,
|
|
participant_id=test_vendor_user.id,
|
|
vendor_id=test_vendor_with_vendor_user.id,
|
|
)
|
|
db.add(vendor_participant)
|
|
|
|
db.commit()
|
|
db.refresh(conversation)
|
|
return conversation
|