diff --git a/src/cronometer_api_mcp/client.py b/src/cronometer_api_mcp/client.py index d645527..928db09 100644 --- a/src/cronometer_api_mcp/client.py +++ b/src/cronometer_api_mcp/client.py @@ -728,14 +728,29 @@ def create_custom_food( "defaultMeasureId": 0, "comments": None, "alternateId": None, + # The first measure becomes the server-assigned default. "measures": [ { "id": 0, "name": serving_name, "value": serving_grams, "amount": 1.0, - "type": "Atomic", - } + "type": "Weight", + }, + { + "id": 0, + "name": "g", + "value": 1.0, + "amount": 1.0, + "type": "Weight", + }, + { + "id": 0, + "name": "oz", + "value": _OZ_GRAMS, + "amount": 1.0, + "type": "Weight", + }, ], "labelType": "AMERICAN_2016", "nutrients": nutrients, diff --git a/tests/test_client.py b/tests/test_client.py index f7deff8..4aa9894 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -868,10 +868,40 @@ def test_import_recipe_rejects_blank_input(tmp_path, monkeypatch): # --------------------------------------------------------------------------- -# create_custom_food: extra_nutrients +# create_custom_food # --------------------------------------------------------------------------- +@pytest.mark.parametrize("serving_grams", [100.0, 200.0]) +def test_create_custom_food_supports_weight_units(tmp_path, serving_grams): + client, state = make_cold_client(tmp_path, [{"result": "SUCCESS", "id": 555}]) + + client.create_custom_food( + "Test Food", + calories=200, + protein_g=10, + fat_g=5, + carbs_g=20, + serving_name="plate", + serving_grams=serving_grams, + ) + + data = state["payloads"][0]["data"] + serving, grams, ounces = data["measures"] + assert [m["name"] for m in data["measures"]] == ["plate", "g", "oz"] + assert all(m["type"] == "Weight" for m in data["measures"]) + assert all(m["amount"] == 1.0 for m in data["measures"]) + assert serving["value"] == serving_grams + assert grams["value"] == 1.0 + assert ounces["value"] == pytest.approx(28.3495231) + + nutrients = {n["id"]: n["amount"] for n in data["nutrients"]} + assert nutrients[208] == 200 * 100 / serving_grams + assert nutrients[203] == 10 * 100 / serving_grams + assert nutrients[204] == 5 * 100 / serving_grams + assert nutrients[205] == 20 * 100 / serving_grams + + def test_create_custom_food_extra_nutrients_payload(tmp_path): """extra_nutrients are appended, normalized to per-100g like the macros.""" client, state = make_cold_client(tmp_path, [{"result": "SUCCESS", "id": 555}]) diff --git a/tests/test_custom_food_edit.py b/tests/test_custom_food_edit.py index 1a3eff2..e66e1f8 100644 --- a/tests/test_custom_food_edit.py +++ b/tests/test_custom_food_edit.py @@ -168,6 +168,34 @@ def test_update_custom_food_serving_overrides_measure_and_scale(tmp_path): assert nutrients_by_id(state["payloads"][1])[208] == 200.0 # 400 per 200 g +def test_update_custom_food_preserves_weight_units(tmp_path): + food = custom_food() + food["measures"][0]["type"] = "Weight" + weight_units = [ + {"id": 901, "name": "g", "amount": 1, "value": 1, "type": "Weight"}, + { + "id": 902, + "name": "oz", + "amount": 1, + "value": 28.3495231, + "type": "Weight", + }, + ] + food["measures"].extend(dict(unit) for unit in weight_units) + client, state = make_cold_client(tmp_path, [food, OK]) + + client.update_custom_food( + FOOD_ID, serving_name="plate", serving_grams=200, calories=400 + ) + + data = state["payloads"][1]["data"] + assert data["defaultMeasureId"] == 900 + assert data["measures"][0]["id"] == 900 + assert data["measures"][0]["value"] == 200 + assert data["measures"][1:] == weight_units + assert nutrients_by_id(state["payloads"][1])[208] == 200 + + def weight_default_food() -> dict: """A food first saved as "400 g": its default measure is 400 units of a Weight measure, which the app renders as "400 "."""