Files
foodplanner/conftest.py
2025-09-29 09:08:24 -07:00

200 lines
4.7 KiB
Python

"""
Pytest configuration and fixtures for meal planner tests
"""
import pytest
import os
import tempfile
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from datetime import date, timedelta
# Import from main application
from main import app, Base, get_db, Food, Meal, MealFood, Plan, Template, TemplateMeal, WeeklyMenu, WeeklyMenuDay, TrackedDay, TrackedMeal
@pytest.fixture(scope="function")
def test_db():
"""Create a temporary test database for each test"""
# Create temporary database file
db_fd, db_path = tempfile.mkstemp(suffix='.db')
database_url = f"sqlite:///{db_path}"
# Create engine and tables
engine = create_engine(database_url, connect_args={"check_same_thread": False})
Base.metadata.create_all(bind=engine)
# Create session
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
yield TestingSessionLocal
# Cleanup
os.close(db_fd)
os.unlink(db_path)
@pytest.fixture(scope="function")
def db_session(test_db):
"""Provide a database session for tests"""
session = test_db()
try:
yield session
finally:
session.close()
@pytest.fixture(scope="function")
def client(test_db):
"""Create a test client with test database"""
def override_get_db():
db = test_db()
try:
yield db
finally:
db.close()
app.dependency_overrides[get_db] = override_get_db
with TestClient(app) as test_client:
yield test_client
app.dependency_overrides.clear()
@pytest.fixture
def sample_food(db_session):
"""Create a sample food item"""
food = Food(
name="Test Food",
serving_size="100",
serving_unit="g",
calories=200.0,
protein=10.0,
carbs=20.0,
fat=5.0,
fiber=2.0,
sugar=3.0,
sodium=100.0,
calcium=50.0,
source="manual",
brand="Test Brand"
)
db_session.add(food)
db_session.commit()
db_session.refresh(food)
return food
@pytest.fixture
def sample_foods(db_session):
"""Create multiple sample food items"""
foods = [
Food(
name=f"Food {i}",
serving_size="100",
serving_unit="g",
calories=100.0 * i,
protein=5.0 * i,
carbs=10.0 * i,
fat=2.0 * i,
fiber=1.0,
sugar=2.0,
sodium=50.0,
calcium=25.0,
source="manual",
brand=f"Brand {i}"
)
for i in range(1, 4)
]
for food in foods:
db_session.add(food)
db_session.commit()
for food in foods:
db_session.refresh(food)
return foods
@pytest.fixture
def sample_meal(db_session, sample_foods):
"""Create a sample meal with foods"""
meal = Meal(
name="Test Meal",
meal_type="breakfast",
meal_time="Breakfast"
)
db_session.add(meal)
db_session.commit()
db_session.refresh(meal)
# Add foods to meal
for i, food in enumerate(sample_foods[:2], 1):
meal_food = MealFood(
meal_id=meal.id,
food_id=food.id,
quantity=float(i)
)
db_session.add(meal_food)
db_session.commit()
db_session.refresh(meal)
return meal
@pytest.fixture
def sample_template(db_session, sample_meal):
"""Create a sample template"""
template = Template(name="Test Template")
db_session.add(template)
db_session.commit()
db_session.refresh(template)
template_meal = TemplateMeal(
template_id=template.id,
meal_id=sample_meal.id,
meal_time="Breakfast"
)
db_session.add(template_meal)
db_session.commit()
db_session.refresh(template)
return template
@pytest.fixture
def sample_plan(db_session, sample_meal):
"""Create a sample plan"""
plan = Plan(
person="Sarah",
date=date.today(),
meal_id=sample_meal.id,
meal_time="Breakfast"
)
db_session.add(plan)
db_session.commit()
db_session.refresh(plan)
return plan
@pytest.fixture
def sample_tracked_day(db_session, sample_meal):
"""Create a sample tracked day with meals"""
tracked_day = TrackedDay(
person="Sarah",
date=date.today(),
is_modified=False
)
db_session.add(tracked_day)
db_session.commit()
db_session.refresh(tracked_day)
tracked_meal = TrackedMeal(
tracked_day_id=tracked_day.id,
meal_id=sample_meal.id,
meal_time="Breakfast",
quantity=1.0
)
db_session.add(tracked_meal)
db_session.commit()
db_session.refresh(tracked_day)
return tracked_day