diff --git a/cookbook/tests/api/test_api_food.py b/cookbook/tests/api/test_api_food.py index 9f5d7c14..129bb76d 100644 --- a/cookbook/tests/api/test_api_food.py +++ b/cookbook/tests/api/test_api_food.py @@ -7,7 +7,6 @@ from django_scopes import scope, scopes_disabled from pytest_factoryboy import LazyFixture, register from cookbook.models import Food, FoodInheritField, Ingredient, ShoppingList, ShoppingListEntry -from cookbook.tests.conftest import get_random_json_recipe from cookbook.tests.factories import (FoodFactory, IngredientFactory, ShoppingListEntryFactory, SupermarketCategoryFactory) diff --git a/cookbook/tests/api/test_api_shopping_list_entryv2.py b/cookbook/tests/api/test_api_shopping_list_entryv2.py new file mode 100644 index 00000000..3599dcfe --- /dev/null +++ b/cookbook/tests/api/test_api_shopping_list_entryv2.py @@ -0,0 +1,129 @@ +import json + +import pytest +from django.contrib import auth +from django.forms import model_to_dict +from django.urls import reverse +from django_scopes import scopes_disabled +from pytest_factoryboy import LazyFixture, register + +from cookbook.models import Food, ShoppingListEntry +from cookbook.tests.factories import ShoppingListEntryFactory + +LIST_URL = 'api:shoppinglistentry-list' +DETAIL_URL = 'api:shoppinglistentry-detail' + +register(ShoppingListEntryFactory, 'sle_1', space=LazyFixture('space_1')) +register(ShoppingListEntryFactory, 'sle_2', space=LazyFixture('space_2')) + + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 200], + ['u1_s1', 200], + ['a1_s1', 200], +]) +def test_list_permission(arg, request): + c = request.getfixturevalue(arg[0]) + assert c.get(reverse(LIST_URL)).status_code == arg[1] + + +def test_list_space(sle_1, sle_2, u1_s1, u1_s2, space_2): + assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 2 + assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 0 + + with scopes_disabled(): + e = ShoppingListEntry.objects.first() + e.space = space_2 + e.save() + + assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 1 + assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 0 + + +def test_get_detail(sle_1): + # r = u1_s1.get(reverse( + # DETAIL_URL, + # args={sle_1.id} + # )) + # assert sle_1.id == 1 + pass + + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 404], + ['u1_s1', 200], + ['a1_s1', 404], + ['g1_s2', 404], + ['u1_s2', 404], + ['a1_s2', 404], +]) +def test_update(arg, request, sle_1): + c = request.getfixturevalue(arg[0]) + r = c.patch( + reverse( + DETAIL_URL, + args={sle_1.id} + ), + {'amount': 2}, + content_type='application/json' + ) + assert r.status_code == arg[1] + if r.status_code == 200: + response = json.loads(r.content) + assert response['amount'] == 2 + + +@pytest.mark.parametrize("arg", [ + ['a_u', 403], + ['g1_s1', 201], + ['u1_s1', 201], + ['a1_s1', 201], +]) +def test_add(arg, request, sle_1): + c = request.getfixturevalue(arg[0]) + r = c.post( + reverse(LIST_URL), + {'food': model_to_dict(sle_1.food), 'amount': 1}, + content_type='application/json' + ) + response = json.loads(r.content) + print(r.content) + assert r.status_code == arg[1] + if r.status_code == 201: + assert response['food']['id'] == sle_1.food.pk + + +def test_delete(u1_s1, u1_s2, sle_1): + r = u1_s2.delete( + reverse( + DETAIL_URL, + args={sle_1.id} + ) + ) + assert r.status_code == 404 + + r = u1_s1.delete( + reverse( + DETAIL_URL, + args={sle_1.id} + ) + ) + + assert r.status_code == 204 + + +# TODO test sharing +# TODO test completed entries still visible if today, but not yesterday +# TODO test create shopping list from recipe +# TODO test delete shopping list from recipe - include created by, shared with and not shared with +# TODO test create shopping list from food +# TODO test delete shopping list from food - include created by, shared with and not shared with +# TODO test create shopping list from mealplan +# TODO test create shopping list from recipe, excluding ingredients +# TODO test auto creating shopping list from meal plan +# TODO test excluding on-hand when auto creating shopping list +# test delay +# test completed_at when checked +# test completed_at cleared when unchecked diff --git a/cookbook/tests/conftest.py b/cookbook/tests/conftest.py index bef27215..9c4892fe 100644 --- a/cookbook/tests/conftest.py +++ b/cookbook/tests/conftest.py @@ -10,7 +10,7 @@ from django_scopes import scopes_disabled from pytest_factoryboy import register from cookbook.models import Food, Ingredient, Recipe, Space, Step, Unit -from cookbook.tests.factories import FoodFactory, SpaceFactory +from cookbook.tests.factories import SpaceFactory register(SpaceFactory, 'space_1') register(SpaceFactory, 'space_2') diff --git a/cookbook/tests/factories/__init__.py b/cookbook/tests/factories/__init__.py index da84a6cd..9f43fdbc 100644 --- a/cookbook/tests/factories/__init__.py +++ b/cookbook/tests/factories/__init__.py @@ -8,6 +8,12 @@ from django.contrib.auth.models import User from django_scopes import scopes_disabled from faker import Factory as FakerFactory +# this code will run immediately prior to creating the model object useful when you want a reverse relationship +# log = factory.RelatedFactory( +# UserLogFactory, +# factory_related_name='user', +# action=models.UserLog.ACTION_CREATE, +# ) faker = FakerFactory.create() @@ -95,6 +101,17 @@ class UnitFactory(factory.django.DjangoModelFactory): model = 'cookbook.Unit' +class KeywordFactory(factory.django.DjangoModelFactory): + """Keyword factory.""" + name = factory.LazyAttribute(lambda x: faker.sentence(nb_words=3)) + # icon = models.CharField(max_length=16, blank=True, null=True) + description = factory.LazyAttribute(lambda x: faker.sentence(nb_words=10)) + space = factory.SubFactory(SpaceFactory) + + class Meta: + model = 'cookbook.Keyword' + + class IngredientFactory(factory.django.DjangoModelFactory): """Ingredient factory.""" food = factory.SubFactory(FoodFactory) @@ -167,7 +184,7 @@ class ShoppingListEntryFactory(factory.django.DjangoModelFactory): ) food = factory.SubFactory(FoodFactory) unit = factory.SubFactory(UnitFactory) - ingredient = factory.SubFactory(IngredientFactory) + # ingredient = factory.SubFactory(IngredientFactory) amount = factory.LazyAttribute(lambda x: Decimal(faker.random_int(min=1, max=10))/100) order = 0 checked = False @@ -216,7 +233,7 @@ class RecipeFactory(factory.django.DjangoModelFactory): description = factory.LazyAttribute(lambda x: faker.sentence(nb_words=10)) servings = factory.LazyAttribute(lambda x: faker.random_int(min=1, max=20)) servings_text = factory.LazyAttribute(lambda x: faker.sentence(nb_words=1)) - # image = models.ImageField(upload_to='recipes/', blank=True, null=True) + # image = models.ImageField(upload_to='recipes/', blank=True, null=True) #TODO test recipe image api # storage = models.ForeignKey( # Storage, on_delete=models.PROTECT, blank=True, null=True # ) @@ -224,7 +241,7 @@ class RecipeFactory(factory.django.DjangoModelFactory): # file_path = models.CharField(max_length=512, default="", blank=True) # link = models.CharField(max_length=512, null=True, blank=True) # cors_link = models.CharField(max_length=1024, null=True, blank=True) - # keywords = factory.SubFactory(KeywordFactory) + keywords = factory.SubFactory(KeywordFactory) steps = factory.SubFactory(StepFactory) working_time = factory.LazyAttribute(lambda x: faker.random_int(min=0, max=360)) waiting_time = factory.LazyAttribute(lambda x: faker.random_int(min=0, max=360)) @@ -239,10 +256,3 @@ class RecipeFactory(factory.django.DjangoModelFactory): class Meta: model = 'cookbook.Recipe' - - # this code will run immediately prior to creating the model object useful when you want a reverse relationship - # log = factory.RelatedFactory( - # UserLogFactory, - # factory_related_name='user', - # action=models.UserLog.ACTION_CREATE, - # )