404 lines
12 KiB
Python
404 lines
12 KiB
Python
import uuid
|
|
from datetime import datetime, timezone, timedelta
|
|
from typing import Dict
|
|
from typing import Optional
|
|
|
|
import pytest
|
|
from fastapi import FastAPI
|
|
from fastapi.routing import APIRouter
|
|
from fastapi.security import OAuth2PasswordBearer
|
|
from fastapi.testclient import TestClient
|
|
from sqlalchemy.orm import Session
|
|
|
|
from app.api.dependencies.auth import get_current_user
|
|
from app.core.database import get_db
|
|
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_plugins = ["pytest_asyncio"]
|
|
|
|
@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 mock_superuser(db_session):
|
|
"""Fixture to create and return a mock User instance."""
|
|
mock_user = User(
|
|
id=uuid.uuid4(),
|
|
email="mocksuperuser@example.com",
|
|
password_hash="mockhashedpassword",
|
|
first_name="Mock",
|
|
last_name="SuperUser",
|
|
phone_number="1234567890",
|
|
is_active=True,
|
|
is_superuser=True,
|
|
preferences=None,
|
|
)
|
|
db_session.add(mock_user)
|
|
db_session.commit()
|
|
return mock_user
|
|
|
|
@pytest.fixture
|
|
def mock_event(db_session, mock_user):
|
|
"""Create a test event fixture."""
|
|
event_data = {
|
|
"title": "Birthday Party",
|
|
"slug": "birthday-party",
|
|
"description": "A test birthday party",
|
|
"event_date": datetime.now(tz=timezone.utc) + timedelta(days=30),
|
|
"timezone": "UTC",
|
|
"is_public": True, # Make sure this is set to True
|
|
"created_by": mock_user.id
|
|
}
|
|
|
|
event = Event(**event_data)
|
|
db_session.add(event)
|
|
db_session.commit()
|
|
db_session.refresh(event)
|
|
return event
|
|
|
|
|
|
@pytest.fixture
|
|
def gift_item_fixture(db_session, mock_user, mock_event):
|
|
"""
|
|
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=mock_event.id,
|
|
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",
|
|
background_image_url="https://example.com/preview/animal_theme.jpg",
|
|
foreground_image_url="https://example.com/preview/animal_theme.jpg",
|
|
is_active=True,
|
|
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, mock_event):
|
|
"""
|
|
Fixture to create and return a default Guest instance.
|
|
"""
|
|
guest = Guest(
|
|
id=uuid.uuid4(),
|
|
event_id=mock_event.id,
|
|
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="<h1>Welcome to {{event_name}}</h1><p>We look forward to seeing you!</p>",
|
|
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, mock_event):
|
|
"""
|
|
Fixture to create and return a GiftCategory instance.
|
|
"""
|
|
gift_category = GiftCategory(
|
|
id=uuid.uuid4(),
|
|
name="Electronics",
|
|
description="Category for electronic gifts",
|
|
event_id=mock_event.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"
|
|
}
|
|
}
|
|
|
|
|
|
@pytest.fixture
|
|
def oauth2_scheme():
|
|
"""Return the OAuth2PasswordBearer instance used by the app."""
|
|
return OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login")
|
|
|
|
@pytest.fixture
|
|
def create_test_client():
|
|
def _create_test_client(router: APIRouter, prefix: str, db_session, user):
|
|
from fastapi import FastAPI
|
|
app = FastAPI()
|
|
|
|
# Mimic your dependency overrides here
|
|
def get_db_override():
|
|
yield db_session
|
|
|
|
def get_current_user_override():
|
|
return user
|
|
|
|
# Include your router
|
|
app.include_router(router, prefix=prefix)
|
|
|
|
# Override dependencies
|
|
app.dependency_overrides[get_db] = get_db_override
|
|
app.dependency_overrides[get_current_user] = get_current_user_override
|
|
|
|
return TestClient(app)
|
|
|
|
return _create_test_client
|