diff --git a/backend/tests/test_routines.py b/backend/tests/test_routines.py index 78b1af6..8b63df1 100644 --- a/backend/tests/test_routines.py +++ b/backend/tests/test_routines.py @@ -1,4 +1,5 @@ import uuid +from unittest.mock import patch # --------------------------------------------------------------------------- # Routines @@ -217,12 +218,17 @@ def test_delete_grooming_schedule_not_found(client): r = client.delete(f"/routines/grooming-schedule/{uuid.uuid4()}") assert r.status_code == 404 -from unittest.mock import patch def test_suggest_routine(client, session): with patch("innercontext.api.routines.call_gemini") as mock_gemini: # Mock the Gemini response - mock_response = type("Response", (), {"text": '{"steps": [{"product_id": null, "action_type": "shaving_razor"}], "reasoning": "because"}'}) + mock_response = type( + "Response", + (), + { + "text": '{"steps": [{"product_id": null, "action_type": "shaving_razor"}], "reasoning": "because"}' + }, + ) mock_gemini.return_value = mock_response r = client.post( @@ -231,8 +237,8 @@ def test_suggest_routine(client, session): "routine_date": "2026-03-03", "part_of_day": "am", "notes": "Testing", - "include_minoxidil_beard": True - } + "include_minoxidil_beard": True, + }, ) assert r.status_code == 200 data = r.json() @@ -240,10 +246,17 @@ def test_suggest_routine(client, session): assert data["steps"][0]["action_type"] == "shaving_razor" assert data["reasoning"] == "because" + def test_suggest_batch(client, session): with patch("innercontext.api.routines.call_gemini") as mock_gemini: # Mock the Gemini response - mock_response = type("Response", (), {"text": '{"days": [{"date": "2026-03-03", "am_steps": [], "pm_steps": [], "reasoning": "none"}], "overall_reasoning": "batch test"}'}) + mock_response = type( + "Response", + (), + { + "text": '{"days": [{"date": "2026-03-03", "am_steps": [], "pm_steps": [], "reasoning": "none"}], "overall_reasoning": "batch test"}' + }, + ) mock_gemini.return_value = mock_response r = client.post( @@ -251,8 +264,8 @@ def test_suggest_batch(client, session): json={ "from_date": "2026-03-03", "to_date": "2026-03-04", - "minimize_products": True - } + "minimize_products": True, + }, ) assert r.status_code == 200 data = r.json() @@ -260,16 +273,18 @@ def test_suggest_batch(client, session): assert data["days"][0]["date"] == "2026-03-03" assert data["overall_reasoning"] == "batch test" + def test_suggest_batch_invalid_date_range(client): r = client.post( "/routines/suggest-batch", - json={"from_date": "2026-03-04", "to_date": "2026-03-03"} + json={"from_date": "2026-03-04", "to_date": "2026-03-03"}, ) assert r.status_code == 400 + def test_suggest_batch_too_long(client): r = client.post( "/routines/suggest-batch", - json={"from_date": "2026-03-01", "to_date": "2026-03-20"} + json={"from_date": "2026-03-01", "to_date": "2026-03-20"}, ) assert r.status_code == 400 diff --git a/backend/tests/test_routines_helpers.py b/backend/tests/test_routines_helpers.py index 5ad6ddd..029d539 100644 --- a/backend/tests/test_routines_helpers.py +++ b/backend/tests/test_routines_helpers.py @@ -1,7 +1,6 @@ from datetime import date, timedelta import uuid -import pytest from sqlmodel import Session from innercontext.api.routines import ( @@ -23,7 +22,6 @@ from innercontext.models import ( RoutineStep, ProductInventory, ) -from innercontext.models.enums import PartOfDay, GroomingAction def test_contains_minoxidil_text(): @@ -89,7 +87,7 @@ def test_build_skin_context(session: Session): barrier_state="intact", active_concerns=["acne", "dryness"], priorities=["hydration"], - notes="Feeling good" + notes="Feeling good", ) session.add(snap) session.commit() @@ -108,10 +106,7 @@ def test_build_grooming_context(session: Session): assert _build_grooming_context(session) == "GROOMING SCHEDULE: none\n" sch = GroomingSchedule( - id=uuid.uuid4(), - day_of_week=0, - action="shaving_oneblade", - notes="Morning" + id=uuid.uuid4(), day_of_week=0, action="shaving_oneblade", notes="Morning" ) session.add(sch) session.commit() @@ -121,27 +116,35 @@ def test_build_grooming_context(session: Session): assert "poniedziaƂek: shaving_oneblade (Morning)" in ctx # Test weekdays filter - ctx2 = _build_grooming_context(session, weekdays=[1]) # not monday + ctx2 = _build_grooming_context(session, weekdays=[1]) # not monday assert "(no entries for specified days)" in ctx2 def test_build_recent_history(session: Session): assert _build_recent_history(session) == "RECENT ROUTINES: none\n" - r = Routine( - id=uuid.uuid4(), - routine_date=date.today(), - part_of_day="am" - ) + r = Routine(id=uuid.uuid4(), routine_date=date.today(), part_of_day="am") session.add(r) - p = Product(id=uuid.uuid4(), name="Cleanser", category="cleanser", brand="Test", recommended_time="both", leave_on=False, product_effect_profile={}) + p = Product( + id=uuid.uuid4(), + name="Cleanser", + category="cleanser", + brand="Test", + recommended_time="both", + leave_on=False, + product_effect_profile={}, + ) session.add(p) session.commit() s1 = RoutineStep(id=uuid.uuid4(), routine_id=r.id, order_index=1, product_id=p.id) - s2 = RoutineStep(id=uuid.uuid4(), routine_id=r.id, order_index=2, action_type="shaving_razor") + s2 = RoutineStep( + id=uuid.uuid4(), routine_id=r.id, order_index=2, action_type="shaving_razor" + ) # Step with non-existent product - s3 = RoutineStep(id=uuid.uuid4(), routine_id=r.id, order_index=3, product_id=uuid.uuid4()) + s3 = RoutineStep( + id=uuid.uuid4(), routine_id=r.id, order_index=3, product_id=uuid.uuid4() + ) session.add_all([s1, s2, s3]) session.commit() @@ -160,19 +163,24 @@ def test_build_products_context(session: Session): name="Regaine", category="serum", is_medication=True, - brand="J&J", recommended_time="both", leave_on=True, product_effect_profile={} + brand="J&J", + recommended_time="both", + leave_on=True, + product_effect_profile={}, ) p2 = Product( id=uuid.uuid4(), name="Sunscreen", - category="spf", brand="Test", leave_on=True, + category="spf", + brand="Test", + leave_on=True, recommended_time="am", pao_months=6, product_effect_profile={"hydration_immediate": 2, "exfoliation_strength": 0}, incompatible_with=[{"target": "retinol", "scope": "same_routine"}], context_rules={"safe_after_shaving": False}, min_interval_hours=12, - max_frequency_per_week=7 + max_frequency_per_week=7, ) session.add_all([p1, p2]) session.commit() @@ -183,13 +191,9 @@ def test_build_products_context(session: Session): product_id=p2.id, is_opened=True, opened_at=date.today() - timedelta(days=10), - expiry_date=date.today() + timedelta(days=365) - ) - inv2 = ProductInventory( - id=uuid.uuid4(), - product_id=p2.id, - is_opened=False + expiry_date=date.today() + timedelta(days=365), ) + inv2 = ProductInventory(id=uuid.uuid4(), product_id=p2.id, is_opened=False) session.add_all([inv1, inv2]) session.commit() @@ -201,16 +205,20 @@ def test_build_products_context(session: Session): session.add(s) session.commit() - ctx = _build_products_context(session, time_filter="am", reference_date=date.today()) + ctx = _build_products_context( + session, time_filter="am", reference_date=date.today() + ) # p1 is medication but not minoxidil (wait, Regaine name doesn't contain minoxidil!) -> skipped assert "Regaine" not in ctx - + # Let's fix p1 to be minoxidil p1.name = "Regaine Minoxidil" session.add(p1) session.commit() - - ctx = _build_products_context(session, time_filter="am", reference_date=date.today()) + + ctx = _build_products_context( + session, time_filter="am", reference_date=date.today() + ) assert "Regaine Minoxidil" in ctx assert "Sunscreen" in ctx assert "inventory_status={active:2,opened:1,sealed:1}" in ctx