from __future__ import annotations from datetime import UTC, datetime, timedelta from unittest.mock import patch from uuid import uuid4 from innercontext.api.auth_deps import get_current_user from innercontext.auth import CurrentUser, IdentityData, TokenClaims from innercontext.models import Role from main import app def _user(subject: str, *, role: Role = Role.MEMBER) -> CurrentUser: claims = TokenClaims( issuer="https://auth.test", subject=subject, audience=("innercontext-web",), expires_at=datetime.now(UTC) + timedelta(hours=1), raw_claims={"iss": "https://auth.test", "sub": subject}, ) return CurrentUser( user_id=uuid4(), role=role, identity=IdentityData.from_claims(claims), claims=claims, ) def _set_current_user(user: CurrentUser) -> None: app.dependency_overrides[get_current_user] = lambda: user def test_suggest_uses_current_user_profile_and_visible_products_only(client): owner = _user("owner") other = _user("other") _set_current_user(owner) owner_profile = client.patch( "/profile", json={"birth_date": "1991-01-15", "sex_at_birth": "male"} ) owner_product = client.post( "/products", json={ "name": "Owner Serum", "brand": "Test", "category": "serum", "recommended_time": "both", "leave_on": True, }, ) assert owner_profile.status_code == 200 assert owner_product.status_code == 201 _set_current_user(other) other_profile = client.patch( "/profile", json={"birth_date": "1975-06-20", "sex_at_birth": "female"} ) other_product = client.post( "/products", json={ "name": "Other Serum", "brand": "Test", "category": "serum", "recommended_time": "both", "leave_on": True, }, ) assert other_profile.status_code == 200 assert other_product.status_code == 201 _set_current_user(owner) with patch( "innercontext.api.routines.call_gemini_with_function_tools" ) as mock_gemini: mock_response = type( "Response", (), { "text": '{"steps": [{"product_id": null, "action_type": "shaving_razor"}], "reasoning": "ok", "summary": {"primary_goal": "safe", "constraints_applied": [], "confidence": 0.7}}' }, ) mock_gemini.return_value = (mock_response, None) response = client.post( "/routines/suggest", json={ "routine_date": "2026-03-05", "part_of_day": "am", "include_minoxidil_beard": False, }, ) assert response.status_code == 200 kwargs = mock_gemini.call_args.kwargs prompt = kwargs["contents"] assert "Birth date: 1991-01-15" in prompt assert "Birth date: 1975-06-20" not in prompt assert "Owner Serum" in prompt assert "Other Serum" not in prompt handler = kwargs["function_handlers"]["get_product_details"] payload = handler( { "product_ids": [ owner_product.json()["id"], other_product.json()["id"], ] } ) assert len(payload["products"]) == 1 assert payload["products"][0]["name"] == "Owner Serum"