mirror of
https://github.com/mealie-recipes/mealie.git
synced 2024-12-22 03:51:21 -08:00
582 lines
22 KiB
Python
582 lines
22 KiB
Python
import random
|
|
from uuid import uuid4
|
|
|
|
import pytest
|
|
from fastapi.testclient import TestClient
|
|
|
|
from mealie.schema.recipe.recipe import Recipe
|
|
from mealie.schema.recipe.recipe_ingredient import IngredientFood, RecipeIngredient, SaveIngredientFood
|
|
from mealie.schema.recipe.recipe_settings import RecipeSettings
|
|
from mealie.schema.recipe.recipe_tool import RecipeToolOut, RecipeToolSave
|
|
from tests.utils import api_routes
|
|
from tests.utils.factories import random_int, random_string
|
|
from tests.utils.fixture_schemas import TestUser
|
|
|
|
|
|
def create_food(user: TestUser, on_hand: bool = False):
|
|
return user.repos.ingredient_foods.create(
|
|
SaveIngredientFood(id=uuid4(), name=random_string(), group_id=user.group_id, on_hand=on_hand)
|
|
)
|
|
|
|
|
|
def create_tool(user: TestUser, on_hand: bool = False):
|
|
return user.repos.tools.create(
|
|
RecipeToolSave(id=uuid4(), name=random_string(), group_id=user.group_id, on_hand=on_hand)
|
|
)
|
|
|
|
|
|
def create_recipe(
|
|
user: TestUser,
|
|
*,
|
|
foods: list[IngredientFood] | None = None,
|
|
tools: list[RecipeToolOut] | None = None,
|
|
disable_amount: bool = False,
|
|
**kwargs,
|
|
):
|
|
if foods:
|
|
ingredients = [RecipeIngredient(food_id=food.id, food=food) for food in foods]
|
|
else:
|
|
ingredients = []
|
|
|
|
recipe = user.repos.recipes.create(
|
|
Recipe(
|
|
user_id=user.user_id,
|
|
group_id=user.group_id,
|
|
name=kwargs.pop("name", random_string()),
|
|
recipe_ingredient=ingredients,
|
|
tools=tools or [],
|
|
settings=RecipeSettings(disable_amount=disable_amount),
|
|
**kwargs,
|
|
)
|
|
)
|
|
|
|
return recipe
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def base_recipes(unique_user: TestUser, h2_user: TestUser):
|
|
for user in [unique_user, h2_user]:
|
|
for _ in range(10):
|
|
create_recipe(
|
|
user,
|
|
foods=[create_food(user) for _ in range(random_int(5, 10))],
|
|
tools=[create_tool(user) for _ in range(random_int(5, 10))],
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("filter_foods", [True, False])
|
|
@pytest.mark.parametrize("filter_tools", [True, False])
|
|
def test_suggestion_filter(api_client: TestClient, unique_user: TestUser, filter_foods: bool, filter_tools: bool):
|
|
create_params: dict = {}
|
|
api_params: dict = {"maxMissingFoods": 0, "maxMissingTools": 0, "limit": 10}
|
|
if filter_foods:
|
|
known_food = create_food(unique_user)
|
|
create_params["foods"] = [known_food]
|
|
api_params["foods"] = [str(known_food.id)]
|
|
if filter_tools:
|
|
known_tool = create_tool(unique_user)
|
|
create_params["tools"] = [known_tool]
|
|
api_params["tools"] = [str(known_tool.id)]
|
|
|
|
recipes = [create_recipe(unique_user, **create_params) for _ in range(3)]
|
|
try:
|
|
expected_recipe_ids = {str(recipe.id) for recipe in recipes if recipe.id}
|
|
response = api_client.get(api_routes.recipes_suggestions, params=api_params, headers=unique_user.token)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
|
|
if not filter_foods and not filter_tools:
|
|
assert len(data["items"]) == 10
|
|
else:
|
|
assert len(data["items"]) == 3
|
|
for item in data["items"]:
|
|
assert item["recipe"]["id"] in expected_recipe_ids
|
|
assert item["missingFoods"] == []
|
|
assert item["missingTools"] == []
|
|
finally:
|
|
for recipe in recipes:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_food_suggestion_filter_with_max(api_client: TestClient, unique_user: TestUser):
|
|
food_1, food_2, food_3, food_4 = (create_food(unique_user) for _ in range(4))
|
|
recipe_exact = create_recipe(unique_user, foods=[food_1])
|
|
recipe_missing_one = create_recipe(unique_user, foods=[food_1, food_2])
|
|
recipe_missing_two = create_recipe(unique_user, foods=[food_1, food_2, food_3])
|
|
recipe_missing_three = create_recipe(unique_user, foods=[food_1, food_2, food_3, food_4])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 1, "includeFoodsOnHand": False, "foods": [str(food_1.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
fetched_recipe_ids = {item["recipe"]["id"] for item in data["items"]}
|
|
assert set(fetched_recipe_ids) == {str(recipe_exact.id), str(recipe_missing_one.id)}
|
|
for item in data["items"]:
|
|
missing_food_ids = [food["id"] for food in item["missingFoods"]]
|
|
if item["recipe"]["id"] == str(recipe_exact.id):
|
|
assert missing_food_ids == []
|
|
else:
|
|
assert missing_food_ids == [str(food_2.id)]
|
|
|
|
finally:
|
|
for recipe in [recipe_exact, recipe_missing_one, recipe_missing_two, recipe_missing_three]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_tool_suggestion_filter_with_max(api_client: TestClient, unique_user: TestUser):
|
|
tool_1, tool_2, tool_3, tool_4 = (create_tool(unique_user) for _ in range(4))
|
|
recipe_exact = create_recipe(unique_user, tools=[tool_1])
|
|
recipe_missing_one = create_recipe(unique_user, tools=[tool_1, tool_2])
|
|
recipe_missing_two = create_recipe(unique_user, tools=[tool_1, tool_2, tool_3])
|
|
recipe_missing_three = create_recipe(unique_user, tools=[tool_1, tool_2, tool_3, tool_4])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingTools": 1, "includeToolsOnHand": False, "tools": [str(tool_1.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
fetched_recipe_ids = {item["recipe"]["id"] for item in data["items"]}
|
|
assert set(fetched_recipe_ids) == {str(recipe_exact.id), str(recipe_missing_one.id)}
|
|
for item in data["items"]:
|
|
missing_tool_ids = [tool["id"] for tool in item["missingTools"]]
|
|
if item["recipe"]["id"] == str(recipe_exact.id):
|
|
assert missing_tool_ids == []
|
|
else:
|
|
assert missing_tool_ids == [str(tool_2.id)]
|
|
|
|
finally:
|
|
for recipe in [recipe_exact, recipe_missing_one, recipe_missing_two, recipe_missing_three]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_ignore_empty_food_filter(api_client: TestClient, unique_user: TestUser):
|
|
known_tool = create_tool(unique_user)
|
|
recipe = create_recipe(
|
|
unique_user, foods=[create_food(unique_user) for _ in range(random_int(3, 5))], tools=[known_tool]
|
|
)
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "maxMissingTools": 0, "tools": [str(known_tool.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert len(data["items"]) == 1
|
|
item = data["items"][0]
|
|
assert item["recipe"]["id"] == str(recipe.id)
|
|
assert item["missingFoods"] == []
|
|
assert item["missingTools"] == []
|
|
|
|
finally:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_ignore_empty_tool_filter(api_client: TestClient, unique_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
recipe = create_recipe(
|
|
unique_user, foods=[known_food], tools=[create_tool(unique_user) for _ in range(random_int(3, 5))]
|
|
)
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "maxMissingTools": 0, "foods": [str(known_food.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert len(data["items"]) == 1
|
|
item = data["items"][0]
|
|
assert item["recipe"]["id"] == str(recipe.id)
|
|
assert item["missingFoods"] == []
|
|
assert item["missingTools"] == []
|
|
|
|
finally:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
@pytest.mark.parametrize("include_on_hand", [True, False])
|
|
def test_include_foods_on_hand(api_client: TestClient, unique_user: TestUser, include_on_hand: bool):
|
|
on_hand_food = create_food(unique_user, on_hand=True)
|
|
off_hand_food = create_food(unique_user, on_hand=False)
|
|
recipe = create_recipe(unique_user, foods=[on_hand_food, off_hand_food])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={
|
|
"maxMissingFoods": 0,
|
|
"maxMissingTools": 0,
|
|
"includeFoodsOnHand": include_on_hand,
|
|
"foods": [str(off_hand_food.id)],
|
|
},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
if not include_on_hand:
|
|
assert len(data["items"]) == 0
|
|
else:
|
|
assert len(data["items"]) == 1
|
|
item = data["items"][0]
|
|
assert item["recipe"]["id"] == str(recipe.id)
|
|
assert item["missingFoods"] == []
|
|
|
|
finally:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
@pytest.mark.parametrize("include_on_hand", [True, False])
|
|
def test_include_tools_on_hand(api_client: TestClient, unique_user: TestUser, include_on_hand: bool):
|
|
on_hand_tool = create_tool(unique_user, on_hand=True)
|
|
off_hand_tool = create_tool(unique_user, on_hand=False)
|
|
recipe = create_recipe(unique_user, tools=[on_hand_tool, off_hand_tool])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={
|
|
"maxMissingFoods": 0,
|
|
"maxMissingTools": 0,
|
|
"includeToolsOnHand": include_on_hand,
|
|
"tools": [str(off_hand_tool.id)],
|
|
},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
if not include_on_hand:
|
|
assert len(data["items"]) == 0
|
|
else:
|
|
assert len(data["items"]) == 1
|
|
item = data["items"][0]
|
|
assert item["recipe"]["id"] == str(recipe.id)
|
|
assert item["missingTools"] == []
|
|
|
|
finally:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_exclude_recipes_with_no_foods(api_client: TestClient, unique_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
recipe_with_foods = create_recipe(unique_user, foods=[known_food])
|
|
recipe_without_foods = create_recipe(unique_user, foods=[])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "maxMissingTools": 0, "foods": [str(known_food.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert {item["recipe"]["id"] for item in data["items"]} == {str(recipe_with_foods.id)}
|
|
for item in data["items"]:
|
|
assert item["missingFoods"] == []
|
|
|
|
finally:
|
|
for recipe in [recipe_with_foods, recipe_without_foods]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_include_recipes_with_no_tools(api_client: TestClient, unique_user: TestUser):
|
|
known_tool = create_tool(unique_user)
|
|
recipe_with_tools = create_recipe(unique_user, tools=[known_tool])
|
|
recipe_without_tools = create_recipe(unique_user, tools=[])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "maxMissingTools": 0, "tools": [str(known_tool.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert {item["recipe"]["id"] for item in data["items"]} == {
|
|
str(recipe_with_tools.id),
|
|
str(recipe_without_tools.id),
|
|
}
|
|
for item in data["items"]:
|
|
assert item["missingTools"] == []
|
|
|
|
finally:
|
|
for recipe in [recipe_with_tools, recipe_without_tools]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_ignore_recipes_with_ingredient_amounts_disabled_with_foods(api_client: TestClient, unique_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
recipe_with_amounts = create_recipe(unique_user, foods=[known_food])
|
|
recipe_without_amounts = create_recipe(unique_user, foods=[known_food], disable_amount=True)
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "maxMissingTools": 0, "foods": [str(known_food.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert {item["recipe"]["id"] for item in data["items"]} == {str(recipe_with_amounts.id)}
|
|
for item in data["items"]:
|
|
assert item["missingFoods"] == []
|
|
|
|
finally:
|
|
for recipe in [recipe_with_amounts, recipe_without_amounts]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_include_recipes_with_ingredient_amounts_disabled_without_foods(api_client: TestClient, unique_user: TestUser):
|
|
known_tool = create_tool(unique_user)
|
|
recipe_with_amounts = create_recipe(unique_user, tools=[known_tool])
|
|
recipe_without_amounts = create_recipe(unique_user, tools=[known_tool], disable_amount=True)
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={
|
|
"maxMissingFoods": 0,
|
|
"maxMissingTools": 0,
|
|
"includeFoodsOnHand": False,
|
|
"tools": [str(known_tool.id)],
|
|
},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert {item["recipe"]["id"] for item in data["items"]} == {
|
|
str(recipe_with_amounts.id),
|
|
str(recipe_without_amounts.id),
|
|
}
|
|
for item in data["items"]:
|
|
assert item["missingFoods"] == []
|
|
|
|
finally:
|
|
for recipe in [recipe_with_amounts, recipe_without_amounts]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_exclude_recipes_with_no_user_foods(api_client: TestClient, unique_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
food_on_hand = create_food(unique_user, on_hand=True)
|
|
recipe_with_user_food = create_recipe(unique_user, foods=[known_food])
|
|
recipe_with_on_hand_food = create_recipe(unique_user, foods=[food_on_hand])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 10, "includeFoodsOnHand": True, "foods": [str(known_food.id)]},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert {item["recipe"]["id"] for item in data["items"]} == {str(recipe_with_user_food.id)}
|
|
assert data["items"][0]["missingFoods"] == []
|
|
|
|
finally:
|
|
for recipe in [recipe_with_user_food, recipe_with_on_hand_food]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_recipe_order(api_client: TestClient, unique_user: TestUser):
|
|
user_food_1, user_food_2, other_food_1, other_food_2, other_food_3 = (create_food(unique_user) for _ in range(5))
|
|
user_tool_1, other_tool_1, other_tool_2 = (create_tool(unique_user) for _ in range(3))
|
|
food_on_hand = create_food(unique_user, on_hand=True)
|
|
|
|
recipe_lambdas = [
|
|
# No missing tools or foods
|
|
(0, lambda: create_recipe(unique_user, tools=[user_tool_1], foods=[user_food_1])),
|
|
# No missing tools, one missing food
|
|
(1, lambda: create_recipe(unique_user, tools=[user_tool_1], foods=[user_food_1, other_food_1])),
|
|
# One missing tool, no missing foods
|
|
(2, lambda: create_recipe(unique_user, tools=[user_tool_1, other_tool_1], foods=[user_food_1])),
|
|
# One missing tool, one missing food
|
|
(3, lambda: create_recipe(unique_user, tools=[user_tool_1, other_tool_1], foods=[user_food_1, other_food_1])),
|
|
# Two missing tools, two missing foods, two user foods
|
|
(
|
|
4,
|
|
lambda: create_recipe(
|
|
unique_user,
|
|
tools=[user_tool_1, other_tool_1, other_tool_2],
|
|
foods=[user_food_1, user_food_2, other_food_1, other_food_2],
|
|
),
|
|
),
|
|
# Two missing tools, two missing foods, one user food
|
|
(
|
|
5,
|
|
lambda: create_recipe(
|
|
unique_user,
|
|
tools=[user_tool_1, other_tool_1, other_tool_2],
|
|
foods=[user_food_1, other_food_1, other_food_2],
|
|
),
|
|
),
|
|
# Two missing tools, three missing foods, two user foods, don't include food on hand
|
|
(
|
|
6,
|
|
lambda: create_recipe(
|
|
unique_user,
|
|
tools=[user_tool_1, other_tool_1, other_tool_2],
|
|
foods=[user_food_1, user_food_2, other_food_1, other_food_2, other_food_3],
|
|
),
|
|
),
|
|
# Two missing tools, three missing foods, one user food, include food on hand
|
|
(
|
|
7,
|
|
lambda: create_recipe(
|
|
unique_user,
|
|
tools=[user_tool_1, other_tool_1, other_tool_2],
|
|
foods=[food_on_hand, user_food_1, other_food_1, other_food_2, other_food_3],
|
|
),
|
|
),
|
|
]
|
|
|
|
# create recipes in a random order
|
|
random.shuffle(recipe_lambdas)
|
|
recipe_tuples: list[tuple[int, Recipe]] = []
|
|
for i, recipe_lambda in recipe_lambdas:
|
|
recipe_tuples.append((i, recipe_lambda()))
|
|
|
|
recipe_tuples.sort(key=lambda x: x[0])
|
|
recipes = [recipe_tuple[1] for recipe_tuple in recipe_tuples]
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={
|
|
"maxMissingFoods": 3,
|
|
"maxMissingTools": 3,
|
|
"includeFoodsOnHand": True,
|
|
"includeToolsOnHand": True,
|
|
"limit": 10,
|
|
"foods": [str(user_food_1.id), str(user_food_2.id)],
|
|
"tools": [str(user_tool_1.id)],
|
|
},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert len(data["items"]) == len(recipes)
|
|
for i, (item, recipe) in enumerate(zip(data["items"], recipes, strict=True)):
|
|
try:
|
|
assert item["recipe"]["id"] == str(recipe.id)
|
|
except AssertionError as e:
|
|
raise AssertionError(f"Recipe in position {i} was incorrect") from e
|
|
|
|
finally:
|
|
for recipe in recipes:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_respect_user_sort(api_client: TestClient, unique_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
|
|
# Create recipes with names A, B, C, D out of order
|
|
recipe_b = create_recipe(unique_user, foods=[known_food], name="B")
|
|
recipe_c = create_recipe(unique_user, foods=[known_food, create_food(unique_user)], name="C")
|
|
recipe_a = create_recipe(unique_user, foods=[known_food, create_food(unique_user)], name="A")
|
|
recipe_d = create_recipe(unique_user, foods=[known_food, create_food(unique_user)], name="D")
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 1, "foods": [str(known_food.id)], "orderBy": "name", "orderDirection": "desc"},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
|
|
data = response.json()
|
|
assert len(data["items"]) == 4
|
|
|
|
# "B" should come first because it matches all foods, even though the user sort would put it last
|
|
assert [item["recipe"]["name"] for item in data["items"]] == ["B", "D", "C", "A"]
|
|
|
|
finally:
|
|
for recipe in [recipe_a, recipe_b, recipe_c, recipe_d]:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_limit_param(api_client: TestClient, unique_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
limit = random_int(12, 20)
|
|
recipes = [create_recipe(unique_user, foods=[known_food]) for _ in range(limit)]
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "foods": [str(known_food.id)], "limit": limit},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
assert len(response.json()["items"]) == limit
|
|
|
|
finally:
|
|
for recipe in recipes:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_query_filter(api_client: TestClient, unique_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
recipes_with_prefix = [
|
|
create_recipe(unique_user, foods=[known_food], name=f"MY_PREFIX{random_string()}") for _ in range(10)
|
|
]
|
|
recipes_without_prefix = [
|
|
create_recipe(unique_user, foods=[known_food], name=f"MY_OTHER_PREFIX{random_string()}") for _ in range(10)
|
|
]
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "foods": [str(known_food.id)], "queryFilter": 'name LIKE "MY_PREFIX%"'},
|
|
headers=unique_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
assert len(response.json()["items"]) == len(recipes_with_prefix)
|
|
assert {item["recipe"]["id"] for item in response.json()["items"]} == {
|
|
str(recipe.id) for recipe in recipes_with_prefix
|
|
}
|
|
|
|
finally:
|
|
for recipe in recipes_with_prefix + recipes_without_prefix:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
|
|
|
|
def test_include_cross_household_recipes(api_client: TestClient, unique_user: TestUser, h2_user: TestUser):
|
|
known_food = create_food(unique_user)
|
|
recipe = create_recipe(unique_user, foods=[known_food])
|
|
other_recipe = create_recipe(h2_user, foods=[known_food])
|
|
|
|
try:
|
|
response = api_client.get(
|
|
api_routes.recipes_suggestions,
|
|
params={"maxMissingFoods": 0, "foods": [str(known_food.id)], "includeCrossHousehold": True},
|
|
headers=h2_user.token,
|
|
)
|
|
response.raise_for_status()
|
|
data = response.json()
|
|
assert len(data["items"]) == 2
|
|
assert {item["recipe"]["id"] for item in data["items"]} == {str(recipe.id), str(other_recipe.id)}
|
|
|
|
finally:
|
|
unique_user.repos.recipes.delete(recipe.slug)
|
|
h2_user.repos.recipes.delete(other_recipe.slug)
|