From b2704f2b438c5b72d6066e2129d3536f1da3be16 Mon Sep 17 00:00:00 2001 From: ssorin Date: Tue, 26 Nov 2024 16:22:29 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=83=EF=B8=8F(dashboard)=20refactor=20D?= =?UTF-8?q?eliveryPoint=20and=20Entity=20models?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replaced `entities` ManyToMany relationship with a ForeignKey in DeliveryPoint. - Introduced slug field for Entity. - Added `proxy_for` ManyToManyField in Entity on itself. - Enhanced model tests for new relationships and integrity checks. - Rename DeliveryPoint.provider_id to DeliveryPoint.provider_assigned_id - Reset Entity and DeliveryPoint migrations - update pipenv --- src/dashboard/Pipfile | 2 +- src/dashboard/Pipfile.lock | 152 +++++++++--------- .../apps/consent/migrations/0001_initial.py | 2 +- src/dashboard/apps/core/factories.py | 22 +-- .../apps/core/migrations/0001_initial.py | 44 +++-- src/dashboard/apps/core/models.py | 28 ++-- src/dashboard/apps/core/tests/test_models.py | 55 +++++-- 7 files changed, 179 insertions(+), 126 deletions(-) diff --git a/src/dashboard/Pipfile b/src/dashboard/Pipfile index 33d15d1f..b9f38395 100644 --- a/src/dashboard/Pipfile +++ b/src/dashboard/Pipfile @@ -7,13 +7,13 @@ name = "pypi" Django = "==5.1.3" django-dsfr = "==1.4.3" django-environ = "==0.11.2" +django-extensions = "==3.2.3" gunicorn = "==23.0.0" psycopg = {extras = ["pool", "binary"], version = "==3.2.3"} whitenoise = "==6.8.2" [dev-packages] 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" diff --git a/src/dashboard/Pipfile.lock b/src/dashboard/Pipfile.lock index 70616951..acab21ff 100644 --- a/src/dashboard/Pipfile.lock +++ b/src/dashboard/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "79cda294b47f3dcd31d36b8839ca41ee529e756de7ce85ae8c375d4d70585822" + "sha256": "b2da53d2f6cafaa4c01c09f0134a9832bfe36c244b0a8f6438f432090c1fa4d0" }, "pipfile-spec": 6, "requires": { @@ -178,6 +178,15 @@ "markers": "python_version >= '3.6' and python_version < '4'", "version": "==0.11.2" }, + "django-extensions": { + "hashes": [ + "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a", + "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401" + ], + "index": "pypi", + "markers": "python_version >= '3.6'", + "version": "==3.2.3" + }, "django-widget-tweaks": { "hashes": [ "sha256:1c2180681ebb994e922c754804c7ffebbe1245014777ac47897a81f57cc629c7", @@ -418,71 +427,71 @@ "toml" ], "hashes": [ - "sha256:0266b62cbea568bd5e93a4da364d05de422110cbed5056d69339bd5af5685433", - "sha256:0573f5cbf39114270842d01872952d301027d2d6e2d84013f30966313cadb529", - "sha256:0ddcb70b3a3a57581b450571b31cb774f23eb9519c2aaa6176d3a84c9fc57671", - "sha256:108bb458827765d538abcbf8288599fee07d2743357bdd9b9dad456c287e121e", - "sha256:14045b8bfd5909196a90da145a37f9d335a5d988a83db34e80f41e965fb7cb42", - "sha256:1a5407a75ca4abc20d6252efeb238377a71ce7bda849c26c7a9bece8680a5d99", - "sha256:2bc3e45c16564cc72de09e37413262b9f99167803e5e48c6156bccdfb22c8327", - "sha256:2d608a7808793e3615e54e9267519351c3ae204a6d85764d8337bd95993581a8", - "sha256:34d23e28ccb26236718a3a78ba72744212aa383141961dd6825f6595005c8b06", - "sha256:37a15573f988b67f7348916077c6d8ad43adb75e478d0910957394df397d2874", - "sha256:3c0317288f032221d35fa4cbc35d9f4923ff0dfd176c79c9b356e8ef8ef2dff4", - "sha256:3c42ec2c522e3ddd683dec5cdce8e62817afb648caedad9da725001fa530d354", - "sha256:3c6b24007c4bcd0b19fac25763a7cac5035c735ae017e9a349b927cfc88f31c1", - "sha256:40cca284c7c310d622a1677f105e8507441d1bb7c226f41978ba7c86979609ab", - "sha256:46f21663e358beae6b368429ffadf14ed0a329996248a847a4322fb2e35d64d3", - "sha256:49ed5ee4109258973630c1f9d099c7e72c5c36605029f3a91fe9982c6076c82b", - "sha256:5c95e0fa3d1547cb6f021ab72f5c23402da2358beec0a8e6d19a368bd7b0fb37", - "sha256:5dd4e4a49d9c72a38d18d641135d2fb0bdf7b726ca60a103836b3d00a1182acd", - "sha256:5e444b8e88339a2a67ce07d41faabb1d60d1004820cee5a2c2b54e2d8e429a0f", - "sha256:60dcf7605c50ea72a14490d0756daffef77a5be15ed1b9fea468b1c7bda1bc3b", - "sha256:623e6965dcf4e28a3debaa6fcf4b99ee06d27218f46d43befe4db1c70841551c", - "sha256:673184b3156cba06154825f25af33baa2671ddae6343f23175764e65a8c4c30b", - "sha256:6cf96ceaa275f071f1bea3067f8fd43bec184a25a962c754024c973af871e1b7", - "sha256:70a56a2ec1869e6e9fa69ef6b76b1a8a7ef709972b9cc473f9ce9d26b5997ce3", - "sha256:77256ad2345c29fe59ae861aa11cfc74579c88d4e8dbf121cbe46b8e32aec808", - "sha256:796c9b107d11d2d69e1849b2dfe41730134b526a49d3acb98ca02f4985eeff7a", - "sha256:7c07de0d2a110f02af30883cd7dddbe704887617d5c27cf373362667445a4c76", - "sha256:7e61b0e77ff4dddebb35a0e8bb5a68bf0f8b872407d8d9f0c726b65dfabe2469", - "sha256:82c809a62e953867cf57e0548c2b8464207f5f3a6ff0e1e961683e79b89f2c55", - "sha256:850cfd2d6fc26f8346f422920ac204e1d28814e32e3a58c19c91980fa74d8289", - "sha256:87ea64b9fa52bf395272e54020537990a28078478167ade6c61da7ac04dc14bc", - "sha256:90746521206c88bdb305a4bf3342b1b7316ab80f804d40c536fc7d329301ee13", - "sha256:951aade8297358f3618a6e0660dc74f6b52233c42089d28525749fc8267dccd2", - "sha256:963e4a08cbb0af6623e61492c0ec4c0ec5c5cf74db5f6564f98248d27ee57d30", - "sha256:987a8e3da7da4eed10a20491cf790589a8e5e07656b6dc22d3814c4d88faf163", - "sha256:9c2eb378bebb2c8f65befcb5147877fc1c9fbc640fc0aad3add759b5df79d55d", - "sha256:a1ab9763d291a17b527ac6fd11d1a9a9c358280adb320e9c2672a97af346ac2c", - "sha256:a3b925300484a3294d1c70f6b2b810d6526f2929de954e5b6be2bf8caa1f12c1", - "sha256:acbb8af78f8f91b3b51f58f288c0994ba63c646bc1a8a22ad072e4e7e0a49f1c", - "sha256:ad32a981bcdedb8d2ace03b05e4fd8dace8901eec64a532b00b15217d3677dd2", - "sha256:aee9cf6b0134d6f932d219ce253ef0e624f4fa588ee64830fcba193269e4daa3", - "sha256:af05bbba896c4472a29408455fe31b3797b4d8648ed0a2ccac03e074a77e2314", - "sha256:b6cce5c76985f81da3769c52203ee94722cd5d5889731cd70d31fee939b74bf0", - "sha256:bb684694e99d0b791a43e9fc0fa58efc15ec357ac48d25b619f207c41f2fd384", - "sha256:c132b5a22821f9b143f87446805e13580b67c670a548b96da945a8f6b4f2efbb", - "sha256:c296263093f099da4f51b3dff1eff5d4959b527d4f2f419e16508c5da9e15e8c", - "sha256:c973b2fe4dc445cb865ab369df7521df9c27bf40715c837a113edaa2aa9faf45", - "sha256:cdd94501d65adc5c24f8a1a0eda110452ba62b3f4aeaba01e021c1ed9cb8f34a", - "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24", - "sha256:dbba8210f5067398b2c4d96b4e64d8fb943644d5eb70be0d989067c8ca40c0f8", - "sha256:df002e59f2d29e889c37abd0b9ee0d0e6e38c24f5f55d71ff0e09e3412a340ec", - "sha256:dfd14bcae0c94004baba5184d1c935ae0d1231b8409eb6c103a5fd75e8ecdc56", - "sha256:e25bacb53a8c7325e34d45dddd2f2fbae0dbc230d0e2642e264a64e17322a777", - "sha256:e2c8e3384c12dfa19fa9a52f23eb091a8fad93b5b81a41b14c17c78e23dd1d8b", - "sha256:e5f2a0f161d126ccc7038f1f3029184dbdf8f018230af17ef6fd6a707a5b881f", - "sha256:e69ad502f1a2243f739f5bd60565d14a278be58be4c137d90799f2c263e7049a", - "sha256:ead9b9605c54d15be228687552916c89c9683c215370c4a44f1f217d2adcc34d", - "sha256:f07ff574986bc3edb80e2c36391678a271d555f91fd1d332a1e0f4b5ea4b6ea9", - "sha256:f2c7a045eef561e9544359a0bf5784b44e55cefc7261a20e730baa9220c83413", - "sha256:f3e8796434a8106b3ac025fd15417315d7a58ee3e600ad4dbcfddc3f4b14342c", - "sha256:f63e21ed474edd23f7501f89b53280014436e383a14b9bd77a648366c81dce7b", - "sha256:fd49c01e5057a451c30c9b892948976f5d38f2cbd04dc556a82743ba8e27ed8c" + "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5", + "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf", + "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb", + "sha256:13618bed0c38acc418896005732e565b317aa9e98d855a0e9f211a7ffc2d6638", + "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4", + "sha256:177f01eeaa3aee4a5ffb0d1439c5952b53d5010f86e9d2667963e632e30082cc", + "sha256:193e3bffca48ad74b8c764fb4492dd875038a2f9925530cb094db92bb5e47bed", + "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a", + "sha256:1f188a2402f8359cf0c4b1fe89eea40dc13b52e7b4fd4812450da9fcd210181d", + "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649", + "sha256:24eda3a24a38157eee639ca9afe45eefa8d2420d49468819ac5f88b10de84f4c", + "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b", + "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4", + "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443", + "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83", + "sha256:3985b9be361d8fb6b2d1adc9924d01dec575a1d7453a14cccd73225cb79243ee", + "sha256:3988665ee376abce49613701336544041f2117de7b7fbfe91b93d8ff8b151c8e", + "sha256:3ac47fa29d8d41059ea3df65bd3ade92f97ee4910ed638e87075b8e8ce69599e", + "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3", + "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0", + "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb", + "sha256:428ac484592f780e8cd7b6b14eb568f7c85460c92e2a37cb0c0e5186e1a0d076", + "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb", + "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787", + "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1", + "sha256:4db3ed6a907b555e57cc2e6f14dc3a4c2458cdad8919e40b5357ab9b6db6c43e", + "sha256:5c52a036535d12590c32c49209e79cabaad9f9ad8aa4cbd875b68c4d67a9cbce", + "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801", + "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764", + "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365", + "sha256:63c19702db10ad79151a059d2d6336fe0c470f2e18d0d4d1a57f7f9713875dcf", + "sha256:644ec81edec0f4ad17d51c838a7d01e42811054543b76d4ba2c5d6af741ce2a6", + "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71", + "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002", + "sha256:716a78a342679cd1177bc8c2fe957e0ab91405bd43a17094324845200b2fddf4", + "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c", + "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8", + "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4", + "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146", + "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc", + "sha256:912e95017ff51dc3d7b6e2be158dedc889d9a5cc3382445589ce554f1a34c0ea", + "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4", + "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad", + "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28", + "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451", + "sha256:b39e6011cd06822eb964d038d5dff5da5d98652b81f5ecd439277b32361a3a50", + "sha256:bd55f8fc8fa494958772a2a7302b0354ab16e0b9272b3c3d83cdb5bec5bd1779", + "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63", + "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e", + "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc", + "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022", + "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d", + "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94", + "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b", + "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d", + "sha256:e19122296822deafce89a0c5e8685704c067ae65d45e79718c92df7b3ec3d331", + "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a", + "sha256:e4c81ed2820b9023a9a90717020315e63b17b18c274a332e3b6437d7ff70abe0", + "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee", + "sha256:f39e2f3530ed1626c66e7493be7a8423b023ca852aacdc91fb30162c350d2a92", + "sha256:f56f49b2553d7dd85fd86e029515a221e5c1f8cb3d9c38b470bc38bde7b8445a", + "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9" ], "markers": "python_version >= '3.9'", - "version": "==7.6.7" + "version": "==7.6.8" }, "cssbeautifier": { "hashes": [ @@ -499,15 +508,6 @@ "markers": "python_version >= '3.10'", "version": "==5.1.3" }, - "django-extensions": { - "hashes": [ - "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a", - "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401" - ], - "index": "pypi", - "markers": "python_version >= '3.6'", - "version": "==3.2.3" - }, "django-stubs": { "extras": [ "compatible-mypy" @@ -974,11 +974,11 @@ }, "tqdm": { "hashes": [ - "sha256:0cd8af9d56911acab92182e88d763100d4788bdf421d251616040cc4d44863be", - "sha256:fe5a6f95e6fe0b9755e9469b77b9c3cf850048224ecaa8293d7d2d31f97d869a" + "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", + "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2" ], "markers": "python_version >= '3.7'", - "version": "==4.67.0" + "version": "==4.67.1" }, "types-pyyaml": { "hashes": [ diff --git a/src/dashboard/apps/consent/migrations/0001_initial.py b/src/dashboard/apps/consent/migrations/0001_initial.py index 5dbb4598..f437a85e 100644 --- a/src/dashboard/apps/consent/migrations/0001_initial.py +++ b/src/dashboard/apps/consent/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 5.1.3 on 2024-11-21 11:26 +# Generated by Django 5.1.3 on 2024-11-26 16:35 import django.db.models.deletion import django.utils.timezone diff --git a/src/dashboard/apps/core/factories.py b/src/dashboard/apps/core/factories.py index 2f7076b9..bc4977d6 100644 --- a/src/dashboard/apps/core/factories.py +++ b/src/dashboard/apps/core/factories.py @@ -23,6 +23,15 @@ def users(self, create, extracted, **kwargs): # Add the iterable of groups using bulk addition self.users.add(*extracted) + @factory.post_generation + def proxy_for(self, create, extracted, **kwargs): + """Method to add `proxy_for` after the entity is created.""" + if not create or not extracted: + # Simple build, or nothing to add, do nothing. + return + + self.proxy_for.add(*extracted) + class DeliveryPointFactory(factory.django.DjangoModelFactory): """Factory class for creating instances of the DeliveryPoint model.""" @@ -30,14 +39,5 @@ class DeliveryPointFactory(factory.django.DjangoModelFactory): 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) + provider_assigned_id = factory.Sequence(lambda n: "dp_%d" % n) + entity = factory.SubFactory(EntityFactory) diff --git a/src/dashboard/apps/core/migrations/0001_initial.py b/src/dashboard/apps/core/migrations/0001_initial.py index a49460cd..1dbe4003 100644 --- a/src/dashboard/apps/core/migrations/0001_initial.py +++ b/src/dashboard/apps/core/migrations/0001_initial.py @@ -1,6 +1,8 @@ -# Generated by Django 5.1.3 on 2024-11-21 11:26 +# Generated by Django 5.1.3 on 2024-11-26 16:35 +import django.db.models.deletion import django.utils.timezone +import django_extensions.db.fields import uuid from django.conf import settings from django.db import migrations, models @@ -41,10 +43,26 @@ class Migration(migrations.Migration): blank=True, null=True, verbose_name="updated at" ), ), + ( + "slug", + django_extensions.db.fields.AutoSlugField( + blank=True, + editable=False, + populate_from="name", + unique=True, + verbose_name="slug", + ), + ), ( "name", models.CharField(max_length=64, unique=True, verbose_name="name"), ), + ( + "proxy_for", + models.ManyToManyField( + blank=True, to="qcd_core.entity", verbose_name="proxy for" + ), + ), ( "users", models.ManyToManyField( @@ -53,8 +71,8 @@ class Migration(migrations.Migration): ), ], options={ - "verbose_name": "Entity", - "verbose_name_plural": "Entities", + "verbose_name": "entity", + "verbose_name_plural": "entities", "ordering": ["name"], }, ), @@ -85,24 +103,28 @@ class Migration(migrations.Migration): ), ), ( - "provider_id", - models.CharField(max_length=64, verbose_name="provider id"), + "provider_assigned_id", + models.CharField( + max_length=64, verbose_name="provider assigned id" + ), ), ( "is_active", models.BooleanField(default=True, verbose_name="is active"), ), ( - "entities", - models.ManyToManyField( - to="qcd_core.entity", verbose_name="entities" + "entity", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="qcd_core.entity", + verbose_name="entity", ), ), ], options={ - "verbose_name": "Delivery point", - "verbose_name_plural": "Delivery points", - "ordering": ["provider_id"], + "verbose_name": "delivery point", + "verbose_name_plural": "delivery points", + "ordering": ["provider_assigned_id"], }, ), ] diff --git a/src/dashboard/apps/core/models.py b/src/dashboard/apps/core/models.py index 91eb4efb..0605a098 100644 --- a/src/dashboard/apps/core/models.py +++ b/src/dashboard/apps/core/models.py @@ -5,6 +5,7 @@ from django.db import models from django.utils import timezone from django.utils.translation import gettext_lazy as _ +from django_extensions.db.fields import AutoSlugField from apps.auth.models import DashboardUser as User @@ -38,16 +39,20 @@ class Entity(DashboardBase): """Represents an operator or an aggregator in the system. Attributes: + - slug (AutoSlugField): Unique slug generated from the name field. - name (CharField): Name of the entity, unique and maximum length of 64. - users (ManyToManyField): Users associated with the entity. + - proxy_for (ManyToManyField): self-referential relationship indicating proxies. """ + slug = AutoSlugField(_("slug"), populate_from="name", unique=True) name = models.CharField(_("name"), max_length=64, unique=True) users = models.ManyToManyField(User, verbose_name=_("users")) + proxy_for = models.ManyToManyField("self", verbose_name=_("proxy for"), blank=True) class Meta: # noqa: D106 - verbose_name = "Entity" - verbose_name_plural = "Entities" + verbose_name = "entity" + verbose_name_plural = "entities" ordering = ["name"] def __str__(self): # noqa: D105 @@ -58,19 +63,22 @@ class DeliveryPoint(DashboardBase): """Represents a delivery point for electric vehicles. Attributes: - - provider_id (CharField): stores the unique identifier for the delivery provider. - - entities (ManyToManyField): linking DeliveryPoint to associated Entity instances. + - provider_assigned_id (CharField): stores the unique identifier + assigned by the provider for the delivery point. + - entity (ForeignKey): linking DeliveryPoint to associated Entity. - is_active (BooleanField): indicating the active status of the delivery point. """ - provider_id = models.CharField(_("provider id"), max_length=64) - entities = models.ManyToManyField(Entity, verbose_name=_("entities")) + provider_assigned_id = models.CharField(_("provider assigned id"), max_length=64) + entity = models.ForeignKey( + Entity, on_delete=models.CASCADE, verbose_name=_("entity") + ) is_active = models.BooleanField(_("is active"), default=True) class Meta: # noqa: D106 - verbose_name = _("Delivery point") - verbose_name_plural = _("Delivery points") - ordering = ["provider_id"] + verbose_name = _("delivery point") + verbose_name_plural = _("delivery points") + ordering = ["provider_assigned_id"] def __str__(self): # noqa: D105 - return self.provider_id + return self.provider_assigned_id diff --git a/src/dashboard/apps/core/tests/test_models.py b/src/dashboard/apps/core/tests/test_models.py index b0d72bd9..9aef8e55 100644 --- a/src/dashboard/apps/core/tests/test_models.py +++ b/src/dashboard/apps/core/tests/test_models.py @@ -14,12 +14,21 @@ def test_create_entity(): user1 = UserFactory() user2 = UserFactory() - entity = EntityFactory(name="entity_1234", users=(user1, user2)) + entity2 = EntityFactory(name="entity 2", users=(user1, user2)) + entity3 = EntityFactory(name="entity 3", users=(user1, user2)) + entity = EntityFactory( + name="entity 1", users=(user1, user2), proxy_for=(entity2, entity3) + ) + + assert entity.name == "entity 1" + assert entity.slug == "entity-1" # test users have been added. - assert entity.name == "entity_1234" assert all(user in entity.users.all() for user in [user1, user2]) + # test `proxy_for` have been added. + assert all(proxy_for in entity.proxy_for.all() for proxy_for in [entity2, entity3]) + # test created_at and updated_at have been updated. assert entity.created_at is not None assert entity.updated_at is not None @@ -33,12 +42,17 @@ def test_create_entity(): def test_update_entity(): """Tests updating an entity.""" user1 = UserFactory() - entity = EntityFactory(users=(user1,)) + entity2 = EntityFactory(name="entity 2") + entity = EntityFactory(users=(user1,), proxy_for=(entity2,)) # test user1 have been removed entity.users.remove(user1) assert all(user != user1 for user in entity.users.all()) + # test `proxy_for` have been removed + entity.proxy_for.remove(entity2) + assert all(entity != entity2 for entity in entity.proxy_for.all()) + # test updated_at has been updated assert entity.updated_at > entity.created_at @@ -51,26 +65,39 @@ def test_create_delivery_point(): # create entities entity1 = EntityFactory(users=(user1,)) - entity2 = EntityFactory(users=(user1,)) # create delivery point delivery_point = DeliveryPointFactory( - provider_id="provider_1234", entities=(entity1, entity2) + provider_assigned_id="dp_1234", entity=entity1 ) - assert delivery_point.provider_id == "provider_1234" + assert delivery_point.provider_assigned_id == "dp_1234" assert delivery_point.is_active is True - - # test entities have been added to delivery point. - assert all(entity in delivery_point.entities.all() for entity in [entity1, entity2]) + assert delivery_point.entity == entity1 # test created_at and updated_at have been updated. assert delivery_point.created_at is not None assert delivery_point.updated_at is not None - # test IntegrityError: provider must not be null + +@pytest.mark.django_db +def test_integrity_error_create_provider_assigned_id_null(): + """Test IntegrityError on provider_assigned_id. + + provider_assigned_id must not be null. + """ with pytest.raises(IntegrityError): - DeliveryPointFactory(provider_id=None) + DeliveryPointFactory(provider_assigned_id=None) + + +@pytest.mark.django_db +def test_integrity_error_create_entity_null(): + """Test IntegrityError on entity. + + Entity fk must not be null. + """ + with pytest.raises(IntegrityError): + DeliveryPointFactory(provider_assigned_id="dp1", entity=None) @pytest.mark.django_db @@ -83,11 +110,7 @@ def test_update_delivery_point(): entity1 = EntityFactory(users=(user1,)) # create delivery point - delivery_point = DeliveryPointFactory(entities=(entity1,)) - - # test entity1 have been removed - delivery_point.entities.remove(entity1) - assert all(entity != entity1 for entity in delivery_point.entities.all()) + delivery_point = DeliveryPointFactory(entity=entity1) # test updated_at has been updated assert delivery_point.updated_at > delivery_point.created_at