mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-08-05 13:35:23 +02:00
feat: Add Households to Mealie (#3970)
This commit is contained in:
parent
0c29cef17d
commit
eb170cc7e5
315 changed files with 6975 additions and 3577 deletions
|
@ -9,13 +9,15 @@ from tests.utils.fixture_schemas import TestUser
|
|||
|
||||
|
||||
@pytest.mark.parametrize("is_private_group", [True, False], ids=["private group", "public group"])
|
||||
def test_public_about_get_app_info(api_client: TestClient, is_private_group: bool, database: AllRepositories):
|
||||
def test_public_about_get_app_info(
|
||||
api_client: TestClient, is_private_group: bool, unfiltered_database: AllRepositories
|
||||
):
|
||||
settings = get_app_settings()
|
||||
group = database.groups.get_by_name(settings.DEFAULT_GROUP)
|
||||
group = unfiltered_database.groups.get_by_name(settings.DEFAULT_GROUP)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
unfiltered_database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
response = api_client.get(api_routes.app_about)
|
||||
as_dict = response.json()
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.core.config import get_app_settings
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.user.user import GroupInDB
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.assertion_helpers import assert_ignore_keys
|
||||
from tests.utils.factories import random_bool, random_string
|
||||
|
@ -29,21 +32,34 @@ def test_admin_create_group(api_client: TestClient, admin_user: TestUser):
|
|||
response = api_client.post(api_routes.admin_groups, json={"name": random_string()}, headers=admin_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
# verify preferences are set and the default household is created
|
||||
group = GroupInDB.model_validate(response.json())
|
||||
assert group.preferences and len(group.households) == 1
|
||||
created_household = group.households[0]
|
||||
assert created_household.name == get_app_settings().DEFAULT_HOUSEHOLD
|
||||
|
||||
response = api_client.get(api_routes.admin_households_item_id(created_household.id), headers=admin_user.token)
|
||||
assert response.status_code == 200
|
||||
assert response.json()["id"] == str(created_household.id)
|
||||
|
||||
# verify no extra households are created
|
||||
response = api_client.get(api_routes.admin_households, headers=admin_user.token, params={"page": 1, "perPage": -1})
|
||||
assert response.status_code == 200
|
||||
items = response.json()["items"]
|
||||
filtered_item_ids: list[str] = []
|
||||
for item in items:
|
||||
if item["groupId"] == str(group.id):
|
||||
filtered_item_ids.append(item["id"])
|
||||
|
||||
assert len(filtered_item_ids) == 1
|
||||
assert filtered_item_ids[0] == str(created_household.id)
|
||||
|
||||
|
||||
def test_admin_update_group(api_client: TestClient, admin_user: TestUser, unique_user: TestUser):
|
||||
update_payload = {
|
||||
"id": unique_user.group_id,
|
||||
"name": "New Name",
|
||||
"preferences": {
|
||||
"privateGroup": random_bool(),
|
||||
"firstDayOfWeek": 2,
|
||||
"recipePublic": random_bool(),
|
||||
"recipeShowNutrition": random_bool(),
|
||||
"recipeShowAssets": random_bool(),
|
||||
"recipeLandscapeView": random_bool(),
|
||||
"recipeDisableComments": random_bool(),
|
||||
"recipeDisableAmount": random_bool(),
|
||||
},
|
||||
"preferences": {"privateGroup": random_bool()},
|
||||
}
|
||||
|
||||
response = api_client.put(
|
||||
|
@ -57,18 +73,13 @@ def test_admin_update_group(api_client: TestClient, admin_user: TestUser, unique
|
|||
as_json = response.json()
|
||||
|
||||
assert as_json["name"] == update_payload["name"]
|
||||
assert_ignore_keys(as_json["preferences"], update_payload["preferences"])
|
||||
assert_ignore_keys(as_json["preferences"], update_payload["preferences"]) # type: ignore
|
||||
|
||||
|
||||
def test_admin_delete_group(api_client: TestClient, admin_user: TestUser, unique_user: TestUser):
|
||||
# Delete User
|
||||
response = api_client.delete(api_routes.admin_users_item_id(unique_user.user_id), headers=admin_user.token)
|
||||
def test_admin_delete_group(unfiltered_database: AllRepositories, api_client: TestClient, admin_user: TestUser):
|
||||
group = unfiltered_database.groups.create({"name": random_string()})
|
||||
response = api_client.delete(api_routes.admin_groups_item_id(group.id), headers=admin_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
# Delete Group
|
||||
response = api_client.delete(api_routes.admin_groups_item_id(unique_user.group_id), headers=admin_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
# Ensure Group is Deleted
|
||||
response = api_client.get(api_routes.admin_groups_item_id(unique_user.group_id), headers=admin_user.token)
|
||||
response = api_client.get(api_routes.admin_groups_item_id(group.id), headers=admin_user.token)
|
||||
assert response.status_code == 404
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.assertion_helpers import assert_ignore_keys
|
||||
from tests.utils.factories import random_bool, random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
def test_home_household_not_deletable(api_client: TestClient, admin_user: TestUser):
|
||||
response = api_client.delete(api_routes.admin_households_item_id(admin_user.household_id), headers=admin_user.token)
|
||||
assert response.status_code == 400
|
||||
|
||||
|
||||
def test_admin_household_routes_are_restricted(api_client: TestClient, unique_user: TestUser, admin_user: TestUser):
|
||||
response = api_client.get(api_routes.admin_households, headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
response = api_client.post(api_routes.admin_households, json={}, headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
response = api_client.get(api_routes.admin_households_item_id(admin_user.household_id), headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
response = api_client.get(api_routes.admin_households_item_id(admin_user.household_id), headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def test_admin_create_household(api_client: TestClient, admin_user: TestUser):
|
||||
response = api_client.post(
|
||||
api_routes.admin_households,
|
||||
json={"name": random_string(), "groupId": admin_user.group_id},
|
||||
headers=admin_user.token,
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
|
||||
def test_admin_update_household(api_client: TestClient, admin_user: TestUser, unique_user: TestUser):
|
||||
update_payload = {
|
||||
"id": unique_user.household_id,
|
||||
"groupId": admin_user.group_id,
|
||||
"name": "New Name",
|
||||
"preferences": {
|
||||
"privateHousehold": random_bool(),
|
||||
"firstDayOfWeek": 2,
|
||||
"recipePublic": random_bool(),
|
||||
"recipeShowNutrition": random_bool(),
|
||||
"recipeShowAssets": random_bool(),
|
||||
"recipeLandscapeView": random_bool(),
|
||||
"recipeDisableComments": random_bool(),
|
||||
"recipeDisableAmount": random_bool(),
|
||||
},
|
||||
}
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.admin_households_item_id(unique_user.household_id),
|
||||
json=update_payload,
|
||||
headers=admin_user.token,
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
as_json = response.json()
|
||||
|
||||
assert as_json["name"] == update_payload["name"]
|
||||
assert_ignore_keys(as_json["preferences"], update_payload["preferences"]) # type: ignore
|
||||
|
||||
|
||||
def test_admin_delete_household(unfiltered_database: AllRepositories, api_client: TestClient, admin_user: TestUser):
|
||||
group = unfiltered_database.groups.create({"name": random_string()})
|
||||
household = unfiltered_database.households.create({"name": random_string(), "group_id": group.id})
|
||||
response = api_client.delete(api_routes.admin_households_item_id(household.id), headers=admin_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.admin_households_item_id(household.id), headers=admin_user.token)
|
||||
assert response.status_code == 404
|
|
@ -32,7 +32,7 @@ def test_init_superuser(api_client: TestClient, admin_user: TestUser):
|
|||
|
||||
admin_data = response.json()
|
||||
|
||||
assert admin_data["id"] == admin_user.user_id
|
||||
assert admin_data["id"] == str(admin_user.user_id)
|
||||
assert admin_data["groupId"] == admin_user.group_id
|
||||
|
||||
assert admin_data["fullName"] == "Change Me"
|
||||
|
@ -93,7 +93,7 @@ def test_update_other_user_as_not_admin(api_client: TestClient, unique_user: Tes
|
|||
settings = get_app_settings()
|
||||
|
||||
update_data = {
|
||||
"id": unique_user.user_id,
|
||||
"id": str(unique_user.user_id),
|
||||
"fullName": "Updated Name",
|
||||
"email": settings._DEFAULT_EMAIL,
|
||||
"group": "Home",
|
||||
|
@ -122,7 +122,7 @@ def test_self_demote_admin(api_client: TestClient, admin_user: TestUser):
|
|||
|
||||
def test_self_promote_admin(api_client: TestClient, unique_user: TestUser):
|
||||
update_data = {
|
||||
"id": unique_user.user_id,
|
||||
"id": str(unique_user.user_id),
|
||||
"fullName": "Updated Name",
|
||||
"email": "user@example.com",
|
||||
"group": "Home",
|
||||
|
|
|
@ -2,9 +2,9 @@ import random
|
|||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.cookbook.cookbook import SaveCookBook
|
||||
from mealie.schema.cookbook.cookbook import ReadCookBook, SaveCookBook
|
||||
from mealie.schema.recipe.recipe import Recipe
|
||||
from mealie.schema.recipe.recipe_category import TagSave
|
||||
from tests.utils import api_routes
|
||||
|
@ -12,41 +12,63 @@ from tests.utils.factories import random_int, random_string
|
|||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_group", [True, False], ids=["group_is_private", "group_is_public"])
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_household_1_private", [True, False])
|
||||
@pytest.mark.parametrize("is_household_2_private", [True, False])
|
||||
def test_get_all_cookbooks(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
h2_user: TestUser,
|
||||
is_private_group: bool,
|
||||
is_household_1_private: bool,
|
||||
is_household_2_private: bool,
|
||||
):
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
group = unique_user.repos.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
group.preferences.recipe_public = not is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
unique_user.repos.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
## Set Up Cookbooks
|
||||
default_cookbooks = database.cookbooks.create_many(
|
||||
[SaveCookBook(name=random_string(), group_id=unique_user.group_id) for _ in range(random_int(15, 20))]
|
||||
)
|
||||
## Set Up Household and Cookbooks
|
||||
household_private_map: dict[UUID4, bool] = {}
|
||||
public_cookbooks: list[ReadCookBook] = []
|
||||
private_cookbooks: list[ReadCookBook] = []
|
||||
for database, is_private_household in [
|
||||
(unique_user.repos, is_household_1_private),
|
||||
(h2_user.repos, is_household_2_private),
|
||||
]:
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
random.shuffle(default_cookbooks)
|
||||
split_index = random_int(6, 12)
|
||||
public_cookbooks = default_cookbooks[:split_index]
|
||||
private_cookbooks = default_cookbooks[split_index:]
|
||||
household_private_map[household.id] = is_private_household
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
for cookbook in public_cookbooks:
|
||||
cookbook.public = True
|
||||
## Set Up Cookbooks
|
||||
default_cookbooks = database.cookbooks.create_many(
|
||||
[
|
||||
SaveCookBook(name=random_string(), group_id=unique_user.group_id, household_id=unique_user.household_id)
|
||||
for _ in range(random_int(15, 20))
|
||||
]
|
||||
)
|
||||
|
||||
for cookbook in private_cookbooks:
|
||||
cookbook.public = False
|
||||
random.shuffle(default_cookbooks)
|
||||
split_index = random_int(6, 12)
|
||||
public_cookbooks.extend(default_cookbooks[:split_index])
|
||||
private_cookbooks.extend(default_cookbooks[split_index:])
|
||||
|
||||
database.cookbooks.update_many(public_cookbooks + private_cookbooks)
|
||||
for cookbook in default_cookbooks[:split_index]:
|
||||
cookbook.public = True
|
||||
|
||||
for cookbook in default_cookbooks[split_index:]:
|
||||
cookbook.public = False
|
||||
|
||||
database.cookbooks.update_many(default_cookbooks)
|
||||
|
||||
## Test Cookbooks
|
||||
response = api_client.get(api_routes.explore_cookbooks_group_slug(unique_user.group_id))
|
||||
response = api_client.get(api_routes.explore_groups_group_slug_cookbooks(unique_user.group_id))
|
||||
if is_private_group:
|
||||
assert response.status_code == 404
|
||||
return
|
||||
|
@ -56,55 +78,61 @@ def test_get_all_cookbooks(
|
|||
fetched_ids: set[str] = {cookbook["id"] for cookbook in cookbooks_data["items"]}
|
||||
|
||||
for cookbook in public_cookbooks:
|
||||
assert str(cookbook.id) in fetched_ids
|
||||
is_private_household = household_private_map[cookbook.household_id]
|
||||
if is_private_household:
|
||||
assert str(cookbook.id) not in fetched_ids
|
||||
else:
|
||||
assert str(cookbook.id) in fetched_ids
|
||||
|
||||
for cookbook in private_cookbooks:
|
||||
assert str(cookbook.id) not in fetched_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"is_private_group, is_private_cookbook",
|
||||
[
|
||||
(True, True),
|
||||
(True, False),
|
||||
(False, True),
|
||||
(False, False),
|
||||
],
|
||||
ids=[
|
||||
"group_is_private_cookbook_is_private",
|
||||
"group_is_private_cookbook_is_public",
|
||||
"group_is_public_cookbook_is_private",
|
||||
"group_is_public_cookbook_is_public",
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
@pytest.mark.parametrize("is_private_cookbook", [True, False])
|
||||
def test_get_one_cookbook(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
is_private_group: bool,
|
||||
is_private_household: bool,
|
||||
is_private_cookbook: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
group.preferences.recipe_public = not is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
## Set Up Household
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
## Set Up Cookbook
|
||||
cookbook = database.cookbooks.create(
|
||||
SaveCookBook(
|
||||
name=random_string(),
|
||||
group_id=unique_user.group_id,
|
||||
household_id=unique_user.household_id,
|
||||
public=not is_private_cookbook,
|
||||
)
|
||||
)
|
||||
|
||||
## Test Cookbook
|
||||
response = api_client.get(api_routes.explore_cookbooks_group_slug_item_id(unique_user.group_id, cookbook.id))
|
||||
if is_private_group or is_private_cookbook:
|
||||
response = api_client.get(api_routes.explore_groups_group_slug_cookbooks_item_id(unique_user.group_id, cookbook.id))
|
||||
if is_private_group or is_private_household or is_private_cookbook:
|
||||
assert response.status_code == 404
|
||||
if is_private_group:
|
||||
assert response.json()["detail"] == "group not found"
|
||||
else:
|
||||
assert response.json()["detail"] == "cookbook not found"
|
||||
return
|
||||
|
||||
assert response.status_code == 200
|
||||
|
@ -112,18 +140,31 @@ def test_get_one_cookbook(
|
|||
assert cookbook_data["id"] == str(cookbook.id)
|
||||
|
||||
|
||||
def test_get_cookbooks_with_recipes(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
|
||||
def test_get_cookbooks_with_recipes(api_client: TestClient, unique_user: TestUser, h2_user: TestUser):
|
||||
database = unique_user.repos
|
||||
|
||||
# Create a public and private recipe with a known tag
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = False
|
||||
group.preferences.recipe_public = True
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = False
|
||||
household.preferences.recipe_public = True
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
tag = database.tags.create(TagSave(name=random_string(), group_id=unique_user.group_id))
|
||||
public_recipe, private_recipe = database.recipes.create_many(
|
||||
Recipe(user_id=unique_user.user_id, group_id=unique_user.group_id, name=random_string()) for _ in range(2)
|
||||
Recipe(
|
||||
user_id=unique_user.user_id,
|
||||
group_id=unique_user.group_id,
|
||||
name=random_string(),
|
||||
)
|
||||
for _ in range(2)
|
||||
)
|
||||
|
||||
assert public_recipe.settings
|
||||
|
@ -136,14 +177,40 @@ def test_get_cookbooks_with_recipes(api_client: TestClient, unique_user: TestUse
|
|||
|
||||
database.recipes.update_many([public_recipe, private_recipe])
|
||||
|
||||
# Create a recipe in another household that's public with the same known tag
|
||||
other_database = h2_user.repos
|
||||
other_household = other_database.households.get_one(h2_user.household_id)
|
||||
assert other_household and other_household.preferences
|
||||
|
||||
other_household.preferences.private_household = False
|
||||
other_household.preferences.recipe_public = True
|
||||
other_database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
other_household_recipe = other_database.recipes.create(
|
||||
Recipe(
|
||||
user_id=h2_user.user_id,
|
||||
group_id=h2_user.group_id,
|
||||
name=random_string(),
|
||||
)
|
||||
)
|
||||
assert other_household_recipe.settings
|
||||
other_household_recipe.settings.public = True
|
||||
other_household_recipe.tags = [tag]
|
||||
other_database.recipes.update(other_household_recipe.slug, other_household_recipe)
|
||||
|
||||
# Create a public cookbook with tag
|
||||
cookbook = database.cookbooks.create(
|
||||
SaveCookBook(name=random_string(), group_id=unique_user.group_id, public=True, tags=[tag])
|
||||
SaveCookBook(
|
||||
name=random_string(),
|
||||
group_id=unique_user.group_id,
|
||||
household_id=unique_user.household_id,
|
||||
public=True,
|
||||
tags=[tag],
|
||||
)
|
||||
)
|
||||
database.cookbooks.create(cookbook)
|
||||
|
||||
# Get the cookbook and make sure we only get the public recipe
|
||||
response = api_client.get(api_routes.explore_cookbooks_group_slug_item_id(unique_user.group_id, cookbook.id))
|
||||
# Get the cookbook and make sure we only get the public recipe from the correct household
|
||||
response = api_client.get(api_routes.explore_groups_group_slug_cookbooks_item_id(unique_user.group_id, cookbook.id))
|
||||
assert response.status_code == 200
|
||||
cookbook_data = response.json()
|
||||
assert cookbook_data["id"] == str(cookbook.id)
|
||||
|
@ -152,3 +219,4 @@ def test_get_cookbooks_with_recipes(api_client: TestClient, unique_user: TestUse
|
|||
assert len(cookbook_recipe_ids) == 1
|
||||
assert str(public_recipe.id) in cookbook_recipe_ids
|
||||
assert str(private_recipe.id) not in cookbook_recipe_ids
|
||||
assert str(other_household_recipe.id) not in cookbook_recipe_ids
|
||||
|
|
|
@ -1,35 +1,46 @@
|
|||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.recipe.recipe_ingredient import SaveIngredientFood
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_int, random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_group", [True, False], ids=["group_is_private", "group_is_public"])
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_get_all_foods(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
is_private_group: bool,
|
||||
is_private_household: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
group.preferences.recipe_public = not is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
## Set Up Household
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
## Set Up Foods
|
||||
foods = database.ingredient_foods.create_many(
|
||||
[SaveIngredientFood(name=random_string(), group_id=unique_user.group_id) for _ in range(random_int(15, 20))]
|
||||
)
|
||||
|
||||
## Test Foods
|
||||
response = api_client.get(api_routes.explore_foods_group_slug(unique_user.group_id))
|
||||
response = api_client.get(api_routes.explore_groups_group_slug_foods(unique_user.group_id))
|
||||
|
||||
# whether or not the household is private shouldn't affect food visibility
|
||||
if is_private_group:
|
||||
assert response.status_code == 404
|
||||
return
|
||||
|
@ -42,26 +53,38 @@ def test_get_all_foods(
|
|||
assert str(food.id) in fetched_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_group", [True, False], ids=["group_is_private", "group_is_public"])
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_get_one_food(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
is_private_group: bool,
|
||||
is_private_household: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
group.preferences.recipe_public = not is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
## Set Up Household
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
## Set Up Food
|
||||
food = database.ingredient_foods.create(SaveIngredientFood(name=random_string(), group_id=unique_user.group_id))
|
||||
|
||||
## Test Food
|
||||
response = api_client.get(api_routes.explore_foods_group_slug_item_id(unique_user.group_id, food.id))
|
||||
response = api_client.get(api_routes.explore_groups_group_slug_foods_item_id(unique_user.group_id, food.id))
|
||||
|
||||
# whether or not the household is private shouldn't affect food visibility
|
||||
if is_private_group:
|
||||
assert response.status_code == 404
|
||||
return
|
||||
|
|
|
@ -3,7 +3,6 @@ from enum import Enum
|
|||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.recipe.recipe_category import CategorySave, TagSave
|
||||
from mealie.schema.recipe.recipe_tool import RecipeToolSave
|
||||
from tests.utils import api_routes
|
||||
|
@ -17,53 +16,46 @@ class OrganizerType(Enum):
|
|||
tools = "tools"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"organizer_type, is_private_group",
|
||||
[
|
||||
(OrganizerType.categories, True),
|
||||
(OrganizerType.categories, False),
|
||||
(OrganizerType.tags, True),
|
||||
(OrganizerType.tags, False),
|
||||
(OrganizerType.tools, True),
|
||||
(OrganizerType.tools, False),
|
||||
],
|
||||
ids=[
|
||||
"private_group_categories",
|
||||
"public_group_categories",
|
||||
"private_group_tags",
|
||||
"public_group_tags",
|
||||
"private_group_tools",
|
||||
"public_group_tools",
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("organizer_type", [OrganizerType.categories, OrganizerType.tags, OrganizerType.tools])
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_get_all_organizers(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
organizer_type: OrganizerType,
|
||||
is_private_group: bool,
|
||||
is_private_household: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
group.preferences.recipe_public = not is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
## Set Up Household
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
## Set Up Organizers
|
||||
if organizer_type is OrganizerType.categories:
|
||||
item_class = CategorySave
|
||||
repo = database.categories # type: ignore
|
||||
route = api_routes.explore_organizers_group_slug_categories
|
||||
route = api_routes.explore_groups_group_slug_organizers_categories
|
||||
elif organizer_type is OrganizerType.tags:
|
||||
item_class = TagSave
|
||||
repo = database.tags # type: ignore
|
||||
route = api_routes.explore_organizers_group_slug_tags
|
||||
route = api_routes.explore_groups_group_slug_organizers_tags
|
||||
else:
|
||||
item_class = RecipeToolSave
|
||||
repo = database.tools # type: ignore
|
||||
route = api_routes.explore_organizers_group_slug_tools
|
||||
route = api_routes.explore_groups_group_slug_organizers_tools
|
||||
|
||||
organizers = repo.create_many(
|
||||
[item_class(name=random_string(), group_id=unique_user.group_id) for _ in range(random_int(15, 20))]
|
||||
|
@ -71,6 +63,8 @@ def test_get_all_organizers(
|
|||
|
||||
## Test Organizers
|
||||
response = api_client.get(route(unique_user.group_id))
|
||||
|
||||
# whether or not the household is private shouldn't affect food visibility
|
||||
if is_private_group:
|
||||
assert response.status_code == 404
|
||||
return
|
||||
|
@ -83,58 +77,53 @@ def test_get_all_organizers(
|
|||
assert str(organizer.id) in fetched_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"organizer_type, is_private_group",
|
||||
[
|
||||
(OrganizerType.categories, True),
|
||||
(OrganizerType.categories, False),
|
||||
(OrganizerType.tags, True),
|
||||
(OrganizerType.tags, False),
|
||||
(OrganizerType.tools, True),
|
||||
(OrganizerType.tools, False),
|
||||
],
|
||||
ids=[
|
||||
"private_group_category",
|
||||
"public_group_category",
|
||||
"private_group_tag",
|
||||
"public_group_tag",
|
||||
"private_group_tool",
|
||||
"public_group_tool",
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("organizer_type", [OrganizerType.categories, OrganizerType.tags, OrganizerType.tools])
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
def test_get_one_organizer(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
organizer_type: OrganizerType,
|
||||
is_private_group: bool,
|
||||
is_private_household: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
group.preferences.recipe_public = not is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
## Set Up Household
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
## Set Up Organizer
|
||||
if organizer_type is OrganizerType.categories:
|
||||
item_class = CategorySave
|
||||
repo = database.categories # type: ignore
|
||||
route = api_routes.explore_organizers_group_slug_categories_item_id
|
||||
route = api_routes.explore_groups_group_slug_organizers_categories_item_id
|
||||
elif organizer_type is OrganizerType.tags:
|
||||
item_class = TagSave
|
||||
repo = database.tags # type: ignore
|
||||
route = api_routes.explore_organizers_group_slug_tags_item_id
|
||||
route = api_routes.explore_groups_group_slug_organizers_tags_item_id
|
||||
else:
|
||||
item_class = RecipeToolSave
|
||||
repo = database.tools # type: ignore
|
||||
route = api_routes.explore_organizers_group_slug_tools_item_id
|
||||
route = api_routes.explore_groups_group_slug_organizers_tools_item_id
|
||||
|
||||
organizer = repo.create(item_class(name=random_string(), group_id=unique_user.group_id))
|
||||
|
||||
## Test Organizer
|
||||
response = api_client.get(route(unique_user.group_id, organizer.id))
|
||||
|
||||
# whether or not the household is private shouldn't affect food visibility
|
||||
if is_private_group:
|
||||
assert response.status_code == 404
|
||||
return
|
||||
|
|
|
@ -1,68 +1,79 @@
|
|||
import random
|
||||
from dataclasses import dataclass
|
||||
from typing import Any
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.cookbook.cookbook import SaveCookBook
|
||||
from mealie.schema.recipe.recipe import Recipe
|
||||
from mealie.schema.recipe.recipe_category import TagSave
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_int, random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
class PublicRecipeTestCase:
|
||||
private_group: bool
|
||||
public_recipe: bool
|
||||
status_code: int
|
||||
error: str | None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_group", [True, False], ids=["group_is_private", "group_is_public"])
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_household_1_private", [True, False])
|
||||
@pytest.mark.parametrize("is_household_2_private", [True, False])
|
||||
def test_get_all_public_recipes(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
h2_user: TestUser,
|
||||
is_private_group: bool,
|
||||
is_household_1_private: bool,
|
||||
is_household_2_private: bool,
|
||||
):
|
||||
## Set Up Public and Private Recipes
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
group = unique_user.repos.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = is_private_group
|
||||
group.preferences.recipe_public = not is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
unique_user.repos.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
default_recipes = database.recipes.create_many(
|
||||
[
|
||||
Recipe(
|
||||
user_id=unique_user.user_id,
|
||||
group_id=unique_user.group_id,
|
||||
name=random_string(),
|
||||
)
|
||||
for _ in range(random_int(15, 20))
|
||||
],
|
||||
)
|
||||
household_private_map: dict[UUID4, bool] = {}
|
||||
public_recipes: list[Recipe] = []
|
||||
private_recipes: list[Recipe] = []
|
||||
for database, is_private_household in [
|
||||
(unique_user.repos, is_household_1_private),
|
||||
(h2_user.repos, is_household_2_private),
|
||||
]:
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
random.shuffle(default_recipes)
|
||||
split_index = random_int(6, 12)
|
||||
public_recipes = default_recipes[:split_index]
|
||||
private_recipes = default_recipes[split_index:]
|
||||
household_private_map[household.id] = is_private_household
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
for recipe in public_recipes:
|
||||
assert recipe.settings
|
||||
recipe.settings.public = True
|
||||
default_recipes = database.recipes.create_many(
|
||||
[
|
||||
Recipe(
|
||||
user_id=unique_user.user_id,
|
||||
group_id=unique_user.group_id,
|
||||
name=random_string(),
|
||||
)
|
||||
for _ in range(random_int(15, 20))
|
||||
],
|
||||
)
|
||||
|
||||
for recipe in private_recipes:
|
||||
assert recipe.settings
|
||||
recipe.settings.public = False
|
||||
random.shuffle(default_recipes)
|
||||
split_index = random_int(6, 12)
|
||||
public_recipes.extend(default_recipes[:split_index])
|
||||
private_recipes.extend(default_recipes[split_index:])
|
||||
|
||||
database.recipes.update_many(public_recipes + private_recipes)
|
||||
for recipe in default_recipes[:split_index]:
|
||||
assert recipe.settings
|
||||
recipe.settings.public = True
|
||||
|
||||
for recipe in default_recipes[split_index:]:
|
||||
assert recipe.settings
|
||||
recipe.settings.public = False
|
||||
|
||||
database.recipes.update_many(default_recipes)
|
||||
|
||||
## Query All Recipes
|
||||
response = api_client.get(api_routes.explore_recipes_group_slug(group.slug))
|
||||
response = api_client.get(api_routes.explore_groups_group_slug_recipes(group.slug))
|
||||
if is_private_group:
|
||||
assert response.status_code == 404
|
||||
return
|
||||
|
@ -72,7 +83,11 @@ def test_get_all_public_recipes(
|
|||
fetched_ids: set[str] = {recipe["id"] for recipe in recipes_data["items"]}
|
||||
|
||||
for recipe in public_recipes:
|
||||
assert str(recipe.id) in fetched_ids
|
||||
is_private_household = household_private_map[recipe.household_id]
|
||||
if is_private_household:
|
||||
assert str(recipe.id) not in fetched_ids
|
||||
else:
|
||||
assert str(recipe.id) in fetched_ids
|
||||
|
||||
for recipe in private_recipes:
|
||||
assert str(recipe.id) not in fetched_ids
|
||||
|
@ -89,82 +104,222 @@ def test_get_all_public_recipes(
|
|||
ids=[
|
||||
"match_slug",
|
||||
"not_match_slug",
|
||||
"bypass_public_filter_1",
|
||||
"bypass_public_filter_2",
|
||||
"bypass_public_settings_filter_1",
|
||||
"bypass_public_settings_filter_2",
|
||||
],
|
||||
)
|
||||
def test_get_all_public_recipes_filtered(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
random_recipe: Recipe,
|
||||
database: AllRepositories,
|
||||
query_filter: str,
|
||||
recipe_data: dict[str, Any],
|
||||
should_fetch: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Recipe
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = False
|
||||
group.preferences.recipe_public = True
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = False
|
||||
household.preferences.recipe_public = True
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
assert random_recipe.settings
|
||||
random_recipe.settings.public = True
|
||||
database.recipes.update(random_recipe.slug, random_recipe.model_dump() | recipe_data)
|
||||
|
||||
## Query All Recipes
|
||||
response = api_client.get(api_routes.explore_recipes_group_slug(group.slug), params={"queryFilter": query_filter})
|
||||
response = api_client.get(
|
||||
api_routes.explore_groups_group_slug_recipes(group.slug),
|
||||
params={"queryFilter": query_filter},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
recipes_data = response.json()
|
||||
fetched_ids: set[str] = {recipe["id"] for recipe in recipes_data["items"]}
|
||||
assert should_fetch is (str(random_recipe.id) in fetched_ids)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"test_case",
|
||||
(
|
||||
PublicRecipeTestCase(private_group=False, public_recipe=True, status_code=200, error=None),
|
||||
PublicRecipeTestCase(private_group=True, public_recipe=True, status_code=404, error="group not found"),
|
||||
PublicRecipeTestCase(private_group=False, public_recipe=False, status_code=404, error="recipe not found"),
|
||||
),
|
||||
ids=("is public", "group private", "recipe private"),
|
||||
)
|
||||
def test_public_recipe_success(
|
||||
@pytest.mark.parametrize("is_private_group", [True, False])
|
||||
@pytest.mark.parametrize("is_private_household", [True, False])
|
||||
@pytest.mark.parametrize("is_private_recipe", [True, False])
|
||||
def test_get_one_recipe(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
random_recipe: Recipe,
|
||||
database: AllRepositories,
|
||||
test_case: PublicRecipeTestCase,
|
||||
is_private_group: bool,
|
||||
is_private_household: bool,
|
||||
is_private_recipe: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = test_case.private_group
|
||||
group.preferences.recipe_public = not test_case.private_group
|
||||
group.preferences.private_group = is_private_group
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
# Set Recipe `settings.public` attribute
|
||||
## Set Up Household
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = is_private_household
|
||||
household.preferences.recipe_public = not is_private_household
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
## Set Recipe `settings.public` attribute
|
||||
assert random_recipe.settings
|
||||
random_recipe.settings.public = test_case.public_recipe
|
||||
random_recipe.settings.public = not is_private_recipe
|
||||
database.recipes.update(random_recipe.slug, random_recipe)
|
||||
|
||||
# Try to access recipe
|
||||
## Try to access recipe
|
||||
recipe_group = database.groups.get_by_slug_or_id(random_recipe.group_id)
|
||||
recipe_household = database.households.get_by_slug_or_id(random_recipe.household_id)
|
||||
assert recipe_group
|
||||
assert recipe_household
|
||||
response = api_client.get(
|
||||
api_routes.explore_recipes_group_slug_recipe_slug(
|
||||
recipe_group.slug,
|
||||
random_recipe.slug,
|
||||
)
|
||||
api_routes.explore_groups_group_slug_recipes_recipe_slug(recipe_group.slug, random_recipe.slug)
|
||||
)
|
||||
assert response.status_code == test_case.status_code
|
||||
|
||||
if test_case.error:
|
||||
assert response.json()["detail"] == test_case.error
|
||||
if is_private_group or is_private_household or is_private_recipe:
|
||||
assert response.status_code == 404
|
||||
if is_private_group:
|
||||
assert response.json()["detail"] == "group not found"
|
||||
else:
|
||||
assert response.json()["detail"] == "recipe not found"
|
||||
return
|
||||
|
||||
as_json = response.json()
|
||||
assert as_json["name"] == random_recipe.name
|
||||
assert as_json["slug"] == random_recipe.slug
|
||||
|
||||
|
||||
@pytest.mark.parametrize("is_private_cookbook", [True, False])
|
||||
def test_public_recipe_cookbook_filter(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
is_private_cookbook: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
## Set Up Group
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = False
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
## Set Up Household
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = False
|
||||
household.preferences.recipe_public = True
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
## Set Up Cookbook
|
||||
cookbook = database.cookbooks.create(
|
||||
SaveCookBook(
|
||||
name=random_string(),
|
||||
group_id=unique_user.group_id,
|
||||
household_id=unique_user.household_id,
|
||||
public=not is_private_cookbook,
|
||||
)
|
||||
)
|
||||
|
||||
## Try to access recipe query
|
||||
response = api_client.get(
|
||||
api_routes.explore_groups_group_slug_recipes(group.slug), params={"cookbook": cookbook.id}
|
||||
)
|
||||
if is_private_cookbook:
|
||||
assert response.status_code == 404
|
||||
else:
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_public_recipe_cookbook_filter_with_recipes(api_client: TestClient, unique_user: TestUser, h2_user: TestUser):
|
||||
database = unique_user.repos
|
||||
|
||||
# Create a public and private recipe with a known tag
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group and group.preferences
|
||||
|
||||
group.preferences.private_group = False
|
||||
database.group_preferences.update(group.id, group.preferences)
|
||||
|
||||
household = database.households.get_one(unique_user.household_id)
|
||||
assert household and household.preferences
|
||||
|
||||
household.preferences.private_household = False
|
||||
household.preferences.recipe_public = True
|
||||
database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
tag = database.tags.create(TagSave(name=random_string(), group_id=unique_user.group_id))
|
||||
public_recipe, private_recipe = database.recipes.create_many(
|
||||
Recipe(
|
||||
user_id=unique_user.user_id,
|
||||
group_id=unique_user.group_id,
|
||||
name=random_string(),
|
||||
)
|
||||
for _ in range(2)
|
||||
)
|
||||
|
||||
assert public_recipe.settings
|
||||
public_recipe.settings.public = True
|
||||
public_recipe.tags = [tag]
|
||||
|
||||
assert private_recipe.settings
|
||||
private_recipe.settings.public = False
|
||||
private_recipe.tags = [tag]
|
||||
|
||||
database.recipes.update_many([public_recipe, private_recipe])
|
||||
|
||||
# Create a recipe in another household that's public with the same known tag
|
||||
other_database = h2_user.repos
|
||||
other_household = other_database.households.get_one(h2_user.household_id)
|
||||
assert other_household and other_household.preferences
|
||||
|
||||
other_household.preferences.private_household = False
|
||||
other_household.preferences.recipe_public = True
|
||||
other_database.household_preferences.update(household.id, household.preferences)
|
||||
|
||||
other_household_recipe = other_database.recipes.create(
|
||||
Recipe(
|
||||
user_id=h2_user.user_id,
|
||||
group_id=h2_user.group_id,
|
||||
name=random_string(),
|
||||
)
|
||||
)
|
||||
assert other_household_recipe.settings
|
||||
other_household_recipe.settings.public = True
|
||||
other_household_recipe.tags = [tag]
|
||||
other_database.recipes.update(other_household_recipe.slug, other_household_recipe)
|
||||
|
||||
# Create a public cookbook with tag
|
||||
cookbook = database.cookbooks.create(
|
||||
SaveCookBook(
|
||||
name=random_string(),
|
||||
group_id=unique_user.group_id,
|
||||
household_id=unique_user.household_id,
|
||||
public=True,
|
||||
tags=[tag],
|
||||
)
|
||||
)
|
||||
|
||||
# Get the cookbook's recipes and make sure we only get the public recipe from the correct household
|
||||
response = api_client.get(
|
||||
api_routes.explore_groups_group_slug_recipes(unique_user.group_id), params={"cookbook": cookbook.id}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
recipe_ids: set[str] = {recipe["id"] for recipe in response.json()["items"]}
|
||||
assert len(recipe_ids) == 1
|
||||
assert str(public_recipe.id) in recipe_ids
|
||||
assert str(private_recipe.id) not in recipe_ids
|
||||
assert str(other_household_recipe.id) not in recipe_ids
|
||||
|
|
364
tests/integration_tests/test_repository_factory.py
Normal file
364
tests/integration_tests/test_repository_factory.py
Normal file
|
@ -0,0 +1,364 @@
|
|||
import inspect
|
||||
import time
|
||||
from functools import cached_property
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from pydantic import UUID4
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from mealie.db.models._model_base import SqlAlchemyBase
|
||||
from mealie.repos._utils import NOT_SET, NotSet
|
||||
from mealie.repos.all_repositories import get_repositories
|
||||
from mealie.repos.repository_generic import GroupRepositoryGeneric, HouseholdRepositoryGeneric, RepositoryGeneric
|
||||
from mealie.schema._mealie.mealie_model import MealieModel
|
||||
from mealie.schema.household.group_shopping_list import ShoppingListCreate
|
||||
from mealie.schema.household.webhook import SaveWebhook
|
||||
from mealie.schema.recipe.recipe import Recipe
|
||||
from mealie.schema.recipe.recipe_ingredient import SaveIngredientFood
|
||||
from mealie.schema.response.pagination import PaginationQuery
|
||||
from mealie.services.household_services.shopping_lists import ShoppingListService
|
||||
from tests.utils.factories import random_email, random_string
|
||||
|
||||
|
||||
@pytest.mark.parametrize("group_id", [uuid4(), None, NOT_SET])
|
||||
@pytest.mark.parametrize("household_id", [uuid4(), None, NOT_SET])
|
||||
def test_get_repositories_sets_ids(
|
||||
session: Session, group_id: UUID4 | None | NotSet, household_id: UUID4 | None | NotSet
|
||||
):
|
||||
kwargs = {}
|
||||
if not isinstance(group_id, NotSet):
|
||||
kwargs["group_id"] = group_id
|
||||
if not isinstance(household_id, NotSet):
|
||||
kwargs["household_id"] = household_id
|
||||
|
||||
repositories = get_repositories(session, **kwargs)
|
||||
assert repositories.group_id == group_id
|
||||
assert repositories.household_id == household_id
|
||||
|
||||
# test that sentinel is used correctly
|
||||
if isinstance(group_id, NotSet):
|
||||
assert repositories.group_id is NOT_SET
|
||||
if isinstance(household_id, NotSet):
|
||||
assert repositories.household_id is NOT_SET
|
||||
|
||||
|
||||
def test_repository_generic_constructor(session: Session):
|
||||
RepositoryGeneric(session, "id", MealieModel, SqlAlchemyBase)
|
||||
|
||||
|
||||
def test_repository_group_constructor(session: Session):
|
||||
BASE_ARGS = (session, "id", MealieModel, SqlAlchemyBase)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
GroupRepositoryGeneric(*BASE_ARGS, group_id=NOT_SET)
|
||||
|
||||
GroupRepositoryGeneric(*BASE_ARGS, group_id=None)
|
||||
GroupRepositoryGeneric(*BASE_ARGS, group_id=uuid4())
|
||||
|
||||
|
||||
def test_repository_household_constructor(session: Session):
|
||||
BASE_ARGS = (session, "id", MealieModel, SqlAlchemyBase)
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
HouseholdRepositoryGeneric(*BASE_ARGS, group_id=NOT_SET, household_id=NOT_SET)
|
||||
HouseholdRepositoryGeneric(*BASE_ARGS, group_id=uuid4(), household_id=NOT_SET)
|
||||
HouseholdRepositoryGeneric(*BASE_ARGS, group_id=NOT_SET, household_id=uuid4())
|
||||
|
||||
HouseholdRepositoryGeneric(*BASE_ARGS, group_id=None, household_id=None)
|
||||
HouseholdRepositoryGeneric(*BASE_ARGS, group_id=uuid4(), household_id=None)
|
||||
HouseholdRepositoryGeneric(*BASE_ARGS, group_id=None, household_id=uuid4())
|
||||
HouseholdRepositoryGeneric(*BASE_ARGS, group_id=uuid4(), household_id=uuid4())
|
||||
|
||||
|
||||
@pytest.mark.parametrize("use_group_id", [True, False])
|
||||
@pytest.mark.parametrize("use_household_id", [True, False])
|
||||
def test_all_repositories_constructors(session: Session, use_group_id: bool, use_household_id: bool):
|
||||
kwargs = {}
|
||||
if use_group_id:
|
||||
kwargs["group_id"] = uuid4()
|
||||
if use_household_id:
|
||||
kwargs["household_id"] = uuid4()
|
||||
repositories = get_repositories(session, **kwargs)
|
||||
for name, member in inspect.getmembers(repositories.__class__):
|
||||
if not isinstance(member, cached_property):
|
||||
continue
|
||||
signature = inspect.signature(member.func)
|
||||
repo_type = signature.return_annotation
|
||||
try:
|
||||
if not issubclass(repo_type, RepositoryGeneric):
|
||||
continue
|
||||
except TypeError:
|
||||
continue
|
||||
|
||||
if issubclass(repo_type, HouseholdRepositoryGeneric):
|
||||
if not (use_group_id and use_household_id):
|
||||
with pytest.raises(ValueError):
|
||||
getattr(repositories, name)
|
||||
else:
|
||||
repo = getattr(repositories, name)
|
||||
assert repo.group_id == kwargs["group_id"]
|
||||
assert repo.household_id == kwargs["household_id"]
|
||||
elif issubclass(repo_type, GroupRepositoryGeneric):
|
||||
if not use_group_id:
|
||||
with pytest.raises(ValueError):
|
||||
getattr(repositories, name)
|
||||
else:
|
||||
repo = getattr(repositories, name)
|
||||
assert repo.group_id == kwargs["group_id"]
|
||||
assert repo.household_id is None
|
||||
else:
|
||||
repo = getattr(repositories, name)
|
||||
assert repo.group_id is None
|
||||
assert repo.household_id is None
|
||||
|
||||
|
||||
def test_group_repositories_filter_by_group(session: Session):
|
||||
unfiltered_repos = get_repositories(session, group_id=None, household_id=None)
|
||||
group_1 = unfiltered_repos.groups.create({"name": random_string()})
|
||||
group_2 = unfiltered_repos.groups.create({"name": random_string()})
|
||||
|
||||
group_1_repos = get_repositories(session, group_id=group_1.id, household_id=None)
|
||||
group_2_repos = get_repositories(session, group_id=group_2.id, household_id=None)
|
||||
food_1 = group_1_repos.ingredient_foods.create(
|
||||
SaveIngredientFood(id=uuid4(), group_id=group_1.id, name=random_string())
|
||||
)
|
||||
food_2 = group_2_repos.ingredient_foods.create(
|
||||
SaveIngredientFood(id=uuid4(), group_id=group_2.id, name=random_string())
|
||||
)
|
||||
|
||||
# unfiltered_repos should find both foods
|
||||
assert food_1 == unfiltered_repos.ingredient_foods.get_one(food_1.id)
|
||||
assert food_2 == unfiltered_repos.ingredient_foods.get_one(food_2.id)
|
||||
all_foods = unfiltered_repos.ingredient_foods.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert food_1 in all_foods
|
||||
assert food_2 in all_foods
|
||||
|
||||
# group_repos should only find foods with the correct group_id
|
||||
assert food_1 == group_1_repos.ingredient_foods.get_one(food_1.id)
|
||||
assert group_1_repos.ingredient_foods.get_one(food_2.id) is None
|
||||
assert [food_1] == group_1_repos.ingredient_foods.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
|
||||
assert group_2_repos.ingredient_foods.get_one(food_1.id) is None
|
||||
assert food_2 == group_2_repos.ingredient_foods.get_one(food_2.id)
|
||||
assert [food_2] == group_2_repos.ingredient_foods.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
|
||||
|
||||
def test_household_repositories_filter_by_household(session: Session):
|
||||
unfiltered_repos = get_repositories(session, group_id=None, household_id=None)
|
||||
group = unfiltered_repos.groups.create({"name": random_string()})
|
||||
group_repos = get_repositories(session, group_id=group.id, household_id=None)
|
||||
household_1 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
household_2 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
|
||||
household_1_repos = get_repositories(session, group_id=group.id, household_id=household_1.id)
|
||||
household_2_repos = get_repositories(session, group_id=group.id, household_id=household_2.id)
|
||||
webhook_1 = household_1_repos.webhooks.create(
|
||||
SaveWebhook(group_id=group.id, household_id=household_1.id, scheduled_time=time.time())
|
||||
)
|
||||
webhook_2 = household_2_repos.webhooks.create(
|
||||
SaveWebhook(group_id=group.id, household_id=household_2.id, scheduled_time=time.time())
|
||||
)
|
||||
|
||||
# unfiltered_repos and group_repos should find both webhooks
|
||||
for repos in [unfiltered_repos, group_repos]:
|
||||
assert webhook_1 == repos.webhooks.get_one(webhook_1.id)
|
||||
assert webhook_2 == repos.webhooks.get_one(webhook_2.id)
|
||||
all_webhooks = repos.webhooks.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert webhook_1 in all_webhooks
|
||||
assert webhook_2 in all_webhooks
|
||||
|
||||
# household_repos should only find webhooks with the correct household_id
|
||||
assert webhook_1 == household_1_repos.webhooks.get_one(webhook_1.id)
|
||||
assert household_1_repos.webhooks.get_one(webhook_2.id) is None
|
||||
assert [webhook_1] == household_1_repos.webhooks.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
|
||||
assert household_2_repos.webhooks.get_one(webhook_1.id) is None
|
||||
assert webhook_2 == household_2_repos.webhooks.get_one(webhook_2.id)
|
||||
assert [webhook_2] == household_2_repos.webhooks.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
|
||||
# a different group's repos shouldn't find anything
|
||||
other_group = unfiltered_repos.groups.create({"name": random_string()})
|
||||
for household_id in [household_1.id, household_2.id]:
|
||||
other_group_repos = get_repositories(session, group_id=other_group.id, household_id=household_id)
|
||||
assert other_group_repos.webhooks.get_one(webhook_1.id) is None
|
||||
assert other_group_repos.webhooks.get_one(webhook_2.id) is None
|
||||
assert other_group_repos.webhooks.page_all(PaginationQuery(page=1, per_page=-1)).items == []
|
||||
|
||||
|
||||
def test_recipe_repo_filter_by_household_with_proxy(session: Session):
|
||||
unfiltered_repos = get_repositories(session, group_id=None, household_id=None)
|
||||
group = unfiltered_repos.groups.create({"name": random_string()})
|
||||
group_repos = get_repositories(session, group_id=group.id, household_id=None)
|
||||
household_1 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
household_2 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
|
||||
user_1 = group_repos.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"household": household_1.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
user_2 = group_repos.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"household": household_2.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
|
||||
household_1_repos = get_repositories(session, group_id=group.id, household_id=household_1.id)
|
||||
household_2_repos = get_repositories(session, group_id=group.id, household_id=household_2.id)
|
||||
recipe_1 = household_1_repos.recipes.create(
|
||||
Recipe(
|
||||
user_id=user_1.id,
|
||||
group_id=group.id,
|
||||
name=random_string(),
|
||||
)
|
||||
)
|
||||
recipe_2 = household_2_repos.recipes.create(
|
||||
Recipe(
|
||||
user_id=user_2.id,
|
||||
group_id=group.id,
|
||||
name=random_string(),
|
||||
)
|
||||
)
|
||||
assert recipe_1.id and recipe_2.id
|
||||
|
||||
assert household_1_repos.recipes.get_one(recipe_1.slug) == recipe_1
|
||||
assert household_1_repos.recipes.get_one(recipe_2.slug) is None
|
||||
result = household_1_repos.recipes.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(result) == 1
|
||||
assert result[0].id == recipe_1.id
|
||||
|
||||
assert household_2_repos.recipes.get_one(recipe_1.slug) is None
|
||||
assert household_2_repos.recipes.get_one(recipe_2.slug) == recipe_2
|
||||
result = household_2_repos.recipes.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(result) == 1
|
||||
assert result[0].id == recipe_2.id
|
||||
|
||||
|
||||
def test_generic_repo_filter_by_household_with_proxy(session: Session):
|
||||
unfiltered_repos = get_repositories(session, group_id=None, household_id=None)
|
||||
group = unfiltered_repos.groups.create({"name": random_string()})
|
||||
group_repos = get_repositories(session, group_id=group.id, household_id=None)
|
||||
household_1 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
household_2 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
|
||||
user_1 = group_repos.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"household": household_1.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
user_2 = group_repos.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"household": household_2.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
|
||||
household_1_repos = get_repositories(session, group_id=group.id, household_id=household_1.id)
|
||||
household_2_repos = get_repositories(session, group_id=group.id, household_id=household_2.id)
|
||||
shopping_list_service_1 = ShoppingListService(household_1_repos)
|
||||
shopping_list_service_2 = ShoppingListService(household_2_repos)
|
||||
shopping_list_1 = shopping_list_service_1.create_one_list(ShoppingListCreate(name=random_string()), user_1.id)
|
||||
shopping_list_2 = shopping_list_service_2.create_one_list(ShoppingListCreate(name=random_string()), user_2.id)
|
||||
|
||||
assert household_1_repos.group_shopping_lists.get_one(shopping_list_1.id) == shopping_list_1
|
||||
assert household_1_repos.group_shopping_lists.get_one(shopping_list_2.id) is None
|
||||
result = household_1_repos.group_shopping_lists.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(result) == 1
|
||||
assert result[0].id == shopping_list_1.id
|
||||
|
||||
assert household_2_repos.group_shopping_lists.get_one(shopping_list_1.id) is None
|
||||
assert household_2_repos.group_shopping_lists.get_one(shopping_list_2.id) == shopping_list_2
|
||||
result = household_2_repos.group_shopping_lists.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(result) == 1
|
||||
assert result[0].id == shopping_list_2.id
|
||||
|
||||
|
||||
def test_changing_user_changes_household(session: Session):
|
||||
unfiltered_repos = get_repositories(session, group_id=None, household_id=None)
|
||||
group = unfiltered_repos.groups.create({"name": random_string()})
|
||||
group_repos = get_repositories(session, group_id=group.id, household_id=None)
|
||||
household_1 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
household_2 = group_repos.households.create({"name": random_string(), "group_id": group.id})
|
||||
|
||||
user_1 = group_repos.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"household": household_1.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
user_2 = group_repos.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"household": household_2.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
|
||||
household_1_repos = get_repositories(session, group_id=group.id, household_id=household_1.id)
|
||||
household_2_repos = get_repositories(session, group_id=group.id, household_id=household_2.id)
|
||||
|
||||
# create shopping list with user_1/household_1
|
||||
shopping_list = ShoppingListService(household_1_repos).create_one_list(
|
||||
ShoppingListCreate(name=random_string()), user_1.id
|
||||
)
|
||||
|
||||
# only household_1_repos should find the list
|
||||
response = household_1_repos.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert response
|
||||
assert response.user_id == user_1.id
|
||||
response = household_2_repos.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert response is None
|
||||
|
||||
items = household_1_repos.group_shopping_lists.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(items) == 1
|
||||
assert items[0].id == shopping_list.id
|
||||
assert household_2_repos.group_shopping_lists.page_all(PaginationQuery(page=1, per_page=-1)).items == []
|
||||
|
||||
# update shopping list to user_2/household_2 using household_1_repos
|
||||
shopping_list.user_id = user_2.id
|
||||
household_1_repos.group_shopping_lists.update(shopping_list.id, shopping_list)
|
||||
|
||||
# now only household_2_repos should find the list
|
||||
response = household_1_repos.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert response is None
|
||||
response = household_2_repos.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert response
|
||||
assert response.user_id == user_2.id
|
||||
|
||||
items = household_2_repos.group_shopping_lists.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(items) == 1
|
||||
assert items[0].id == shopping_list.id
|
||||
assert household_1_repos.group_shopping_lists.page_all(PaginationQuery(page=1, per_page=-1)).items == []
|
|
@ -3,13 +3,12 @@ from uuid import UUID
|
|||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.recipe.recipe import Recipe
|
||||
from tests.utils import api_routes, random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
@dataclass(slots=True)
|
||||
@dataclass()
|
||||
class SimpleCase:
|
||||
value: str
|
||||
is_valid: bool
|
||||
|
@ -41,8 +40,10 @@ def test_validators_email(api_client: TestClient, unique_user: TestUser):
|
|||
assert response_data["valid"] == user.is_valid
|
||||
|
||||
|
||||
def test_validators_group_name(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
|
||||
def test_validators_group_name(api_client: TestClient, unique_user: TestUser):
|
||||
database = unique_user.repos
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
assert group
|
||||
|
||||
groups = [
|
||||
SimpleCase(value=group.name, is_valid=False),
|
||||
|
@ -65,7 +66,7 @@ class RecipeValidators:
|
|||
|
||||
def test_validators_recipe(api_client: TestClient, random_recipe: Recipe):
|
||||
recipes = [
|
||||
RecipeValidators(name=random_recipe.name, group=random_recipe.group_id, is_valid=False),
|
||||
RecipeValidators(name=random_recipe.name or "", group=random_recipe.group_id, is_valid=False),
|
||||
RecipeValidators(name=random_string(), group=random_recipe.group_id, is_valid=True),
|
||||
RecipeValidators(name=random_string(), group=random_recipe.group_id, is_valid=True),
|
||||
]
|
||||
|
|
|
@ -3,6 +3,7 @@ from fastapi.testclient import TestClient
|
|||
from mealie.schema.group.group_preferences import UpdateGroupPreferences
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.assertion_helpers import assert_ignore_keys
|
||||
from tests.utils.factories import random_bool
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
|
@ -12,8 +13,7 @@ def test_get_preferences(api_client: TestClient, unique_user: TestUser) -> None:
|
|||
|
||||
preferences = response.json()
|
||||
|
||||
assert preferences["recipePublic"] in {True, False}
|
||||
assert preferences["recipeShowNutrition"] in {True, False}
|
||||
assert preferences["privateGroup"] in {True, False}
|
||||
|
||||
|
||||
def test_preferences_in_group(api_client: TestClient, unique_user: TestUser) -> None:
|
||||
|
@ -26,12 +26,11 @@ def test_preferences_in_group(api_client: TestClient, unique_user: TestUser) ->
|
|||
assert group["preferences"] is not None
|
||||
|
||||
# Spot Check
|
||||
assert group["preferences"]["recipePublic"] in {True, False}
|
||||
assert group["preferences"]["recipeShowNutrition"] in {True, False}
|
||||
assert group["preferences"]["privateGroup"] in {True, False}
|
||||
|
||||
|
||||
def test_update_preferences(api_client: TestClient, unique_user: TestUser) -> None:
|
||||
new_data = UpdateGroupPreferences(recipe_public=False, recipe_show_nutrition=True)
|
||||
new_data = UpdateGroupPreferences(private_group=random_bool())
|
||||
|
||||
response = api_client.put(api_routes.groups_preferences, json=new_data.model_dump(), headers=unique_user.token)
|
||||
|
||||
|
@ -40,7 +39,6 @@ def test_update_preferences(api_client: TestClient, unique_user: TestUser) -> No
|
|||
preferences = response.json()
|
||||
|
||||
assert preferences is not None
|
||||
assert preferences["recipePublic"] is False
|
||||
assert preferences["recipeShowNutrition"] is True
|
||||
assert preferences["privateGroup"] == new_data.private_group
|
||||
|
||||
assert_ignore_keys(new_data.model_dump(by_alias=True), preferences, ["id", "groupId"])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.response.pagination import PaginationQuery
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
@ -11,46 +11,49 @@ def test_seed_invalid_locale(api_client: TestClient, unique_user: TestUser):
|
|||
assert resp.status_code == 422
|
||||
|
||||
|
||||
def test_seed_foods(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
|
||||
def test_seed_foods(api_client: TestClient, unique_user: TestUser):
|
||||
CREATED_FOODS = 220
|
||||
database = unique_user.repos
|
||||
|
||||
# Check that the foods was created
|
||||
foods = database.ingredient_foods.by_group(unique_user.group_id).get_all()
|
||||
foods = database.ingredient_foods.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(foods) == 0
|
||||
|
||||
resp = api_client.post(api_routes.groups_seeders_foods, json={"locale": "en-US"}, headers=unique_user.token)
|
||||
assert resp.status_code == 200
|
||||
|
||||
# Check that the foods was created
|
||||
foods = database.ingredient_foods.by_group(unique_user.group_id).get_all()
|
||||
foods = database.ingredient_foods.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(foods) == CREATED_FOODS
|
||||
|
||||
|
||||
def test_seed_units(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
|
||||
def test_seed_units(api_client: TestClient, unique_user: TestUser):
|
||||
CREATED_UNITS = 23
|
||||
database = unique_user.repos
|
||||
|
||||
# Check that the foods was created
|
||||
units = database.ingredient_units.by_group(unique_user.group_id).get_all()
|
||||
units = database.ingredient_units.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(units) == 0
|
||||
|
||||
resp = api_client.post(api_routes.groups_seeders_units, json={"locale": "en-US"}, headers=unique_user.token)
|
||||
assert resp.status_code == 200
|
||||
|
||||
# Check that the foods was created
|
||||
units = database.ingredient_units.by_group(unique_user.group_id).get_all()
|
||||
units = database.ingredient_units.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(units) == CREATED_UNITS
|
||||
|
||||
|
||||
def test_seed_labels(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
|
||||
def test_seed_labels(api_client: TestClient, unique_user: TestUser):
|
||||
CREATED_LABELS = 21
|
||||
database = unique_user.repos
|
||||
|
||||
# Check that the foods was created
|
||||
labels = database.group_multi_purpose_labels.by_group(unique_user.group_id).get_all()
|
||||
labels = database.group_multi_purpose_labels.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(labels) == 0
|
||||
|
||||
resp = api_client.post(api_routes.groups_seeders_labels, json={"locale": "en-US"}, headers=unique_user.token)
|
||||
assert resp.status_code == 200
|
||||
|
||||
# Check that the foods was created
|
||||
labels = database.group_multi_purpose_labels.by_group(unique_user.group_id).get_all()
|
||||
labels = database.group_multi_purpose_labels.page_all(PaginationQuery(page=1, per_page=-1)).items
|
||||
assert len(labels) == CREATED_LABELS
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from tests.utils import api_routes, random_int, random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
def test_get_group_members(api_client: TestClient, unique_user: TestUser, h2_user: TestUser):
|
||||
response = api_client.get(api_routes.groups_members, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
members = response.json()
|
||||
assert len(members) >= 2
|
||||
|
||||
all_ids = [x["id"] for x in members]
|
||||
|
||||
assert str(unique_user.user_id) in all_ids
|
||||
assert str(h2_user.user_id) in all_ids
|
||||
|
||||
|
||||
def test_get_group_members_filtered(api_client: TestClient, unique_user: TestUser, h2_user: TestUser):
|
||||
response = api_client.get(
|
||||
api_routes.groups_members, params={"householdId": h2_user.household_id}, headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
members = response.json()
|
||||
assert len(members) >= 1
|
||||
|
||||
all_ids = [x["id"] for x in members]
|
||||
|
||||
assert str(unique_user.user_id) not in all_ids
|
||||
assert str(h2_user.user_id) in all_ids
|
||||
|
||||
|
||||
def test_get_households(api_client: TestClient, admin_user: TestUser):
|
||||
households = [admin_user.repos.households.create({"name": random_string()}) for _ in range(5)]
|
||||
response = api_client.get(api_routes.groups_households, headers=admin_user.token)
|
||||
response_ids = [item["id"] for item in response.json()]
|
||||
for household in households:
|
||||
assert str(household.id) in response_ids
|
||||
|
||||
|
||||
def test_get_households_filtered(unfiltered_database: AllRepositories, api_client: TestClient, admin_user: TestUser):
|
||||
group_1_id = admin_user.group_id
|
||||
group_2_id = str(unfiltered_database.groups.create({"name": random_string()}).id)
|
||||
|
||||
group_1_households = [
|
||||
unfiltered_database.households.create({"name": random_string(), "group_id": group_1_id})
|
||||
for _ in range(random_int(2, 5))
|
||||
]
|
||||
group_2_households = [
|
||||
unfiltered_database.households.create({"name": random_string(), "group_id": group_2_id})
|
||||
for _ in range(random_int(2, 5))
|
||||
]
|
||||
|
||||
response = api_client.get(api_routes.groups_households, headers=admin_user.token)
|
||||
response_ids = [item["id"] for item in response.json()]
|
||||
for household in group_1_households:
|
||||
assert str(household.id) in response_ids
|
||||
for household in group_2_households:
|
||||
assert str(household.id) not in response_ids
|
|
@ -6,7 +6,6 @@ import pytest
|
|||
from fastapi.testclient import TestClient
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.cookbook.cookbook import ReadCookBook, SaveCookBook
|
||||
from tests import utils
|
||||
from tests.utils import api_routes
|
||||
|
@ -14,7 +13,7 @@ from tests.utils.factories import random_string
|
|||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
def get_page_data(group_id: UUID | str):
|
||||
def get_page_data(group_id: UUID | str, household_id: UUID4 | str):
|
||||
name_and_slug = random_string(10)
|
||||
return {
|
||||
"name": name_and_slug,
|
||||
|
@ -23,6 +22,7 @@ def get_page_data(group_id: UUID | str):
|
|||
"position": 0,
|
||||
"categories": [],
|
||||
"group_id": str(group_id),
|
||||
"household_id": str(household_id),
|
||||
}
|
||||
|
||||
|
||||
|
@ -35,11 +35,13 @@ class TestCookbook:
|
|||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def cookbooks(database: AllRepositories, unique_user: TestUser) -> list[TestCookbook]:
|
||||
def cookbooks(unique_user: TestUser) -> list[TestCookbook]:
|
||||
database = unique_user.repos
|
||||
|
||||
data: list[ReadCookBook] = []
|
||||
yield_data: list[TestCookbook] = []
|
||||
for _ in range(3):
|
||||
cb = database.cookbooks.create(SaveCookBook(**get_page_data(unique_user.group_id)))
|
||||
cb = database.cookbooks.create(SaveCookBook(**get_page_data(unique_user.group_id, unique_user.household_id)))
|
||||
data.append(cb)
|
||||
yield_data.append(TestCookbook(id=cb.id, slug=cb.slug, name=cb.name, data=cb.model_dump()))
|
||||
|
||||
|
@ -53,14 +55,14 @@ def cookbooks(database: AllRepositories, unique_user: TestUser) -> list[TestCook
|
|||
|
||||
|
||||
def test_create_cookbook(api_client: TestClient, unique_user: TestUser):
|
||||
page_data = get_page_data(unique_user.group_id)
|
||||
response = api_client.post(api_routes.groups_cookbooks, json=page_data, headers=unique_user.token)
|
||||
page_data = get_page_data(unique_user.group_id, unique_user.household_id)
|
||||
response = api_client.post(api_routes.households_cookbooks, json=page_data, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
|
||||
def test_read_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
|
||||
sample = random.choice(cookbooks)
|
||||
response = api_client.get(api_routes.groups_cookbooks_item_id(sample.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_cookbooks_item_id(sample.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
page_data = response.json()
|
||||
|
@ -74,16 +76,16 @@ def test_read_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks:
|
|||
def test_update_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
|
||||
cookbook = random.choice(cookbooks)
|
||||
|
||||
update_data = get_page_data(unique_user.group_id)
|
||||
update_data = get_page_data(unique_user.group_id, unique_user.household_id)
|
||||
|
||||
update_data["name"] = random_string(10)
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_cookbooks_item_id(cookbook.id), json=update_data, headers=unique_user.token
|
||||
api_routes.households_cookbooks_item_id(cookbook.id), json=update_data, headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.groups_cookbooks_item_id(cookbook.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_cookbooks_item_id(cookbook.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
page_data = response.json()
|
||||
|
@ -99,10 +101,12 @@ def test_update_cookbooks_many(api_client: TestClient, unique_user: TestUser, co
|
|||
page["position"] = x
|
||||
page["group_id"] = str(unique_user.group_id)
|
||||
|
||||
response = api_client.put(api_routes.groups_cookbooks, json=utils.jsonify(reverse_order), headers=unique_user.token)
|
||||
response = api_client.put(
|
||||
api_routes.households_cookbooks, json=utils.jsonify(reverse_order), headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.groups_cookbooks, headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_cookbooks, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
known_ids = [x.id for x in cookbooks]
|
||||
|
@ -115,9 +119,9 @@ def test_update_cookbooks_many(api_client: TestClient, unique_user: TestUser, co
|
|||
|
||||
def test_delete_cookbook(api_client: TestClient, unique_user: TestUser, cookbooks: list[TestCookbook]):
|
||||
sample = random.choice(cookbooks)
|
||||
response = api_client.delete(api_routes.groups_cookbooks_item_id(sample.id), headers=unique_user.token)
|
||||
response = api_client.delete(api_routes.households_cookbooks_item_id(sample.id), headers=unique_user.token)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.groups_cookbooks_item_id(sample.slug), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_cookbooks_item_id(sample.slug), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
|
@ -9,7 +9,7 @@ from tests.utils.fixture_schemas import TestUser
|
|||
@pytest.fixture(scope="function")
|
||||
def invite(api_client: TestClient, unique_user: TestUser) -> None:
|
||||
# Test Creation
|
||||
r = api_client.post(api_routes.groups_invitations, json={"uses": 2}, headers=unique_user.token)
|
||||
r = api_client.post(api_routes.households_invitations, json={"uses": 2}, headers=unique_user.token)
|
||||
assert r.status_code == 201
|
||||
invitation = r.json()
|
||||
return invitation["token"]
|
||||
|
@ -17,7 +17,7 @@ def invite(api_client: TestClient, unique_user: TestUser) -> None:
|
|||
|
||||
def test_get_all_invitation(api_client: TestClient, unique_user: TestUser, invite: str) -> None:
|
||||
# Get All Invites
|
||||
r = api_client.get(api_routes.groups_invitations, headers=unique_user.token)
|
||||
r = api_client.get(api_routes.households_invitations, headers=unique_user.token)
|
||||
|
||||
assert r.status_code == 200
|
||||
|
||||
|
@ -27,13 +27,15 @@ def test_get_all_invitation(api_client: TestClient, unique_user: TestUser, invit
|
|||
|
||||
for item in items:
|
||||
assert item["groupId"] == unique_user.group_id
|
||||
assert item["householdId"] == unique_user.household_id
|
||||
assert item["token"] == invite
|
||||
|
||||
|
||||
def register_user(api_client, invite):
|
||||
def register_user(api_client: TestClient, invite: str):
|
||||
# Test User can Join Group
|
||||
registration = user_registration_factory()
|
||||
registration.group = ""
|
||||
registration.household = ""
|
||||
registration.group_token = invite
|
||||
|
||||
response = api_client.post(api_routes.users_register, json=registration.model_dump(by_alias=True))
|
||||
|
@ -52,11 +54,12 @@ def test_group_invitation_link(api_client: TestClient, unique_user: TestUser, in
|
|||
token = r.json().get("access_token")
|
||||
assert token is not None
|
||||
|
||||
# Check user Group is Same
|
||||
# Check user Group and Household match
|
||||
r = api_client.get(api_routes.users_self, headers={"Authorization": f"Bearer {token}"})
|
||||
|
||||
assert r.status_code == 200
|
||||
assert r.json()["groupId"] == unique_user.group_id
|
||||
assert r.json()["householdId"] == unique_user.household_id
|
||||
|
||||
|
||||
def test_group_invitation_delete_after_uses(api_client: TestClient, invite: str) -> None:
|
|
@ -9,7 +9,9 @@ from tests.utils.fixture_schemas import TestUser
|
|||
|
||||
|
||||
def route_all_slice(page: int, perPage: int, start_date: str, end_date: str):
|
||||
return f"{api_routes.groups_mealplans}?page={page}&perPage={perPage}&start_date={start_date}&end_date={end_date}"
|
||||
return (
|
||||
f"{api_routes.households_mealplans}?page={page}&perPage={perPage}&start_date={start_date}&end_date={end_date}"
|
||||
)
|
||||
|
||||
|
||||
def test_create_mealplan_no_recipe(api_client: TestClient, unique_user: TestUser):
|
||||
|
@ -20,7 +22,7 @@ def test_create_mealplan_no_recipe(api_client: TestClient, unique_user: TestUser
|
|||
).model_dump()
|
||||
new_plan["date"] = datetime.now(timezone.utc).date().strftime("%Y-%m-%d")
|
||||
|
||||
response = api_client.post(api_routes.groups_mealplans, json=new_plan, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_mealplans, json=new_plan, headers=unique_user.token)
|
||||
|
||||
assert response.status_code == 201
|
||||
|
||||
|
@ -44,7 +46,7 @@ def test_create_mealplan_with_recipe(api_client: TestClient, unique_user: TestUs
|
|||
new_plan["date"] = datetime.now(timezone.utc).date().strftime("%Y-%m-%d")
|
||||
new_plan["recipeId"] = str(recipe_id)
|
||||
|
||||
response = api_client.post(api_routes.groups_mealplans, json=new_plan, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_mealplans, json=new_plan, headers=unique_user.token)
|
||||
response_json = response.json()
|
||||
assert response.status_code == 201
|
||||
|
||||
|
@ -61,7 +63,7 @@ def test_crud_mealplan(api_client: TestClient, unique_user: TestUser):
|
|||
|
||||
# Create
|
||||
new_plan["date"] = datetime.now(timezone.utc).date().strftime("%Y-%m-%d")
|
||||
response = api_client.post(api_routes.groups_mealplans, json=new_plan, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_mealplans, json=new_plan, headers=unique_user.token)
|
||||
response_json = response.json()
|
||||
assert response.status_code == 201
|
||||
plan_id = response_json["id"]
|
||||
|
@ -71,7 +73,7 @@ def test_crud_mealplan(api_client: TestClient, unique_user: TestUser):
|
|||
response_json["text"] = random_string()
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_mealplans_item_id(plan_id), headers=unique_user.token, json=response_json
|
||||
api_routes.households_mealplans_item_id(plan_id), headers=unique_user.token, json=response_json
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
@ -80,11 +82,11 @@ def test_crud_mealplan(api_client: TestClient, unique_user: TestUser):
|
|||
assert response.json()["text"] == response_json["text"]
|
||||
|
||||
# Delete
|
||||
response = api_client.delete(api_routes.groups_mealplans_item_id(plan_id), headers=unique_user.token)
|
||||
response = api_client.delete(api_routes.households_mealplans_item_id(plan_id), headers=unique_user.token)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.groups_mealplans_item_id(plan_id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_mealplans_item_id(plan_id), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
|
@ -98,10 +100,12 @@ def test_get_all_mealplans(api_client: TestClient, unique_user: TestUser):
|
|||
).model_dump()
|
||||
|
||||
new_plan["date"] = datetime.now(timezone.utc).date().strftime("%Y-%m-%d")
|
||||
response = api_client.post(api_routes.groups_mealplans, json=new_plan, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_mealplans, json=new_plan, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
response = api_client.get(api_routes.groups_mealplans, headers=unique_user.token, params={"page": 1, "perPage": -1})
|
||||
response = api_client.get(
|
||||
api_routes.households_mealplans, headers=unique_user.token, params={"page": 1, "perPage": -1}
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert len(response.json()["items"]) >= 3
|
||||
|
@ -120,7 +124,7 @@ def test_get_slice_mealplans(api_client: TestClient, unique_user: TestUser):
|
|||
# Add the meal plans to the database
|
||||
for meal_plan in meal_plans:
|
||||
meal_plan["date"] = meal_plan["date"].strftime("%Y-%m-%d")
|
||||
response = api_client.post(api_routes.groups_mealplans, json=meal_plan, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_mealplans, json=meal_plan, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
# Get meal slice of meal plans from database
|
||||
|
@ -151,11 +155,11 @@ def test_get_mealplan_today(api_client: TestClient, unique_user: TestUser):
|
|||
# Add the meal plans to the database
|
||||
for meal_plan in test_meal_plans:
|
||||
meal_plan["date"] = meal_plan["date"].strftime("%Y-%m-%d")
|
||||
response = api_client.post(api_routes.groups_mealplans, json=meal_plan, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_mealplans, json=meal_plan, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
# Get meal plan for today
|
||||
response = api_client.get(api_routes.groups_mealplans_today, headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_mealplans_today, headers=unique_user.token)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
|
@ -3,8 +3,7 @@ from uuid import UUID
|
|||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.all_repositories import AllRepositories
|
||||
from mealie.schema.meal_plan.plan_rules import PlanRulesOut, PlanRulesSave
|
||||
from mealie.schema.meal_plan.plan_rules import PlanRulesOut
|
||||
from mealie.schema.recipe.recipe import RecipeCategory
|
||||
from mealie.schema.recipe.recipe_category import CategorySave
|
||||
from tests import utils
|
||||
|
@ -13,10 +12,8 @@ from tests.utils.fixture_schemas import TestUser
|
|||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def category(
|
||||
database: AllRepositories,
|
||||
unique_user: TestUser,
|
||||
):
|
||||
def category(unique_user: TestUser):
|
||||
database = unique_user.repos
|
||||
slug = utils.random_string(length=10)
|
||||
model = database.categories.create(CategorySave(group_id=unique_user.group_id, slug=slug, name=slug))
|
||||
|
||||
|
@ -29,42 +26,45 @@ def category(
|
|||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def plan_rule(database: AllRepositories, unique_user: TestUser):
|
||||
schema = PlanRulesSave(
|
||||
group_id=unique_user.group_id,
|
||||
day="monday",
|
||||
entry_type="breakfast",
|
||||
categories=[],
|
||||
)
|
||||
|
||||
model = database.group_meal_plan_rules.create(schema)
|
||||
|
||||
yield model
|
||||
|
||||
try:
|
||||
database.group_meal_plan_rules.delete(model.id)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
def test_group_mealplan_rules_create(
|
||||
api_client: TestClient, unique_user: TestUser, category: RecipeCategory, database: AllRepositories
|
||||
):
|
||||
def plan_rule(api_client: TestClient, unique_user: TestUser):
|
||||
payload = {
|
||||
"groupId": unique_user.group_id,
|
||||
"householdId": unique_user.household_id,
|
||||
"day": "monday",
|
||||
"entryType": "breakfast",
|
||||
"categories": [],
|
||||
}
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.households_mealplans_rules, json=utils.jsonify(payload), headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 201
|
||||
plan_rule = PlanRulesOut.model_validate(response.json())
|
||||
yield plan_rule
|
||||
|
||||
# cleanup
|
||||
api_client.delete(api_routes.households_mealplans_rules_item_id(plan_rule.id), headers=unique_user.token)
|
||||
|
||||
|
||||
def test_group_mealplan_rules_create(api_client: TestClient, unique_user: TestUser, category: RecipeCategory):
|
||||
database = unique_user.repos
|
||||
payload = {
|
||||
"groupId": unique_user.group_id,
|
||||
"householdId": unique_user.household_id,
|
||||
"day": "monday",
|
||||
"entryType": "breakfast",
|
||||
"categories": [category.model_dump()],
|
||||
}
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_mealplans_rules, json=utils.jsonify(payload), headers=unique_user.token
|
||||
api_routes.households_mealplans_rules, json=utils.jsonify(payload), headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 201
|
||||
|
||||
# Validate the response data
|
||||
response_data = response.json()
|
||||
assert response_data["groupId"] == str(unique_user.group_id)
|
||||
assert response_data["householdId"] == str(unique_user.household_id)
|
||||
assert response_data["day"] == "monday"
|
||||
assert response_data["entryType"] == "breakfast"
|
||||
assert len(response_data["categories"]) == 1
|
||||
|
@ -72,8 +72,10 @@ def test_group_mealplan_rules_create(
|
|||
|
||||
# Validate database entry
|
||||
rule = database.group_meal_plan_rules.get_one(UUID(response_data["id"]))
|
||||
assert rule
|
||||
|
||||
assert str(rule.group_id) == unique_user.group_id
|
||||
assert str(rule.household_id) == unique_user.household_id
|
||||
assert rule.day == "monday"
|
||||
assert rule.entry_type == "breakfast"
|
||||
assert len(rule.categories) == 1
|
||||
|
@ -84,13 +86,14 @@ def test_group_mealplan_rules_create(
|
|||
|
||||
|
||||
def test_group_mealplan_rules_read(api_client: TestClient, unique_user: TestUser, plan_rule: PlanRulesOut):
|
||||
response = api_client.get(api_routes.groups_mealplans_rules_item_id(plan_rule.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_mealplans_rules_item_id(plan_rule.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
# Validate the response data
|
||||
response_data = response.json()
|
||||
assert response_data["id"] == str(plan_rule.id)
|
||||
assert response_data["groupId"] == str(unique_user.group_id)
|
||||
assert response_data["householdId"] == str(unique_user.household_id)
|
||||
assert response_data["day"] == "monday"
|
||||
assert response_data["entryType"] == "breakfast"
|
||||
assert len(response_data["categories"]) == 0
|
||||
|
@ -99,12 +102,13 @@ def test_group_mealplan_rules_read(api_client: TestClient, unique_user: TestUser
|
|||
def test_group_mealplan_rules_update(api_client: TestClient, unique_user: TestUser, plan_rule: PlanRulesOut):
|
||||
payload = {
|
||||
"groupId": unique_user.group_id,
|
||||
"householdId": unique_user.household_id,
|
||||
"day": "tuesday",
|
||||
"entryType": "lunch",
|
||||
}
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_mealplans_rules_item_id(plan_rule.id), json=payload, headers=unique_user.token
|
||||
api_routes.households_mealplans_rules_item_id(plan_rule.id), json=payload, headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
@ -112,16 +116,18 @@ def test_group_mealplan_rules_update(api_client: TestClient, unique_user: TestUs
|
|||
response_data = response.json()
|
||||
assert response_data["id"] == str(plan_rule.id)
|
||||
assert response_data["groupId"] == str(unique_user.group_id)
|
||||
assert response_data["householdId"] == str(unique_user.household_id)
|
||||
assert response_data["day"] == "tuesday"
|
||||
assert response_data["entryType"] == "lunch"
|
||||
assert len(response_data["categories"]) == 0
|
||||
|
||||
|
||||
def test_group_mealplan_rules_delete(
|
||||
api_client: TestClient, unique_user: TestUser, plan_rule: PlanRulesOut, database: AllRepositories
|
||||
):
|
||||
response = api_client.delete(api_routes.groups_mealplans_rules_item_id(plan_rule.id), headers=unique_user.token)
|
||||
def test_group_mealplan_rules_delete(api_client: TestClient, unique_user: TestUser, plan_rule: PlanRulesOut):
|
||||
response = api_client.get(api_routes.households_mealplans_rules_item_id(plan_rule.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
# Validate no entry in database
|
||||
assert database.group_meal_plan_rules.get_one(plan_rule.id) is None
|
||||
response = api_client.delete(api_routes.households_mealplans_rules_item_id(plan_rule.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.households_mealplans_rules_item_id(plan_rule.id), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
|
@ -1,6 +1,6 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.schema.group.group_events import GroupEventNotifierCreate, GroupEventNotifierOptions
|
||||
from mealie.schema.household.group_events import GroupEventNotifierCreate, GroupEventNotifierOptions
|
||||
from mealie.services.event_bus_service.event_bus_listeners import AppriseEventListener
|
||||
from mealie.services.event_bus_service.event_bus_service import Event
|
||||
from mealie.services.event_bus_service.event_types import (
|
||||
|
@ -59,7 +59,7 @@ def event_generator():
|
|||
|
||||
def test_create_notification(api_client: TestClient, unique_user: TestUser):
|
||||
payload = notifier_generator()
|
||||
response = api_client.post(api_routes.groups_events_notifications, json=payload, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_events_notifications, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
payload_as_dict = response.json()
|
||||
|
@ -72,13 +72,13 @@ def test_create_notification(api_client: TestClient, unique_user: TestUser):
|
|||
|
||||
# Cleanup
|
||||
response = api_client.delete(
|
||||
api_routes.groups_events_notifications_item_id(payload_as_dict["id"]), headers=unique_user.token
|
||||
api_routes.households_events_notifications_item_id(payload_as_dict["id"]), headers=unique_user.token
|
||||
)
|
||||
|
||||
|
||||
def test_ensure_apprise_url_is_secret(api_client: TestClient, unique_user: TestUser):
|
||||
payload = notifier_generator()
|
||||
response = api_client.post(api_routes.groups_events_notifications, json=payload, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_events_notifications, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
payload_as_dict = response.json()
|
||||
|
@ -89,7 +89,7 @@ def test_ensure_apprise_url_is_secret(api_client: TestClient, unique_user: TestU
|
|||
|
||||
def test_update_apprise_notification(api_client: TestClient, unique_user: TestUser):
|
||||
payload = notifier_generator()
|
||||
response = api_client.post(api_routes.groups_events_notifications, json=payload, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_events_notifications, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
update_payload = response.json()
|
||||
|
@ -100,7 +100,7 @@ def test_update_apprise_notification(api_client: TestClient, unique_user: TestUs
|
|||
update_payload["options"] = preferences_generator()
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_events_notifications_item_id(update_payload["id"]),
|
||||
api_routes.households_events_notifications_item_id(update_payload["id"]),
|
||||
json=update_payload,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -109,7 +109,7 @@ def test_update_apprise_notification(api_client: TestClient, unique_user: TestUs
|
|||
|
||||
# Re-Get The Item
|
||||
response = api_client.get(
|
||||
api_routes.groups_events_notifications_item_id(update_payload["id"]), headers=unique_user.token
|
||||
api_routes.households_events_notifications_item_id(update_payload["id"]), headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
@ -122,24 +122,24 @@ def test_update_apprise_notification(api_client: TestClient, unique_user: TestUs
|
|||
|
||||
# Cleanup
|
||||
response = api_client.delete(
|
||||
api_routes.groups_events_notifications_item_id(update_payload["id"]), headers=unique_user.token
|
||||
api_routes.households_events_notifications_item_id(update_payload["id"]), headers=unique_user.token
|
||||
)
|
||||
|
||||
|
||||
def test_delete_apprise_notification(api_client: TestClient, unique_user: TestUser):
|
||||
payload = notifier_generator()
|
||||
response = api_client.post(api_routes.groups_events_notifications, json=payload, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_events_notifications, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
||||
payload_as_dict = response.json()
|
||||
|
||||
response = api_client.delete(
|
||||
api_routes.groups_events_notifications_item_id(payload_as_dict["id"]), headers=unique_user.token
|
||||
api_routes.households_events_notifications_item_id(payload_as_dict["id"]), headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 204
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_events_notifications_item_id(payload_as_dict["id"]), headers=unique_user.token
|
||||
api_routes.households_events_notifications_item_id(payload_as_dict["id"]), headers=unique_user.token
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.schema.group.group_recipe_action import (
|
||||
from mealie.schema.household.group_recipe_action import (
|
||||
CreateGroupRecipeAction,
|
||||
GroupRecipeActionOut,
|
||||
GroupRecipeActionType,
|
||||
|
@ -22,7 +22,7 @@ def new_link_action() -> CreateGroupRecipeAction:
|
|||
def test_group_recipe_actions_create_one(api_client: TestClient, unique_user: TestUser):
|
||||
action_in = new_link_action()
|
||||
response = api_client.post(
|
||||
api_routes.groups_recipe_actions,
|
||||
api_routes.households_recipe_actions,
|
||||
json=action_in.model_dump(),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -31,6 +31,7 @@ def test_group_recipe_actions_create_one(api_client: TestClient, unique_user: Te
|
|||
action_out = GroupRecipeActionOut(**data)
|
||||
assert action_out.id
|
||||
assert str(action_out.group_id) == unique_user.group_id
|
||||
assert str(action_out.household_id) == unique_user.household_id
|
||||
assert action_out.action_type == action_in.action_type
|
||||
assert action_out.title == action_in.title
|
||||
assert action_out.url == action_in.url
|
||||
|
@ -40,14 +41,14 @@ def test_group_recipe_actions_get_all(api_client: TestClient, unique_user: TestU
|
|||
expected_ids: set[str] = set()
|
||||
for _ in range(random_int(3, 5)):
|
||||
response = api_client.post(
|
||||
api_routes.groups_recipe_actions,
|
||||
api_routes.households_recipe_actions,
|
||||
json=new_link_action().model_dump(),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
data = assert_deserialize(response, 201)
|
||||
expected_ids.add(data["id"])
|
||||
|
||||
response = api_client.get(api_routes.groups_recipe_actions, headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_recipe_actions, headers=unique_user.token)
|
||||
data = assert_deserialize(response, 200)
|
||||
fetched_ids = {item["id"] for item in data["items"]}
|
||||
for expected_id in expected_ids:
|
||||
|
@ -60,7 +61,7 @@ def test_group_recipe_actions_get_one(
|
|||
):
|
||||
action_in = new_link_action()
|
||||
response = api_client.post(
|
||||
api_routes.groups_recipe_actions,
|
||||
api_routes.households_recipe_actions,
|
||||
json=action_in.model_dump(),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -73,7 +74,7 @@ def test_group_recipe_actions_get_one(
|
|||
fetch_user = g2_user
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_recipe_actions_item_id(expected_action_out.id),
|
||||
api_routes.households_recipe_actions_item_id(expected_action_out.id),
|
||||
headers=fetch_user.token,
|
||||
)
|
||||
if not is_own_group:
|
||||
|
@ -88,7 +89,7 @@ def test_group_recipe_actions_get_one(
|
|||
def test_group_recipe_actions_update_one(api_client: TestClient, unique_user: TestUser):
|
||||
action_in = new_link_action()
|
||||
response = api_client.post(
|
||||
api_routes.groups_recipe_actions,
|
||||
api_routes.households_recipe_actions,
|
||||
json=action_in.model_dump(),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -98,7 +99,7 @@ def test_group_recipe_actions_update_one(api_client: TestClient, unique_user: Te
|
|||
new_title = random_string()
|
||||
data["title"] = new_title
|
||||
response = api_client.put(
|
||||
api_routes.groups_recipe_actions_item_id(action_id),
|
||||
api_routes.households_recipe_actions_item_id(action_id),
|
||||
json=data,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -111,15 +112,15 @@ def test_group_recipe_actions_update_one(api_client: TestClient, unique_user: Te
|
|||
def test_group_recipe_actions_delete_one(api_client: TestClient, unique_user: TestUser):
|
||||
action_in = new_link_action()
|
||||
response = api_client.post(
|
||||
api_routes.groups_recipe_actions,
|
||||
api_routes.households_recipe_actions,
|
||||
json=action_in.model_dump(),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
data = assert_deserialize(response, 201)
|
||||
action_id = data["id"]
|
||||
|
||||
response = api_client.delete(api_routes.groups_recipe_actions_item_id(action_id), headers=unique_user.token)
|
||||
response = api_client.delete(api_routes.households_recipe_actions_item_id(action_id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.groups_recipe_actions_item_id(action_id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_recipe_actions_item_id(action_id), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
|
@ -7,7 +7,7 @@ from fastapi.testclient import TestClient
|
|||
from pydantic import UUID4
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.group.group_shopping_list import ShoppingListItemOut, ShoppingListOut
|
||||
from mealie.schema.household.group_shopping_list import ShoppingListItemOut, ShoppingListOut
|
||||
from mealie.schema.recipe.recipe_ingredient import SaveIngredientFood
|
||||
from tests import utils
|
||||
from tests.utils import api_routes
|
||||
|
@ -42,14 +42,14 @@ def test_shopping_list_items_create_one(
|
|||
) -> None:
|
||||
item = create_item(shopping_list.id)
|
||||
|
||||
response = api_client.post(api_routes.groups_shopping_items, json=item, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_items, json=item, headers=unique_user.token)
|
||||
as_json = utils.assert_deserialize(response, 201)
|
||||
assert len(as_json["createdItems"]) == 1
|
||||
|
||||
# Test Item is Getable
|
||||
created_item_id = as_json["createdItems"][0]["id"]
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_items_item_id(created_item_id),
|
||||
api_routes.households_shopping_items_item_id(created_item_id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -59,7 +59,7 @@ def test_shopping_list_items_create_one(
|
|||
|
||||
# Test Item In List
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
response_list = utils.assert_deserialize(response, 200)
|
||||
|
@ -76,7 +76,7 @@ def test_shopping_list_items_create_many(
|
|||
items = [create_item(shopping_list.id) for _ in range(10)]
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_items_create_bulk,
|
||||
api_routes.households_shopping_items_create_bulk,
|
||||
json=items,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -88,7 +88,7 @@ def test_shopping_list_items_create_many(
|
|||
# test items in list
|
||||
created_item_ids = [item["id"] for item in as_json["createdItems"]]
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -107,15 +107,13 @@ def test_shopping_list_items_create_many(
|
|||
|
||||
|
||||
def test_shopping_list_items_auto_assign_label_with_food_without_label(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
shopping_list: ShoppingListOut,
|
||||
database: AllRepositories,
|
||||
api_client: TestClient, unique_user: TestUser, shopping_list: ShoppingListOut
|
||||
):
|
||||
database = unique_user.repos
|
||||
food = database.ingredient_foods.create(SaveIngredientFood(name=random_string(10), group_id=unique_user.group_id))
|
||||
|
||||
item = create_item(shopping_list.id, food_id=str(food.id))
|
||||
response = api_client.post(api_routes.groups_shopping_items, json=item, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_items, json=item, headers=unique_user.token)
|
||||
as_json = utils.assert_deserialize(response, 201)
|
||||
assert len(as_json["createdItems"]) == 1
|
||||
|
||||
|
@ -125,18 +123,16 @@ def test_shopping_list_items_auto_assign_label_with_food_without_label(
|
|||
|
||||
|
||||
def test_shopping_list_items_auto_assign_label_with_food_with_label(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
shopping_list: ShoppingListOut,
|
||||
database: AllRepositories,
|
||||
api_client: TestClient, unique_user: TestUser, shopping_list: ShoppingListOut
|
||||
):
|
||||
database = unique_user.repos
|
||||
label = database.group_multi_purpose_labels.create({"name": random_string(10), "group_id": unique_user.group_id})
|
||||
food = database.ingredient_foods.create(
|
||||
SaveIngredientFood(name=random_string(10), group_id=unique_user.group_id, label_id=label.id)
|
||||
)
|
||||
|
||||
item = create_item(shopping_list.id, food_id=str(food.id))
|
||||
response = api_client.post(api_routes.groups_shopping_items, json=item, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_items, json=item, headers=unique_user.token)
|
||||
as_json = utils.assert_deserialize(response, 201)
|
||||
assert len(as_json["createdItems"]) == 1
|
||||
|
||||
|
@ -151,9 +147,9 @@ def test_shopping_list_items_auto_assign_label_with_food_search(
|
|||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
shopping_list: ShoppingListOut,
|
||||
database: AllRepositories,
|
||||
use_fuzzy_name: bool,
|
||||
):
|
||||
database = unique_user.repos
|
||||
label = database.group_multi_purpose_labels.create({"name": random_string(10), "group_id": unique_user.group_id})
|
||||
food = database.ingredient_foods.create(
|
||||
SaveIngredientFood(name=random_string(20), group_id=unique_user.group_id, label_id=label.id)
|
||||
|
@ -165,7 +161,7 @@ def test_shopping_list_items_auto_assign_label_with_food_search(
|
|||
name = name + random_string(2)
|
||||
item["note"] = name
|
||||
|
||||
response = api_client.post(api_routes.groups_shopping_items, json=item, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_items, json=item, headers=unique_user.token)
|
||||
as_json = utils.assert_deserialize(response, 201)
|
||||
assert len(as_json["createdItems"]) == 1
|
||||
|
||||
|
@ -183,7 +179,7 @@ def test_shopping_list_items_get_one(
|
|||
for _ in range(3):
|
||||
item = random.choice(list_with_items.list_items)
|
||||
|
||||
response = api_client.get(api_routes.groups_shopping_items_item_id(item.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_items_item_id(item.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
|
@ -197,13 +193,13 @@ def test_shopping_list_items_get_all(
|
|||
"perPage": -1,
|
||||
"queryFilter": f"shopping_list_id={list_with_items.id}",
|
||||
}
|
||||
response = api_client.get(api_routes.groups_shopping_items, params=params, headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_items, params=params, headers=unique_user.token)
|
||||
pagination_json = utils.assert_deserialize(response, 200)
|
||||
assert len(pagination_json["items"]) == len(list_with_items.list_items)
|
||||
|
||||
|
||||
def test_shopping_list_items_get_one_404(api_client: TestClient, unique_user: TestUser) -> None:
|
||||
response = api_client.get(api_routes.groups_shopping_items_item_id(uuid4()), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_items_item_id(uuid4()), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
|
@ -221,7 +217,7 @@ def test_shopping_list_items_update_one(
|
|||
update_data["id"] = str(item.id)
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items_item_id(item.id),
|
||||
api_routes.households_shopping_items_item_id(item.id),
|
||||
json=update_data,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -235,7 +231,7 @@ def test_shopping_list_items_update_one(
|
|||
|
||||
# make sure the list didn't change sizes
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(list_with_items.id),
|
||||
api_routes.households_shopping_lists_item_id(list_with_items.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -251,7 +247,7 @@ def test_shopping_list_items_update_many(
|
|||
item["quantity"] += 10
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_items_create_bulk,
|
||||
api_routes.households_shopping_items_create_bulk,
|
||||
json=items,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -265,7 +261,7 @@ def test_shopping_list_items_update_many(
|
|||
item_quantity_map[update_item["id"]] = update_item["quantity"]
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items,
|
||||
api_routes.households_shopping_items,
|
||||
json=as_json["createdItems"],
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -277,7 +273,7 @@ def test_shopping_list_items_update_many(
|
|||
|
||||
# make sure the list didn't change sizes
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -306,12 +302,12 @@ def test_shopping_list_items_update_many_reorder(
|
|||
# update list
|
||||
# the default serializer fails on certain complex objects, so we use FastAPI's serializer first
|
||||
as_dict = utils.jsonify(as_dict)
|
||||
response = api_client.put(api_routes.groups_shopping_items, json=as_dict, headers=unique_user.token)
|
||||
response = api_client.put(api_routes.households_shopping_items, json=as_dict, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
# retrieve list and check positions against list
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(list_with_items.id),
|
||||
api_routes.households_shopping_lists_item_id(list_with_items.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
response_list = utils.assert_deserialize(response, 200)
|
||||
|
@ -329,11 +325,11 @@ def test_shopping_list_items_delete_one(
|
|||
item = random.choice(list_with_items.list_items)
|
||||
|
||||
# Delete Item
|
||||
response = api_client.delete(api_routes.groups_shopping_items_item_id(item.id), headers=unique_user.token)
|
||||
response = api_client.delete(api_routes.households_shopping_items_item_id(item.id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
# Validate Get Item Returns 404
|
||||
response = api_client.get(api_routes.groups_shopping_items_item_id(item.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_items_item_id(item.id), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
||||
|
@ -353,7 +349,7 @@ def test_shopping_list_items_update_many_consolidates_common_items(
|
|||
|
||||
# update list
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items,
|
||||
api_routes.households_shopping_items,
|
||||
json=serialize_list_items(list_items),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -361,7 +357,7 @@ def test_shopping_list_items_update_many_consolidates_common_items(
|
|||
|
||||
# retrieve list and check positions against list
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(list_with_items.id),
|
||||
api_routes.households_shopping_lists_item_id(list_with_items.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
response_list = utils.assert_deserialize(response, 200)
|
||||
|
@ -385,7 +381,7 @@ def test_shopping_list_items_add_mergeable(
|
|||
merged_qty = sum([item["quantity"] for item in duplicate_items]) # type: ignore
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_items_create_bulk,
|
||||
api_routes.households_shopping_items_create_bulk,
|
||||
json=items + duplicate_items,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -409,7 +405,7 @@ def test_shopping_list_items_add_mergeable(
|
|||
new_item["note"] = item_to_merge_into["note"]
|
||||
updated_quantity = new_item["quantity"] + item_to_merge_into["quantity"]
|
||||
|
||||
response = api_client.post(api_routes.groups_shopping_items, json=new_item, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_items, json=new_item, headers=unique_user.token)
|
||||
item_json = utils.assert_deserialize(response, 201)
|
||||
|
||||
# we should have received an updated item, not a created item
|
||||
|
@ -421,7 +417,7 @@ def test_shopping_list_items_add_mergeable(
|
|||
|
||||
# fetch the list and make sure we have the correct number of items
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
list_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -439,7 +435,7 @@ def test_shopping_list_items_update_mergable(
|
|||
item.note = list_with_items.list_items[i - 1].note
|
||||
|
||||
payload = utils.jsonify([item.model_dump() for item in list_with_items.list_items])
|
||||
response = api_client.put(api_routes.groups_shopping_items, json=payload, headers=unique_user.token)
|
||||
response = api_client.put(api_routes.households_shopping_items, json=payload, headers=unique_user.token)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
||||
assert len(as_json["createdItems"]) == 0
|
||||
|
@ -458,7 +454,7 @@ def test_shopping_list_items_update_mergable(
|
|||
|
||||
# confirm the number of items on the list matches
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(list_with_items.id),
|
||||
api_routes.households_shopping_lists_item_id(list_with_items.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -474,7 +470,7 @@ def test_shopping_list_items_update_mergable(
|
|||
merged_quantity = sum([item["quantity"] for item in items_to_merge])
|
||||
|
||||
payload = utils.jsonify(items_to_merge)
|
||||
response = api_client.put(api_routes.groups_shopping_items, json=payload, headers=unique_user.token)
|
||||
response = api_client.put(api_routes.households_shopping_items, json=payload, headers=unique_user.token)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
||||
assert len(as_json["createdItems"]) == 0
|
||||
|
@ -503,7 +499,7 @@ def test_shopping_list_items_checked_off(
|
|||
checked_item.checked = True
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items_item_id(checked_item.id),
|
||||
api_routes.households_shopping_items_item_id(checked_item.id),
|
||||
json=utils.jsonify(checked_item.model_dump()),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -517,7 +513,7 @@ def test_shopping_list_items_checked_off(
|
|||
|
||||
# get the reference item and make sure it didn't change
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_items_item_id(reference_item.id),
|
||||
api_routes.households_shopping_items_item_id(reference_item.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -531,7 +527,7 @@ def test_shopping_list_items_checked_off(
|
|||
|
||||
# rename an item to match another item and check both off, and make sure they are not merged
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(list_with_items.id),
|
||||
api_routes.households_shopping_lists_item_id(list_with_items.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -543,7 +539,7 @@ def test_shopping_list_items_checked_off(
|
|||
item_2.note = item_1.note
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items,
|
||||
api_routes.households_shopping_items,
|
||||
json=utils.jsonify([item_1.model_dump(), item_2.model_dump()]),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -571,7 +567,7 @@ def test_shopping_list_items_with_zero_quantity(
|
|||
item["quantity"] = 0
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_items_create_bulk,
|
||||
api_routes.households_shopping_items_create_bulk,
|
||||
json=normal_items + zero_qty_items,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -580,7 +576,7 @@ def test_shopping_list_items_with_zero_quantity(
|
|||
|
||||
# confirm the number of items on the list matches
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -594,7 +590,7 @@ def test_shopping_list_items_with_zero_quantity(
|
|||
new_item_to_merge["note"] = target_item["note"]
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_items,
|
||||
api_routes.households_shopping_items,
|
||||
json=new_item_to_merge,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -610,7 +606,7 @@ def test_shopping_list_items_with_zero_quantity(
|
|||
|
||||
# confirm the number of items on the list stayed the same
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -622,7 +618,7 @@ def test_shopping_list_items_with_zero_quantity(
|
|||
update_item_to_merge["quantity"] = 0
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items_item_id(update_item_to_merge["id"]),
|
||||
api_routes.households_shopping_items_item_id(update_item_to_merge["id"]),
|
||||
json=update_item_to_merge,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -639,7 +635,7 @@ def test_shopping_list_items_with_zero_quantity(
|
|||
|
||||
# confirm the number of items on the list shrunk by one
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -659,7 +655,7 @@ def test_shopping_list_item_extras(
|
|||
new_item_data = create_item(shopping_list.id)
|
||||
new_item_data["extras"] = {key_str_1: val_str_1}
|
||||
|
||||
response = api_client.post(api_routes.groups_shopping_items, json=new_item_data, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_items, json=new_item_data, headers=unique_user.token)
|
||||
collection = utils.assert_deserialize(response, 201)
|
||||
item_as_json = collection["createdItems"][0]
|
||||
|
||||
|
@ -672,7 +668,7 @@ def test_shopping_list_item_extras(
|
|||
item_as_json["extras"][key_str_2] = val_str_2
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items_item_id(item_as_json["id"]),
|
||||
api_routes.households_shopping_items_item_id(item_as_json["id"]),
|
||||
json=item_as_json,
|
||||
headers=unique_user.token,
|
||||
)
|
|
@ -2,8 +2,7 @@ import random
|
|||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.group.group_shopping_list import (
|
||||
from mealie.schema.household.group_shopping_list import (
|
||||
ShoppingListItemOut,
|
||||
ShoppingListItemUpdate,
|
||||
ShoppingListItemUpdateBulk,
|
||||
|
@ -18,7 +17,7 @@ from tests.utils.fixture_schemas import TestUser
|
|||
|
||||
|
||||
def test_shopping_lists_get_all(api_client: TestClient, unique_user: TestUser, shopping_lists: list[ShoppingListOut]):
|
||||
response = api_client.get(api_routes.groups_shopping_lists, headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_lists, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
all_lists = response.json()["items"]
|
||||
|
||||
|
@ -35,11 +34,12 @@ def test_shopping_lists_create_one(api_client: TestClient, unique_user: TestUser
|
|||
"name": random_string(10),
|
||||
}
|
||||
|
||||
response = api_client.post(api_routes.groups_shopping_lists, json=payload, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_lists, json=payload, headers=unique_user.token)
|
||||
response_list = utils.assert_deserialize(response, 201)
|
||||
|
||||
assert response_list["name"] == payload["name"]
|
||||
assert response_list["groupId"] == str(unique_user.group_id)
|
||||
assert response_list["householdId"] == str(unique_user.household_id)
|
||||
assert response_list["userId"] == str(unique_user.user_id)
|
||||
|
||||
|
||||
|
@ -47,7 +47,7 @@ def test_shopping_lists_get_one(api_client: TestClient, unique_user: TestUser, s
|
|||
shopping_list = shopping_lists[0]
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
@ -57,6 +57,7 @@ def test_shopping_lists_get_one(api_client: TestClient, unique_user: TestUser, s
|
|||
assert response_list["id"] == str(shopping_list.id)
|
||||
assert response_list["name"] == shopping_list.name
|
||||
assert response_list["groupId"] == str(shopping_list.group_id)
|
||||
assert response_list["householdId"] == str(unique_user.household_id)
|
||||
assert response_list["userId"] == str(shopping_list.user_id)
|
||||
|
||||
|
||||
|
@ -69,12 +70,13 @@ def test_shopping_lists_update_one(
|
|||
"name": random_string(10),
|
||||
"id": str(sample_list.id),
|
||||
"groupId": str(sample_list.group_id),
|
||||
"householdId": str(sample_list.household_id),
|
||||
"userId": str(sample_list.user_id),
|
||||
"listItems": [],
|
||||
}
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
json=payload,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -85,6 +87,7 @@ def test_shopping_lists_update_one(
|
|||
assert response_list["id"] == str(sample_list.id)
|
||||
assert response_list["name"] == payload["name"]
|
||||
assert response_list["groupId"] == str(sample_list.group_id)
|
||||
assert response_list["householdId"] == str(sample_list.household_id)
|
||||
assert response_list["userId"] == str(sample_list.user_id)
|
||||
|
||||
|
||||
|
@ -94,13 +97,13 @@ def test_shopping_lists_delete_one(
|
|||
sample_list = random.choice(shopping_lists)
|
||||
|
||||
response = api_client.delete(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 404
|
||||
|
@ -116,14 +119,14 @@ def test_shopping_lists_add_recipe(
|
|||
recipe = recipe_ingredient_only
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
# get list and verify items against ingredients
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -144,13 +147,13 @@ def test_shopping_lists_add_recipe(
|
|||
|
||||
# add the recipe again and check the resulting items
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -206,12 +209,12 @@ def test_shopping_lists_add_one_with_zero_quantity(
|
|||
|
||||
# add the recipe to the list and make sure there are three list items
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
shopping_list_out = ShoppingListOut.model_validate(utils.assert_deserialize(response, 200))
|
||||
|
@ -239,14 +242,14 @@ def test_shopping_lists_add_custom_recipe_items(
|
|||
recipe = recipe_ingredient_only
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
custom_items = random.sample(recipe_ingredient_only.recipe_ingredient, k=3)
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
json={"recipeIngredients": utils.jsonify(custom_items)},
|
||||
)
|
||||
|
@ -254,7 +257,7 @@ def test_shopping_lists_add_custom_recipe_items(
|
|||
|
||||
# get list and verify items against ingredients
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -288,13 +291,13 @@ def test_shopping_list_ref_removes_itself(
|
|||
# add a recipe to a list, then check off all recipe items and make sure the recipe ref is deleted
|
||||
recipe = recipe_ingredient_only
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
utils.assert_deserialize(response, 200)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
shopping_list_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -305,14 +308,14 @@ def test_shopping_list_ref_removes_itself(
|
|||
item["checked"] = True
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items,
|
||||
api_routes.households_shopping_items,
|
||||
json=shopping_list_json["listItems"],
|
||||
headers=unique_user.token,
|
||||
)
|
||||
utils.assert_deserialize(response, 200)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
shopping_list_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -362,12 +365,12 @@ def test_shopping_lists_add_recipe_with_merge(
|
|||
|
||||
# add the recipe to the list and make sure there are only three list items, and their quantities/refs are correct
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
shopping_list_out = ShoppingListOut.model_validate(utils.assert_deserialize(response, 200))
|
||||
|
@ -410,12 +413,12 @@ def test_shopping_list_add_recipe_scale(
|
|||
recipe = recipe_ingredient_only
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -440,13 +443,13 @@ def test_shopping_list_add_recipe_scale(
|
|||
payload = {"recipeIncrementQuantity": recipe_scale}
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
json=payload,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -475,7 +478,7 @@ def test_shopping_lists_remove_recipe(
|
|||
# add two instances of the recipe
|
||||
payload = {"recipeIncrementQuantity": 2}
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
json=payload,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -483,14 +486,14 @@ def test_shopping_lists_remove_recipe(
|
|||
|
||||
# remove one instance of the recipe
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
# get list and verify items against ingredients
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -511,13 +514,13 @@ def test_shopping_lists_remove_recipe(
|
|||
|
||||
# remove the recipe again and check if the list is empty
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -536,13 +539,13 @@ def test_shopping_lists_remove_recipe_multiple_quantity(
|
|||
|
||||
for _ in range(3):
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -556,13 +559,13 @@ def test_shopping_lists_remove_recipe_multiple_quantity(
|
|||
|
||||
# Remove Recipe
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
||||
# Get List and Check for Ingredients
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -593,13 +596,13 @@ def test_shopping_list_remove_recipe_scale(
|
|||
|
||||
# first add a bunch of quantity to the list
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
json=payload,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -621,13 +624,13 @@ def test_shopping_list_remove_recipe_scale(
|
|||
|
||||
# remove some of the recipes
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
json=payload,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -658,13 +661,13 @@ def test_recipe_decrement_max(
|
|||
|
||||
# first add a bunch of quantity to the list
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
json=payload,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -686,7 +689,7 @@ def test_recipe_decrement_max(
|
|||
item_json["quantity"] += item_additional_quantity
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items_item_id(item_json["id"]),
|
||||
api_routes.households_shopping_items_item_id(item_json["id"]),
|
||||
json=item_json,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -697,13 +700,13 @@ def test_recipe_decrement_max(
|
|||
# now remove way too many instances of the recipe
|
||||
payload = {"recipeDecrementQuantity": recipe_scale * 100}
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id_delete(sample_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
json=payload,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(sample_list.id),
|
||||
api_routes.households_shopping_lists_item_id(sample_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
as_json = utils.assert_deserialize(response, 200)
|
||||
|
@ -754,19 +757,19 @@ def test_recipe_manipulation_with_zero_quantities(
|
|||
|
||||
# add the recipe to the list twice and make sure the quantity is still zero
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
utils.assert_deserialize(response, 200)
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id(shopping_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
utils.assert_deserialize(response, 200)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
updated_list = ShoppingListOut.model_validate_json(response.content)
|
||||
|
@ -790,12 +793,12 @@ def test_recipe_manipulation_with_zero_quantities(
|
|||
|
||||
# remove the recipe once and make sure the item is still on the list
|
||||
api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id_delete(shopping_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id_delete(shopping_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
updated_list = ShoppingListOut.model_validate_json(response.content)
|
||||
|
@ -819,12 +822,12 @@ def test_recipe_manipulation_with_zero_quantities(
|
|||
|
||||
# remove the recipe one more time and make sure the item is gone and the list is empty
|
||||
api_client.post(
|
||||
api_routes.groups_shopping_lists_item_id_recipe_recipe_id_delete(shopping_list.id, recipe.id),
|
||||
api_routes.households_shopping_lists_item_id_recipe_recipe_id_delete(shopping_list.id, recipe.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
||||
response = api_client.get(
|
||||
api_routes.groups_shopping_lists_item_id(shopping_list.id),
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
updated_list = ShoppingListOut.model_validate_json(response.content)
|
||||
|
@ -845,7 +848,7 @@ def test_shopping_list_extras(
|
|||
new_list_data: dict = {"name": random_string()}
|
||||
new_list_data["extras"] = {key_str_1: val_str_1}
|
||||
|
||||
response = api_client.post(api_routes.groups_shopping_lists, json=new_list_data, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_lists, json=new_list_data, headers=unique_user.token)
|
||||
list_as_json = utils.assert_deserialize(response, 201)
|
||||
|
||||
# make sure the extra persists
|
||||
|
@ -857,7 +860,7 @@ def test_shopping_list_extras(
|
|||
list_as_json["extras"][key_str_2] = val_str_2
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_lists_item_id(list_as_json["id"]),
|
||||
api_routes.households_shopping_lists_item_id(list_as_json["id"]),
|
||||
json=list_as_json,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -872,60 +875,68 @@ def test_shopping_list_extras(
|
|||
|
||||
|
||||
def test_modify_shopping_list_items_updates_shopping_list(
|
||||
database: AllRepositories,
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
shopping_lists: list[ShoppingListOut],
|
||||
api_client: TestClient, unique_user: TestUser, shopping_lists: list[ShoppingListOut]
|
||||
):
|
||||
shopping_list = random.choice(shopping_lists)
|
||||
last_update_at = shopping_list.update_at
|
||||
last_update_at = shopping_list.updated_at
|
||||
assert last_update_at
|
||||
|
||||
# Create
|
||||
new_item_data = {"note": random_string(), "shopping_list_id": str(shopping_list.id)}
|
||||
response = api_client.post(api_routes.groups_shopping_items, json=new_item_data, headers=unique_user.token)
|
||||
response = api_client.post(api_routes.households_shopping_items, json=new_item_data, headers=unique_user.token)
|
||||
data = assert_deserialize(response, 201)
|
||||
updated_list = database.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert updated_list and updated_list.update_at
|
||||
assert updated_list.update_at > last_update_at
|
||||
last_update_at = updated_list.update_at
|
||||
updated_list = ShoppingListOut.model_validate_json(
|
||||
api_client.get(
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id), headers=unique_user.token
|
||||
).content
|
||||
)
|
||||
assert updated_list and updated_list.updated_at
|
||||
assert updated_list.updated_at > last_update_at
|
||||
last_update_at = updated_list.updated_at
|
||||
|
||||
list_item_id = data["createdItems"][0]["id"]
|
||||
list_item = database.group_shopping_list_item.get_one(list_item_id)
|
||||
list_item = ShoppingListItemOut.model_validate_json(
|
||||
api_client.get(api_routes.households_shopping_items_item_id(list_item_id), headers=unique_user.token).content
|
||||
)
|
||||
assert list_item
|
||||
|
||||
# Update
|
||||
list_item.note = random_string()
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_items_item_id(list_item_id),
|
||||
api_routes.households_shopping_items_item_id(list_item_id),
|
||||
json=utils.jsonify(list_item.cast(ShoppingListItemUpdate).model_dump()),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
updated_list = database.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert updated_list and updated_list.update_at
|
||||
assert updated_list.update_at > last_update_at
|
||||
last_update_at = updated_list.update_at
|
||||
updated_list = ShoppingListOut.model_validate_json(
|
||||
api_client.get(
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id), headers=unique_user.token
|
||||
).content
|
||||
)
|
||||
assert updated_list and updated_list.updated_at
|
||||
assert updated_list.updated_at > last_update_at
|
||||
last_update_at = updated_list.updated_at
|
||||
|
||||
# Delete
|
||||
response = api_client.delete(
|
||||
api_routes.groups_shopping_items_item_id(list_item_id),
|
||||
api_routes.households_shopping_items_item_id(list_item_id),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
updated_list = database.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert updated_list and updated_list.update_at
|
||||
assert updated_list.update_at > last_update_at
|
||||
updated_list = ShoppingListOut.model_validate_json(
|
||||
api_client.get(
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id), headers=unique_user.token
|
||||
).content
|
||||
)
|
||||
assert updated_list and updated_list.updated_at
|
||||
assert updated_list.updated_at > last_update_at
|
||||
|
||||
|
||||
def test_bulk_modify_shopping_list_items_updates_shopping_list(
|
||||
database: AllRepositories,
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
shopping_lists: list[ShoppingListOut],
|
||||
api_client: TestClient, unique_user: TestUser, shopping_lists: list[ShoppingListOut]
|
||||
):
|
||||
shopping_list = random.choice(shopping_lists)
|
||||
last_update_at = shopping_list.update_at
|
||||
last_update_at = shopping_list.updated_at
|
||||
assert last_update_at
|
||||
|
||||
# Create
|
||||
|
@ -933,40 +944,57 @@ def test_bulk_modify_shopping_list_items_updates_shopping_list(
|
|||
{"note": random_string(), "shopping_list_id": str(shopping_list.id)} for _ in range(random_int(3, 5))
|
||||
]
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_items_create_bulk,
|
||||
api_routes.households_shopping_items_create_bulk,
|
||||
json=new_item_data,
|
||||
headers=unique_user.token,
|
||||
)
|
||||
data = assert_deserialize(response, 201)
|
||||
updated_list = database.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert updated_list and updated_list.update_at
|
||||
assert updated_list.update_at > last_update_at
|
||||
last_update_at = updated_list.update_at
|
||||
updated_list = ShoppingListOut.model_validate_json(
|
||||
api_client.get(
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id), headers=unique_user.token
|
||||
).content
|
||||
)
|
||||
assert updated_list and updated_list.updated_at
|
||||
assert updated_list.updated_at > last_update_at
|
||||
last_update_at = updated_list.updated_at
|
||||
|
||||
# Update
|
||||
list_item_ids = [item["id"] for item in data["createdItems"]]
|
||||
list_items: list[ShoppingListItemOut] = []
|
||||
for list_item_id in list_item_ids:
|
||||
list_item = database.group_shopping_list_item.get_one(list_item_id)
|
||||
list_item = ShoppingListItemOut.model_validate_json(
|
||||
api_client.get(
|
||||
api_routes.households_shopping_items_item_id(list_item_id), headers=unique_user.token
|
||||
).content
|
||||
)
|
||||
assert list_item
|
||||
assert list_item
|
||||
list_item.note = random_string()
|
||||
list_items.append(list_item)
|
||||
|
||||
payload = [utils.jsonify(list_item.cast(ShoppingListItemUpdateBulk).model_dump()) for list_item in list_items]
|
||||
response = api_client.put(api_routes.groups_shopping_items, json=payload, headers=unique_user.token)
|
||||
response = api_client.put(api_routes.households_shopping_items, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
updated_list = database.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert updated_list and updated_list.update_at
|
||||
assert updated_list.update_at > last_update_at
|
||||
last_update_at = updated_list.update_at
|
||||
updated_list = ShoppingListOut.model_validate_json(
|
||||
api_client.get(
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id), headers=unique_user.token
|
||||
).content
|
||||
)
|
||||
assert updated_list and updated_list.updated_at
|
||||
assert updated_list.updated_at > last_update_at
|
||||
last_update_at = updated_list.updated_at
|
||||
|
||||
# Delete
|
||||
response = api_client.delete(
|
||||
api_routes.groups_shopping_items,
|
||||
api_routes.households_shopping_items,
|
||||
params={"ids": [str(list_item.id) for list_item in list_items]},
|
||||
headers=unique_user.token,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
updated_list = database.group_shopping_lists.get_one(shopping_list.id)
|
||||
assert updated_list and updated_list.update_at
|
||||
assert updated_list.update_at > last_update_at
|
||||
updated_list = ShoppingListOut.model_validate_json(
|
||||
api_client.get(
|
||||
api_routes.households_shopping_lists_item_id(shopping_list.id), headers=unique_user.token
|
||||
).content
|
||||
)
|
||||
assert updated_list and updated_list.updated_at
|
||||
assert updated_list.updated_at > last_update_at
|
|
@ -20,7 +20,7 @@ def webhook_data():
|
|||
|
||||
def test_create_webhook(api_client: TestClient, unique_user: TestUser, webhook_data):
|
||||
response = api_client.post(
|
||||
api_routes.groups_webhooks,
|
||||
api_routes.households_webhooks,
|
||||
json=jsonify(webhook_data),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -29,13 +29,13 @@ def test_create_webhook(api_client: TestClient, unique_user: TestUser, webhook_d
|
|||
|
||||
def test_read_webhook(api_client: TestClient, unique_user: TestUser, webhook_data):
|
||||
response = api_client.post(
|
||||
api_routes.groups_webhooks,
|
||||
api_routes.households_webhooks,
|
||||
json=jsonify(webhook_data),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
item_id = response.json()["id"]
|
||||
|
||||
response = api_client.get(api_routes.groups_webhooks_item_id(item_id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_webhooks_item_id(item_id), headers=unique_user.token)
|
||||
webhook = assert_deserialize(response, 200)
|
||||
|
||||
assert webhook["id"] == item_id
|
||||
|
@ -47,7 +47,7 @@ def test_read_webhook(api_client: TestClient, unique_user: TestUser, webhook_dat
|
|||
|
||||
def test_update_webhook(api_client: TestClient, webhook_data, unique_user: TestUser):
|
||||
response = api_client.post(
|
||||
api_routes.groups_webhooks,
|
||||
api_routes.households_webhooks,
|
||||
json=jsonify(webhook_data),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -59,7 +59,7 @@ def test_update_webhook(api_client: TestClient, webhook_data, unique_user: TestU
|
|||
webhook_data["enabled"] = False
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_webhooks_item_id(item_id),
|
||||
api_routes.households_webhooks_item_id(item_id),
|
||||
json=jsonify(webhook_data),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -72,15 +72,15 @@ def test_update_webhook(api_client: TestClient, webhook_data, unique_user: TestU
|
|||
|
||||
def test_delete_webhook(api_client: TestClient, webhook_data, unique_user: TestUser):
|
||||
response = api_client.post(
|
||||
api_routes.groups_webhooks,
|
||||
api_routes.households_webhooks,
|
||||
json=jsonify(webhook_data),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
item_dict = assert_deserialize(response, 201)
|
||||
item_id = item_dict["id"]
|
||||
|
||||
response = api_client.delete(api_routes.groups_webhooks_item_id(item_id), headers=unique_user.token)
|
||||
response = api_client.delete(api_routes.households_webhooks_item_id(item_id), headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
response = api_client.get(api_routes.groups_webhooks_item_id(item_id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_webhooks_item_id(item_id), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
|
@ -0,0 +1,47 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.schema.household.household_preferences import UpdateHouseholdPreferences
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.assertion_helpers import assert_ignore_keys
|
||||
from tests.utils.factories import random_bool
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
def test_get_preferences(api_client: TestClient, unique_user: TestUser) -> None:
|
||||
response = api_client.get(api_routes.households_preferences, headers=unique_user.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
preferences = response.json()
|
||||
|
||||
assert preferences["recipePublic"] in {True, False}
|
||||
assert preferences["recipeShowNutrition"] in {True, False}
|
||||
|
||||
|
||||
def test_preferences_in_household(api_client: TestClient, unique_user: TestUser) -> None:
|
||||
response = api_client.get(api_routes.households_self, headers=unique_user.token)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
household = response.json()
|
||||
|
||||
assert household["preferences"] is not None
|
||||
|
||||
# Spot Check
|
||||
assert household["preferences"]["recipePublic"] in {True, False}
|
||||
assert household["preferences"]["recipeShowNutrition"] in {True, False}
|
||||
|
||||
|
||||
def test_update_preferences(api_client: TestClient, unique_user: TestUser) -> None:
|
||||
new_data = UpdateHouseholdPreferences(recipe_public=random_bool(), recipe_show_nutrition=random_bool())
|
||||
|
||||
response = api_client.put(api_routes.households_preferences, json=new_data.model_dump(), headers=unique_user.token)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
preferences = response.json()
|
||||
|
||||
assert preferences is not None
|
||||
assert preferences["recipePublic"] == new_data.recipe_public
|
||||
assert preferences["recipeShowNutrition"] == new_data.recipe_show_nutrition
|
||||
|
||||
assert_ignore_keys(new_data.model_dump(by_alias=True), preferences, ["id", "householdId"])
|
|
@ -2,7 +2,6 @@ from uuid import uuid4
|
|||
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_bool
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
@ -17,39 +16,28 @@ def get_permissions_payload(user_id: str, can_manage=None) -> dict:
|
|||
}
|
||||
|
||||
|
||||
def test_get_group_members(api_client: TestClient, user_tuple: list[TestUser]):
|
||||
usr_1, usr_2 = user_tuple
|
||||
|
||||
response = api_client.get(api_routes.groups_members, headers=usr_1.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
members = response.json()
|
||||
assert len(members) >= 2
|
||||
|
||||
all_ids = [x["id"] for x in members]
|
||||
|
||||
assert str(usr_1.user_id) in all_ids
|
||||
assert str(usr_2.user_id) in all_ids
|
||||
|
||||
|
||||
def test_set_memeber_permissions(api_client: TestClient, user_tuple: list[TestUser], database: AllRepositories):
|
||||
def test_set_member_permissions(api_client: TestClient, user_tuple: list[TestUser]):
|
||||
usr_1, usr_2 = user_tuple
|
||||
|
||||
# Set Acting User
|
||||
acting_user = database.users.get_one(usr_1.user_id)
|
||||
acting_user = usr_1.repos.users.get_one(usr_1.user_id)
|
||||
assert acting_user
|
||||
acting_user.can_manage = True
|
||||
database.users.update(acting_user.id, acting_user)
|
||||
usr_1.repos.users.update(acting_user.id, acting_user)
|
||||
|
||||
payload = get_permissions_payload(str(usr_2.user_id))
|
||||
|
||||
# Test
|
||||
response = api_client.put(api_routes.groups_permissions, json=payload, headers=usr_1.token)
|
||||
response = api_client.put(api_routes.households_permissions, json=payload, headers=usr_1.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
def test_set_memeber_permissions_unauthorized(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
|
||||
def test_set_member_permissions_unauthorized(api_client: TestClient, unique_user: TestUser):
|
||||
database = unique_user.repos
|
||||
|
||||
# Setup
|
||||
user = database.users.get_one(unique_user.user_id)
|
||||
assert user
|
||||
user.can_manage = False
|
||||
database.users.update(user.id, user)
|
||||
|
||||
|
@ -62,34 +50,38 @@ def test_set_memeber_permissions_unauthorized(api_client: TestClient, unique_use
|
|||
}
|
||||
|
||||
# Test
|
||||
response = api_client.put(api_routes.groups_permissions, json=payload, headers=unique_user.token)
|
||||
response = api_client.put(api_routes.households_permissions, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def test_set_memeber_permissions_other_group(
|
||||
def test_set_member_permissions_other_household(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
g2_user: TestUser,
|
||||
database: AllRepositories,
|
||||
h2_user: TestUser,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
user = database.users.get_one(unique_user.user_id)
|
||||
assert user
|
||||
user.can_manage = True
|
||||
database.users.update(user.id, user)
|
||||
|
||||
payload = get_permissions_payload(str(g2_user.user_id))
|
||||
response = api_client.put(api_routes.groups_permissions, json=payload, headers=unique_user.token)
|
||||
payload = get_permissions_payload(str(h2_user.user_id))
|
||||
response = api_client.put(api_routes.households_permissions, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 403
|
||||
|
||||
|
||||
def test_set_memeber_permissions_no_user(
|
||||
def test_set_member_permissions_no_user(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
user = database.users.get_one(unique_user.user_id)
|
||||
assert user
|
||||
user.can_manage = True
|
||||
database.users.update(user.id, user)
|
||||
|
||||
payload = get_permissions_payload(str(uuid4()))
|
||||
response = api_client.put(api_routes.groups_permissions, json=payload, headers=unique_user.token)
|
||||
response = api_client.put(api_routes.households_permissions, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 404
|
|
@ -0,0 +1,20 @@
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
def test_get_household_members(api_client: TestClient, user_tuple: list[TestUser], h2_user: TestUser):
|
||||
usr_1, usr_2 = user_tuple
|
||||
|
||||
response = api_client.get(api_routes.households_members, headers=usr_1.token)
|
||||
assert response.status_code == 200
|
||||
|
||||
members = response.json()
|
||||
assert len(members) >= 2
|
||||
|
||||
all_ids = [x["id"] for x in members]
|
||||
|
||||
assert str(usr_1.user_id) in all_ids
|
||||
assert str(usr_2.user_id) in all_ids
|
||||
assert str(h2_user.user_id) not in all_ids
|
|
@ -3,7 +3,7 @@ import random
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.group.group_shopping_list import ShoppingListOut
|
||||
from mealie.schema.household.group_shopping_list import ShoppingListOut
|
||||
from mealie.schema.labels.multi_purpose_label import MultiPurposeLabelOut
|
||||
from mealie.services.seeder.seeder_service import SeederService
|
||||
from tests.utils import api_routes, jsonify
|
||||
|
@ -23,7 +23,7 @@ def create_labels(api_client: TestClient, unique_user: TestUser, count: int = 10
|
|||
def test_new_list_creates_list_labels(api_client: TestClient, unique_user: TestUser):
|
||||
labels = create_labels(api_client, unique_user)
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
)
|
||||
new_list = ShoppingListOut.model_validate(response.json())
|
||||
|
||||
|
@ -37,14 +37,14 @@ def test_new_label_creates_list_labels(api_client: TestClient, unique_user: Test
|
|||
# create a list with some labels
|
||||
create_labels(api_client, unique_user)
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
)
|
||||
new_list = ShoppingListOut.model_validate(response.json())
|
||||
existing_label_settings = new_list.label_settings
|
||||
|
||||
# create more labels and make sure they were added to the list's label settings
|
||||
new_labels = create_labels(api_client, unique_user)
|
||||
response = api_client.get(api_routes.groups_shopping_lists_item_id(new_list.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_lists_item_id(new_list.id), headers=unique_user.token)
|
||||
updated_list = ShoppingListOut.model_validate(response.json())
|
||||
updated_label_settings = updated_list.label_settings
|
||||
assert len(updated_label_settings) == len(existing_label_settings) + len(new_labels)
|
||||
|
@ -58,23 +58,66 @@ def test_new_label_creates_list_labels(api_client: TestClient, unique_user: Test
|
|||
assert label.id in label_settings_label_ids
|
||||
|
||||
|
||||
def test_seed_label_creates_list_labels(database: AllRepositories, api_client: TestClient, unique_user: TestUser):
|
||||
def test_new_label_creates_list_labels_in_all_households(
|
||||
api_client: TestClient, unique_user: TestUser, h2_user: TestUser
|
||||
):
|
||||
# unique_user and h2_user are in the same group, so these labels should be for both of them
|
||||
create_labels(api_client, unique_user)
|
||||
|
||||
# create a list with some labels for each user
|
||||
response = api_client.post(
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
)
|
||||
new_list_h1 = ShoppingListOut.model_validate(response.json())
|
||||
existing_label_settings_h1 = new_list_h1.label_settings
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=h2_user.token
|
||||
)
|
||||
new_list_h2 = ShoppingListOut.model_validate(response.json())
|
||||
existing_label_settings_h2 = new_list_h2.label_settings
|
||||
|
||||
# create more labels and make sure they were added to both lists' label settings
|
||||
new_labels = create_labels(api_client, unique_user)
|
||||
|
||||
for user, new_list, existing_label_settings in [
|
||||
(unique_user, new_list_h1, existing_label_settings_h1),
|
||||
(h2_user, new_list_h2, existing_label_settings_h2),
|
||||
]:
|
||||
response = api_client.get(api_routes.households_shopping_lists_item_id(new_list.id), headers=user.token)
|
||||
updated_list = ShoppingListOut.model_validate(response.json())
|
||||
updated_label_settings = updated_list.label_settings
|
||||
assert len(updated_label_settings) == len(existing_label_settings) + len(new_labels)
|
||||
|
||||
label_settings_ids = [setting.id for setting in updated_list.label_settings]
|
||||
for label_setting in existing_label_settings:
|
||||
assert label_setting.id in label_settings_ids
|
||||
|
||||
label_settings_label_ids = [setting.label_id for setting in updated_list.label_settings]
|
||||
for label in new_labels:
|
||||
assert label.id in label_settings_label_ids
|
||||
|
||||
|
||||
def test_seed_label_creates_list_labels(api_client: TestClient, unique_user: TestUser):
|
||||
CREATED_LABELS = 21
|
||||
database = unique_user.repos
|
||||
|
||||
# create a list with some labels
|
||||
create_labels(api_client, unique_user)
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
)
|
||||
new_list = ShoppingListOut.model_validate(response.json())
|
||||
existing_label_settings = new_list.label_settings
|
||||
|
||||
# seed labels and make sure they were added to the list's label settings
|
||||
group = database.groups.get_one(unique_user.group_id)
|
||||
seeder = SeederService(database, None, group) # type: ignore
|
||||
assert group
|
||||
database = AllRepositories(database.session, group_id=group.id)
|
||||
seeder = SeederService(database)
|
||||
seeder.seed_labels("en-US")
|
||||
|
||||
response = api_client.get(api_routes.groups_shopping_lists_item_id(new_list.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_lists_item_id(new_list.id), headers=unique_user.token)
|
||||
updated_list = ShoppingListOut.model_validate(response.json())
|
||||
updated_label_settings = updated_list.label_settings
|
||||
assert len(updated_label_settings) == len(existing_label_settings) + CREATED_LABELS
|
||||
|
@ -87,7 +130,7 @@ def test_seed_label_creates_list_labels(database: AllRepositories, api_client: T
|
|||
def test_delete_label_deletes_list_labels(api_client: TestClient, unique_user: TestUser):
|
||||
new_labels = create_labels(api_client, unique_user)
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
)
|
||||
new_list = ShoppingListOut.model_validate(response.json())
|
||||
|
||||
|
@ -95,7 +138,7 @@ def test_delete_label_deletes_list_labels(api_client: TestClient, unique_user: T
|
|||
label_to_delete = random.choice(new_labels)
|
||||
api_client.delete(api_routes.groups_labels_item_id(label_to_delete.id), headers=unique_user.token)
|
||||
|
||||
response = api_client.get(api_routes.groups_shopping_lists_item_id(new_list.id), headers=unique_user.token)
|
||||
response = api_client.get(api_routes.households_shopping_lists_item_id(new_list.id), headers=unique_user.token)
|
||||
updated_list = ShoppingListOut.model_validate(response.json())
|
||||
assert len(updated_list.label_settings) == len(existing_label_settings) - 1
|
||||
|
||||
|
@ -114,7 +157,7 @@ def test_update_list_doesnt_change_list_labels(api_client: TestClient, unique_us
|
|||
updated_name = random_string()
|
||||
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists, json={"name": original_name}, headers=unique_user.token
|
||||
api_routes.households_shopping_lists, json={"name": original_name}, headers=unique_user.token
|
||||
)
|
||||
new_list = ShoppingListOut.model_validate(response.json())
|
||||
assert new_list.name == original_name
|
||||
|
@ -122,13 +165,13 @@ def test_update_list_doesnt_change_list_labels(api_client: TestClient, unique_us
|
|||
|
||||
updated_list_data = new_list.model_dump()
|
||||
updated_list_data.pop("created_at", None)
|
||||
updated_list_data.pop("update_at", None)
|
||||
updated_list_data.pop("updated_at", None)
|
||||
|
||||
updated_list_data["name"] = updated_name
|
||||
updated_list_data["label_settings"][0]["position"] = random_int(999, 9999)
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_lists_item_id(new_list.id),
|
||||
api_routes.households_shopping_lists_item_id(new_list.id),
|
||||
json=jsonify(updated_list_data),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -140,14 +183,14 @@ def test_update_list_doesnt_change_list_labels(api_client: TestClient, unique_us
|
|||
def test_update_list_labels(api_client: TestClient, unique_user: TestUser):
|
||||
create_labels(api_client, unique_user)
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
)
|
||||
new_list = ShoppingListOut.model_validate(response.json())
|
||||
changed_setting = random.choice(new_list.label_settings)
|
||||
changed_setting.position = random_int(999, 9999)
|
||||
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_lists_item_id_label_settings(new_list.id),
|
||||
api_routes.households_shopping_lists_item_id_label_settings(new_list.id),
|
||||
json=jsonify(new_list.label_settings),
|
||||
headers=unique_user.token,
|
||||
)
|
||||
|
@ -168,7 +211,7 @@ def test_update_list_labels(api_client: TestClient, unique_user: TestUser):
|
|||
|
||||
def test_list_label_order(api_client: TestClient, unique_user: TestUser):
|
||||
response = api_client.post(
|
||||
api_routes.groups_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
api_routes.households_shopping_lists, json={"name": random_string()}, headers=unique_user.token
|
||||
)
|
||||
new_list = ShoppingListOut.model_validate(response.json())
|
||||
for i, setting in enumerate(new_list.label_settings):
|
||||
|
@ -179,7 +222,7 @@ def test_list_label_order(api_client: TestClient, unique_user: TestUser):
|
|||
|
||||
random.shuffle(new_list.label_settings)
|
||||
response = api_client.put(
|
||||
api_routes.groups_shopping_lists_item_id_label_settings(new_list.id),
|
||||
api_routes.households_shopping_lists_item_id_label_settings(new_list.id),
|
||||
json=jsonify(new_list.label_settings),
|
||||
headers=unique_user.token,
|
||||
)
|
|
@ -16,9 +16,8 @@ from tests.utils.fixture_schemas import TestUser
|
|||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def ten_slugs(
|
||||
api_client: TestClient, unique_user: TestUser, database: AllRepositories
|
||||
) -> Generator[list[str], None, None]:
|
||||
def ten_slugs(api_client: TestClient, unique_user: TestUser) -> Generator[list[str], None, None]:
|
||||
database = unique_user.repos
|
||||
slugs: list[str] = []
|
||||
|
||||
for _ in range(10):
|
||||
|
@ -38,9 +37,9 @@ def ten_slugs(
|
|||
pass
|
||||
|
||||
|
||||
def test_bulk_tag_recipes(
|
||||
api_client: TestClient, unique_user: TestUser, database: AllRepositories, ten_slugs: list[str]
|
||||
):
|
||||
def test_bulk_tag_recipes(api_client: TestClient, unique_user: TestUser, ten_slugs: list[str]):
|
||||
database = unique_user.repos
|
||||
|
||||
# Setup Tags
|
||||
tags = []
|
||||
for _ in range(3):
|
||||
|
@ -66,9 +65,10 @@ def test_bulk_tag_recipes(
|
|||
def test_bulk_categorize_recipes(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
ten_slugs: list[str],
|
||||
):
|
||||
database = unique_user.repos
|
||||
|
||||
# Setup Tags
|
||||
categories = []
|
||||
for _ in range(3):
|
||||
|
@ -94,9 +94,9 @@ def test_bulk_categorize_recipes(
|
|||
def test_bulk_delete_recipes(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
ten_slugs: list[str],
|
||||
):
|
||||
database = unique_user.repos
|
||||
payload = {"recipes": ten_slugs}
|
||||
|
||||
response = api_client.post(api_routes.recipes_bulk_actions_delete, json=payload, headers=unique_user.token)
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
from pydantic import UUID4
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.recipe.recipe import Recipe
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_string
|
||||
|
@ -39,7 +42,7 @@ def test_create_comment(api_client: TestClient, unique_recipe: Recipe, unique_us
|
|||
|
||||
assert response_data["recipeId"] == str(unique_recipe.id)
|
||||
assert response_data["text"] == create_data["text"]
|
||||
assert response_data["userId"] == unique_user.user_id
|
||||
assert response_data["userId"] == str(unique_user.user_id)
|
||||
|
||||
# Check for Proper Association
|
||||
response = api_client.get(api_routes.recipes_slug_comments(unique_recipe.slug), headers=unique_user.token)
|
||||
|
@ -50,7 +53,7 @@ def test_create_comment(api_client: TestClient, unique_recipe: Recipe, unique_us
|
|||
assert len(response_data) == 1
|
||||
assert response_data[0]["recipeId"] == str(unique_recipe.id)
|
||||
assert response_data[0]["text"] == create_data["text"]
|
||||
assert response_data[0]["userId"] == unique_user.user_id
|
||||
assert response_data[0]["userId"] == str(unique_user.user_id)
|
||||
|
||||
|
||||
def test_update_comment(api_client: TestClient, unique_recipe: Recipe, unique_user: TestUser):
|
||||
|
@ -73,7 +76,7 @@ def test_update_comment(api_client: TestClient, unique_recipe: Recipe, unique_us
|
|||
|
||||
assert response_data["recipeId"] == str(unique_recipe.id)
|
||||
assert response_data["text"] == update_data["text"]
|
||||
assert response_data["userId"] == unique_user.user_id
|
||||
assert response_data["userId"] == str(unique_user.user_id)
|
||||
|
||||
|
||||
def test_delete_comment(api_client: TestClient, unique_recipe: Recipe, unique_user: TestUser):
|
||||
|
@ -93,7 +96,20 @@ def test_delete_comment(api_client: TestClient, unique_recipe: Recipe, unique_us
|
|||
assert response.status_code == 404
|
||||
|
||||
|
||||
def test_admin_can_delete(api_client: TestClient, unique_recipe: Recipe, unique_user: TestUser, admin_user: TestUser):
|
||||
def test_admin_can_delete(
|
||||
unfiltered_database: AllRepositories,
|
||||
api_client: TestClient,
|
||||
unique_recipe: Recipe,
|
||||
unique_user: TestUser,
|
||||
admin_user: TestUser,
|
||||
):
|
||||
# Make sure admin belongs to same group/household as user
|
||||
admin_data = unfiltered_database.users.get_one(admin_user.user_id)
|
||||
assert admin_data
|
||||
admin_data.group_id = UUID(unique_user.group_id)
|
||||
admin_data.household_id = UUID(unique_user.household_id)
|
||||
unfiltered_database.users.update(admin_user.user_id, admin_data)
|
||||
|
||||
# Create Comment
|
||||
create_data = random_comment(unique_recipe.id)
|
||||
response = api_client.post(api_routes.comments, json=create_data, headers=unique_user.token)
|
||||
|
|
|
@ -9,10 +9,10 @@ from pathlib import Path
|
|||
from uuid import uuid4
|
||||
from zipfile import ZipFile
|
||||
|
||||
from httpx import Response
|
||||
import pytest
|
||||
from bs4 import BeautifulSoup
|
||||
from fastapi.testclient import TestClient
|
||||
from httpx import Response
|
||||
from pytest import MonkeyPatch
|
||||
from recipe_scrapers._abstract import AbstractScraper
|
||||
from recipe_scrapers._schemaorg import SchemaOrg
|
||||
|
@ -20,14 +20,13 @@ from recipe_scrapers.plugins import SchemaOrgFillPlugin
|
|||
from slugify import slugify
|
||||
|
||||
from mealie.pkgs.safehttp.transport import AsyncSafeTransport
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.recipe.recipe import Recipe, RecipeCategory, RecipeSummary, RecipeTag
|
||||
from mealie.schema.recipe.recipe_category import CategorySave, TagSave
|
||||
from mealie.schema.recipe.recipe_notes import RecipeNote
|
||||
from mealie.schema.recipe.recipe_tool import RecipeToolSave
|
||||
from mealie.services.recipe.recipe_data_service import RecipeDataService
|
||||
from mealie.services.scraper.recipe_scraper import DEFAULT_SCRAPER_STRATEGIES
|
||||
from tests import data, utils
|
||||
from tests import utils
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_int, random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
@ -82,7 +81,7 @@ def get_init(html_path: Path):
|
|||
current_method = getattr(self.__class__, name)
|
||||
current_method = SchemaOrgFillPlugin.run(current_method)
|
||||
setattr(self.__class__, name, current_method)
|
||||
setattr(self.__class__, "plugins_initialized", True)
|
||||
self.__class__.plugins_initialized = True
|
||||
|
||||
return init_override
|
||||
|
||||
|
@ -162,7 +161,8 @@ def test_create_by_url(
|
|||
assert tag["name"] in expected_tags
|
||||
|
||||
|
||||
def test_create_recipe_from_zip(database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
def test_create_recipe_from_zip(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
recipe_name = random_string()
|
||||
recipe = RecipeSummary(
|
||||
id=uuid4(),
|
||||
|
@ -181,9 +181,8 @@ def test_create_recipe_from_zip(database: AllRepositories, api_client: TestClien
|
|||
assert fetched_recipe
|
||||
|
||||
|
||||
def test_create_recipe_from_zip_invalid_group(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
def test_create_recipe_from_zip_invalid_group(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
recipe_name = random_string()
|
||||
recipe = RecipeSummary(
|
||||
id=uuid4(),
|
||||
|
@ -205,9 +204,8 @@ def test_create_recipe_from_zip_invalid_group(
|
|||
assert str(fetched_recipe.group_id) == str(unique_user.group_id)
|
||||
|
||||
|
||||
def test_create_recipe_from_zip_invalid_user(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
def test_create_recipe_from_zip_invalid_user(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
recipe_name = random_string()
|
||||
recipe = RecipeSummary(
|
||||
id=uuid4(),
|
||||
|
@ -229,10 +227,9 @@ def test_create_recipe_from_zip_invalid_user(
|
|||
assert str(fetched_recipe.user_id) == str(unique_user.user_id)
|
||||
|
||||
|
||||
def test_create_recipe_from_zip_existing_category(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
categories = database.categories.by_group(unique_user.group_id).create_many(
|
||||
def test_create_recipe_from_zip_existing_category(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
categories = database.categories.create_many(
|
||||
[{"name": random_string(), "group_id": unique_user.group_id} for _ in range(random_int(5, 10))]
|
||||
)
|
||||
category = random.choice(categories)
|
||||
|
@ -259,10 +256,9 @@ def test_create_recipe_from_zip_existing_category(
|
|||
assert str(fetched_recipe.recipe_category[0].id) == str(category.id)
|
||||
|
||||
|
||||
def test_create_recipe_from_zip_existing_tag(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
tags = database.tags.by_group(unique_user.group_id).create_many(
|
||||
def test_create_recipe_from_zip_existing_tag(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
tags = database.tags.create_many(
|
||||
[{"name": random_string(), "group_id": unique_user.group_id} for _ in range(random_int(5, 10))]
|
||||
)
|
||||
tag = random.choice(tags)
|
||||
|
@ -290,9 +286,10 @@ def test_create_recipe_from_zip_existing_tag(
|
|||
|
||||
|
||||
def test_create_recipe_from_zip_existing_category_wrong_ids(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
categories = database.categories.by_group(unique_user.group_id).create_many(
|
||||
database = unique_user.repos
|
||||
categories = database.categories.create_many(
|
||||
[{"name": random_string(), "group_id": unique_user.group_id} for _ in range(random_int(5, 10))]
|
||||
)
|
||||
category = random.choice(categories)
|
||||
|
@ -320,10 +317,9 @@ def test_create_recipe_from_zip_existing_category_wrong_ids(
|
|||
assert str(fetched_recipe.recipe_category[0].id) == str(category.id)
|
||||
|
||||
|
||||
def test_create_recipe_from_zip_existing_tag_wrong_ids(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
tags = database.tags.by_group(unique_user.group_id).create_many(
|
||||
def test_create_recipe_from_zip_existing_tag_wrong_ids(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
tags = database.tags.create_many(
|
||||
[{"name": random_string(), "group_id": unique_user.group_id} for _ in range(random_int(5, 10))]
|
||||
)
|
||||
tag = random.choice(tags)
|
||||
|
@ -351,9 +347,8 @@ def test_create_recipe_from_zip_existing_tag_wrong_ids(
|
|||
assert str(fetched_recipe.tags[0].id) == str(tag.id)
|
||||
|
||||
|
||||
def test_create_recipe_from_zip_invalid_category(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
def test_create_recipe_from_zip_invalid_category(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
invalid_name = random_string()
|
||||
invalid_category = RecipeCategory(id=uuid4(), name=invalid_name, slug=invalid_name)
|
||||
|
||||
|
@ -382,9 +377,8 @@ def test_create_recipe_from_zip_invalid_category(
|
|||
assert fetched_recipe.recipe_category[0].slug == invalid_name
|
||||
|
||||
|
||||
def test_create_recipe_from_zip_invalid_tag(
|
||||
database: AllRepositories, api_client: TestClient, unique_user: TestUser, tempdir: str
|
||||
):
|
||||
def test_create_recipe_from_zip_invalid_tag(api_client: TestClient, unique_user: TestUser, tempdir: str):
|
||||
database = unique_user.repos
|
||||
invalid_name = random_string()
|
||||
invalid_tag = RecipeTag(id=uuid4(), name=invalid_name, slug=invalid_name)
|
||||
|
||||
|
@ -713,17 +707,15 @@ def test_get_recipe_by_slug_or_id(api_client: TestClient, unique_user: utils.Tes
|
|||
|
||||
|
||||
@pytest.mark.parametrize("organizer_type", ["tags", "categories", "tools"])
|
||||
def test_get_recipes_organizer_filter(
|
||||
api_client: TestClient, unique_user: utils.TestUser, organizer_type: str, database: AllRepositories
|
||||
):
|
||||
def test_get_recipes_organizer_filter(api_client: TestClient, unique_user: utils.TestUser, organizer_type: str):
|
||||
database = unique_user.repos
|
||||
|
||||
# create recipes with different organizers
|
||||
tags = database.tags.by_group(unique_user.group_id).create_many(
|
||||
[TagSave(name=random_string(), group_id=unique_user.group_id) for _ in range(3)]
|
||||
)
|
||||
categories = database.categories.by_group(unique_user.group_id).create_many(
|
||||
tags = database.tags.create_many([TagSave(name=random_string(), group_id=unique_user.group_id) for _ in range(3)])
|
||||
categories = database.categories.create_many(
|
||||
[CategorySave(name=random_string(), group_id=unique_user.group_id) for _ in range(3)]
|
||||
)
|
||||
tools = database.tools.by_group(unique_user.group_id).create_many(
|
||||
tools = database.tools.create_many(
|
||||
[RecipeToolSave(name=random_string(), group_id=unique_user.group_id) for _ in range(3)]
|
||||
)
|
||||
|
||||
|
@ -743,7 +735,7 @@ def test_get_recipes_organizer_filter(
|
|||
)
|
||||
)
|
||||
|
||||
recipes = database.recipes.by_group(unique_user.group_id).create_many(new_recipes_data) # type: ignore
|
||||
recipes = database.recipes.create_many(new_recipes_data) # type: ignore
|
||||
|
||||
# get recipes by organizer
|
||||
if organizer_type == "tags":
|
||||
|
|
|
@ -14,8 +14,8 @@ def test_ownership_on_new_with_admin(api_client: TestClient, admin_user: TestUse
|
|||
|
||||
recipe = api_client.get(api_routes.recipes + f"/{recipe_name}", headers=admin_user.token).json()
|
||||
|
||||
assert recipe["userId"] == admin_user.user_id
|
||||
assert recipe["groupId"] == admin_user.group_id
|
||||
assert recipe["userId"] == str(admin_user.user_id)
|
||||
assert recipe["groupId"] == str(admin_user.group_id)
|
||||
|
||||
|
||||
def test_ownership_on_new_with_user(api_client: TestClient, g2_user: TestUser):
|
||||
|
@ -29,8 +29,8 @@ def test_ownership_on_new_with_user(api_client: TestClient, g2_user: TestUser):
|
|||
|
||||
recipe = response.json()
|
||||
|
||||
assert recipe["userId"] == g2_user.user_id
|
||||
assert recipe["groupId"] == g2_user.group_id
|
||||
assert recipe["userId"] == str(g2_user.user_id)
|
||||
assert recipe["groupId"] == str(g2_user.group_id)
|
||||
|
||||
|
||||
def test_get_all_only_includes_group_recipes(api_client: TestClient, unique_user: TestUser):
|
||||
|
@ -47,8 +47,8 @@ def test_get_all_only_includes_group_recipes(api_client: TestClient, unique_user
|
|||
assert len(recipes) == 5
|
||||
|
||||
for recipe in recipes:
|
||||
assert recipe["groupId"] == unique_user.group_id
|
||||
assert recipe["userId"] == unique_user.user_id
|
||||
assert recipe["groupId"] == str(unique_user.group_id)
|
||||
assert recipe["userId"] == str(unique_user.user_id)
|
||||
|
||||
|
||||
def test_unique_slug_by_group(api_client: TestClient, unique_user: TestUser, g2_user: TestUser) -> None:
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
import random
|
||||
from collections.abc import Generator
|
||||
from uuid import UUID
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.recipe.recipe import Recipe
|
||||
from mealie.schema.user.user import UserRatingUpdate
|
||||
from tests.utils import api_routes
|
||||
|
@ -14,9 +12,10 @@ from tests.utils.fixture_schemas import TestUser
|
|||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def recipes(database: AllRepositories, user_tuple: tuple[TestUser, TestUser]) -> Generator[list[Recipe], None, None]:
|
||||
def recipes(user_tuple: tuple[TestUser, TestUser]) -> Generator[list[Recipe], None, None]:
|
||||
unique_user = random.choice(user_tuple)
|
||||
recipes_repo = database.recipes.by_group(UUID(unique_user.group_id))
|
||||
database = unique_user.repos
|
||||
recipes_repo = database.recipes
|
||||
|
||||
recipes: list[Recipe] = []
|
||||
for _ in range(random_int(10, 20)):
|
||||
|
@ -51,7 +50,6 @@ def test_user_recipe_favorites(
|
|||
unique_user = user_tuple[1]
|
||||
|
||||
response = api_client.get(api_routes.users_id_favorites(unique_user.user_id), headers=unique_user.token)
|
||||
assert response.json()["ratings"] == []
|
||||
|
||||
recipes_to_favorite = random.sample(recipes, random_int(5, len(recipes)))
|
||||
|
||||
|
@ -89,7 +87,11 @@ def test_user_recipe_favorites(
|
|||
assert len(ratings) == len(recipes_to_favorite) - len(recipe_favorites_to_remove)
|
||||
fetched_recipe_ids = {rating["recipeId"] for rating in ratings}
|
||||
removed_recipe_ids = {str(recipe.id) for recipe in recipe_favorites_to_remove}
|
||||
assert fetched_recipe_ids == favorited_recipe_ids - removed_recipe_ids
|
||||
|
||||
for recipe_id in removed_recipe_ids:
|
||||
assert recipe_id not in fetched_recipe_ids
|
||||
for recipe_id in fetched_recipe_ids:
|
||||
assert recipe_id in favorited_recipe_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize("add_favorite", [True, False])
|
||||
|
@ -119,8 +121,6 @@ def test_set_user_recipe_ratings(
|
|||
unique_user = user_tuple[1]
|
||||
|
||||
response = api_client.get(api_routes.users_id_ratings(unique_user.user_id), headers=unique_user.token)
|
||||
assert response.json()["ratings"] == []
|
||||
|
||||
recipes_to_rate = random.sample(recipes, random_int(8, len(recipes)))
|
||||
|
||||
expected_ratings_by_recipe_id: dict[str, UserRatingUpdate] = {}
|
||||
|
@ -144,12 +144,16 @@ def test_set_user_recipe_ratings(
|
|||
response = api_client.get(get_url, headers=unique_user.token)
|
||||
ratings = response.json()["ratings"]
|
||||
|
||||
assert len(ratings) == len(recipes_to_rate)
|
||||
for rating in ratings:
|
||||
recipe_id = rating["recipeId"]
|
||||
assert rating["rating"] == expected_ratings_by_recipe_id[recipe_id].rating
|
||||
if recipe_id not in expected_ratings_by_recipe_id:
|
||||
continue
|
||||
|
||||
assert rating["rating"] == expected_ratings_by_recipe_id.pop(recipe_id).rating
|
||||
assert not rating["isFavorite"]
|
||||
|
||||
assert not expected_ratings_by_recipe_id # we should have popped all of them
|
||||
|
||||
|
||||
def test_set_user_rating_invalid_recipe_404(api_client: TestClient, user_tuple: tuple[TestUser, TestUser]):
|
||||
unique_user = random.choice(user_tuple)
|
||||
|
@ -289,9 +293,10 @@ def test_set_rating_to_zero(api_client: TestClient, user_tuple: tuple[TestUser,
|
|||
|
||||
|
||||
def test_delete_recipe_deletes_ratings(
|
||||
database: AllRepositories, api_client: TestClient, user_tuple: tuple[TestUser, TestUser], recipes: list[Recipe]
|
||||
api_client: TestClient, user_tuple: tuple[TestUser, TestUser], recipes: list[Recipe]
|
||||
):
|
||||
unique_user = random.choice(user_tuple)
|
||||
database = unique_user.repos
|
||||
recipe = random.choice(recipes)
|
||||
rating = UserRatingUpdate(rating=random.uniform(1, 5), is_favorite=random.choice([True, False, None]))
|
||||
response = api_client.post(
|
||||
|
@ -306,6 +311,7 @@ def test_delete_recipe_deletes_ratings(
|
|||
assert response.json()
|
||||
|
||||
database.recipes.delete(recipe.id, match_key="id")
|
||||
database.session.commit()
|
||||
response = api_client.get(api_routes.users_self_ratings_recipe_id(recipe.id), headers=unique_user.token)
|
||||
assert response.status_code == 404
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@ import pytest
|
|||
import sqlalchemy
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.schema.recipe.recipe_share_token import RecipeShareTokenSave
|
||||
from mealie.schema.recipe.recipe_share_token import RecipeShareToken, RecipeShareTokenSave
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_string
|
||||
from tests.utils.fixture_schemas import TestUser
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def slug(api_client: TestClient, unique_user: TestUser, database: AllRepositories) -> Generator[str, None, None]:
|
||||
def slug(api_client: TestClient, unique_user: TestUser) -> Generator[str, None, None]:
|
||||
database = unique_user.repos
|
||||
payload = {"name": random_string(length=20)}
|
||||
response = api_client.post(api_routes.recipes, json=payload, headers=unique_user.token)
|
||||
assert response.status_code == 201
|
||||
|
@ -27,14 +27,13 @@ def slug(api_client: TestClient, unique_user: TestUser, database: AllRepositorie
|
|||
pass
|
||||
|
||||
|
||||
def test_recipe_share_tokens_get_all(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
slug: str,
|
||||
):
|
||||
def test_recipe_share_tokens_get_all(api_client: TestClient, unique_user: TestUser, slug: str):
|
||||
database = unique_user.repos
|
||||
|
||||
# Create 5 Tokens
|
||||
recipe = database.recipes.get_one(slug)
|
||||
assert recipe
|
||||
|
||||
tokens = []
|
||||
for _ in range(5):
|
||||
token = database.recipe_share_tokens.create(
|
||||
|
@ -50,14 +49,13 @@ def test_recipe_share_tokens_get_all(
|
|||
assert len(response_data) == 5
|
||||
|
||||
|
||||
def test_recipe_share_tokens_get_all_with_id(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
slug: str,
|
||||
):
|
||||
def test_recipe_share_tokens_get_all_with_id(api_client: TestClient, unique_user: TestUser, slug: str):
|
||||
database = unique_user.repos
|
||||
|
||||
# Create 5 Tokens
|
||||
recipe = database.recipes.get_one(slug)
|
||||
assert recipe
|
||||
|
||||
tokens = []
|
||||
for _ in range(3):
|
||||
token = database.recipe_share_tokens.create(
|
||||
|
@ -73,13 +71,10 @@ def test_recipe_share_tokens_get_all_with_id(
|
|||
assert len(response_data) == 3
|
||||
|
||||
|
||||
def test_recipe_share_tokens_create_and_get_one(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
slug: str,
|
||||
):
|
||||
def test_recipe_share_tokens_create_and_get_one(api_client: TestClient, unique_user: TestUser, slug: str):
|
||||
database = unique_user.repos
|
||||
recipe = database.recipes.get_one(slug)
|
||||
assert recipe
|
||||
|
||||
payload = {
|
||||
"recipeId": str(recipe.id),
|
||||
|
@ -95,14 +90,13 @@ def test_recipe_share_tokens_create_and_get_one(
|
|||
assert response_data["recipe"]["id"] == str(recipe.id)
|
||||
|
||||
|
||||
def test_recipe_share_tokens_delete_one(
|
||||
api_client: TestClient,
|
||||
unique_user: TestUser,
|
||||
database: AllRepositories,
|
||||
slug: str,
|
||||
):
|
||||
def test_recipe_share_tokens_delete_one(api_client: TestClient, unique_user: TestUser, slug: str):
|
||||
database = unique_user.repos
|
||||
|
||||
# Create Token
|
||||
token: RecipeShareToken | None = None
|
||||
recipe = database.recipes.get_one(slug)
|
||||
assert recipe
|
||||
|
||||
token = database.recipe_share_tokens.create(
|
||||
RecipeShareTokenSave(recipe_id=recipe.id, group_id=unique_user.group_id)
|
||||
|
|
|
@ -15,7 +15,7 @@ def test_associate_ingredient_with_step(api_client: TestClient, unique_user: Tes
|
|||
# Associate an ingredient with a step
|
||||
steps = {} # key=step_id, value=ingredient_id
|
||||
|
||||
for idx, step in enumerate(recipe.recipe_instructions):
|
||||
for idx, step in enumerate(recipe.recipe_instructions or []):
|
||||
ingredients = random.choices(recipe.recipe_ingredient, k=2)
|
||||
|
||||
step.ingredient_references = [
|
||||
|
@ -39,7 +39,7 @@ def test_associate_ingredient_with_step(api_client: TestClient, unique_user: Tes
|
|||
|
||||
data: dict = json.loads(response.text)
|
||||
|
||||
for idx, stp in enumerate(data.get("recipeInstructions")):
|
||||
for idx, stp in enumerate(data.get("recipeInstructions") or []):
|
||||
all_refs = [ref["referenceId"] for ref in stp.get("ingredientReferences")]
|
||||
|
||||
assert len(all_refs) == 2
|
||||
|
|
|
@ -39,7 +39,7 @@ def test_create_timeline_event(api_client: TestClient, unique_user: TestUser, re
|
|||
recipe = recipes[0]
|
||||
new_event = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": unique_user.user_id,
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
|
@ -63,7 +63,7 @@ def test_get_all_timeline_events(api_client: TestClient, unique_user: TestUser,
|
|||
events_data = [
|
||||
{
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": unique_user.user_id,
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
|
@ -98,7 +98,7 @@ def test_get_timeline_event(api_client: TestClient, unique_user: TestUser, recip
|
|||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": unique_user.user_id,
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
|
@ -127,7 +127,7 @@ def test_update_timeline_event(api_client: TestClient, unique_user: TestUser, re
|
|||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": unique_user.user_id,
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": old_subject,
|
||||
"event_type": "info",
|
||||
}
|
||||
|
@ -157,7 +157,7 @@ def test_delete_timeline_event(api_client: TestClient, unique_user: TestUser, re
|
|||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": unique_user.user_id,
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
|
@ -187,7 +187,7 @@ def test_timeline_event_message_alias(api_client: TestClient, unique_user: TestU
|
|||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipeId": str(recipe.id),
|
||||
"userId": unique_user.user_id,
|
||||
"userId": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"eventType": "info",
|
||||
"eventMessage": random_string(), # eventMessage is the correct alias for the message
|
||||
|
@ -234,7 +234,7 @@ def test_timeline_event_update_image(
|
|||
recipe = recipes[0]
|
||||
new_event_data = {
|
||||
"recipe_id": str(recipe.id),
|
||||
"user_id": unique_user.user_id,
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"message": random_string(),
|
||||
"event_type": "info",
|
||||
|
@ -281,7 +281,7 @@ def test_create_recipe_with_timeline_event(api_client: TestClient, unique_user:
|
|||
def test_invalid_recipe_id(api_client: TestClient, unique_user: TestUser):
|
||||
new_event_data = {
|
||||
"recipe_id": str(uuid4()),
|
||||
"user_id": unique_user.user_id,
|
||||
"user_id": str(unique_user.user_id),
|
||||
"subject": random_string(),
|
||||
"event_type": "info",
|
||||
"message": random_string(),
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from tests.utils import TestUser, api_routes
|
||||
from tests.utils.factories import random_email, random_int, random_string
|
||||
|
||||
|
||||
@pytest.mark.parametrize("use_admin_user", [True, False])
|
||||
def test_get_all_users_admin(
|
||||
request: pytest.FixtureRequest, database: AllRepositories, api_client: TestClient, use_admin_user: bool
|
||||
):
|
||||
def test_get_all_users_admin(request: pytest.FixtureRequest, api_client: TestClient, use_admin_user: bool):
|
||||
user: TestUser
|
||||
if use_admin_user:
|
||||
user = request.getfixturevalue("admin_user")
|
||||
else:
|
||||
user = request.getfixturevalue("unique_user")
|
||||
|
||||
database = user.repos
|
||||
user_ids: set[str] = set()
|
||||
for _ in range(random_int(2, 5)):
|
||||
group = database.groups.create({"name": random_string()})
|
||||
household = database.households.create({"name": random_string(), "group_id": group.id})
|
||||
for _ in range(random_int(2, 5)):
|
||||
new_user = database.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"household": household.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
|
@ -43,56 +43,3 @@ def test_get_all_users_admin(
|
|||
response_user_ids = {user["id"] for user in response.json()["items"]}
|
||||
for user_id in user_ids:
|
||||
assert user_id in response_user_ids
|
||||
|
||||
|
||||
@pytest.mark.parametrize("use_admin_user", [True, False])
|
||||
def test_get_all_group_users(
|
||||
request: pytest.FixtureRequest, database: AllRepositories, api_client: TestClient, use_admin_user: bool
|
||||
):
|
||||
user: TestUser
|
||||
if use_admin_user:
|
||||
user = request.getfixturevalue("admin_user")
|
||||
else:
|
||||
user = request.getfixturevalue("unique_user")
|
||||
|
||||
other_group_user_ids: set[str] = set()
|
||||
for _ in range(random_int(2, 5)):
|
||||
group = database.groups.create({"name": random_string()})
|
||||
for _ in range(random_int(2, 5)):
|
||||
new_user = database.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": group.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
other_group_user_ids.add(str(new_user.id))
|
||||
|
||||
user_group = database.groups.get_by_slug_or_id(user.group_id)
|
||||
assert user_group
|
||||
same_group_user_ids: set[str] = {user.user_id}
|
||||
for _ in range(random_int(2, 5)):
|
||||
new_user = database.users.create(
|
||||
{
|
||||
"username": random_string(),
|
||||
"email": random_email(),
|
||||
"group": user_group.name,
|
||||
"full_name": random_string(),
|
||||
"password": random_string(),
|
||||
"admin": False,
|
||||
}
|
||||
)
|
||||
same_group_user_ids.add(str(new_user.id))
|
||||
|
||||
response = api_client.get(api_routes.users_group_users, params={"perPage": -1}, headers=user.token)
|
||||
assert response.status_code == 200
|
||||
response_user_ids = {user["id"] for user in response.json()["items"]}
|
||||
|
||||
# assert only users from the same group are returned
|
||||
for user_id in other_group_user_ids:
|
||||
assert user_id not in response_user_ids
|
||||
for user_id in same_group_user_ids:
|
||||
assert user_id in response_user_ids
|
||||
|
|
|
@ -4,7 +4,6 @@ import pytest
|
|||
from fastapi.testclient import TestClient
|
||||
|
||||
from mealie.core.config import get_app_settings
|
||||
from mealie.repos.repository_factory import AllRepositories
|
||||
from mealie.services.user_services.user_service import UserService
|
||||
from tests.utils import api_routes
|
||||
from tests.utils.factories import random_string
|
||||
|
@ -45,11 +44,12 @@ def test_get_logged_in_user_invalid_token(api_client: TestClient, use_token: boo
|
|||
assert response.status_code == 401
|
||||
|
||||
|
||||
def test_user_lockout_after_bad_attemps(api_client: TestClient, unique_user: TestUser, database: AllRepositories):
|
||||
def test_user_lockout_after_bad_attemps(api_client: TestClient, unique_user: TestUser):
|
||||
"""
|
||||
if the user has more than 5 bad login attempts the user will be locked out for 4 hours
|
||||
This only applies if there is a user in the database with the same username
|
||||
"""
|
||||
database = unique_user.repos
|
||||
settings = get_app_settings()
|
||||
|
||||
for _ in range(settings.SECURITY_MAX_LOGIN_ATTEMPTS):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue