mirror of
https://github.com/sstent/foodplanner.git
synced 2025-12-05 23:51:46 +00:00
sync - build workin
This commit is contained in:
193
tests/test_meals.py
Normal file
193
tests/test_meals.py
Normal file
@@ -0,0 +1,193 @@
|
||||
"""
|
||||
Tests for Meals CRUD operations
|
||||
"""
|
||||
import pytest
|
||||
import json
|
||||
|
||||
|
||||
class TestMealsRoutes:
|
||||
"""Test meal-related routes"""
|
||||
|
||||
def test_get_meals_page(self, client):
|
||||
"""Test GET /meals page"""
|
||||
response = client.get("/meals")
|
||||
assert response.status_code == 200
|
||||
assert b"Meals" in response.content or b"meals" in response.content
|
||||
|
||||
def test_add_meal(self, client):
|
||||
"""Test POST /meals/add"""
|
||||
response = client.post("/meals/add", data={
|
||||
"name": "New Test Meal",
|
||||
"meal_type": "lunch",
|
||||
"meal_time": "Lunch"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
assert "meal_id" in data
|
||||
|
||||
def test_edit_meal(self, client, sample_meal):
|
||||
"""Test POST /meals/edit"""
|
||||
response = client.post("/meals/edit", data={
|
||||
"meal_id": sample_meal.id,
|
||||
"name": "Updated Meal Name",
|
||||
"meal_type": "dinner",
|
||||
"meal_time": "Dinner"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_edit_nonexistent_meal(self, client):
|
||||
"""Test editing non-existent meal"""
|
||||
response = client.post("/meals/edit", data={
|
||||
"meal_id": 99999,
|
||||
"name": "Updated Meal Name",
|
||||
"meal_type": "dinner",
|
||||
"meal_time": "Dinner"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
def test_get_meal_details(self, client, sample_meal):
|
||||
"""Test GET /meals/{meal_id}"""
|
||||
response = client.get(f"/meals/{sample_meal.id}")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
assert data["id"] == sample_meal.id
|
||||
assert data["name"] == sample_meal.name
|
||||
|
||||
def test_get_nonexistent_meal_details(self, client):
|
||||
"""Test getting details for non-existent meal"""
|
||||
response = client.get("/meals/99999")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
def test_delete_meals(self, client, sample_meal):
|
||||
"""Test POST /meals/delete"""
|
||||
response = client.post("/meals/delete",
|
||||
json={"meal_ids": [sample_meal.id]})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
|
||||
class TestMealFoods:
|
||||
"""Test meal-food relationships"""
|
||||
|
||||
def test_get_meal_foods(self, client, sample_meal):
|
||||
"""Test GET /meals/{meal_id}/foods"""
|
||||
response = client.get(f"/meals/{sample_meal.id}/foods")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
if len(data) > 0:
|
||||
assert "food_id" in data[0]
|
||||
assert "quantity" in data[0]
|
||||
|
||||
def test_add_food_to_meal(self, client, sample_meal, sample_food):
|
||||
"""Test POST /meals/{meal_id}/add_food"""
|
||||
response = client.post(f"/meals/{sample_meal.id}/add_food", data={
|
||||
"food_id": sample_food.id,
|
||||
"quantity": 2.5
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_remove_food_from_meal(self, client, sample_meal, db_session):
|
||||
"""Test DELETE /meals/remove_food/{meal_food_id}"""
|
||||
# Get the first meal food
|
||||
from main import MealFood
|
||||
meal_food = db_session.query(MealFood).filter(
|
||||
MealFood.meal_id == sample_meal.id
|
||||
).first()
|
||||
|
||||
if meal_food:
|
||||
response = client.delete(f"/meals/remove_food/{meal_food.id}")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_remove_nonexistent_meal_food(self, client):
|
||||
"""Test removing non-existent meal food"""
|
||||
response = client.delete("/meals/remove_food/99999")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
|
||||
class TestMealsBulkUpload:
|
||||
"""Test bulk meal upload functionality"""
|
||||
|
||||
def test_bulk_upload_meals_csv(self, client, sample_foods, tmp_path):
|
||||
"""Test POST /meals/upload with CSV"""
|
||||
# Create test CSV file with meal recipes
|
||||
csv_content = f"""Meal Name,Food 1,Grams 1,Food 2,Grams 2
|
||||
Test Meal 1,{sample_foods[0].name},150,{sample_foods[1].name},200
|
||||
Test Meal 2,{sample_foods[1].name},100,{sample_foods[2].name},150"""
|
||||
|
||||
csv_file = tmp_path / "test_meals.csv"
|
||||
csv_file.write_text(csv_content)
|
||||
|
||||
with open(csv_file, 'rb') as f:
|
||||
response = client.post("/meals/upload",
|
||||
files={"file": ("test_meals.csv", f, "text/csv")})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "created" in data or "updated" in data or "errors" in data
|
||||
|
||||
def test_bulk_upload_meals_missing_food(self, client, tmp_path):
|
||||
"""Test bulk upload with missing food"""
|
||||
csv_content = """Meal Name,Food 1,Grams 1,Food 2,Grams 2
|
||||
Invalid Meal,Nonexistent Food,150,Another Fake Food,200"""
|
||||
|
||||
csv_file = tmp_path / "invalid_meals.csv"
|
||||
csv_file.write_text(csv_content)
|
||||
|
||||
with open(csv_file, 'rb') as f:
|
||||
response = client.post("/meals/upload",
|
||||
files={"file": ("invalid_meals.csv", f, "text/csv")})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "errors" in data
|
||||
assert len(data["errors"]) > 0
|
||||
|
||||
|
||||
class TestMealNutrition:
|
||||
"""Test meal nutrition calculations"""
|
||||
|
||||
def test_meal_nutrition_calculation(self, client, sample_meal, db_session):
|
||||
"""Test that meal nutrition is calculated correctly"""
|
||||
from main import calculate_meal_nutrition
|
||||
|
||||
nutrition = calculate_meal_nutrition(sample_meal, db_session)
|
||||
|
||||
assert "calories" in nutrition
|
||||
assert "protein" in nutrition
|
||||
assert "carbs" in nutrition
|
||||
assert "fat" in nutrition
|
||||
assert "fiber" in nutrition
|
||||
assert nutrition["calories"] > 0
|
||||
|
||||
def test_empty_meal_nutrition(self, client, db_session):
|
||||
"""Test nutrition calculation for empty meal"""
|
||||
from main import Meal, calculate_meal_nutrition
|
||||
|
||||
empty_meal = Meal(
|
||||
name="Empty Meal",
|
||||
meal_type="snack",
|
||||
meal_time="Snack 1"
|
||||
)
|
||||
db_session.add(empty_meal)
|
||||
db_session.commit()
|
||||
|
||||
nutrition = calculate_meal_nutrition(empty_meal, db_session)
|
||||
|
||||
assert nutrition["calories"] == 0
|
||||
assert nutrition["protein"] == 0
|
||||
184
tests/test_plans.py
Normal file
184
tests/test_plans.py
Normal file
@@ -0,0 +1,184 @@
|
||||
"""
|
||||
Tests for Plans CRUD operations
|
||||
"""
|
||||
import pytest
|
||||
from datetime import date, timedelta
|
||||
|
||||
|
||||
class TestPlansRoutes:
|
||||
"""Test plan-related routes"""
|
||||
|
||||
def test_get_plan_page(self, client):
|
||||
"""Test GET /plan page"""
|
||||
response = client.get("/plan?person=Sarah")
|
||||
assert response.status_code == 200
|
||||
assert b"Plan" in response.content or b"plan" in response.content
|
||||
|
||||
def test_get_plan_page_with_date(self, client):
|
||||
"""Test GET /plan page with specific date"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.get(f"/plan?person=Stuart&week_start_date={test_date}")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_add_to_plan(self, client, sample_meal):
|
||||
"""Test POST /plan/add"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/plan/add", data={
|
||||
"person": "Sarah",
|
||||
"plan_date": test_date,
|
||||
"meal_id": str(sample_meal.id),
|
||||
"meal_time": "Breakfast"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_add_to_plan_missing_fields(self, client):
|
||||
"""Test adding to plan with missing fields"""
|
||||
response = client.post("/plan/add", data={
|
||||
"person": "Sarah"
|
||||
# Missing plan_date, meal_id, meal_time
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
def test_add_to_plan_invalid_meal(self, client):
|
||||
"""Test adding non-existent meal to plan"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/plan/add", data={
|
||||
"person": "Sarah",
|
||||
"plan_date": test_date,
|
||||
"meal_id": "99999",
|
||||
"meal_time": "Breakfast"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
def test_get_day_plan(self, client, sample_plan):
|
||||
"""Test GET /plan/{person}/{date}"""
|
||||
test_date = sample_plan.date.isoformat()
|
||||
response = client.get(f"/plan/{sample_plan.person}/{test_date}")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "meals" in data
|
||||
assert "day_totals" in data
|
||||
assert isinstance(data["meals"], list)
|
||||
|
||||
def test_get_day_plan_empty(self, client):
|
||||
"""Test getting plan for day with no meals"""
|
||||
future_date = (date.today() + timedelta(days=365)).isoformat()
|
||||
response = client.get(f"/plan/Sarah/{future_date}")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "meals" in data
|
||||
assert len(data["meals"]) == 0
|
||||
|
||||
def test_update_day_plan(self, client, sample_meal):
|
||||
"""Test POST /plan/update_day"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/plan/update_day", data={
|
||||
"person": "Stuart",
|
||||
"date": test_date,
|
||||
"meal_ids": f"{sample_meal.id}"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_update_day_plan_multiple_meals(self, client, sample_meal, sample_foods, db_session):
|
||||
"""Test updating plan with multiple meals"""
|
||||
from main import Meal
|
||||
|
||||
# Create another meal
|
||||
meal2 = Meal(name="Second Meal", meal_type="lunch", meal_time="Lunch")
|
||||
db_session.add(meal2)
|
||||
db_session.commit()
|
||||
db_session.refresh(meal2)
|
||||
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/plan/update_day", data={
|
||||
"person": "Sarah",
|
||||
"date": test_date,
|
||||
"meal_ids": f"{sample_meal.id},{meal2.id}"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_remove_from_plan(self, client, sample_plan):
|
||||
"""Test DELETE /plan/{plan_id}"""
|
||||
response = client.delete(f"/plan/{sample_plan.id}")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_remove_nonexistent_plan(self, client):
|
||||
"""Test removing non-existent plan"""
|
||||
response = client.delete("/plan/99999")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
|
||||
class TestPlanNavigation:
|
||||
"""Test plan navigation functionality"""
|
||||
|
||||
def test_plan_week_navigation(self, client, sample_meal):
|
||||
"""Test navigating between weeks"""
|
||||
# Get current week
|
||||
response = client.get("/plan?person=Sarah")
|
||||
assert response.status_code == 200
|
||||
|
||||
# Add meal to today
|
||||
test_date = date.today().isoformat()
|
||||
client.post("/plan/add", data={
|
||||
"person": "Sarah",
|
||||
"plan_date": test_date,
|
||||
"meal_id": str(sample_meal.id),
|
||||
"meal_time": "Breakfast"
|
||||
})
|
||||
|
||||
# Get next week
|
||||
next_week = (date.today() + timedelta(days=7)).isoformat()
|
||||
response = client.get(f"/plan?person=Sarah&week_start_date={next_week}")
|
||||
assert response.status_code == 200
|
||||
|
||||
# Get previous week
|
||||
prev_week = (date.today() - timedelta(days=7)).isoformat()
|
||||
response = client.get(f"/plan?person=Sarah&week_start_date={prev_week}")
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
class TestDayNutrition:
|
||||
"""Test day nutrition calculations"""
|
||||
|
||||
def test_calculate_day_nutrition(self, client, sample_plan, db_session):
|
||||
"""Test day nutrition calculation"""
|
||||
from main import calculate_day_nutrition, Plan
|
||||
|
||||
plans = db_session.query(Plan).filter(
|
||||
Plan.person == sample_plan.person,
|
||||
Plan.date == sample_plan.date
|
||||
).all()
|
||||
|
||||
nutrition = calculate_day_nutrition(plans, db_session)
|
||||
|
||||
assert "calories" in nutrition
|
||||
assert "protein" in nutrition
|
||||
assert "carbs" in nutrition
|
||||
assert "fat" in nutrition
|
||||
assert "protein_pct" in nutrition
|
||||
assert "carbs_pct" in nutrition
|
||||
assert "fat_pct" in nutrition
|
||||
|
||||
def test_empty_day_nutrition(self, db_session):
|
||||
"""Test nutrition calculation for day with no meals"""
|
||||
from main import calculate_day_nutrition
|
||||
|
||||
nutrition = calculate_day_nutrition([], db_session)
|
||||
|
||||
assert nutrition["calories"] == 0
|
||||
assert nutrition["protein"] == 0
|
||||
assert nutrition["protein_pct"] == 0
|
||||
157
tests/test_templates.py
Normal file
157
tests/test_templates.py
Normal file
@@ -0,0 +1,157 @@
|
||||
import sys
|
||||
import os
|
||||
print(f"DEBUG: Running with Python executable: {sys.executable}")
|
||||
print(f"DEBUG: Python version: {sys.version}")
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from main import app, get_db, SessionLocal, engine, Base, Template, TemplateMeal, Meal, MealFood, Food
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
# Setup test database
|
||||
SQLALCHEMY_DATABASE_URL = "sqlite:///./test_meal_planner.db"
|
||||
test_engine = create_engine(SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False})
|
||||
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=test_engine)
|
||||
|
||||
@pytest.fixture(name="session")
|
||||
def session_fixture():
|
||||
Base.metadata.create_all(bind=test_engine)
|
||||
db = TestingSessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
Base.metadata.drop_all(bind=test_engine)
|
||||
|
||||
@pytest.fixture(name="client")
|
||||
def client_fixture(session):
|
||||
def override_get_db():
|
||||
yield session
|
||||
app.dependency_overrides[get_db] = override_get_db
|
||||
with TestClient(app) as client:
|
||||
yield client
|
||||
app.dependency_overrides.clear()
|
||||
|
||||
def test_templates_page(client, session):
|
||||
response = client.get("/templates")
|
||||
assert response.status_code == 200
|
||||
assert "Meal Templates" in response.text
|
||||
|
||||
def test_create_template(client, session):
|
||||
# Create a food and a meal first
|
||||
food1 = Food(name="Apple", serving_size="1", serving_unit="medium", calories=95, protein=0.5, carbs=25, fat=0.3)
|
||||
session.add(food1)
|
||||
session.commit()
|
||||
session.refresh(food1)
|
||||
|
||||
meal1 = Meal(name="Fruit Salad", meal_type="breakfast", meal_time="Breakfast")
|
||||
session.add(meal1)
|
||||
session.commit()
|
||||
session.refresh(meal1)
|
||||
|
||||
meal_food1 = MealFood(meal_id=meal1.id, food_id=food1.id, quantity=1.0)
|
||||
session.add(meal_food1)
|
||||
session.commit()
|
||||
|
||||
response = client.post(
|
||||
"/templates/create",
|
||||
data={"name": "Test Template", "meal_assignments": f"Breakfast:{meal1.id},Lunch:"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "success", "message": "Template created successfully"}
|
||||
|
||||
template = session.query(Template).filter(Template.name == "Test Template").first()
|
||||
assert template is not None
|
||||
assert len(template.template_meals) == 1
|
||||
assert template.template_meals[0].meal_time == "Breakfast"
|
||||
assert template.template_meals[0].meal_id == meal1.id
|
||||
|
||||
def test_create_template_duplicate_name(client, session):
|
||||
template = Template(name="Existing Template")
|
||||
session.add(template)
|
||||
session.commit()
|
||||
|
||||
response = client.post("/templates/create", data={"name": "Existing Template"})
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "error", "message": "Template with name 'Existing Template' already exists"}
|
||||
|
||||
def test_get_template_details(client, session):
|
||||
template = Template(name="Detail Template")
|
||||
session.add(template)
|
||||
session.commit()
|
||||
session.refresh(template)
|
||||
|
||||
response = client.get(f"/templates/{template.id}")
|
||||
assert response.status_code == 200
|
||||
assert response.json()["status"] == "success"
|
||||
assert response.json()["template"]["name"] == "Detail Template"
|
||||
|
||||
def test_update_template(client, session):
|
||||
food1 = Food(name="Orange", serving_size="1", serving_unit="medium", calories=62, protein=1.2, carbs=15.4, fat=0.2)
|
||||
session.add(food1)
|
||||
session.commit()
|
||||
session.refresh(food1)
|
||||
|
||||
meal1 = Meal(name="Orange Juice", meal_type="breakfast", meal_time="Breakfast")
|
||||
session.add(meal1)
|
||||
session.commit()
|
||||
session.refresh(meal1)
|
||||
|
||||
template = Template(name="Update Template")
|
||||
session.add(template)
|
||||
session.commit()
|
||||
session.refresh(template)
|
||||
|
||||
response = client.put(
|
||||
f"/templates/{template.id}",
|
||||
data={"name": "Updated Template Name", "meal_assignments": f"Breakfast:{meal1.id}"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "success", "message": "Template updated successfully"}
|
||||
|
||||
updated_template = session.query(Template).filter(Template.id == template.id).first()
|
||||
assert updated_template.name == "Updated Template Name"
|
||||
assert len(updated_template.template_meals) == 1
|
||||
assert updated_template.template_meals[0].meal_time == "Breakfast"
|
||||
assert updated_template.template_meals[0].meal_id == meal1.id
|
||||
|
||||
def test_delete_template(client, session):
|
||||
template = Template(name="Delete Template")
|
||||
session.add(template)
|
||||
session.commit()
|
||||
session.refresh(template)
|
||||
|
||||
response = client.delete(f"/templates/{template.id}")
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "success"}
|
||||
|
||||
deleted_template = session.query(Template).filter(Template.id == template.id).first()
|
||||
assert deleted_template is None
|
||||
|
||||
def test_use_template(client, session):
|
||||
food1 = Food(name="Banana", serving_size="1", serving_unit="medium", calories=105, protein=1.3, carbs=27, fat=0.4)
|
||||
session.add(food1)
|
||||
session.commit()
|
||||
session.refresh(food1)
|
||||
|
||||
meal1 = Meal(name="Banana Smoothie", meal_type="breakfast", meal_time="Breakfast")
|
||||
session.add(meal1)
|
||||
session.commit()
|
||||
session.refresh(meal1)
|
||||
|
||||
template = Template(name="Use Template")
|
||||
session.add(template)
|
||||
session.commit()
|
||||
session.refresh(template)
|
||||
|
||||
template_meal = TemplateMeal(template_id=template.id, meal_id=meal1.id, meal_time="Breakfast")
|
||||
session.add(template_meal)
|
||||
session.commit()
|
||||
|
||||
response = client.post(
|
||||
f"/templates/{template.id}/use",
|
||||
data={"person": "Sarah", "start_date": "2025-01-01"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert response.json() == {"status": "success", "message": "Template applied successfully"}
|
||||
215
tests/test_tracker.py
Normal file
215
tests/test_tracker.py
Normal file
@@ -0,0 +1,215 @@
|
||||
"""
|
||||
Tests for Tracker CRUD operations
|
||||
"""
|
||||
import pytest
|
||||
from datetime import date, timedelta
|
||||
|
||||
|
||||
class TestTrackerRoutes:
|
||||
"""Test tracker-related routes"""
|
||||
|
||||
def test_get_tracker_page(self, client):
|
||||
"""Test GET /tracker page"""
|
||||
response = client.get("/tracker?person=Sarah")
|
||||
assert response.status_code == 200
|
||||
assert b"Tracker" in response.content or b"tracker" in response.content
|
||||
|
||||
def test_get_tracker_page_with_date(self, client):
|
||||
"""Test GET /tracker page with specific date"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.get(f"/tracker?person=Stuart&date={test_date}")
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_tracker_add_meal(self, client, sample_meal):
|
||||
"""Test POST /tracker/add_meal"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/tracker/add_meal", data={
|
||||
"person": "Sarah",
|
||||
"date": test_date,
|
||||
"meal_id": str(sample_meal.id),
|
||||
"meal_time": "Breakfast",
|
||||
"quantity": "1.5"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_tracker_add_meal_default_quantity(self, client, sample_meal):
|
||||
"""Test adding meal with default quantity"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/tracker/add_meal", data={
|
||||
"person": "Stuart",
|
||||
"date": test_date,
|
||||
"meal_id": str(sample_meal.id),
|
||||
"meal_time": "Lunch"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_tracker_remove_meal(self, client, sample_tracked_day, db_session):
|
||||
"""Test DELETE /tracker/remove_meal/{tracked_meal_id}"""
|
||||
from main import TrackedMeal
|
||||
|
||||
tracked_meal = db_session.query(TrackedMeal).filter(
|
||||
TrackedMeal.tracked_day_id == sample_tracked_day.id
|
||||
).first()
|
||||
|
||||
if tracked_meal:
|
||||
response = client.delete(f"/tracker/remove_meal/{tracked_meal.id}")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_tracker_remove_nonexistent_meal(self, client):
|
||||
"""Test removing non-existent tracked meal"""
|
||||
response = client.delete("/tracker/remove_meal/99999")
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
|
||||
class TestTrackerTemplates:
|
||||
"""Test tracker template functionality"""
|
||||
|
||||
def test_tracker_save_template(self, client, sample_tracked_day):
|
||||
"""Test POST /tracker/save_template"""
|
||||
test_date = sample_tracked_day.date.isoformat()
|
||||
response = client.post("/tracker/save_template", data={
|
||||
"person": sample_tracked_day.person,
|
||||
"date": test_date,
|
||||
"template_name": "New Saved Template"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_tracker_save_template_no_meals(self, client):
|
||||
"""Test saving template from day with no meals"""
|
||||
future_date = (date.today() + timedelta(days=365)).isoformat()
|
||||
response = client.post("/tracker/save_template", data={
|
||||
"person": "Sarah",
|
||||
"date": future_date,
|
||||
"template_name": "Empty Template"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
def test_tracker_apply_template(self, client, sample_template):
|
||||
"""Test POST /tracker/apply_template"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/tracker/apply_template", data={
|
||||
"person": "Sarah",
|
||||
"date": test_date,
|
||||
"template_id": str(sample_template.id)
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_tracker_apply_nonexistent_template(self, client):
|
||||
"""Test applying non-existent template"""
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/tracker/apply_template", data={
|
||||
"person": "Sarah",
|
||||
"date": test_date,
|
||||
"template_id": "99999"
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
def test_tracker_apply_empty_template(self, client, db_session):
|
||||
"""Test applying template with no meals"""
|
||||
from main import Template
|
||||
|
||||
empty_template = Template(name="Empty Tracker Template")
|
||||
db_session.add(empty_template)
|
||||
db_session.commit()
|
||||
db_session.refresh(empty_template)
|
||||
|
||||
test_date = date.today().isoformat()
|
||||
response = client.post("/tracker/apply_template", data={
|
||||
"person": "Sarah",
|
||||
"date": test_date,
|
||||
"template_id": str(empty_template.id)
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
|
||||
class TestTrackerReset:
|
||||
"""Test tracker reset functionality"""
|
||||
|
||||
def test_tracker_reset_to_plan(self, client, sample_tracked_day):
|
||||
"""Test POST /tracker/reset_to_plan"""
|
||||
test_date = sample_tracked_day.date.isoformat()
|
||||
response = client.post("/tracker/reset_to_plan", data={
|
||||
"person": sample_tracked_day.person,
|
||||
"date": test_date
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "success"
|
||||
|
||||
def test_tracker_reset_nonexistent_day(self, client):
|
||||
"""Test resetting non-existent tracked day"""
|
||||
future_date = (date.today() + timedelta(days=365)).isoformat()
|
||||
response = client.post("/tracker/reset_to_plan", data={
|
||||
"person": "Sarah",
|
||||
"date": future_date
|
||||
})
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["status"] == "error"
|
||||
|
||||
|
||||
class TestTrackerNutrition:
|
||||
"""Test tracker nutrition calculations"""
|
||||
|
||||
def test_calculate_tracked_day_nutrition(self, client, sample_tracked_day, db_session):
|
||||
"""Test tracked day nutrition calculation"""
|
||||
from main import calculate_day_nutrition_tracked, TrackedMeal
|
||||
|
||||
tracked_meals = db_session.query(TrackedMeal).filter(
|
||||
TrackedMeal.tracked_day_id == sample_tracked_day.id
|
||||
).all()
|
||||
|
||||
nutrition = calculate_day_nutrition_tracked(tracked_meals, db_session)
|
||||
|
||||
assert "calories" in nutrition
|
||||
assert "protein" in nutrition
|
||||
assert "carbs" in nutrition
|
||||
assert "fat" in nutrition
|
||||
assert nutrition["calories"] >= 0
|
||||
|
||||
def test_tracked_day_with_quantity_multiplier(self, client, sample_meal, db_session):
|
||||
"""Test nutrition calculation with quantity multiplier"""
|
||||
from main import TrackedDay, TrackedMeal, calculate_day_nutrition_tracked
|
||||
|
||||
# Create tracked day with meal at 2x quantity
|
||||
tracked_day = TrackedDay(
|
||||
person="Sarah",
|
||||
date=date.today(),
|
||||
is_modified=True
|
||||
)
|
||||
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=2.0
|
||||
)
|
||||
db_session.add(tracked_meal)
|
||||
db_session.commit()
|
||||
|
||||
tracked_meals = [tracked_meal]
|
||||
nutrition = calculate_day_nutrition_tracked(tracked_meals, db_session)
|
||||
|
||||
# Should be double the base meal nutrition
|
||||
assert nutrition["calories"] > 0
|
||||
62
tests/test_weekly_menu.py
Normal file
62
tests/test_weekly_menu.py
Normal file
@@ -0,0 +1,62 @@
|
||||
"""
|
||||
Tests for Weekly Menu operations
|
||||
"""
|
||||
import pytest
|
||||
|
||||
|
||||
class TestWeeklyMenuRoutes:
|
||||
"""Test weekly menu-related routes"""
|
||||
|
||||
def test_get_weekly_menu_page(self, client):
|
||||
"""Test GET /weeklymenu page"""
|
||||
response = client.get("/weeklymenu")
|
||||
assert response.status_code == 200
|
||||
assert b"Weekly" in response.content or b"weekly" in response.content or b"Menu" in response.content
|
||||
|
||||
|
||||
class TestWeeklyMenuCRUD:
|
||||
"""Test weekly menu CRUD operations"""
|
||||
|
||||
def test_create_weekly_menu(self, client, db_session, sample_template):
|
||||
"""Test creating a weekly menu"""
|
||||
from main import WeeklyMenu, WeeklyMenuDay
|
||||
|
||||
weekly_menu = WeeklyMenu(name="Test Weekly Menu")
|
||||
db_session.add(weekly_menu)
|
||||
db_session.commit()
|
||||
db_session.refresh(weekly_menu)
|
||||
|
||||
# Add days to weekly menu
|
||||
for day in range(7):
|
||||
menu_day = WeeklyMenuDay(
|
||||
weekly_menu_id=weekly_menu.id,
|
||||
day_of_week=day,
|
||||
template_id=sample_template.id
|
||||
)
|
||||
db_session.add(menu_day)
|
||||
|
||||
db_session.commit()
|
||||
|
||||
assert weekly_menu.id is not None
|
||||
assert len(weekly_menu.weekly_menu_days) == 7
|
||||
|
||||
def test_weekly_menu_relationships(self, client, db_session, sample_template):
|
||||
"""Test weekly menu relationships"""
|
||||
from main import WeeklyMenu, WeeklyMenuDay
|
||||
|
||||
weekly_menu = WeeklyMenu(name="Relationship Test Menu")
|
||||
db_session.add(weekly_menu)
|
||||
db_session.commit()
|
||||
db_session.refresh(weekly_menu)
|
||||
|
||||
menu_day = WeeklyMenuDay(
|
||||
weekly_menu_id=weekly_menu.id,
|
||||
day_of_week=0, # Monday
|
||||
template_id=sample_template.id
|
||||
)
|
||||
db_session.add(menu_day)
|
||||
db_session.commit()
|
||||
|
||||
# Verify relationships
|
||||
assert menu_day.weekly_menu.id == weekly_menu.id
|
||||
assert menu_day.template.id == sample_template.id
|
||||
Reference in New Issue
Block a user