diff --git a/crowdin.yml b/crowdin.yml index 82b9d9921da6..2e468cdf39ae 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,9 +1,9 @@ preserve_hierarchy: false files: - - source: /frontend/src/locales/messages/en-US.json - translation: /frontend/src/locales/messages/%locale%.json - - source: /frontend/src/locales/dateTimeFormats/en-US.json - translation: /frontend/src/locales/dateTimeFormats/%locale%.json + - source: /frontend/lang/messages/en-US.json + translation: /frontend/lang/messages/%locale%.json + - source: /frontend/lang/dateTimeFormats/en-US.json + translation: /frontend/lang/dateTimeFormats/%locale%.json # Backend General Messages - source: /mealie/lang/messages/en-US.json diff --git a/mealie/repos/repository_generic.py b/mealie/repos/repository_generic.py index a7076f56b74d..48669b5248b4 100644 --- a/mealie/repos/repository_generic.py +++ b/mealie/repos/repository_generic.py @@ -149,8 +149,8 @@ class RepositoryGeneric(Generic[T, D]): if match_key is None: match_key = self.primary_key - filter = self._filter_builder(**{match_key: match_value}) - return self.session.query(self.sql_model).filter_by(**filter).one() + fltr = self._filter_builder(**{match_key: match_value}) + return self.session.query(self.sql_model).filter_by(**fltr).one() def get_one(self, value: str | int | UUID4, key: str = None, any_case=False, override_schema=None) -> T | None: key = key or self.primary_key @@ -210,7 +210,7 @@ class RepositoryGeneric(Generic[T, D]): return [eff_schema.from_orm(x) for x in result] - def create(self, document: T | BaseModel) -> T: + def create(self, document: T | BaseModel | dict) -> T: """Creates a new database entry for the given SQL Alchemy Model. Args: @@ -266,8 +266,10 @@ class RepositoryGeneric(Generic[T, D]): return self.update(match_value, entry_as_dict) - def delete(self, primary_key_value) -> D: - result = self.session.query(self.sql_model).filter_by(**{self.primary_key: primary_key_value}).one() + def delete(self, value, match_key: str | None = None) -> T: + match_key = match_key or self.primary_key + + result = self.session.query(self.sql_model).filter_by(**{match_key: value}).one() results_as_model = self.schema.from_orm(result) try: @@ -313,7 +315,7 @@ class RepositoryGeneric(Generic[T, D]): for x in self.session.query(self.sql_model).filter(attribute_name == attr_match).all() # noqa: 711 ] - def create_many(self, documents: list[T]) -> list[T]: + def create_many(self, documents: list[T | dict]) -> list[T]: new_documents = [] for document in documents: document = document if isinstance(document, dict) else document.dict() diff --git a/mealie/repos/repository_users.py b/mealie/repos/repository_users.py index 4189f94900ac..aeb8cb83b1ce 100644 --- a/mealie/repos/repository_users.py +++ b/mealie/repos/repository_users.py @@ -2,6 +2,8 @@ import random import shutil from typing import Optional +from pydantic import UUID4 + from mealie.assets import users as users_assets from mealie.schema.user.user import PrivateUser, User @@ -30,11 +32,11 @@ class RepositoryUsers(RepositoryGeneric[PrivateUser, User]): return new_user - def delete(self, id: str) -> User: - entry = super().delete(id) + def delete(self, value: str | UUID4, match_key: str | None = None) -> User: + entry = super().delete(value, match_key) # Delete the user's directory - shutil.rmtree(PrivateUser.get_directory(id)) - return entry + shutil.rmtree(PrivateUser.get_directory(value)) + return entry # type: ignore def get_by_username(self, username: str, limit=1) -> Optional[User]: dbuser = self.session.query(User).filter(User.username == username).one_or_none() diff --git a/mealie/schema/user/user.py b/mealie/schema/user/user.py index 596bbf0f170a..a0c3256ddde9 100644 --- a/mealie/schema/user/user.py +++ b/mealie/schema/user/user.py @@ -128,7 +128,7 @@ class PrivateUser(UserOut): orm_mode = True @staticmethod - def get_directory(user_id: UUID4) -> Path: + def get_directory(user_id: UUID4 | str) -> Path: user_dir = get_app_dirs().USER_DIR / str(user_id) user_dir.mkdir(parents=True, exist_ok=True) return user_dir diff --git a/mealie/services/recipe/recipe_service.py b/mealie/services/recipe/recipe_service.py index 5173400ddf55..b40d848fd5a7 100644 --- a/mealie/services/recipe/recipe_service.py +++ b/mealie/services/recipe/recipe_service.py @@ -178,7 +178,7 @@ class RecipeService(BaseService): def delete_one(self, slug) -> Recipe: recipe = self._get_recipe(slug) self.can_update(recipe) - data = self.repos.recipes.delete(slug) + data = self.repos.recipes.delete(recipe.id, "id") self.delete_assets(data) return data diff --git a/tests/integration_tests/admin_tests/test_admin_user_actions.py b/tests/integration_tests/admin_tests/test_admin_user_actions.py index 8e90480df89f..136fcc92b8ef 100644 --- a/tests/integration_tests/admin_tests/test_admin_user_actions.py +++ b/tests/integration_tests/admin_tests/test_admin_user_actions.py @@ -27,7 +27,7 @@ def generate_create_data() -> dict: def test_init_superuser(api_client: TestClient, admin_user: TestUser): settings = get_app_settings() - response = api_client.get(routes.RoutesAdminUsers.item(admin_user.user_id), headers=admin_user.token) + response = api_client.get(routes.admin.AdminUsers.item(admin_user.user_id), headers=admin_user.token) assert response.status_code == 200 admin_data = response.json() @@ -41,13 +41,13 @@ def test_init_superuser(api_client: TestClient, admin_user: TestUser): def test_create_user(api_client: TestClient, api_routes: AppRoutes, admin_token): create_data = generate_create_data() - response = api_client.post(routes.RoutesAdminUsers.base, json=create_data, headers=admin_token) + response = api_client.post(routes.admin.AdminUsers.base, json=create_data, headers=admin_token) assert response.status_code == 201 form_data = {"username": create_data["email"], "password": create_data["password"]} header = utils.login(form_data=form_data, api_client=api_client, api_routes=api_routes) - response = api_client.get(routes.RoutesUsers.self, headers=header) + response = api_client.get(routes.user.Users.self, headers=header) assert response.status_code == 200 user_data = response.json() @@ -60,14 +60,14 @@ def test_create_user(api_client: TestClient, api_routes: AppRoutes, admin_token) def test_create_user_as_non_admin(api_client: TestClient, user_token): create_data = generate_create_data() - response = api_client.post(routes.RoutesAdminUsers.base, json=create_data, headers=user_token) + response = api_client.post(routes.admin.AdminUsers.base, json=create_data, headers=user_token) assert response.status_code == 403 def test_update_user(api_client: TestClient, admin_user: TestUser): # Create a new user create_data = generate_create_data() - response = api_client.post(routes.RoutesAdminUsers.base, json=create_data, headers=admin_user.token) + response = api_client.post(routes.admin.AdminUsers.base, json=create_data, headers=admin_user.token) assert response.status_code == 201 update_data = response.json() @@ -76,7 +76,7 @@ def test_update_user(api_client: TestClient, admin_user: TestUser): update_data["email"] = random_email() response = api_client.put( - routes.RoutesAdminUsers.item(update_data["id"]), headers=admin_user.token, json=update_data + routes.admin.AdminUsers.item(update_data["id"]), headers=admin_user.token, json=update_data ) assert response.status_code == 200 @@ -93,21 +93,21 @@ def test_update_other_user_as_not_admin(api_client: TestClient, unique_user: Tes "admin": True, } response = api_client.put( - routes.RoutesAdminUsers.item(g2_user.user_id), headers=unique_user.token, json=update_data + routes.admin.AdminUsers.item(g2_user.user_id), headers=unique_user.token, json=update_data ) assert response.status_code == 403 def test_self_demote_admin(api_client: TestClient, admin_user: TestUser): - response = api_client.get(routes.RoutesUsers.self, headers=admin_user.token) + response = api_client.get(routes.user.Users.self, headers=admin_user.token) assert response.status_code == 200 user_data = response.json() user_data["admin"] = False response = api_client.put( - routes.RoutesAdminUsers.item(admin_user.user_id), headers=admin_user.token, json=user_data + routes.admin.AdminUsers.item(admin_user.user_id), headers=admin_user.token, json=user_data ) assert response.status_code == 403 @@ -122,12 +122,12 @@ def test_self_promote_admin(api_client: TestClient, unique_user: TestUser): "admin": True, } response = api_client.put( - routes.RoutesAdminUsers.item(unique_user.user_id), headers=unique_user.token, json=update_data + routes.admin.AdminUsers.item(unique_user.user_id), headers=unique_user.token, json=update_data ) assert response.status_code == 403 def test_delete_user(api_client: TestClient, admin_token, unique_user: TestUser): - response = api_client.delete(routes.RoutesAdminUsers.item(unique_user.user_id), headers=admin_token) + response = api_client.delete(routes.admin.AdminUsers.item(unique_user.user_id), headers=admin_token) assert response.status_code == 200 diff --git a/tests/integration_tests/category_tag_tool_tests/test_organizers_common.py b/tests/integration_tests/category_tag_tool_tests/test_organizers_common.py index 742c6853a983..befa67e6ca9b 100644 --- a/tests/integration_tests/category_tag_tool_tests/test_organizers_common.py +++ b/tests/integration_tests/category_tag_tool_tests/test_organizers_common.py @@ -14,9 +14,9 @@ test_ids = [ ] organizer_routes = [ - (routes.RoutesCategory), - (routes.RoutesTags), - (routes.RoutesTools), + (routes.organizers.Categories), + (routes.organizers.Tags), + (routes.organizers.Tools), ] @@ -43,9 +43,9 @@ def test_organizers_create_read(api_client: TestClient, unique_user: TestUser, r update_data = [ - (routes.RoutesCategory, {"name": random_string(10)}), - (routes.RoutesTags, {"name": random_string(10)}), - (routes.RoutesTools, {"name": random_string(10), "onHand": random_bool()}), + (routes.organizers.Categories, {"name": random_string(10)}), + (routes.organizers.Tags, {"name": random_string(10)}), + (routes.organizers.Tools, {"name": random_string(10), "onHand": random_bool()}), ] @@ -101,9 +101,9 @@ def test_organizer_delete( association_data = [ - (routes.RoutesCategory, recipe_keys.recipe_category), - (routes.RoutesTags, "tags"), - (routes.RoutesTools, "tools"), + (routes.organizers.Categories, recipe_keys.recipe_category), + (routes.organizers.Tags, "tags"), + (routes.organizers.Tools, "tools"), ] @@ -123,28 +123,28 @@ def test_organizer_association( # Setup Recipe recipe_data = {"name": random_string(10)} - response = api_client.post(routes.RoutesRecipe.base, json=recipe_data, headers=unique_user.token) + response = api_client.post(routes.recipes.Recipe.base, json=recipe_data, headers=unique_user.token) slug = response.json() assert response.status_code == 201 # Get Recipe Data - response = api_client.get(routes.RoutesRecipe.item(slug), headers=unique_user.token) + response = api_client.get(routes.recipes.Recipe.item(slug), headers=unique_user.token) as_json = response.json() as_json[recipe_key] = [ {"id": item["id"], "group_id": unique_user.group_id, "name": item["name"], "slug": item["slug"]} ] # Update Recipe - response = api_client.put(routes.RoutesRecipe.item(slug), json=as_json, headers=unique_user.token) + response = api_client.put(routes.recipes.Recipe.item(slug), json=as_json, headers=unique_user.token) assert response.status_code == 200 # Get Recipe Data - response = api_client.get(routes.RoutesRecipe.item(slug), headers=unique_user.token) + response = api_client.get(routes.recipes.Recipe.item(slug), headers=unique_user.token) as_json = response.json() assert as_json[recipe_key][0]["slug"] == item["slug"] # Cleanup - response = api_client.delete(routes.RoutesRecipe.item(slug), headers=unique_user.token) + response = api_client.delete(routes.recipes.Recipe.item(slug), headers=unique_user.token) assert response.status_code == 200 response = api_client.delete(route.item(item["id"]), headers=unique_user.token) @@ -155,7 +155,7 @@ def test_organizer_association( def test_organizer_get_by_slug( api_client: TestClient, unique_user: TestUser, - route: routes.RoutesOrganizerBase, + route: routes.organizers.RoutesOrganizerBase, recipe_key: str, ): # Create Organizer @@ -170,20 +170,20 @@ def test_organizer_get_by_slug( for _ in range(10): # Setup Recipe recipe_data = {"name": random_string(10)} - response = api_client.post(routes.RoutesRecipe.base, json=recipe_data, headers=unique_user.token) + response = api_client.post(routes.recipes.Recipe.base, json=recipe_data, headers=unique_user.token) assert response.status_code == 201 slug = response.json() recipe_slugs.append(slug) # Associate 10 Recipes to Organizer for slug in recipe_slugs: - response = api_client.get(routes.RoutesRecipe.item(slug), headers=unique_user.token) + response = api_client.get(routes.recipes.Recipe.item(slug), headers=unique_user.token) as_json = response.json() as_json[recipe_key] = [ {"id": item["id"], "group_id": unique_user.group_id, "name": item["name"], "slug": item["slug"]} ] - response = api_client.put(routes.RoutesRecipe.item(slug), json=as_json, headers=unique_user.token) + response = api_client.put(routes.recipes.Recipe.item(slug), json=as_json, headers=unique_user.token) assert response.status_code == 200 # Get Organizer by Slug diff --git a/tests/integration_tests/user_group_tests/test_group_seeder.py b/tests/integration_tests/user_group_tests/test_group_seeder.py index a45111a820a9..c326ffddbc8e 100644 --- a/tests/integration_tests/user_group_tests/test_group_seeder.py +++ b/tests/integration_tests/user_group_tests/test_group_seeder.py @@ -1,12 +1,12 @@ from fastapi.testclient import TestClient from mealie.repos.repository_factory import AllRepositories +from tests.utils import routes from tests.utils.fixture_schemas import TestUser -from tests.utils.routes import RoutesSeeders def test_seed_invalid_locale(api_client: TestClient, unique_user: TestUser): - for route in [RoutesSeeders.foods, RoutesSeeders.labels, RoutesSeeders.units]: + for route in [routes.seeders.Seeders.foods, routes.seeders.Seeders.labels, routes.seeders.Seeders.units]: resp = api_client.post(route, json={"locale": "invalid"}, headers=unique_user.token) assert resp.status_code == 422 @@ -18,7 +18,7 @@ def test_seed_foods(api_client: TestClient, unique_user: TestUser, database: All foods = database.ingredient_foods.by_group(unique_user.group_id).get_all() assert len(foods) == 0 - resp = api_client.post(RoutesSeeders.foods, json={"locale": "en-US"}, headers=unique_user.token) + resp = api_client.post(routes.seeders.Seeders.foods, json={"locale": "en-US"}, headers=unique_user.token) assert resp.status_code == 200 # Check that the foods was created @@ -33,7 +33,7 @@ def test_seed_units(api_client: TestClient, unique_user: TestUser, database: All units = database.ingredient_units.by_group(unique_user.group_id).get_all() assert len(units) == 0 - resp = api_client.post(RoutesSeeders.units, json={"locale": "en-US"}, headers=unique_user.token) + resp = api_client.post(routes.seeders.Seeders.units, json={"locale": "en-US"}, headers=unique_user.token) assert resp.status_code == 200 # Check that the foods was created @@ -48,7 +48,7 @@ def test_seed_labels(api_client: TestClient, unique_user: TestUser, database: Al labels = database.group_multi_purpose_labels.by_group(unique_user.group_id).get_all() assert len(labels) == 0 - resp = api_client.post(RoutesSeeders.labels, json={"locale": "en-US"}, headers=unique_user.token) + resp = api_client.post(routes.seeders.Seeders.labels, json={"locale": "en-US"}, headers=unique_user.token) assert resp.status_code == 200 # Check that the foods was created diff --git a/tests/integration_tests/user_recipe_tests/test_recipe_crud.py b/tests/integration_tests/user_recipe_tests/test_recipe_crud.py index a63a824cd09f..9900b55a23ab 100644 --- a/tests/integration_tests/user_recipe_tests/test_recipe_crud.py +++ b/tests/integration_tests/user_recipe_tests/test_recipe_crud.py @@ -14,6 +14,7 @@ from mealie.schema.recipe.recipe import RecipeCategory from mealie.services.recipe.recipe_data_service import RecipeDataService from mealie.services.scraper.scraper_strategies import RecipeScraperOpenGraph from tests import data, utils +from tests.utils import routes from tests.utils.app_routes import AppRoutes from tests.utils.factories import random_string from tests.utils.fixture_schemas import TestUser @@ -157,12 +158,11 @@ def test_create_by_url_with_tags( @pytest.mark.parametrize("recipe_data", recipe_test_data) def test_read_update( api_client: TestClient, - api_routes: AppRoutes, recipe_data: RecipeSiteTestCase, unique_user: TestUser, recipe_categories: list[RecipeCategory], ): - recipe_url = api_routes.recipes_recipe_slug(recipe_data.expected_slug) + recipe_url = routes.recipes.Recipe.item(recipe_data.expected_slug) response = api_client.get(recipe_url, headers=unique_user.token) assert response.status_code == 200 @@ -196,8 +196,8 @@ def test_read_update( @pytest.mark.parametrize("recipe_data", recipe_test_data) -def test_rename(api_client: TestClient, api_routes: AppRoutes, recipe_data: RecipeSiteTestCase, unique_user: TestUser): - recipe_url = api_routes.recipes_recipe_slug(recipe_data.expected_slug) +def test_rename(api_client: TestClient, recipe_data: RecipeSiteTestCase, unique_user: TestUser): + recipe_url = routes.recipes.Recipe.item(recipe_data.expected_slug) response = api_client.get(recipe_url, headers=unique_user.token) assert response.status_code == 200 @@ -215,44 +215,66 @@ def test_rename(api_client: TestClient, api_routes: AppRoutes, recipe_data: Reci @pytest.mark.parametrize("recipe_data", recipe_test_data) -def test_delete(api_client: TestClient, api_routes: AppRoutes, recipe_data: RecipeSiteTestCase, unique_user: TestUser): - recipe_url = api_routes.recipes_recipe_slug(recipe_data.expected_slug) - response = api_client.delete(recipe_url, headers=unique_user.token) +def test_delete(api_client: TestClient, recipe_data: RecipeSiteTestCase, unique_user: TestUser): + response = api_client.delete(routes.recipes.Recipe.item(recipe_data.expected_slug), headers=unique_user.token) assert response.status_code == 200 def test_recipe_crud_404(api_client: TestClient, api_routes: AppRoutes, unique_user: TestUser): - response = api_client.put(api_routes.recipes_recipe_slug("test"), json={"test": "stest"}, headers=unique_user.token) + response = api_client.put(routes.recipes.Recipe.item("test"), json={"test": "stest"}, headers=unique_user.token) assert response.status_code == 404 - response = api_client.get(api_routes.recipes_recipe_slug("test"), headers=unique_user.token) + response = api_client.get(routes.recipes.Recipe.item("test"), headers=unique_user.token) assert response.status_code == 404 - response = api_client.delete(api_routes.recipes_recipe_slug("test"), headers=unique_user.token) + response = api_client.delete(routes.recipes.Recipe.item("test"), headers=unique_user.token) assert response.status_code == 404 response = api_client.patch(api_routes.recipes_create_url, json={"test": "stest"}, headers=unique_user.token) assert response.status_code == 404 -def test_create_recipe_same_name(api_client: TestClient, api_routes: AppRoutes, unique_user: TestUser): +def test_create_recipe_same_name(api_client: TestClient, unique_user: TestUser): slug = random_string(10) - response = api_client.post("/api/recipes", json={"name": slug}, headers=unique_user.token) + response = api_client.post(routes.recipes.Recipe.base, json={"name": slug}, headers=unique_user.token) assert response.status_code == 201 assert json.loads(response.text) == slug - response = api_client.post("/api/recipes", json={"name": slug}, headers=unique_user.token) + response = api_client.post(routes.recipes.Recipe.base, json={"name": slug}, headers=unique_user.token) assert response.status_code == 201 assert json.loads(response.text) == f"{slug}-1" -def test_create_recipe_too_many_time(api_client: TestClient, api_routes: AppRoutes, unique_user: TestUser): +def test_create_recipe_too_many_time(api_client: TestClient, unique_user: TestUser): slug = random_string(10) for _ in range(10): - response = api_client.post("/api/recipes", json={"name": slug}, headers=unique_user.token) + response = api_client.post(routes.recipes.Recipe.base, json={"name": slug}, headers=unique_user.token) assert response.status_code == 201 - response = api_client.post("/api/recipes", json={"name": slug}, headers=unique_user.token) + response = api_client.post(routes.recipes.Recipe.base, json={"name": slug}, headers=unique_user.token) assert response.status_code == 400 + + +def test_delete_recipe_same_name(api_client: TestClient, unique_user: utils.TestUser, g2_user: utils.TestUser): + slug = random_string(10) + + # Create recipe for both users + for user in (unique_user, g2_user): + response = api_client.post(routes.recipes.Recipe.base, json={"name": slug}, headers=user.token) + assert response.status_code == 201 + assert json.loads(response.text) == slug + + # Delete recipe for user 1 + response = api_client.delete(routes.recipes.Recipe.item(slug), headers=unique_user.token) + assert response.status_code == 200 + + # Ensure recipe for user 2 still exists + response = api_client.get(routes.recipes.Recipe.item(slug), headers=g2_user.token) + assert response.status_code == 200 + + # Make sure recipe for user 1 doesn't exist + response = api_client.get(routes.recipes.Recipe.item(slug), headers=unique_user.token) + response = api_client.get(routes.recipes.Recipe.item(slug), headers=unique_user.token) + assert response.status_code == 404 diff --git a/tests/integration_tests/user_recipe_tests/test_recipe_steps.py b/tests/integration_tests/user_recipe_tests/test_recipe_steps.py index 0c1c2cff50e0..6d0bd56f4d06 100644 --- a/tests/integration_tests/user_recipe_tests/test_recipe_steps.py +++ b/tests/integration_tests/user_recipe_tests/test_recipe_steps.py @@ -26,7 +26,7 @@ def test_associate_ingredient_with_step(api_client: TestClient, unique_user: Tes steps[idx] = [str(ingredient.reference_id) for ingredient in ingredients] response = api_client.put( - routes.RoutesRecipe.item(recipe.slug), + routes.recipes.Recipe.item(recipe.slug), json=jsonify(recipe.dict()), headers=unique_user.token, ) @@ -35,14 +35,14 @@ def test_associate_ingredient_with_step(api_client: TestClient, unique_user: Tes # Get Recipe and check that the ingredient is associated with the step - response = api_client.get(routes.RoutesRecipe.item(recipe.slug), headers=unique_user.token) + response = api_client.get(routes.recipes.Recipe.item(recipe.slug), headers=unique_user.token) assert response.status_code == 200 - recipe = json.loads(response.text) + data: dict = json.loads(response.text) - for idx, step in enumerate(recipe.get("recipeInstructions")): - all_refs = [ref["referenceId"] for ref in step.get("ingredientReferences")] + for idx, stp in enumerate(data.get("recipeInstructions")): + all_refs = [ref["referenceId"] for ref in stp.get("ingredientReferences")] assert len(all_refs) == 2 diff --git a/tests/multitenant_tests/case_categories.py b/tests/multitenant_tests/case_categories.py index f84b664deaf8..c24ece8be32d 100644 --- a/tests/multitenant_tests/case_categories.py +++ b/tests/multitenant_tests/case_categories.py @@ -10,8 +10,8 @@ from tests.utils import routes class CategoryTestCase(ABCMultiTenantTestCase): items: list[RecipeCategory] - def seed_action(self, group_id: str) -> set[int]: - category_ids: set[int] = set() + def seed_action(self, group_id: str) -> set[str]: + category_ids: set[str] = set() for _ in range(10): category = self.database.categories.create( CategorySave( @@ -26,8 +26,8 @@ class CategoryTestCase(ABCMultiTenantTestCase): return category_ids def seed_multi(self, group1_id: str, group2_id: str) -> tuple[set[str], set[str]]: - g1_item_ids = set() - g2_item_ids = set() + g1_item_ids: set[str] = set() + g2_item_ids: set[str] = set() for group_id, item_ids in [(group1_id, g1_item_ids), (group2_id, g2_item_ids)]: for _ in range(10): @@ -44,7 +44,7 @@ class CategoryTestCase(ABCMultiTenantTestCase): return g1_item_ids, g2_item_ids def get_all(self, token: str) -> Response: - return self.client.get(routes.RoutesCategory.base, headers=token) + return self.client.get(routes.organizers.Categories.base, headers=token) def cleanup(self) -> None: for item in self.items: diff --git a/tests/multitenant_tests/case_foods.py b/tests/multitenant_tests/case_foods.py index 40b688276510..fbd2b0d5a315 100644 --- a/tests/multitenant_tests/case_foods.py +++ b/tests/multitenant_tests/case_foods.py @@ -43,7 +43,7 @@ class FoodsTestCase(ABCMultiTenantTestCase): return g1_item_ids, g2_item_ids def get_all(self, token: str) -> Response: - return self.client.get(routes.RoutesFoods.base, headers=token) + return self.client.get(routes.recipes.Foods.base, headers=token) def cleanup(self) -> None: for item in self.items: diff --git a/tests/multitenant_tests/case_tags.py b/tests/multitenant_tests/case_tags.py index 6ab1f6fc118a..11b79a1bf62d 100644 --- a/tests/multitenant_tests/case_tags.py +++ b/tests/multitenant_tests/case_tags.py @@ -10,8 +10,8 @@ from tests.utils import routes class TagsTestCase(ABCMultiTenantTestCase): items: list[RecipeTag] - def seed_action(self, group_id: str) -> set[int]: - tag_ids: set[int] = set() + def seed_action(self, group_id: str) -> set[str]: + tag_ids: set[str] = set() for _ in range(10): tag = self.database.tags.create( TagSave( @@ -26,8 +26,8 @@ class TagsTestCase(ABCMultiTenantTestCase): return tag_ids def seed_multi(self, group1_id: str, group2_id: str) -> tuple[set[str], set[str]]: - g1_item_ids = set() - g2_item_ids = set() + g1_item_ids: set[str] = set() + g2_item_ids: set[str] = set() for group_id, item_ids in [(group1_id, g1_item_ids), (group2_id, g2_item_ids)]: for _ in range(10): @@ -44,7 +44,7 @@ class TagsTestCase(ABCMultiTenantTestCase): return g1_item_ids, g2_item_ids def get_all(self, token: str) -> Response: - return self.client.get(routes.RoutesTags.base, headers=token) + return self.client.get(routes.organizers.Tags.base, headers=token) def cleanup(self) -> None: for item in self.items: diff --git a/tests/multitenant_tests/case_tools.py b/tests/multitenant_tests/case_tools.py index ef417841d8a0..c0ae73598048 100644 --- a/tests/multitenant_tests/case_tools.py +++ b/tests/multitenant_tests/case_tools.py @@ -44,7 +44,7 @@ class ToolsTestCase(ABCMultiTenantTestCase): return g1_item_ids, g2_item_ids def get_all(self, token: str) -> Response: - return self.client.get(routes.RoutesTools.base, headers=token) + return self.client.get(routes.organizers.Tools.base, headers=token) def cleanup(self) -> None: for item in self.items: diff --git a/tests/multitenant_tests/case_units.py b/tests/multitenant_tests/case_units.py index c40466d9116b..8d6ef53ebcb7 100644 --- a/tests/multitenant_tests/case_units.py +++ b/tests/multitenant_tests/case_units.py @@ -9,8 +9,8 @@ from tests.utils import routes class UnitsTestCase(ABCMultiTenantTestCase): items: list[IngredientUnit] - def seed_action(self, group_id: str) -> set[int]: - unit_ids: set[int] = set() + def seed_action(self, group_id: str) -> set[str]: + unit_ids: set[str] = set() for _ in range(10): unit = self.database.ingredient_units.create( SaveIngredientUnit( @@ -25,8 +25,8 @@ class UnitsTestCase(ABCMultiTenantTestCase): return unit_ids def seed_multi(self, group1_id: str, group2_id: str) -> tuple[set[str], set[str]]: - g1_item_ids = set() - g2_item_ids = set() + g1_item_ids: set[str] = set() + g2_item_ids: set[str] = set() for group_id, item_ids in [(group1_id, g1_item_ids), (group2_id, g2_item_ids)]: for _ in range(10): @@ -43,7 +43,7 @@ class UnitsTestCase(ABCMultiTenantTestCase): return g1_item_ids, g2_item_ids def get_all(self, token: str) -> Response: - return self.client.get(routes.RoutesUnits.base, headers=token) + return self.client.get(routes.recipes.Units.base, headers=token) def cleanup(self) -> None: for item in self.items: diff --git a/tests/utils/routes.py b/tests/utils/routes.py deleted file mode 100644 index 6eb55ace1651..000000000000 --- a/tests/utils/routes.py +++ /dev/null @@ -1,60 +0,0 @@ -from pydantic import UUID4 - - -class RoutesBase: - prefix = "/api" - base = f"{prefix}/" - - def __init__(self) -> None: - raise Exception("This class is not meant to be instantiated.") - - @classmethod - def item(cls, item_id: int | str | UUID4) -> str: - return f"{cls.base}/{item_id}" - - -class RoutesFoods(RoutesBase): - base = "/api/foods" - - -class RoutesUnits(RoutesBase): - base = "/api/units" - - -class RoutesOrganizerBase(RoutesBase): - @classmethod - def slug(cls, slug: str) -> str: - return f"{cls.base}/slug/{slug}" - - -class RoutesTools(RoutesOrganizerBase): - base = "/api/organizers/tools" - - -class RoutesTags(RoutesOrganizerBase): - base = "/api/organizers/tags" - - -class RoutesCategory(RoutesOrganizerBase): - base = "/api/organizers/categories" - - -class RoutesRecipe(RoutesBase): - base = "/api/recipes" - - -class RoutesAdminUsers(RoutesBase): - base = "/api/admin/users" - - -class RoutesUsers(RoutesBase): - base = "/api/users" - self = f"{base}/self" - - -class RoutesSeeders(RoutesBase): - base = "/api/groups/seeders" - - foods = f"{base}/foods" - units = f"{base}/units" - labels = f"{base}/labels" diff --git a/tests/utils/routes/__init__.py b/tests/utils/routes/__init__.py new file mode 100644 index 000000000000..0e73eb0cb394 --- /dev/null +++ b/tests/utils/routes/__init__.py @@ -0,0 +1,6 @@ +from . import routes_admin as admin +from . import routes_organizers as organizers +from . import routes_recipes as recipes +from . import routes_seeders as seeders +from . import routes_user as user +from ._base import RoutesBase diff --git a/tests/utils/routes/_base.py b/tests/utils/routes/_base.py new file mode 100644 index 000000000000..83a1eaae7fe6 --- /dev/null +++ b/tests/utils/routes/_base.py @@ -0,0 +1,17 @@ +from pydantic import UUID4 + + +def v1(route: str) -> str: + return f"/api{route}" + + +class RoutesBase: + prefix = "/api" + base = f"{prefix}/" + + def __init__(self) -> None: + raise NotImplementedError("This class is not meant to be instantiated.") + + @classmethod + def item(cls, item_id: int | str | UUID4) -> str: + return f"{cls.base}/{item_id}" diff --git a/tests/utils/routes/routes_admin.py b/tests/utils/routes/routes_admin.py new file mode 100644 index 000000000000..d483109a382d --- /dev/null +++ b/tests/utils/routes/routes_admin.py @@ -0,0 +1,5 @@ +from ._base import RoutesBase, v1 + + +class AdminUsers(RoutesBase): + base = v1("/admin/users") diff --git a/tests/utils/routes/routes_organizers.py b/tests/utils/routes/routes_organizers.py new file mode 100644 index 000000000000..7db02d061cee --- /dev/null +++ b/tests/utils/routes/routes_organizers.py @@ -0,0 +1,19 @@ +from ._base import RoutesBase, v1 + + +class RoutesOrganizerBase(RoutesBase): + @classmethod + def slug(cls, slug: str) -> str: + return f"{cls.base}/slug/{slug}" + + +class Tools(RoutesOrganizerBase): + base = v1("/organizers/tools") + + +class Tags(RoutesOrganizerBase): + base = v1("/organizers/tags") + + +class Categories(RoutesOrganizerBase): + base = v1("/organizers/categories") diff --git a/tests/utils/routes/routes_recipes.py b/tests/utils/routes/routes_recipes.py new file mode 100644 index 000000000000..36f6d9bc2144 --- /dev/null +++ b/tests/utils/routes/routes_recipes.py @@ -0,0 +1,13 @@ +from ._base import RoutesBase, v1 + + +class Foods(RoutesBase): + base = v1("/foods") + + +class Units(RoutesBase): + base = v1("/units") + + +class Recipe(RoutesBase): + base = v1("/recipes") diff --git a/tests/utils/routes/routes_seeders.py b/tests/utils/routes/routes_seeders.py new file mode 100644 index 000000000000..bb2ed5db3b98 --- /dev/null +++ b/tests/utils/routes/routes_seeders.py @@ -0,0 +1,9 @@ +from ._base import RoutesBase, v1 + + +class Seeders(RoutesBase): + base = v1("/groups/seeders") + + foods = f"{base}/foods" + units = f"{base}/units" + labels = f"{base}/labels" diff --git a/tests/utils/routes/routes_user.py b/tests/utils/routes/routes_user.py new file mode 100644 index 000000000000..3b6c70907180 --- /dev/null +++ b/tests/utils/routes/routes_user.py @@ -0,0 +1,6 @@ +from ._base import RoutesBase, v1 + + +class Users(RoutesBase): + base = v1("/users") + self = f"{base}/self"