From 1cfa47fa87e74f0d4c2142c0c36d3bee352b8e4d Mon Sep 17 00:00:00 2001 From: ssorin Date: Fri, 22 Nov 2024 14:56:25 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=85(dashboard)=20update=20tests=20with=20?= =?UTF-8?q?factory=20boy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add factory-boy to Pipfile - add factories for apps: auth, content, core - Update tests with new factories --- src/dashboard/Pipfile | 1 + src/dashboard/Pipfile.lock | 27 +++++++- src/dashboard/apps/auth/factories.py | 25 ++++++++ src/dashboard/apps/auth/tests/test_models.py | 13 ++-- src/dashboard/apps/consent/factories.py | 24 ++++++++ .../apps/consent/tests/test_models.py | 35 ++++------- src/dashboard/apps/core/factories.py | 43 +++++++++++++ src/dashboard/apps/core/tests/test_models.py | 61 +++++++------------ 8 files changed, 157 insertions(+), 72 deletions(-) create mode 100644 src/dashboard/apps/auth/factories.py create mode 100644 src/dashboard/apps/consent/factories.py create mode 100644 src/dashboard/apps/core/factories.py diff --git a/src/dashboard/Pipfile b/src/dashboard/Pipfile index ec6d1a31..33d15d1f 100644 --- a/src/dashboard/Pipfile +++ b/src/dashboard/Pipfile @@ -16,6 +16,7 @@ black = "==24.10.0" django-extensions = "==3.2.3" django-stubs = {extras = ["compatible-mypy"], version = "==5.1.1"} djlint = "==1.36.1" +factory-boy = "==3.3.1" honcho = "==2.0.0" mypy = "==1.13.0" pytest = "==8.3.3" diff --git a/src/dashboard/Pipfile.lock b/src/dashboard/Pipfile.lock index b843f186..70616951 100644 --- a/src/dashboard/Pipfile.lock +++ b/src/dashboard/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "3f32e0803e61d9eabc94751e7dd8736f4cd7b24c2196e55d4fad247527c5b9aa" + "sha256": "79cda294b47f3dcd31d36b8839ca41ee529e756de7ce85ae8c375d4d70585822" }, "pipfile-spec": 6, "requires": { @@ -562,6 +562,23 @@ ], "version": "==0.12.4" }, + "factory-boy": { + "hashes": [ + "sha256:7b1113c49736e1e9995bc2a18f4dbf2c52cf0f841103517010b1d825712ce3ca", + "sha256:8317aa5289cdfc45f9cae570feb07a6177316c82e34d14df3c2e1f22f26abef0" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==3.3.1" + }, + "faker": { + "hashes": [ + "sha256:68e5580cb6b4226710886e595eabc13127149d6e71e9d1db65506a7fbe2c7fce", + "sha256:9b01019c1ddaf2253ca2308c0472116e993f4ad8fc9905f82fa965e0c6f932e9" + ], + "markers": "python_version >= '3.8'", + "version": "==33.0.0" + }, "h11": { "hashes": [ "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", @@ -739,6 +756,14 @@ "markers": "python_version >= '3.9'", "version": "==0.34.0" }, + "python-dateutil": { + "hashes": [ + "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==2.9.0.post0" + }, "pyyaml": { "hashes": [ "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff", diff --git a/src/dashboard/apps/auth/factories.py b/src/dashboard/apps/auth/factories.py new file mode 100644 index 00000000..27e2cd39 --- /dev/null +++ b/src/dashboard/apps/auth/factories.py @@ -0,0 +1,25 @@ +"""Dashboard auth factories.""" + +import factory +from django.contrib.auth import get_user_model + + +class UserFactory(factory.django.DjangoModelFactory): + """Factory class for creating a “standard” user.""" + + username = factory.Faker("user_name") + password = factory.django.Password("foo") + + class Meta: # noqa: D106 + model = get_user_model() + + +class AdminUserFactory(UserFactory): + """Factory class for creating a superuser.""" + + @classmethod + def _create(cls, model_class, *args, **kwargs): + """Override the default ``_create`` with ``create_superuser``.""" + manager = cls._get_manager(model_class) + # The default would use ``manager.create(*args, **kwargs)`` + return manager.create_superuser(*args, **kwargs) diff --git a/src/dashboard/apps/auth/tests/test_models.py b/src/dashboard/apps/auth/tests/test_models.py index 25b19c65..d72564b0 100644 --- a/src/dashboard/apps/auth/tests/test_models.py +++ b/src/dashboard/apps/auth/tests/test_models.py @@ -1,16 +1,16 @@ """Dashboard auth models tests.""" import pytest -from django.contrib.auth import get_user_model + +from apps.auth.factories import AdminUserFactory, UserFactory @pytest.mark.django_db def test_create_user(): """Tests the creation of a default user model.""" - User = get_user_model() - user = User.objects.create_user(username="john", password="foo") # noqa: S106 + user = UserFactory(username="John") - assert user.username == "john" + assert user.username == "John" assert user.is_active is True assert user.is_staff is False assert user.is_superuser is False @@ -19,10 +19,7 @@ def test_create_user(): @pytest.mark.django_db def test_create_superuser(): """Tests the creation of a superuser with the user model.""" - User = get_user_model() - admin_user = User.objects.create_superuser( - username="superadmin", password="foo" # noqa: S106 - ) + admin_user = AdminUserFactory(username="superadmin") assert admin_user.username == "superadmin" assert admin_user.is_active is True diff --git a/src/dashboard/apps/consent/factories.py b/src/dashboard/apps/consent/factories.py new file mode 100644 index 00000000..61d012d6 --- /dev/null +++ b/src/dashboard/apps/consent/factories.py @@ -0,0 +1,24 @@ +"""Dashboard consent factories.""" + +from datetime import timedelta + +import factory +from django.utils import timezone +from factory import fuzzy + +from apps.auth.factories import UserFactory +from apps.core.factories import DeliveryPointFactory + +from .models import Consent + + +class ConsentFactory(factory.django.DjangoModelFactory): + """Factory class for creating instances of the Consent model.""" + + delivery_point = factory.SubFactory(DeliveryPointFactory) + created_by = factory.SubFactory(UserFactory) + start = fuzzy.FuzzyDateTime(timezone.now()) + end = factory.LazyAttribute(lambda o: o.start + timedelta(days=90)) + + class Meta: # noqa: D106 + model = Consent diff --git a/src/dashboard/apps/consent/tests/test_models.py b/src/dashboard/apps/consent/tests/test_models.py index f79170d0..fe34a29f 100644 --- a/src/dashboard/apps/consent/tests/test_models.py +++ b/src/dashboard/apps/consent/tests/test_models.py @@ -3,30 +3,25 @@ from datetime import timedelta import pytest -from django.contrib.auth import get_user_model -from django.utils import formats, timezone +from django.utils import formats +from apps.auth.factories import UserFactory +from apps.consent.factories import ConsentFactory from apps.consent.models import Consent -from apps.core.models import DeliveryPoint +from apps.core.factories import DeliveryPointFactory @pytest.mark.django_db def test_create_consent(): """Tests the creation of a consent.""" - # create user - User = get_user_model() - user1 = User.objects.create_user(username="user1", password="foo") # noqa: S106 + user1 = UserFactory() + delivery_point = DeliveryPointFactory() - # create delivery point - delivery_point = DeliveryPoint.objects.create(provider_id="provider_1234") - - # create consent - consent = Consent.objects.create( + consent = ConsentFactory( delivery_point=delivery_point, created_by=user1, - start=timezone.now(), - end=timezone.now() + timedelta(days=90), ) + assert consent.delivery_point == delivery_point assert consent.created_by == user1 assert consent.status == Consent.AWAITING @@ -48,20 +43,14 @@ def test_create_consent(): @pytest.mark.django_db def test_update_consent_status(): """Tests updating a consent status.""" - # create user - User = get_user_model() - user1 = User.objects.create_user(username="user1", password="foo") # noqa: S106 + user1 = UserFactory() + delivery_point = DeliveryPointFactory() - # create delivery point - delivery_point = DeliveryPoint.objects.create(provider_id="provider_1234") - - # create consent - consent = Consent.objects.create( + consent = ConsentFactory( delivery_point=delivery_point, created_by=user1, - start=timezone.now(), - end=timezone.now() + timedelta(days=90), ) + new_updated_at = consent.updated_at # update status to VALIDATED diff --git a/src/dashboard/apps/core/factories.py b/src/dashboard/apps/core/factories.py new file mode 100644 index 00000000..2f7076b9 --- /dev/null +++ b/src/dashboard/apps/core/factories.py @@ -0,0 +1,43 @@ +"""Dashboard core factories.""" + +import factory + +from .models import DeliveryPoint, Entity + + +class EntityFactory(factory.django.DjangoModelFactory): + """Factory class for creating instances of the Entity model.""" + + name = factory.Faker("company") + + class Meta: # noqa: D106 + model = Entity + + @factory.post_generation + def users(self, create, extracted, **kwargs): + """Method to add users after the entity is created.""" + if not create or not extracted: + # Simple build, or nothing to add, do nothing. + return + + # Add the iterable of groups using bulk addition + self.users.add(*extracted) + + +class DeliveryPointFactory(factory.django.DjangoModelFactory): + """Factory class for creating instances of the DeliveryPoint model.""" + + class Meta: # noqa: D106 + model = DeliveryPoint + + provider_id = factory.Sequence(lambda n: "provider_%d" % n) + + @factory.post_generation + def entities(self, create, extracted, **kwargs): + """Method to add entities after the delivery point is created.""" + if not create or not extracted: + # Simple build, or nothing to add, do nothing. + return + + # Add the iterable of groups using bulk addition + self.entities.add(*extracted) diff --git a/src/dashboard/apps/core/tests/test_models.py b/src/dashboard/apps/core/tests/test_models.py index 877ec4fb..b0d72bd9 100644 --- a/src/dashboard/apps/core/tests/test_models.py +++ b/src/dashboard/apps/core/tests/test_models.py @@ -1,27 +1,24 @@ """Dashboard core models tests.""" import pytest -from django.contrib.auth import get_user_model from django.db import IntegrityError -from apps.core.models import DeliveryPoint, Entity +from apps.auth.factories import UserFactory +from apps.core.factories import DeliveryPointFactory, EntityFactory +from apps.core.models import Entity @pytest.mark.django_db def test_create_entity(): """Tests the creation of an entity.""" - User = get_user_model() - user1 = User.objects.create_user(username="user1", password="foo") # noqa: S106 - user2 = User.objects.create_user(username="user2", password="foo") # noqa: S106 + user1 = UserFactory() + user2 = UserFactory() - entity = Entity.objects.create(name="abc_entity") - entity.users.add(user1) - entity.users.add(user2) - entity.save() + entity = EntityFactory(name="entity_1234", users=(user1, user2)) # test users have been added. - assert entity.name == "abc_entity" - assert all(user in [user1, user2] for user in entity.users.all()) + assert entity.name == "entity_1234" + assert all(user in entity.users.all() for user in [user1, user2]) # test created_at and updated_at have been updated. assert entity.created_at is not None @@ -35,12 +32,8 @@ def test_create_entity(): @pytest.mark.django_db def test_update_entity(): """Tests updating an entity.""" - User = get_user_model() - user1 = User.objects.create_user(username="user1", password="foo") # noqa: S106 - - entity = Entity.objects.create(name="abc_entity") - entity.users.add(user1) - entity.save() + user1 = UserFactory() + entity = EntityFactory(users=(user1,)) # test user1 have been removed entity.users.remove(user1) @@ -54,29 +47,22 @@ def test_update_entity(): def test_create_delivery_point(): """Tests the creation of a delivery point.""" # create users - User = get_user_model() - user1 = User.objects.create_user(username="user1", password="foo") # noqa: S106 + user1 = UserFactory() # create entities - entity1 = Entity.objects.create(name="entity_1") - entity1.users.add(user1) - entity1.save() - - entity2 = Entity.objects.create(name="entity_2") - entity2.users.add(user1) - entity2.save() + entity1 = EntityFactory(users=(user1,)) + entity2 = EntityFactory(users=(user1,)) # create delivery point - delivery_point = DeliveryPoint.objects.create(provider_id="provider_1234") - delivery_point.entities.add(entity1) - delivery_point.entities.add(entity2) - delivery_point.save() + delivery_point = DeliveryPointFactory( + provider_id="provider_1234", entities=(entity1, entity2) + ) assert delivery_point.provider_id == "provider_1234" assert delivery_point.is_active is True # test entities have been added to delivery point. - assert all(entity in [entity1, entity2] for entity in delivery_point.entities.all()) + assert all(entity in delivery_point.entities.all() for entity in [entity1, entity2]) # test created_at and updated_at have been updated. assert delivery_point.created_at is not None @@ -84,25 +70,20 @@ def test_create_delivery_point(): # test IntegrityError: provider must not be null with pytest.raises(IntegrityError): - DeliveryPoint.objects.create(provider_id=None) + DeliveryPointFactory(provider_id=None) @pytest.mark.django_db def test_update_delivery_point(): """Tests updating a delivery point.""" # create users - User = get_user_model() - user1 = User.objects.create_user(username="user1", password="foo") # noqa: S106 + user1 = UserFactory() # create entity - entity1 = Entity.objects.create(name="entity_1") - entity1.users.add(user1) - entity1.save() + entity1 = EntityFactory(users=(user1,)) # create delivery point - delivery_point = DeliveryPoint.objects.create(provider_id="provider_1234") - delivery_point.entities.add(entity1) - delivery_point.save() + delivery_point = DeliveryPointFactory(entities=(entity1,)) # test entity1 have been removed delivery_point.entities.remove(entity1)