diff --git a/cookbook/models.py b/cookbook/models.py index 93983d26..83bf3b9b 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -139,6 +139,7 @@ class TreeModel(MP_Node): return self.get_children().count() # use self.objects.get_or_create() instead + @classmethod def add_root(self, **kwargs): with scopes_disabled(): diff --git a/cookbook/tests/api/test_api_food.py b/cookbook/tests/api/test_api_food.py index cb6843fe..8d92325e 100644 --- a/cookbook/tests/api/test_api_food.py +++ b/cookbook/tests/api/test_api_food.py @@ -4,8 +4,11 @@ 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.models import Food, Ingredient, ShoppingList, ShoppingListEntry +from cookbook.tests.conftest import get_random_json_recipe +from cookbook.tests.factories import FoodFactory # ------------------ IMPORTANT ------------------- # @@ -26,9 +29,14 @@ else: node_location = 'last-child' -@pytest.fixture() -def obj_1(space_1): - return Food.objects.get_or_create(name='test_1', space=space_1)[0] +register(FoodFactory, 'obj_1', space=LazyFixture('space_1')) +register(FoodFactory, 'obj_2', space=LazyFixture('space_1')) +register(FoodFactory, 'obj_3', space=LazyFixture('space_2')) + + +# @pytest.fixture() +# def obj_1(food_factory, space_1): +# return food_factory(space=space_1) @pytest.fixture() @@ -41,14 +49,14 @@ def obj_1_1_1(obj_1_1, space_1): return obj_1_1.add_child(name='test_1_1_1', space=space_1) -@pytest.fixture -def obj_2(space_1): - return Food.objects.get_or_create(name='test_2', space=space_1)[0] +# @pytest.fixture() +# def obj_2(food_factory, space_1): +# return food_factory(space=space_1) -@pytest.fixture() -def obj_3(space_2): - return Food.objects.get_or_create(name='test_3', space=space_2)[0] +# @pytest.fixture() +# def obj_3(food_factory, space_2): +# return food_factory(space=space_2) @pytest.fixture() @@ -127,7 +135,10 @@ def test_list_filter(obj_1, obj_2, u1_s1): assert r.status_code == 200 response = json.loads(r.content) assert response['count'] == 2 - assert response['results'][0]['name'] == obj_1.name + + assert obj_1.name in [x['name'] for x in response['results']] + assert obj_2.name in [x['name'] for x in response['results']] + assert response['results'][0]['name'] < response['results'][1]['name'] response = json.loads(u1_s1.get(f'{reverse(LIST_URL)}?page_size=1').content) assert len(response['results']) == 1 @@ -193,7 +204,6 @@ def test_add(arg, request, u1_s2): assert r.status_code == 404 -@pytest.mark.django_db(transaction=True) def test_add_duplicate(u1_s1, u1_s2, obj_1, obj_3): assert json.loads(u1_s1.get(reverse(LIST_URL)).content)['count'] == 1 assert json.loads(u1_s2.get(reverse(LIST_URL)).content)['count'] == 1 diff --git a/cookbook/tests/conftest.py b/cookbook/tests/conftest.py index 7b9b945c..bef27215 100644 --- a/cookbook/tests/conftest.py +++ b/cookbook/tests/conftest.py @@ -7,12 +7,19 @@ import pytest from django.contrib import auth from django.contrib.auth.models import Group, User 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 + +register(SpaceFactory, 'space_1') +register(SpaceFactory, 'space_2') # hack from https://github.com/raphaelm/django-scopes to disable scopes for all fixtures # does not work on yield fixtures as only one yield can be used per fixture (i think) + + @pytest.hookimpl(hookwrapper=True) def pytest_fixture_setup(fixturedef, request): if inspect.isgeneratorfunction(fixturedef.func): @@ -27,16 +34,16 @@ def enable_db_access_for_all_tests(db): pass -@pytest.fixture() -def space_1(): - with scopes_disabled(): - return Space.objects.get_or_create(name='space_1')[0] +# @pytest.fixture() +# def space_1(): +# with scopes_disabled(): +# return Space.objects.get_or_create(name='space_1')[0] -@pytest.fixture() -def space_2(): - with scopes_disabled(): - return Space.objects.get_or_create(name='space_2')[0] +# @pytest.fixture() +# def space_2(): +# with scopes_disabled(): +# return Space.objects.get_or_create(name='space_2')[0] # ---------------------- OBJECT FIXTURES --------------------- diff --git a/cookbook/tests/factories/__init__.py b/cookbook/tests/factories/__init__.py new file mode 100644 index 00000000..84110f95 --- /dev/null +++ b/cookbook/tests/factories/__init__.py @@ -0,0 +1,28 @@ +import factory +from django_scopes import scopes_disabled +from faker import Factory as FakerFactory + +faker = FakerFactory.create() + + +class SpaceFactory(factory.django.DjangoModelFactory): + """Space factory.""" + name = factory.LazyAttribute(lambda x: faker.word()) + + @classmethod + def _create(cls, model_class, **kwargs): + with scopes_disabled(): + return super()._create(model_class, **kwargs) + + class Meta: + model = 'cookbook.Space' + + +class FoodFactory(factory.django.DjangoModelFactory): + """Food factory.""" + name = factory.LazyAttribute(lambda x: faker.sentence(nb_words=3)) + description = factory.LazyAttribute(lambda x: faker.sentence(nb_words=10)) + space = factory.SubFactory(SpaceFactory) + + class Meta: + model = 'cookbook.Food' diff --git a/requirements.txt b/requirements.txt index 64c3b7d1..ce1e9304 100644 --- a/requirements.txt +++ b/requirements.txt @@ -41,4 +41,5 @@ boto3==1.20.19 django-prometheus==2.1.0 django-hCaptcha==0.1.0 python-ldap==3.4.0 -django-auth-ldap==3.0.0 \ No newline at end of file +django-auth-ldap==3.0.0 +factory-boy==3.2.1