fixing db tables and onplace upgrde

This commit is contained in:
2025-10-02 05:46:58 -07:00
parent ed5839e222
commit 342eceff1f
9 changed files with 271 additions and 12 deletions

133
tests/test_add_food_bug.py Normal file
View File

@@ -0,0 +1,133 @@
import pytest
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from app.database import Base, Food, Meal, MealFood, TrackedDay, TrackedMeal, get_db
from main import app
from datetime import date
import os
import tempfile
@pytest.fixture(scope="function")
def test_engine():
"""Create a temporary test database engine 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)
yield engine
# Cleanup
os.close(db_fd)
os.unlink(db_path)
@pytest.fixture(scope="function")
def db_session(test_engine):
"""Provide a database session for tests using the test engine"""
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=test_engine)
session = TestingSessionLocal()
yield session
session.close()
@pytest.fixture(scope="function")
def test_client(test_engine):
"""Create a test client with test database"""
def override_get_db():
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=test_engine)
db = TestingSessionLocal()
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()
def test_add_food_quantity_saved_correctly(test_client: TestClient, test_engine):
"""
Test that the quantity from the add food endpoint is saved correctly as grams.
This test reproduces the bug where the backend expects "grams" but frontend sends "quantity".
"""
# Create a session for initial setup
setup_session = sessionmaker(autocommit=False, autoflush=False, bind=test_engine)()
try:
# Create a test food using setup session
food = Food(
name="Test Food",
serving_size=100.0,
serving_unit="g",
calories=100.0,
protein=10.0,
carbs=20.0,
fat=5.0
)
setup_session.add(food)
setup_session.commit()
setup_session.refresh(food)
# Simulate the frontend request: sends "quantity" key (as the frontend does)
response = test_client.post(
"/tracker/add_food",
json={
"person": "Sarah",
"date": date.today().isoformat(),
"food_id": food.id,
"quantity": 50.0, # User enters 50 grams
"meal_time": "Snack 1"
}
)
assert response.status_code == 200
data = response.json()
assert data["status"] == "success"
# Create a new session to query the committed data
query_session = sessionmaker(autocommit=False, autoflush=False, bind=test_engine)()
try:
# Find the created Meal
created_meal = query_session.query(Meal).order_by(Meal.id.desc()).first()
assert created_meal is not None
assert created_meal.name == "Test Food"
assert created_meal.meal_type == "single_food"
# Find the MealFood
meal_food = query_session.query(MealFood).filter(MealFood.meal_id == created_meal.id).first()
assert meal_food is not None
assert meal_food.food_id == food.id
# This assertion fails because the backend used data.get("grams", 1.0), so quantity=1.0 instead of 50.0
# After the fix changing to data.get("quantity", 1.0), it will pass
assert meal_food.quantity == 50.0, f"Expected quantity 50.0, but got {meal_food.quantity}"
# Also verify TrackedDay and TrackedMeal were created
tracked_day = query_session.query(TrackedDay).filter(
TrackedDay.person == "Sarah",
TrackedDay.date == date.today()
).first()
assert tracked_day is not None
assert tracked_day.is_modified is True
tracked_meal = query_session.query(TrackedMeal).filter(TrackedMeal.tracked_day_id == tracked_day.id).first()
assert tracked_meal is not None
assert tracked_meal.meal_id == created_meal.id
assert tracked_meal.meal_time == "Snack 1"
finally:
query_session.close()
finally:
setup_session.close()

View File

@@ -132,7 +132,7 @@ def test_tracker_add_food_grams_input(client, session, sample_food_100g):
"person": person,
"date": date_str,
"food_id": sample_food_100g.id,
"grams": grams, # 75 grams
"quantity": grams, # 75 grams
"meal_time": "Breakfast"
}
)

View File

@@ -389,7 +389,7 @@ class TestTrackerAddFood:
# Verify the food is in the tracked meal's foods
assert len(tracked_meal.meal.meal_foods) == 1
assert tracked_meal.meal.meal_foods[0].food_id == sample_food.id
assert tracked_meal.meal.meal_foods[0].quantity == 1.0
assert tracked_meal.meal.meal_foods[0].quantity == 100.0
def test_add_food_to_tracker_with_meal_time(self, client, sample_food, db_session):
@@ -404,7 +404,7 @@ class TestTrackerAddFood:
"person": "Sarah",
"date": date.today().isoformat(),
"food_id": sample_food.id,
"grams": 150.0,
"quantity": 150.0,
"meal_time": "Dinner"
})
assert response.status_code == 200
@@ -449,7 +449,7 @@ class TestTrackerAddFood:
"person": "Sarah",
"date": date.today().isoformat(),
"food_id": food.id,
"grams": grams_to_add,
"quantity": grams_to_add,
"meal_time": "Snack 1"
})
assert response.status_code == 200