diff --git a/frontend/components/Domain/Household/GroupMealPlanRuleForm.vue b/frontend/components/Domain/Household/GroupMealPlanRuleForm.vue index 259e399ad00..5dfad408700 100644 --- a/frontend/components/Domain/Household/GroupMealPlanRuleForm.vue +++ b/frontend/components/Domain/Household/GroupMealPlanRuleForm.vue @@ -148,6 +148,27 @@ export default defineComponent({ label: i18n.tc("general.date-updated"), type: "date", }, + { + name: "nutrition.calories", + label: i18n.tc("recipe.calories"), + type: "number", + }, + { + name: "nutrition.carbohydrateContent", + label: i18n.tc("recipe.carbohydrate-content"), + type: "number", + }, + { + name: "nutrition.proteinContent", + label: i18n.tc("recipe.protein-content"), + type: "number", + }, + { + name: "nutrition.fatContent", + label: i18n.tc("recipe.fat-content"), + type: "number", + }, + ]; return { diff --git a/tests/integration_tests/user_household_tests/test_group_mealplan_rules.py b/tests/integration_tests/user_household_tests/test_group_mealplan_rules.py index 1405dbdab1a..97ac76f2d78 100644 --- a/tests/integration_tests/user_household_tests/test_group_mealplan_rules.py +++ b/tests/integration_tests/user_household_tests/test_group_mealplan_rules.py @@ -140,12 +140,20 @@ def test_group_mealplan_rules_delete(api_client: TestClient, unique_user: TestUs "qf_string, expected_code", [ ('tags.name CONTAINS ALL ["tag1","tag2"]', 200), + ("nutrition.calories >= 100", 200), + ("nutrition.fatContent <= 10", 200), + ("nutrition.proteinContent >= 40", 200), + ("nutrition.carbohydrateContent = 200", 200), ('badfield = "badvalue"', 422), ('recipe_category.id IN ["1"]', 422), ('created_at >= "not-a-date"', 422), ], ids=[ "valid qf", + "valid calorie filter", + "valid fat filter", + "valid protein filter", + "valid carb filter", "invalid field", "invalid UUID", "invalid date", diff --git a/tests/unit_tests/repository_tests/test_pagination.py b/tests/unit_tests/repository_tests/test_pagination.py index cdc4f725b28..651616895f4 100644 --- a/tests/unit_tests/repository_tests/test_pagination.py +++ b/tests/unit_tests/repository_tests/test_pagination.py @@ -167,7 +167,10 @@ def test_pagination_guides(unique_user: TestUser): next_params: dict = dict(parse_qsl(urlsplit(random_page_of_results.next).query)) # type: ignore assert int(next_params["page"]) == random_page + 1 - prev_params: dict = dict(parse_qsl(urlsplit(random_page_of_results.previous).query)) # type: ignore + prev_params: dict = dict( + # type: ignore + parse_qsl(urlsplit(random_page_of_results.previous).query) + ) assert int(prev_params["page"]) == random_page - 1 source_params = camelize(query.model_dump()) @@ -532,7 +535,7 @@ def test_pagination_filter_datetimes( # units are created in order with increasing createdAt values units_repo, unit_1, unit_2, unit_3 = query_units - ## GT + # GT past_dt: datetime = unit_1.created_at - timedelta(seconds=1) # type: ignore dt = past_dt.isoformat() query = PaginationQuery(page=1, per_page=-1, query_filter=f'createdAt>"{dt}"') @@ -574,7 +577,7 @@ def test_pagination_filter_datetimes( unit_ids = {unit.id for unit in unit_results} assert len(unit_ids) == 0 - ## GTE + # GTE past_dt = unit_1.created_at - timedelta(seconds=1) # type: ignore dt = past_dt.isoformat() query = PaginationQuery(page=1, per_page=-1, query_filter=f'createdAt>="{dt}"') @@ -937,7 +940,7 @@ def test_pagination_filter_dates(api_client: TestClient, unique_user: TestUser): response = api_client.post(api_routes.households_mealplans, json=data, headers=unique_user.token) assert response.status_code == 201 - ## Yesterday + # Yesterday params = { "page": 1, "perPage": -1, @@ -966,7 +969,7 @@ def test_pagination_filter_dates(api_client: TestClient, unique_user: TestUser): assert mealplan_today.title in fetched_mealplan_titles assert mealplan_tomorrow.title in fetched_mealplan_titles - ## Today + # Today params = { "page": 1, "perPage": -1, @@ -995,7 +998,7 @@ def test_pagination_filter_dates(api_client: TestClient, unique_user: TestUser): assert mealplan_today.title not in fetched_mealplan_titles assert mealplan_tomorrow.title in fetched_mealplan_titles - ## Tomorrow + # Tomorrow params = { "page": 1, "perPage": -1, @@ -1021,7 +1024,7 @@ def test_pagination_filter_dates(api_client: TestClient, unique_user: TestUser): assert len(response_json["items"]) == 0 - ## Day After Tomorrow + # Day After Tomorrow params = { "page": 1, "perPage": -1, @@ -1050,7 +1053,8 @@ def test_pagination_filter_booleans(query_units: tuple[RepositoryUnit, Ingredien query = PaginationQuery( page=1, per_page=-1, - query_filter=f"useAbbreviation=true AND id IN [{', '.join([str(unit.id) for unit in query_units[1:]])}]", + query_filter=f"useAbbreviation=true AND id IN [{ + ', '.join([str(unit.id) for unit in query_units[1:]])}]", ) unit_results = units_repo.page_all(query).items assert len(unit_results) == 1 @@ -1061,7 +1065,8 @@ def test_pagination_filter_advanced(query_units: tuple[RepositoryUnit, Ingredien units_repo, unit_1, unit_2, unit_3 = query_units dt = str(unit_3.created_at.isoformat()) # type: ignore - qf = f'name="test unit 1" OR (useAbbreviation=f AND (name="{unit_2.name}" OR createdAt > "{dt}"))' + qf = f'name="test unit 1" OR (useAbbreviation=f AND (name="{ + unit_2.name}" OR createdAt > "{dt}"))' query = PaginationQuery(page=1, per_page=-1, query_filter=qf) unit_results = units_repo.page_all(query).items @@ -1070,7 +1075,8 @@ def test_pagination_filter_advanced(query_units: tuple[RepositoryUnit, Ingredien assert unit_2.id in result_ids assert unit_3.id not in result_ids - qf = f'(name LIKE %_1 OR name IN ["{unit_2.name}"]) AND createdAt IS NOT NONE' + qf = f'(name LIKE %_1 OR name IN ["{ + unit_2.name}"]) AND createdAt IS NOT NONE' query = PaginationQuery(page=1, per_page=-1, query_filter=qf) unit_results = units_repo.page_all(query).items @@ -1185,7 +1191,8 @@ def test_pagination_filter_advanced_frontend_sort(unique_user: TestUser): repo = database.recipes - qf = f'recipeCategory.id IN ["{category_1.id}"] AND tools.id IN ["{tool_1.id}"]' + qf = f'recipeCategory.id IN ["{ + category_1.id}"] AND tools.id IN ["{tool_1.id}"]' query = PaginationQuery(page=1, per_page=-1, query_filter=qf) recipe_results = repo.page_all(query).items assert len(recipe_results) == 1 @@ -1198,7 +1205,8 @@ def test_pagination_filter_advanced_frontend_sort(unique_user: TestUser): assert recipe_ct0_tg2_tl2.id not in recipe_ids assert recipe_ct12_tg12_tl2.id not in recipe_ids - qf = f'recipeCategory.id CONTAINS ALL ["{category_1.id}", "{category_2.id}"] AND tags.id IN ["{tag_1.id}"]' + qf = f'recipeCategory.id CONTAINS ALL ["{category_1.id}", "{ + category_2.id}"] AND tags.id IN ["{tag_1.id}"]' query = PaginationQuery(page=1, per_page=-1, query_filter=qf) recipe_results = repo.page_all(query).items assert len(recipe_results) == 1 @@ -1211,7 +1219,8 @@ def test_pagination_filter_advanced_frontend_sort(unique_user: TestUser): assert recipe_ct0_tg2_tl2.id not in recipe_ids assert recipe_ct12_tg12_tl2.id in recipe_ids - qf = f'tags.id IN ["{tag_1.id}", "{tag_2.id}"] AND tools.id IN ["{tool_2.id}"]' + qf = f'tags.id IN ["{tag_1.id}", "{ + tag_2.id}"] AND tools.id IN ["{tool_2.id}"]' query = PaginationQuery(page=1, per_page=-1, query_filter=qf) recipe_results = repo.page_all(query).items assert len(recipe_results) == 2 @@ -1225,8 +1234,10 @@ def test_pagination_filter_advanced_frontend_sort(unique_user: TestUser): assert recipe_ct12_tg12_tl2.id in recipe_ids qf = ( - f'recipeCategory.id CONTAINS ALL ["{category_1.id}", "{category_2.id}"]' - f'AND tags.id IN ["{tag_1.id}", "{tag_2.id}"] AND tools.id IN ["{tool_1.id}", "{tool_2.id}"]' + f'recipeCategory.id CONTAINS ALL ["{ + category_1.id}", "{category_2.id}"]' + f'AND tags.id IN ["{tag_1.id}", "{ + tag_2.id}"] AND tools.id IN ["{tool_1.id}", "{tool_2.id}"]' ) query = PaginationQuery(page=1, per_page=-1, query_filter=qf) recipe_results = repo.page_all(query).items @@ -1266,6 +1277,7 @@ def test_pagination_filter_advanced_frontend_sort(unique_user: TestUser): 'group.preferences.badAttribute="test value"', id="bad double nested attribute", ), + pytest.param('nutrition.calories="test"', id="comparing int to string"), ], ) def test_malformed_query_filters(api_client: TestClient, unique_user: TestUser, qf: str):