test userpreference food_inherit defaults
This commit is contained in:
parent
7e081d4389
commit
ea7d34c8d2
@ -157,6 +157,8 @@ class UserPreferenceSerializer(serializers.ModelSerializer):
|
|||||||
food_ignore_default = serializers.SerializerMethodField('get_ignore_default')
|
food_ignore_default = serializers.SerializerMethodField('get_ignore_default')
|
||||||
plan_share = UserNameSerializer(many=True, allow_null=True, required=False, read_only=True)
|
plan_share = UserNameSerializer(many=True, allow_null=True, required=False, read_only=True)
|
||||||
|
|
||||||
|
# TODO decide: default inherit field values for foods are being handled via VUE client through user preference
|
||||||
|
## should inherit field instead be set during the django model create?
|
||||||
def get_ignore_default(self, obj):
|
def get_ignore_default(self, obj):
|
||||||
return FoodInheritFieldSerializer(Food.inherit_fields.difference(obj.space.food_inherit.all()), many=True).data
|
return FoodInheritFieldSerializer(Food.inherit_fields.difference(obj.space.food_inherit.all()), many=True).data
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -496,11 +496,11 @@ def test_inherit(request, obj_tree_1, field, inherit, new_val, u1_s1):
|
|||||||
assert (getattr(child, field) == new_val) == inherit
|
assert (getattr(child, field) == new_val) == inherit
|
||||||
|
|
||||||
|
|
||||||
# This is more about the model than the API - should this be moved to a different test?
|
|
||||||
@pytest.mark.parametrize("obj_tree_1, field, inherit, new_val", [
|
@pytest.mark.parametrize("obj_tree_1, field, inherit, new_val", [
|
||||||
({'has_category': True, 'inherit': True, }, 'supermarket_category', True, 'cat_1'),
|
({'has_category': True, 'inherit': True, }, 'supermarket_category', True, 'cat_1'),
|
||||||
({'ignore_shopping': True, 'inherit': True, }, 'ignore_shopping', True, 'false'),
|
({'ignore_shopping': True, 'inherit': True, }, 'ignore_shopping', True, 'false'),
|
||||||
], indirect=['obj_tree_1']) # indirect=True populates magic variable request.param of obj_tree_1 with the parameter
|
], indirect=['obj_tree_1'])
|
||||||
|
# This is more about the model than the API - should this be moved to a different test?
|
||||||
def test_ignoreinherit_field(request, obj_tree_1, field, inherit, new_val, u1_s1):
|
def test_ignoreinherit_field(request, obj_tree_1, field, inherit, new_val, u1_s1):
|
||||||
with scope(space=obj_tree_1.space):
|
with scope(space=obj_tree_1.space):
|
||||||
parent = obj_tree_1.get_parent()
|
parent = obj_tree_1.get_parent()
|
||||||
|
@ -11,6 +11,8 @@ from cookbook.models import Food, MealPlan, MealType
|
|||||||
LIST_URL = 'api:mealplan-list'
|
LIST_URL = 'api:mealplan-list'
|
||||||
DETAIL_URL = 'api:mealplan-detail'
|
DETAIL_URL = 'api:mealplan-detail'
|
||||||
|
|
||||||
|
# NOTE: auto adding shopping list from meal plan is tested in test_shopping_recipe as tests are identical
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture()
|
@pytest.fixture()
|
||||||
def meal_type(space_1, u1_s1):
|
def meal_type(space_1, u1_s1):
|
||||||
@ -139,7 +141,3 @@ def test_delete(u1_s1, u1_s2, obj_1):
|
|||||||
assert r.status_code == 204
|
assert r.status_code == 204
|
||||||
with scopes_disabled():
|
with scopes_disabled():
|
||||||
assert MealPlan.objects.count() == 0
|
assert MealPlan.objects.count() == 0
|
||||||
|
|
||||||
|
|
||||||
# TODO test auto creating shopping list from meal plan
|
|
||||||
# TODO test excluding on-hand when auto creating shopping list
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import pytest
|
|
||||||
|
|
||||||
|
import pytest
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scopes_disabled
|
||||||
|
|
||||||
@ -111,16 +111,3 @@ def test_delete(u1_s1, u1_s2, recipe_1_s1):
|
|||||||
|
|
||||||
assert r.status_code == 204
|
assert r.status_code == 204
|
||||||
assert not Recipe.objects.filter(pk=recipe_1_s1.id).exists()
|
assert not Recipe.objects.filter(pk=recipe_1_s1.id).exists()
|
||||||
|
|
||||||
|
|
||||||
# TODO test related_recipes api
|
|
||||||
# -- step recipes
|
|
||||||
# -- ingredient recipes
|
|
||||||
# -- recipe wrong space
|
|
||||||
# -- steps wrong space
|
|
||||||
# -- ingredients wrong space
|
|
||||||
# -- step recipes included in step recipes
|
|
||||||
# -- step recipes included in food recipes
|
|
||||||
# -- food recipes included in step recipes
|
|
||||||
# -- food recipes included in food recipes
|
|
||||||
# -- included recipes in the wrong space
|
|
74
cookbook/tests/api/test_api_related_recipe.py
Normal file
74
cookbook/tests/api/test_api_related_recipe.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
import factory
|
||||||
|
import pytest
|
||||||
|
from django.contrib import auth
|
||||||
|
from django.urls import reverse
|
||||||
|
from django_scopes import scopes_disabled
|
||||||
|
from pytest_factoryboy import LazyFixture, register
|
||||||
|
|
||||||
|
from cookbook.tests.factories import RecipeFactory
|
||||||
|
|
||||||
|
RELATED_URL = 'api:recipe-related'
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture()
|
||||||
|
def recipe(request, space_1, u1_s1):
|
||||||
|
try:
|
||||||
|
params = request.param # request.param is a magic variable
|
||||||
|
except AttributeError:
|
||||||
|
params = {}
|
||||||
|
step_recipe = params.get('steps__count', 1)
|
||||||
|
steps__recipe_count = params.get('steps__recipe_count', 0)
|
||||||
|
steps__food_recipe_count = params.get('steps__food_recipe_count', {})
|
||||||
|
created_by = params.get('created_by', auth.get_user(u1_s1))
|
||||||
|
|
||||||
|
return RecipeFactory.create(
|
||||||
|
steps__recipe_count=steps__recipe_count,
|
||||||
|
steps__food_recipe_count=steps__food_recipe_count,
|
||||||
|
created_by=created_by,
|
||||||
|
space=space_1,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("arg", [
|
||||||
|
['g1_s1', 200],
|
||||||
|
['u1_s1', 200],
|
||||||
|
['u1_s2', 404],
|
||||||
|
['a1_s1', 200],
|
||||||
|
])
|
||||||
|
@pytest.mark.parametrize("recipe, related_count", [
|
||||||
|
({}, 0),
|
||||||
|
({'steps__recipe_count': 1}, 1), # shopping list from recipe with StepRecipe
|
||||||
|
({'steps__food_recipe_count': {'step': 0, 'count': 1}}, 1), # shopping list from recipe with food recipe
|
||||||
|
({'steps__food_recipe_count': {'step': 0, 'count': 1}, 'steps__recipe_count': 1}, 2), # shopping list from recipe with StepRecipe and food recipe
|
||||||
|
], indirect=['recipe'])
|
||||||
|
def test_get_related_recipes(request, arg, recipe, related_count, u1_s1, space_2):
|
||||||
|
c = request.getfixturevalue(arg[0])
|
||||||
|
r = c.get(reverse(RELATED_URL, args={recipe.id}))
|
||||||
|
assert r.status_code == arg[1]
|
||||||
|
if r.status_code == 200:
|
||||||
|
assert len(json.loads(r.content)) == related_count
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("recipe", [
|
||||||
|
({'steps__recipe_count': 1}), # shopping list from recipe with StepRecipe
|
||||||
|
({'steps__food_recipe_count': {'step': 0, 'count': 1}}), # shopping list from recipe with food recipe
|
||||||
|
({'steps__food_recipe_count': {'step': 0, 'count': 1}, 'steps__recipe_count': 1}), # shopping list from recipe with StepRecipe and food recipe
|
||||||
|
], indirect=['recipe'])
|
||||||
|
def test_related_mixed_space(request, recipe, u1_s2):
|
||||||
|
with scopes_disabled():
|
||||||
|
recipe.space = auth.get_user(u1_s2).userpreference.space
|
||||||
|
recipe.save()
|
||||||
|
assert len(json.loads(
|
||||||
|
u1_s2.get(
|
||||||
|
reverse(RELATED_URL, args={recipe.id})).content)) == 0
|
||||||
|
|
||||||
|
|
||||||
|
# TODO add tests for mealplan related when thats added
|
||||||
|
# TODO if/when related recipes includes multiple levels (related recipes of related recipes) add the following tests
|
||||||
|
# -- step recipes included in step recipes
|
||||||
|
# -- step recipes included in food recipes
|
||||||
|
# -- food recipes included in step recipes
|
||||||
|
# -- food recipes included in food recipes
|
||||||
|
# -- -- included recipes in the wrong space
|
@ -3,9 +3,9 @@ import json
|
|||||||
import pytest
|
import pytest
|
||||||
from django.contrib import auth
|
from django.contrib import auth
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django_scopes import scopes_disabled
|
from django_scopes import scope, scopes_disabled
|
||||||
|
|
||||||
from cookbook.models import UserPreference
|
from cookbook.models import Food, UserPreference
|
||||||
|
|
||||||
LIST_URL = 'api:userpreference-list'
|
LIST_URL = 'api:userpreference-list'
|
||||||
DETAIL_URL = 'api:userpreference-detail'
|
DETAIL_URL = 'api:userpreference-detail'
|
||||||
@ -111,4 +111,31 @@ def test_preference_delete(u1_s1, u2_s1):
|
|||||||
assert r.status_code == 204
|
assert r.status_code == 204
|
||||||
|
|
||||||
|
|
||||||
# TODO test existance of default food_inherit fields, test multiple users same space work and users in difference space do not
|
def test_default_inherit_fields(u1_s1, u1_s2, space_1, space_2):
|
||||||
|
food_inherit_fields = Food.inherit_fields.all()
|
||||||
|
|
||||||
|
r = u1_s1.get(
|
||||||
|
reverse(DETAIL_URL, args={auth.get_user(u1_s1).id}),
|
||||||
|
)
|
||||||
|
|
||||||
|
# by default space food will not inherit any fields, so all of them will be ignored
|
||||||
|
assert space_1.food_inherit.all().count() == 0
|
||||||
|
assert len([x.field for x in food_inherit_fields]) == len([x['field'] for x in json.loads(r.content)['food_ignore_default']]) > 0
|
||||||
|
|
||||||
|
# inherit all possible fields
|
||||||
|
with scope(space=space_1):
|
||||||
|
space_1.food_inherit.add(*Food.inherit_fields.values_list('id', flat=True))
|
||||||
|
r = u1_s1.get(
|
||||||
|
reverse(DETAIL_URL, args={auth.get_user(u1_s1).id}),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert space_1.food_inherit.all().count() == Food.inherit_fields.all().count() > 0
|
||||||
|
# now by default, food is not ignoring inheritance on any field
|
||||||
|
assert len([x['field'] for x in json.loads(r.content)['food_ignore_default']]) == 0
|
||||||
|
|
||||||
|
# other spaces and users in those spaced not effected
|
||||||
|
r = u1_s2.get(
|
||||||
|
reverse(DETAIL_URL, args={auth.get_user(u1_s2).id}),
|
||||||
|
)
|
||||||
|
assert space_2.food_inherit.all().count() == 0
|
||||||
|
assert len([x.field for x in food_inherit_fields]) == len([x['field'] for x in json.loads(r.content)['food_ignore_default']]) > 0
|
||||||
|
@ -412,7 +412,6 @@ class FoodViewSet(viewsets.ModelViewSet, TreeMixin):
|
|||||||
permission_classes = [CustomIsUser]
|
permission_classes = [CustomIsUser]
|
||||||
pagination_class = DefaultPagination
|
pagination_class = DefaultPagination
|
||||||
|
|
||||||
''
|
|
||||||
@decorators.action(detail=True, methods=['PUT'], serializer_class=FoodShoppingUpdateSerializer,)
|
@decorators.action(detail=True, methods=['PUT'], serializer_class=FoodShoppingUpdateSerializer,)
|
||||||
def shopping(self, request, pk):
|
def shopping(self, request, pk):
|
||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
@ -457,7 +456,7 @@ class RecipeBookEntryViewSet(viewsets.ModelViewSet, viewsets.GenericViewSet):
|
|||||||
- **recipe**: id of recipe - only return books for that recipe
|
- **recipe**: id of recipe - only return books for that recipe
|
||||||
- **book**: id of book - only return recipes in that book
|
- **book**: id of book - only return recipes in that book
|
||||||
|
|
||||||
"""
|
"""
|
||||||
queryset = RecipeBookEntry.objects
|
queryset = RecipeBookEntry.objects
|
||||||
serializer_class = RecipeBookEntrySerializer
|
serializer_class = RecipeBookEntrySerializer
|
||||||
permission_classes = [CustomIsOwner]
|
permission_classes = [CustomIsOwner]
|
||||||
@ -682,7 +681,8 @@ class RecipeViewSet(viewsets.ModelViewSet):
|
|||||||
obj = self.get_object()
|
obj = self.get_object()
|
||||||
if obj.get_space() != request.space:
|
if obj.get_space() != request.space:
|
||||||
raise PermissionDenied(detail='You do not have the required permission to perform this action', code=403)
|
raise PermissionDenied(detail='You do not have the required permission to perform this action', code=403)
|
||||||
qs = obj.get_related_recipes(levels=2) # TODO: make levels a user setting, included in request data, keep solely in the backend?
|
qs = obj.get_related_recipes(levels=1) # TODO: make levels a user setting, included in request data?, keep solely in the backend?
|
||||||
|
# mealplans= TODO get todays mealplans
|
||||||
return Response(self.serializer_class(qs, many=True).data)
|
return Response(self.serializer_class(qs, many=True).data)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user