Files
2026-07-01 11:20:13 +03:00

94 lines
3.1 KiB
Python

import unittest
from datetime import date, datetime, time, timedelta, timezone
from sqlalchemy import create_engine
from sqlalchemy.orm import Session, sessionmaker
from app.db.models import Base, FitnessProfile, FoodLog, User, WorkoutLog
from app.daily.metrics import plan_hit
from app.fitness.gamification import build_gamification, clear_gamification_cache
class GamificationTests(unittest.TestCase):
def setUp(self) -> None:
clear_gamification_cache()
self.engine = create_engine("sqlite:///:memory:")
Base.metadata.create_all(self.engine)
self.Session = sessionmaker(bind=self.engine)
with Session(self.engine) as db:
user = User(username="g1", api_token_hash="x")
db.add(user)
db.commit()
self.user_id = user.id
db.add(
FitnessProfile(
user_id=self.user_id,
goal="lose",
weekly_workouts=3,
calorie_target=2000,
)
)
db.commit()
def test_plan_hit_lose_goal(self) -> None:
self.assertTrue(
plan_hit(
{"calories": 1900},
{"calories": 2000},
"lose",
has_meals=True,
)
)
self.assertFalse(
plan_hit(
{"calories": 2200},
{"calories": 2000},
"lose",
has_meals=True,
)
)
def test_meal_streak_and_medals(self) -> None:
d1 = date(2026, 6, 16)
d2 = date(2026, 6, 17)
d3 = date(2026, 6, 18)
with Session(self.engine) as db:
for d in (d1, d2, d3):
db.add(
FoodLog(
user_id=self.user_id,
description="meal",
calories=1800,
logged_at=datetime.combine(d, time(12), tzinfo=timezone.utc),
)
)
db.commit()
result = build_gamification(db, self.user_id, end_day=d3)
self.assertEqual(result["streaks"]["meal_log"], 3)
meal_medal = next(m for m in result["medals"] if m["id"] == "meal_streak_3")
self.assertTrue(meal_medal["earned"])
def test_workout_week_goal_uses_profile(self) -> None:
d = date(2026, 6, 18)
with Session(self.engine) as db:
for i in range(3):
db.add(
WorkoutLog(
user_id=self.user_id,
title=f"w{i}",
duration_min=30,
logged_at=datetime.combine(
d - timedelta(days=i),
time(10),
tzinfo=timezone.utc,
),
)
)
db.commit()
result = build_gamification(db, self.user_id, end_day=d)
medal = next(m for m in result["medals"] if m["id"] == "workout_week_goal")
self.assertTrue(medal["earned"])
self.assertEqual(result["workouts"]["weekly_target"], 3)