import pytest from unittest.mock import patch from foods.sources.usda import ( USDAFoodAPI, NutritionCalculator, ) class TestUSDAFoodAPI: @pytest.fixture def usda_api(self): with patch("vrobbler.apps.foods.sources.usda.settings") as mock_settings: mock_settings.USDA_API_KEY = "test_api_key" return USDAFoodAPI(api_key="test_api_key") def test_extract_nutrients_with_nutrient_number(self, usda_api): food_data = { "description": "Test Food", "foodNutrients": [ { "nutrientNumber": "203", "nutrientName": "Protein", "value": 10.0, }, { "nutrientNumber": "204", "nutrientName": "Total lipid (fat)", "value": 5.0, }, { "nutrientNumber": "205", "nutrientName": "Carbohydrate, by difference", "value": 20.0, }, { "nutrientNumber": "208", "nutrientName": "Energy", "value": 150.0, }, { "nutrientNumber": "269", "nutrientName": "Sugars, total", "value": 5.0, }, ], } result = usda_api.extract_nutrients(food_data) assert result["protein"] == 10.0 assert result["fat"] == 5.0 assert result["carbohydrates"] == 20.0 assert result["calories"] == 150.0 assert result["sugar"] == 5.0 def test_extract_nutrients_with_nested_nutrient(self, usda_api): food_data = { "description": "Test Food", "foodNutrients": [ { "nutrient": {"id": 203, "name": "Protein"}, "value": 10.0, }, ], } result = usda_api.extract_nutrients(food_data) assert result["protein"] == 10.0 def test_extract_nutrients_with_empty_nutrients(self, usda_api): food_data = {"description": "Test Food", "foodNutrients": []} result = usda_api.extract_nutrients(food_data) assert result["protein"] == 0 assert result["calories"] == 0 def test_extract_nutrients_with_no_nutrients_key(self, usda_api): food_data = {"description": "Test Food"} result = usda_api.extract_nutrients(food_data) assert result["protein"] == 0 class TestNutritionCalculator: @pytest.fixture def calculator(self): with patch("vrobbler.apps.foods.sources.usda.USDAFoodAPI"): return NutritionCalculator() def test_parse_ingredient_with_fraction(self, calculator): result = calculator.parse_ingredient("1/2 cup flour") assert result["quantity"] == 0.5 assert result["unit"] == "cup" assert result["ingredient"] == "flour" def test_parse_ingredient_with_mixed_number(self, calculator): result = calculator.parse_ingredient("1 1/2 cups sugar") assert result["quantity"] == 1.5 assert result["unit"] == "cups" assert result["ingredient"] == "sugar" def test_parse_ingredient_with_decimal(self, calculator): result = calculator.parse_ingredient("0.5 tsp salt") assert result["quantity"] == 0.5 assert result["unit"] == "tsp" assert result["ingredient"] == "salt" def test_parse_ingredient_with_whole_number(self, calculator): result = calculator.parse_ingredient("3 eggs") assert result["quantity"] == 3 assert result["unit"] is None assert result["ingredient"] == "eggs" def test_parse_ingredient_with_no_quantity(self, calculator): result = calculator.parse_ingredient("salt to taste") assert result["quantity"] == 1 def test_clean_ingredient_name_removes_modifiers(self, calculator): result = calculator._clean_ingredient_name("fresh chopped onions") assert "fresh" not in result.lower() assert "chopped" not in result.lower() def test_clean_ingredient_name_removes_parentheses(self, calculator): result = calculator._clean_ingredient_name("flour (sifted)") assert "(" not in result assert ")" not in result def test_convert_to_grams_cup(self, calculator): result = calculator._convert_to_grams(2, "cups", "flour") assert result == 480 def test_convert_to_grams_tablespoon(self, calculator): result = calculator._convert_to_grams(3, "tbsp", "olive oil") assert result == 45 def test_convert_to_grams_unknown_unit(self, calculator): result = calculator._convert_to_grams(1, "unknown", "something") assert result == 100