# tests/conftest.py import uuid from datetime import datetime, timezone from typing import Dict import pytest from app.models import Event, GiftItem, GiftStatus, GiftPriority, GiftCategory, GiftPurchase, RSVP, RSVPStatus, \ EventMedia, MediaType, MediaPurpose, \ EventTheme, Guest, GuestStatus, ActivityType, ActivityLog, EmailTemplate, TemplateType, NotificationLog, \ NotificationType, NotificationStatus from app.models.user import User from app.utils.test_utils import setup_test_db, teardown_test_db, setup_async_test_db, teardown_async_test_db @pytest.fixture(scope="function") def db_session(): """ Creates a fresh SQLite in-memory database for each test function. Yields a SQLAlchemy session that can be used for testing. """ # Set up the database test_engine, TestingSessionLocal = setup_test_db() # Create a session with TestingSessionLocal() as session: yield session # Clean up teardown_test_db(test_engine) @pytest.fixture(scope="function") # Define a fixture async def async_test_db(): """Fixture provides new testing engine and session for each test run to improve isolation.""" test_engine, AsyncTestingSessionLocal = await setup_async_test_db() yield test_engine, AsyncTestingSessionLocal await teardown_async_test_db(test_engine) @pytest.fixture def user_create_data(): return { "email": "newtest@example.com", # Changed to avoid conflict with mock_user "password": "TestPassword123!", "first_name": "Test", "last_name": "User", "phone_number": "+1234567890", "is_superuser": False, "preferences": None } @pytest.fixture def mock_user(db_session): """Fixture to create and return a mock User instance.""" mock_user = User( id=uuid.uuid4(), email="mockuser@example.com", password_hash="mockhashedpassword", first_name="Mock", last_name="User", phone_number="1234567890", is_active=True, is_superuser=False, preferences=None, ) db_session.add(mock_user) db_session.commit() return mock_user @pytest.fixture def event_fixture(db_session, mock_user): """ Fixture to create and return an Event instance with valid data. """ event = Event( id=uuid.uuid4(), title="Birthday Party", slug="birthday-party-1", # Required unique slug description="A special 1st birthday celebration event.", event_date=datetime(2023, 12, 25, tzinfo=timezone.utc), timezone="UTC", # Required timezone created_by=mock_user.id, # Reference to a valid mock_user is_public=False, # Default value is_active=True, # Default value rsvp_enabled=False, # Default value gift_registry_enabled=True, # Default value updates_enabled=True # Default value ) db_session.add(event) db_session.commit() return event @pytest.fixture def gift_item_fixture(db_session, mock_user): """ Fixture to create and return a default GiftItem instance. The event_id, added_by, and other necessary attributes are predefined. """ gift_item = GiftItem( id=uuid.uuid4(), event_id=uuid.uuid4(), added_by=mock_user.id, name="Default Gift", description="Default gift description.", price=100.00, currency="USD", quantity_requested=5, quantity_received=0, status=GiftStatus.AVAILABLE, priority=GiftPriority.MEDIUM, is_visible=True ) db_session.add(gift_item) db_session.commit() return gift_item @pytest.fixture def rsvp_fixture(db_session, mock_user): """ Fixture to create and return a default RSVP instance. The event_id and guest_id fields are predefined for testing. """ rsvp = RSVP( id=uuid.uuid4(), event_id=uuid.uuid4(), guest_id=uuid.uuid4(), status=RSVPStatus.ATTENDING, number_of_guests=2, response_message="Looking forward to the event!", dietary_requirements="Vegetarian", ) db_session.add(rsvp) db_session.commit() return rsvp @pytest.fixture def event_media_fixture(db_session, mock_user): """ Fixture to create and return a default EventMedia instance. """ event_media = EventMedia( id=uuid.uuid4(), event_id=uuid.uuid4(), uploaded_by=mock_user.id, file_path="uploads/sample.jpg", original_filename="sample.jpg", media_type=MediaType.IMAGE, content_type="image/jpeg", file_size=2048, purpose=MediaPurpose.GALLERY, is_public=True, display_order=1, title="Sample Image", description="A sample image for testing.", media_metadata={"resolution": "1920x1080"}, ) db_session.add(event_media) db_session.commit() return event_media @pytest.fixture def event_theme_fixture(db_session): """ Fixture to create and return a default EventTheme instance. """ event_theme = EventTheme( id=uuid.uuid4(), name="Animal Theme", description="An animal-themed design for events.", preview_image_url="https://example.com/preview/animal_theme.jpg", color_palette={ "primary": "#ff5722", "secondary": "#4caf50", "background": "#ffffff", "text": "#000000" }, fonts={ "header": "Roboto", "body": "Open Sans" } ) db_session.add(event_theme) db_session.commit() return event_theme @pytest.fixture def guest_fixture(db_session, mock_user): """ Fixture to create and return a default Guest instance. """ guest = Guest( id=uuid.uuid4(), event_id=uuid.uuid4(), invited_by=mock_user.id, full_name="John Doe", email="johndoe@example.com", phone="1234567890", invitation_code="INV123456", status=GuestStatus.INVITED, max_additional_guests=2, actual_additional_guests=1, invitation_sent_at=datetime.now(timezone.utc), dietary_restrictions="None", notes="VIP Guest", custom_fields={"allergies": "None", "special_request": "Near the stage"}, is_blocked=False, can_bring_guests=True, ) db_session.add(guest) db_session.commit() return guest @pytest.fixture def activity_log_fixture(db_session, mock_user, guest_fixture): """ Fixture to create and return a default ActivityLog entry. """ activity_log_entry = ActivityLog( id=uuid.uuid4(), activity_type=ActivityType.USER_LOGIN, description="User successfully logged in.", event_id=None, user_id=mock_user.id, guest_id=None, target_id=None, target_type=None, ip_address="192.168.1.1", user_agent="Mozilla/5.0", activity_data={"extra_info": "Login from web app"}, created_at=datetime.now(timezone.utc) ) db_session.add(activity_log_entry) db_session.commit() return activity_log_entry @pytest.fixture def email_template_fixture(db_session, mock_user): """ Fixture to create and return a default EmailTemplate instance. """ email_template = EmailTemplate( id=uuid.uuid4(), name="Invitation Template", description="A template for event invitations.", template_type=TemplateType.INVITATION, subject="You're invited to {{event_name}}!", html_content="

