pytest edit shopping list recipes
This commit is contained in:
parent
262387da3e
commit
a51eb7a2cb
@ -52,12 +52,14 @@ def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None
|
||||
if not r:
|
||||
raise ValueError(_("You must supply a recipe or mealplan"))
|
||||
|
||||
created_by = created_by or getattr(mealplan, 'created_by', None) or getattr(list_recipe, 'created_by', None)
|
||||
if not created_by:
|
||||
raise ValueError(_("You must supply a created_by"))
|
||||
|
||||
if type(servings) not in [int, float]:
|
||||
try:
|
||||
servings = float(servings)
|
||||
except ValueError:
|
||||
servings = getattr(mealplan, 'servings', 1.0)
|
||||
|
||||
servings_factor = servings / r.servings
|
||||
|
||||
shared_users = list(created_by.get_shopping_share())
|
||||
@ -68,6 +70,7 @@ def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None
|
||||
list_recipe = ShoppingListRecipe.objects.create(recipe=r, mealplan=mealplan, servings=servings)
|
||||
created = True
|
||||
|
||||
related_step_ing = []
|
||||
if servings == 0 and not created:
|
||||
list_recipe.delete()
|
||||
return []
|
||||
@ -79,7 +82,6 @@ def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None
|
||||
if exclude_onhand := created_by.userpreference.mealplan_autoexclude_onhand:
|
||||
ingredients = ingredients.exclude(food__on_hand=True)
|
||||
|
||||
related_step_ing = []
|
||||
if related := created_by.userpreference.mealplan_autoinclude_related:
|
||||
# TODO: add levels of related recipes to use when auto-adding mealplans
|
||||
related_recipes = r.get_related_recipes()
|
||||
@ -128,6 +130,8 @@ def list_from_recipe(list_recipe=None, recipe=None, mealplan=None, servings=None
|
||||
|
||||
if not created and list_recipe.servings != servings:
|
||||
update_ingredients = set(ingredients.values_list('id', flat=True)) - set(add_ingredients.values_list('id', flat=True))
|
||||
list_recipe.servings = servings
|
||||
list_recipe.save()
|
||||
for sle in ShoppingListEntry.objects.filter(list_recipe=list_recipe, ingredient__id__in=update_ingredients):
|
||||
sle.amount = sle.ingredient.amount * Decimal(servings_factor)
|
||||
sle.save()
|
||||
|
@ -10,7 +10,7 @@ from django.utils import timezone
|
||||
from django_scopes import scopes_disabled
|
||||
from pytest_factoryboy import LazyFixture, register
|
||||
|
||||
from cookbook.models import ShoppingListEntry
|
||||
from cookbook.models import Ingredient, ShoppingListEntry
|
||||
from cookbook.tests.factories import RecipeFactory
|
||||
|
||||
SHOPPING_LIST_URL = 'api:shoppinglistentry-list'
|
||||
@ -82,7 +82,69 @@ def test_shopping_recipe_method(request, arg, recipe, sle_count, u1_s1, u2_s1):
|
||||
assert r.status_code == 405
|
||||
|
||||
|
||||
@pytest.mark.parametrize("recipe, sle_count", [
|
||||
({}, 10),
|
||||
({'steps__recipe_count': 1}, 20), # shopping list from recipe with StepRecipe
|
||||
({'steps__food_recipe_count': {'step': 0, 'count': 1}}, 19), # shopping list from recipe with food recipe
|
||||
({'steps__food_recipe_count': {'step': 0, 'count': 1}, 'steps__recipe_count': 1}, 29), # shopping list from recipe with StepRecipe and food recipe
|
||||
], indirect=['recipe'])
|
||||
def test_shopping_recipe_edit(request, recipe, sle_count, u1_s1, u2_s1):
|
||||
with scopes_disabled(): # TODO take out
|
||||
|
||||
user = auth.get_user(u1_s1)
|
||||
user2 = auth.get_user(u2_s1)
|
||||
user.userpreference.mealplan_autoinclude_related = True
|
||||
user.userpreference.shopping_share.add(user2)
|
||||
user.userpreference.save()
|
||||
|
||||
r = u1_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe.id}))
|
||||
r = json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
||||
assert [x['created_by']['id'] for x in r].count(user.id) == sle_count
|
||||
all_ing = [x['ingredient'] for x in r]
|
||||
keep_ing = [x['ingredient'] for x in r[2:]] # TODO change this to remove 1 from each third
|
||||
list_recipe = r[0]['list_recipe']
|
||||
amount_sum = sum([x['amount'] for x in r])
|
||||
|
||||
# test modifying shopping list as different user
|
||||
# test increasing servings size of recipe shopping list
|
||||
u2_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe.id}),
|
||||
{'list_recipe': list_recipe, 'servings': 2*recipe.servings},
|
||||
content_type='application/json'
|
||||
)
|
||||
r = json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
||||
assert sum([x['amount'] for x in r]) == amount_sum * 2
|
||||
assert len(r) == sle_count
|
||||
assert len(json.loads(u2_s1.get(reverse(SHOPPING_LIST_URL)).content)) == sle_count
|
||||
|
||||
# testing decreasing servings size of recipe shopping list
|
||||
u1_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe.id}),
|
||||
{'list_recipe': list_recipe, 'servings': .5 * recipe.servings},
|
||||
content_type='application/json'
|
||||
)
|
||||
r = json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
||||
assert sum([x['amount'] for x in r]) == amount_sum * .5
|
||||
assert len(r) == sle_count
|
||||
assert len(json.loads(u2_s1.get(reverse(SHOPPING_LIST_URL)).content)) == sle_count
|
||||
|
||||
# test removing 2 items from shopping list
|
||||
u2_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe.id}),
|
||||
{'list_recipe': list_recipe, 'ingredients': keep_ing},
|
||||
content_type='application/json'
|
||||
)
|
||||
r = json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
||||
assert len(r) == sle_count - 2
|
||||
assert len(json.loads(u2_s1.get(reverse(SHOPPING_LIST_URL)).content)) == sle_count - 2
|
||||
|
||||
# add all ingredients to existing shopping list - don't change serving size
|
||||
u2_s1.put(reverse(SHOPPING_RECIPE_URL, args={recipe.id}),
|
||||
{'list_recipe': list_recipe, 'ingredients': all_ing},
|
||||
content_type='application/json'
|
||||
)
|
||||
r = json.loads(u1_s1.get(reverse(SHOPPING_LIST_URL)).content)
|
||||
assert sum([x['amount'] for x in r]) == amount_sum * .5
|
||||
assert len(r) == sle_count
|
||||
assert len(json.loads(u2_s1.get(reverse(SHOPPING_LIST_URL)).content)) == sle_count
|
||||
|
||||
|
||||
# TODO test creating shopping list from recipe that includes recipes from multiple users
|
||||
# TODO test create shopping list from recipe, excluding ingredients
|
||||
# TODO meal plan recipe with all the user preferences tested
|
||||
# TODO shopping list from recipe with different servings
|
||||
|
@ -661,10 +661,15 @@ class RecipeViewSet(viewsets.ModelViewSet):
|
||||
def shopping(self, request, pk):
|
||||
obj = self.get_object()
|
||||
ingredients = request.data.get('ingredients', None)
|
||||
servings = request.data.get('servings', obj.servings)
|
||||
list_recipe = request.data.get('list_recipe', None)
|
||||
servings = request.data.get('servings', None)
|
||||
list_recipe = ShoppingListRecipe.objects.filter(id=request.data.get('list_recipe', None)).first()
|
||||
if servings is None:
|
||||
servings = getattr(list_recipe, 'servings', obj.servings)
|
||||
# created_by needs to be sticky to original creator as it is 'their' shopping list
|
||||
# changing shopping list created_by can shift some items to new owner which may not share in the other direction
|
||||
created_by = getattr(ShoppingListEntry.objects.filter(list_recipe=list_recipe).first(), 'created_by', request.user)
|
||||
content = {'msg': _(f'{obj.name} was added to the shopping list.')}
|
||||
list_from_recipe(list_recipe=list_recipe, recipe=obj, ingredients=ingredients, servings=servings, space=request.space, created_by=request.user)
|
||||
list_from_recipe(list_recipe=list_recipe, recipe=obj, ingredients=ingredients, servings=servings, space=request.space, created_by=created_by)
|
||||
|
||||
return Response(content, status=status.HTTP_204_NO_CONTENT)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user