test_meal_math.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import unittest
  2. import httpx
  3. import json
  4. class TestMealMath(unittest.TestCase):
  5. BASE_URL = "http://192.168.130.171:8000/api"
  6. TOKEN = None
  7. FOOD_ID_1 = None # Will be populated
  8. FOOD_1_DATA = None
  9. @classmethod
  10. def setUpClass(cls):
  11. with httpx.Client(timeout=30.0) as client:
  12. # 1. Login to get token
  13. login_res = client.post(f"{cls.BASE_URL}/login", json={
  14. "username": "ferro988",
  15. "password": "password"
  16. })
  17. if login_res.status_code == 200:
  18. cls.TOKEN = login_res.json()["token"]
  19. # 2. Search for a baseline food (e.g., Chicken)
  20. search_res = client.get(f"{cls.BASE_URL}/food/search?q=Chicken", headers={
  21. "Authorization": f"Bearer {cls.TOKEN}"
  22. })
  23. if search_res.status_code == 200:
  24. foods = search_res.json()
  25. if foods:
  26. cls.FOOD_ID_1 = foods[0]["id"]
  27. cls.FOOD_1_DATA = foods[0]
  28. def test_baseline_100g(self):
  29. """Verify that 100g returns the exact database values."""
  30. payload = {"items": [{"food_id": self.FOOD_ID_1, "amount_g": 100}]}
  31. with httpx.Client(timeout=30.0) as client:
  32. res = client.post(f"{self.BASE_URL}/meal/calculate", json=payload, headers={
  33. "Authorization": f"Bearer {self.TOKEN}"
  34. })
  35. self.assertEqual(res.status_code, 200)
  36. data = res.json()
  37. # Check macros
  38. self.assertEqual(data["macros"]["calories"], self.FOOD_1_DATA["calories"])
  39. self.assertEqual(data["macros"]["protein_g"], self.FOOD_1_DATA["protein_g"])
  40. def test_half_portion_50g(self):
  41. """Verify that 50g returns exactly 50% of the database values."""
  42. payload = {"items": [{"food_id": self.FOOD_ID_1, "amount_g": 50}]}
  43. with httpx.Client(timeout=30.0) as client:
  44. res = client.post(f"{self.BASE_URL}/meal/calculate", json=payload, headers={
  45. "Authorization": f"Bearer {self.TOKEN}"
  46. })
  47. self.assertEqual(res.status_code, 200)
  48. data = res.json()
  49. expected_cal = round(self.FOOD_1_DATA["calories"] * 0.5, 2)
  50. expected_pro = round(self.FOOD_1_DATA["protein_g"] * 0.5, 2)
  51. self.assertEqual(data["macros"]["calories"], expected_cal)
  52. self.assertEqual(data["macros"]["protein_g"], expected_pro)
  53. def test_irregular_portion_237g(self):
  54. """Verify that 237g correctly applies the ratio (2.37x)."""
  55. payload = {"items": [{"food_id": self.FOOD_ID_1, "amount_g": 237}]}
  56. with httpx.Client(timeout=30.0) as client:
  57. res = client.post(f"{self.BASE_URL}/meal/calculate", json=payload, headers={
  58. "Authorization": f"Bearer {self.TOKEN}"
  59. })
  60. self.assertEqual(res.status_code, 200)
  61. data = res.json()
  62. ratio = 2.37
  63. expected_cal = round(self.FOOD_1_DATA["calories"] * ratio, 2)
  64. self.assertEqual(data["macros"]["calories"], expected_cal)
  65. def test_multi_item_aggregation(self):
  66. """Verify that two items sum up correctly."""
  67. with httpx.Client(timeout=30.0) as client:
  68. # Get a second food
  69. search_res = client.get(f"{self.BASE_URL}/food/search?q=Rice", headers={
  70. "Authorization": f"Bearer {self.TOKEN}"
  71. })
  72. food2 = search_res.json()[0]
  73. payload = {
  74. "items": [
  75. {"food_id": self.FOOD_ID_1, "amount_g": 100},
  76. {"food_id": food2["id"], "amount_g": 200}
  77. ]
  78. }
  79. res = client.post(f"{self.BASE_URL}/meal/calculate", json=payload, headers={
  80. "Authorization": f"Bearer {self.TOKEN}"
  81. })
  82. self.assertEqual(res.status_code, 200)
  83. data = res.json()
  84. expected_cal = round(self.FOOD_1_DATA["calories"] + (food2["calories"] * 2.0), 2)
  85. expected_weight = 100 + 200
  86. self.assertEqual(data["macros"]["calories"], expected_cal)
  87. self.assertEqual(data["total_weight_g"], expected_weight)
  88. if __name__ == "__main__":
  89. unittest.main()