Welcome to {{event_name}}

We look forward to seeing you!

", text_content="Welcome to {{event_name}}. We look forward to seeing you!", variables={"event_name": "Birthday Party"}, event_id=None, # Global template created_by=mock_user.id, is_active=True, is_system=False, ) db_session.add(email_template) db_session.commit() return email_template @pytest.fixture def notification_log_fixture(db_session, email_template_fixture, guest_fixture): """ Fixture to create and return a default NotificationLog entry. """ notification_log = NotificationLog( id=uuid.uuid4(), notification_type=NotificationType.EMAIL, status=NotificationStatus.QUEUED, subject="You're invited!", content_preview="Join us for an unforgettable event.", template_id=email_template_fixture.id, event_id=guest_fixture.event_id, guest_id=guest_fixture.id, recipient="example@example.com", notification_metadata={"extra_info": "Email sent via SendGrid"}, ) db_session.add(notification_log) db_session.commit() return notification_log @pytest.fixture def gift_purchase_fixture(db_session, gift_item_fixture, guest_fixture): """ Fixture to create and return a GiftPurchase instance. """ gift_purchase = GiftPurchase( id=uuid.uuid4(), gift_id=gift_item_fixture.id, guest_id=guest_fixture.id, quantity=1, purchased_at=datetime.now(timezone.utc), purchase_price=25.0, purchase_currency="USD", notes="Gift purchased through store link" ) db_session.add(gift_purchase) db_session.commit() return gift_purchase @pytest.fixture def gift_category_fixture(db_session, mock_user, event_fixture): """ Fixture to create and return a GiftCategory instance. """ gift_category = GiftCategory( id=uuid.uuid4(), name="Electronics", description="Category for electronic gifts", event_id=event_fixture.id, created_by=mock_user.id, display_order=0, is_visible=True ) db_session.add(gift_category) db_session.commit() return gift_category @pytest.fixture def theme_data() -> Dict: return { "name": "Animal Safari", "description": "A wild and fun theme with safari animals", "preview_image_url": "https://example.com/safari.jpg", "color_palette": { "primary": "#f4a261", "secondary": "#2a9d8f", "background": "#ffffff", "text": "#264653" }, "fonts": { "header": "Safari Display", "body": "Nunito Sans" } }