mirror of
https://github.com/mealie-recipes/mealie.git
synced 2025-07-09 03:04:54 -04:00
Feature/auto increment recipe name (#1088)
* auto-increment-recipe-name * add test-case * re-implement as try/except
This commit is contained in:
parent
0f82523cdd
commit
7f102f513d
@ -2,7 +2,9 @@ from random import randint
|
|||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
|
|
||||||
|
from slugify import slugify
|
||||||
from sqlalchemy import and_, func
|
from sqlalchemy import and_, func
|
||||||
|
from sqlalchemy.exc import IntegrityError
|
||||||
from sqlalchemy.orm import joinedload
|
from sqlalchemy.orm import joinedload
|
||||||
|
|
||||||
from mealie.db.models.recipe.category import Category
|
from mealie.db.models.recipe.category import Category
|
||||||
@ -17,6 +19,21 @@ from .repository_generic import RepositoryGeneric
|
|||||||
|
|
||||||
|
|
||||||
class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
class RepositoryRecipes(RepositoryGeneric[Recipe, RecipeModel]):
|
||||||
|
def create(self, document: Recipe) -> Recipe: # type: ignore
|
||||||
|
max_retries = 10
|
||||||
|
original_name: str = document.name # type: ignore
|
||||||
|
|
||||||
|
for i in range(1, 11):
|
||||||
|
try:
|
||||||
|
return super().create(document)
|
||||||
|
except IntegrityError:
|
||||||
|
self.session.rollback()
|
||||||
|
document.name = f"{original_name} ({i})"
|
||||||
|
document.slug = slugify(document.name)
|
||||||
|
|
||||||
|
if i >= max_retries:
|
||||||
|
raise
|
||||||
|
|
||||||
def by_group(self, group_id: UUID) -> "RepositoryRecipes":
|
def by_group(self, group_id: UUID) -> "RepositoryRecipes":
|
||||||
return super().by_group(group_id) # type: ignore
|
return super().by_group(group_id) # type: ignore
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ from mealie.services.recipe.recipe_data_service import RecipeDataService
|
|||||||
from mealie.services.scraper.scraper_strategies import RecipeScraperOpenGraph
|
from mealie.services.scraper.scraper_strategies import RecipeScraperOpenGraph
|
||||||
from tests import utils
|
from tests import utils
|
||||||
from tests.utils.app_routes import AppRoutes
|
from tests.utils.app_routes import AppRoutes
|
||||||
|
from tests.utils.factories import random_string
|
||||||
from tests.utils.fixture_schemas import TestUser
|
from tests.utils.fixture_schemas import TestUser
|
||||||
from tests.utils.recipe_data import RecipeSiteTestCase, get_recipe_test_cases
|
from tests.utils.recipe_data import RecipeSiteTestCase, get_recipe_test_cases
|
||||||
|
|
||||||
@ -167,3 +168,26 @@ def test_recipe_crud_404(api_client: TestClient, api_routes: AppRoutes, unique_u
|
|||||||
|
|
||||||
response = api_client.patch(api_routes.recipes_create_url, json={"test": "stest"}, headers=unique_user.token)
|
response = api_client.patch(api_routes.recipes_create_url, json={"test": "stest"}, headers=unique_user.token)
|
||||||
assert response.status_code == 404
|
assert response.status_code == 404
|
||||||
|
|
||||||
|
|
||||||
|
def test_create_recipe_same_name(api_client: TestClient, api_routes: AppRoutes, unique_user: TestUser):
|
||||||
|
slug = random_string(10)
|
||||||
|
|
||||||
|
response = api_client.post("/api/recipes", 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)
|
||||||
|
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):
|
||||||
|
slug = random_string(10)
|
||||||
|
|
||||||
|
for _ in range(10):
|
||||||
|
response = api_client.post("/api/recipes", 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)
|
||||||
|
assert response.status_code == 400
|
||||||
|
@ -62,9 +62,10 @@ def test_unique_slug_by_group(api_client: TestClient, unique_user: TestUser, g2_
|
|||||||
response = api_client.post(Routes.base, json=create_data, headers=g2_user.token)
|
response = api_client.post(Routes.base, json=create_data, headers=g2_user.token)
|
||||||
assert response.status_code == 201
|
assert response.status_code == 201
|
||||||
|
|
||||||
# Try to create a recipe again with the same name
|
# Try to create a recipe again with the same name and check that the name was incremented
|
||||||
response = api_client.post(Routes.base, json=create_data, headers=g2_user.token)
|
response = api_client.post(Routes.base, json=create_data, headers=g2_user.token)
|
||||||
assert response.status_code == 400
|
assert response.status_code == 201
|
||||||
|
assert response.json() == create_data["name"] + "-1"
|
||||||
|
|
||||||
|
|
||||||
def test_user_locked_recipe(api_client: TestClient, user_tuple: list[TestUser]) -> None:
|
def test_user_locked_recipe(api_client: TestClient, user_tuple: list[TestUser]) -> None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user