test case to detect 833
This commit is contained in:
parent
75e46b8023
commit
7e9a8d4d86
@ -218,7 +218,7 @@ def fill_annotated_parents(annotation, filters):
|
||||
|
||||
annotation[i][1]['id'] = r[0].id
|
||||
annotation[i][1]['name'] = r[0].name
|
||||
annotation[i][1]['count'] = getattr(r[0], 'kw_count', 0)
|
||||
annotation[i][1]['count'] = getattr(r[0], 'recipe_count', 0)
|
||||
annotation[i][1]['isDefaultExpanded'] = False
|
||||
|
||||
if str(r[0].id) in filters:
|
||||
@ -236,7 +236,7 @@ def fill_annotated_parents(annotation, filters):
|
||||
|
||||
while j < level:
|
||||
# this causes some double counting when a recipe has both a child and an ancestor
|
||||
annotation[parent[j]][1]['count'] += getattr(r[0], 'kw_count', 0)
|
||||
annotation[parent[j]][1]['count'] += getattr(r[0], 'recipe_count', 0)
|
||||
if expand:
|
||||
annotation[parent[j]][1]['isDefaultExpanded'] = True
|
||||
j += 1
|
||||
|
@ -5,7 +5,6 @@ import uuid
|
||||
from datetime import date, timedelta
|
||||
|
||||
from annoying.fields import AutoOneToOneField
|
||||
from django.conf import settings
|
||||
from django.contrib import auth
|
||||
from django.contrib.auth.models import Group, User
|
||||
from django.contrib.postgres.indexes import GinIndex
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,10 +1,11 @@
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from django.urls import reverse
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
from cookbook.models import Recipe
|
||||
from cookbook.tests.conftest import get_random_json_recipe, validate_recipe
|
||||
|
||||
LIST_URL = 'api:recipe-list'
|
||||
DETAIL_URL = 'api:recipe-detail'
|
||||
@ -49,18 +50,19 @@ def test_list_space(recipe_1_s1, u1_s1, u1_s2, space_2):
|
||||
def test_update(arg, request, recipe_1_s1):
|
||||
with scopes_disabled():
|
||||
c = request.getfixturevalue(arg[0])
|
||||
j = get_random_json_recipe()
|
||||
r = c.patch(
|
||||
reverse(
|
||||
DETAIL_URL,
|
||||
args={recipe_1_s1.id}
|
||||
),
|
||||
{'name': 'new'},
|
||||
j,
|
||||
content_type='application/json'
|
||||
)
|
||||
response = json.loads(r.content)
|
||||
assert r.status_code == arg[1]
|
||||
if r.status_code == 200:
|
||||
assert response['name'] == 'new'
|
||||
validate_recipe(j, json.loads(r.content))
|
||||
|
||||
|
||||
@pytest.mark.parametrize("arg", [
|
||||
@ -70,22 +72,24 @@ def test_update(arg, request, recipe_1_s1):
|
||||
['a1_s1', 201],
|
||||
])
|
||||
def test_add(arg, request, u1_s2):
|
||||
c = request.getfixturevalue(arg[0])
|
||||
r = c.post(
|
||||
reverse(LIST_URL),
|
||||
{'name': 'test', 'waiting_time': 0, 'working_time': 0, 'keywords': [], 'steps': []},
|
||||
content_type='application/json'
|
||||
)
|
||||
response = json.loads(r.content)
|
||||
print(r.content)
|
||||
assert r.status_code == arg[1]
|
||||
if r.status_code == 201:
|
||||
# id can change when running multiple tests, changed to validate name
|
||||
assert response['name'] == 'test'
|
||||
r = c.get(reverse(DETAIL_URL, args={response['id']}))
|
||||
assert r.status_code == 200
|
||||
r = u1_s2.get(reverse(DETAIL_URL, args={response['id']}))
|
||||
assert r.status_code == 404
|
||||
x = 0
|
||||
while x < 2:
|
||||
c = request.getfixturevalue(arg[0])
|
||||
j = get_random_json_recipe()
|
||||
r = c.post(
|
||||
reverse(LIST_URL), j, content_type='application/json'
|
||||
)
|
||||
response = json.loads(r.content)
|
||||
print(r.content)
|
||||
assert r.status_code == arg[1]
|
||||
if r.status_code == 201:
|
||||
# id can change when running multiple tests, changed to validate name
|
||||
validate_recipe(j, json.loads(r.content))
|
||||
r = c.get(reverse(DETAIL_URL, args={response['id']}))
|
||||
assert r.status_code == 200
|
||||
r = u1_s2.get(reverse(DETAIL_URL, args={response['id']}))
|
||||
assert r.status_code == 404
|
||||
x += 1
|
||||
|
||||
|
||||
def test_delete(u1_s1, u1_s2, recipe_1_s1):
|
||||
|
@ -1,5 +1,6 @@
|
||||
import copy
|
||||
import inspect
|
||||
import random
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
@ -81,6 +82,74 @@ def get_random_recipe(space_1, u1_s1):
|
||||
return r
|
||||
|
||||
|
||||
def get_random_json_recipe():
|
||||
return {
|
||||
"name": str(uuid.uuid4()),
|
||||
"description": str(uuid.uuid4()),
|
||||
"keywords": [{"name": str(uuid.uuid4())}, {"name": str(uuid.uuid4())}],
|
||||
"steps": [
|
||||
{
|
||||
"instruction": str(uuid.uuid4()),
|
||||
"ingredients": [
|
||||
{"food": {"name": str(uuid.uuid4())}, "unit": {"name": str(uuid.uuid4())}, "amount": random.randint(0, 10)},
|
||||
{"food": {"name": str(uuid.uuid4())}, "unit": {"name": str(uuid.uuid4())}, "amount": random.randint(0, 10)},
|
||||
],
|
||||
}
|
||||
],
|
||||
"working_time": random.randint(0, 120),
|
||||
"waiting_time": random.randint(0, 120),
|
||||
}
|
||||
|
||||
|
||||
def validate_recipe(expected, recipe):
|
||||
expected_lists = {}
|
||||
target_lists = {}
|
||||
# file and url are metadata not related to the recipe
|
||||
[expected.pop(k) for k in ['file', 'url'] if k in expected]
|
||||
# if a key is a list remove it to deal with later
|
||||
lists = [k for k, v in expected.items() if type(v) == list]
|
||||
for k in lists:
|
||||
expected_lists[k] = expected.pop(k)
|
||||
target_lists[k] = recipe.pop(k)
|
||||
try:
|
||||
# recipe dicts will have additional keys (IDs, default values, etc)
|
||||
# this will check for an exact match from expected key:value to a superset of key:value pairs
|
||||
assert expected.items() <= recipe.items()
|
||||
except AssertionError:
|
||||
for key in expected:
|
||||
if expected[key] != recipe[key]:
|
||||
print('Expected : ', expected[key], ' got: ', recipe[key])
|
||||
|
||||
# this is later, it may or may not work with keys that have list values
|
||||
# it also may or may not work on complex nested dicts
|
||||
for key in expected_lists:
|
||||
for k in expected_lists[key]:
|
||||
try:
|
||||
assert any([dict_compare(k, i) for i in target_lists[key]])
|
||||
except AssertionError:
|
||||
for result in [dict_compare(k, i, details=True) for i in target_lists[key]]:
|
||||
print('Added Keys: ', result[0])
|
||||
print('Removed Keys', result[1])
|
||||
print('Modified Value Keys', result[2])
|
||||
print('Modified Dictionary Keys', result[3])
|
||||
|
||||
|
||||
def dict_compare(d1, d2, details=False):
|
||||
d1_keys = set(d1.keys())
|
||||
d2_keys = set(d2.keys())
|
||||
shared = d1_keys.intersection(d2_keys)
|
||||
sub_dicts = [i for i, j in d1.items() if type(j) == dict]
|
||||
not_dicts = shared - set(sub_dicts)
|
||||
added = d1_keys - d2_keys
|
||||
removed = d2_keys - d1_keys
|
||||
modified = {o: (d1[o], d2[o]) for o in not_dicts if d1[o] != d2[o]}
|
||||
modified_dicts = {o: (d1[o], d2[o]) for o in sub_dicts if not d1[o].items() <= d2[o].items()}
|
||||
if details:
|
||||
return added, removed, modified, modified_dicts
|
||||
else:
|
||||
return any([not added, not removed, not modified, not modified_dicts])
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def recipe_1_s1(space_1, u1_s1):
|
||||
return get_random_recipe(space_1, u1_s1)
|
||||
|
@ -9,6 +9,7 @@ from ._recipes import (
|
||||
ALLRECIPES, AMERICAS_TEST_KITCHEN, CHEF_KOCH, CHEF_KOCH2, COOKPAD,
|
||||
COOKS_COUNTRY, DELISH, FOOD_NETWORK, GIALLOZAFFERANO, JOURNAL_DES_FEMMES,
|
||||
MADAME_DESSERT, MARMITON, TASTE_OF_HOME, THE_SPRUCE_EATS, TUDOGOSTOSO)
|
||||
from cookbook.tests.conftest import validate_recipe
|
||||
|
||||
IMPORT_SOURCE_URL = 'api_recipe_from_source'
|
||||
DATA_DIR = "cookbook/tests/other/test_data/"
|
||||
@ -56,7 +57,8 @@ def test_import_permission(arg, request):
|
||||
TUDOGOSTOSO,
|
||||
])
|
||||
def test_recipe_import(arg, u1_s1):
|
||||
for f in arg['file']:
|
||||
url = arg['url']
|
||||
for f in list(arg['file']) : # url and files get popped later
|
||||
if 'cookbook' in os.getcwd():
|
||||
test_file = os.path.join(os.getcwd(), 'other', 'test_data', f)
|
||||
else:
|
||||
@ -66,33 +68,10 @@ def test_recipe_import(arg, u1_s1):
|
||||
reverse(IMPORT_SOURCE_URL),
|
||||
{
|
||||
'data': d.read(),
|
||||
'url': arg['url'],
|
||||
'url': url,
|
||||
'mode': 'source'
|
||||
},
|
||||
files={'foo': 'bar'}
|
||||
)
|
||||
recipe = json.loads(response.content)['recipe_json']
|
||||
for key in list(set(arg) - set(['file', 'url'])):
|
||||
if type(arg[key]) == list:
|
||||
assert len(recipe[key]) == len(arg[key])
|
||||
if key == 'keywords':
|
||||
valid_keywords = [i['text'] for i in arg[key]]
|
||||
for k in recipe[key]:
|
||||
assert k['text'] in valid_keywords
|
||||
elif key == 'recipeIngredient':
|
||||
valid_ing = ["{:g}{}{}{}{}".format(
|
||||
i['amount'],
|
||||
i['unit']['text'],
|
||||
i['ingredient']['text'],
|
||||
i['note'],
|
||||
i['original'])
|
||||
for i in arg[key]]
|
||||
for i in recipe[key]:
|
||||
assert "{:g}{}{}{}{}".format(
|
||||
i['amount'],
|
||||
i['unit']['text'],
|
||||
i['ingredient']['text'],
|
||||
i['note'],
|
||||
i['original']) in valid_ing
|
||||
else:
|
||||
assert recipe[key] == arg[key]
|
||||
validate_recipe(arg, recipe)
|
||||
|
@ -98,7 +98,6 @@ class DefaultPagination(PageNumberPagination):
|
||||
|
||||
|
||||
class FuzzyFilterMixin(ViewSetMixin):
|
||||
|
||||
def get_queryset(self):
|
||||
self.queryset = self.queryset.filter(space=self.request.space)
|
||||
query = self.request.query_params.get('query', None)
|
||||
@ -365,10 +364,6 @@ class FoodViewSet(viewsets.ModelViewSet, FuzzyFilterMixin):
|
||||
serializer_class = FoodSerializer
|
||||
permission_classes = [CustomIsUser]
|
||||
|
||||
def get_queryset(self):
|
||||
self.queryset = self.queryset.filter(space=self.request.space)
|
||||
return super().get_queryset()
|
||||
|
||||
|
||||
class RecipeBookViewSet(viewsets.ModelViewSet, StandardFilterMixin):
|
||||
queryset = RecipeBook.objects
|
||||
|
@ -227,14 +227,11 @@
|
||||
<recipe-card v-bind:key="`mp_${m.id}`" v-for="m in meal_plans" :recipe="m.recipe"
|
||||
:meal_plan="m" :footer_text="m.meal_type_name"
|
||||
footer_icon="far fa-calendar-alt"></recipe-card>
|
||||
|
||||
<recipe-card v-for="r in recipes" v-bind:key="`rv_${r.id}`" :recipe="r"
|
||||
</template>
|
||||
<recipe-card v-for="r in recipes" v-bind:key="r.id" :recipe="r"
|
||||
:footer_text="isRecentOrNew(r)[0]"
|
||||
:footer_icon="isRecentOrNew(r)[1]">
|
||||
</recipe-card>
|
||||
</template>
|
||||
|
||||
<!-- <recipe-card v-for="r in recipes" v-bind:key="r.id" :recipe="r"></recipe-card> -->
|
||||
</recipe-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -396,10 +393,12 @@ export default {
|
||||
this.settings.page_count,
|
||||
{query: {last_viewed: this.settings.recently_viewed}}
|
||||
).then(result => {
|
||||
|
||||
window.scrollTo(0, 0);
|
||||
this.pagination_count = result.data.count
|
||||
this.recipes = result.data.results
|
||||
this.facets = result.data.facets
|
||||
console.log(this.recipes)
|
||||
})
|
||||
},
|
||||
openRandom: function () {
|
||||
|
Loading…
Reference in New Issue
Block a user