diff --git a/dojo/fixtures/defect_dojo_sample_data.json b/dojo/fixtures/defect_dojo_sample_data.json index 081881a478..fa791f3275 100644 --- a/dojo/fixtures/defect_dojo_sample_data.json +++ b/dojo/fixtures/defect_dojo_sample_data.json @@ -2512,6 +2512,146 @@ "model": "dojo.tagulous_product_tags", "pk": 1 }, + { + "fields": { + "display_order": 10, + "icon": "plug", + "name": "API", + "value": "web service" + }, + "model": "dojo.product_platform", + "pk": 1 + }, + { + "fields": { + "display_order": 20, + "icon": "desktop", + "name": "Desktop", + "value": "desktop" + }, + "model": "dojo.product_platform", + "pk": 2 + }, + { + "fields": { + "display_order": 30, + "icon": "shuffle", + "name": "Internet of Things", + "value": "iot" + }, + "model": "dojo.product_platform", + "pk": 3 + }, + { + "fields": { + "display_order": 40, + "icon": "mobile", + "name": "Mobile", + "value": "mobile" + }, + "model": "dojo.product_platform", + "pk": 4 + }, + { + "fields": { + "display_order": 50, + "icon": "rectangle-list", + "name": "Web", + "value": "web" + }, + "model": "dojo.product_platform", + "pk": 5 + }, + { + "fields": { + "display_order": 10, + "icon": "compass", + "name": "Construction", + "value": "construction" + }, + "model": "dojo.product_lifecycle", + "pk": 1 + }, + { + "fields": { + "display_order": 20, + "icon": "ship", + "name": "Production", + "value": "production" + }, + "model": "dojo.product_lifecycle", + "pk": 2 + }, + { + "fields": { + "display_order": 30, + "icon": "moon", + "name": "Retirement", + "value": "retirement" + }, + "model": "dojo.product_lifecycle", + "pk": 3 + }, + { + "fields": { + "display_order": 10, + "icon": "book", + "name": "Third Party Library", + "value": "third party library" + }, + "model": "dojo.product_origin", + "pk": 1 + }, + { + "fields": { + "display_order": 20, + "icon": "money-bill", + "name": "Purchased", + "value": "purchased" + }, + "model": "dojo.product_origin", + "pk": 2 + }, + { + "fields": { + "display_order": 30, + "icon": "suitcase", + "name": "Contractor Developed", + "value": "contractor" + }, + "model": "dojo.product_origin", + "pk": 3 + }, + { + "fields": { + "display_order": 40, + "icon": "home", + "name": "Internally Developed", + "value": "internal" + }, + "model": "dojo.product_origin", + "pk": 4 + }, + { + "fields": { + "display_order": 50, + "icon": "code", + "name": "Open Source", + "value": "open source" + }, + "model": "dojo.product_origin", + "pk": 5 + }, + { + "fields": { + "display_order": 60, + "icon": "globe", + "name": "Outsourced", + "value": "outsourced" + }, + "model": "dojo.product_origin", + "pk": 6 + }, { "fields": { "async_updating": false, diff --git a/dojo/fixtures/defect_dojo_sample_data_locations.json b/dojo/fixtures/defect_dojo_sample_data_locations.json index 9741486eec..0f1d8faf2c 100644 --- a/dojo/fixtures/defect_dojo_sample_data_locations.json +++ b/dojo/fixtures/defect_dojo_sample_data_locations.json @@ -2521,6 +2521,146 @@ "model": "dojo.tagulous_product_tags", "pk": 1 }, + { + "fields": { + "display_order": 10, + "icon": "plug", + "name": "API", + "value": "web service" + }, + "model": "dojo.product_platform", + "pk": 1 + }, + { + "fields": { + "display_order": 20, + "icon": "desktop", + "name": "Desktop", + "value": "desktop" + }, + "model": "dojo.product_platform", + "pk": 2 + }, + { + "fields": { + "display_order": 30, + "icon": "shuffle", + "name": "Internet of Things", + "value": "iot" + }, + "model": "dojo.product_platform", + "pk": 3 + }, + { + "fields": { + "display_order": 40, + "icon": "mobile", + "name": "Mobile", + "value": "mobile" + }, + "model": "dojo.product_platform", + "pk": 4 + }, + { + "fields": { + "display_order": 50, + "icon": "rectangle-list", + "name": "Web", + "value": "web" + }, + "model": "dojo.product_platform", + "pk": 5 + }, + { + "fields": { + "display_order": 10, + "icon": "compass", + "name": "Construction", + "value": "construction" + }, + "model": "dojo.product_lifecycle", + "pk": 1 + }, + { + "fields": { + "display_order": 20, + "icon": "ship", + "name": "Production", + "value": "production" + }, + "model": "dojo.product_lifecycle", + "pk": 2 + }, + { + "fields": { + "display_order": 30, + "icon": "moon", + "name": "Retirement", + "value": "retirement" + }, + "model": "dojo.product_lifecycle", + "pk": 3 + }, + { + "fields": { + "display_order": 10, + "icon": "book", + "name": "Third Party Library", + "value": "third party library" + }, + "model": "dojo.product_origin", + "pk": 1 + }, + { + "fields": { + "display_order": 20, + "icon": "money-bill", + "name": "Purchased", + "value": "purchased" + }, + "model": "dojo.product_origin", + "pk": 2 + }, + { + "fields": { + "display_order": 30, + "icon": "suitcase", + "name": "Contractor Developed", + "value": "contractor" + }, + "model": "dojo.product_origin", + "pk": 3 + }, + { + "fields": { + "display_order": 40, + "icon": "home", + "name": "Internally Developed", + "value": "internal" + }, + "model": "dojo.product_origin", + "pk": 4 + }, + { + "fields": { + "display_order": 50, + "icon": "code", + "name": "Open Source", + "value": "open source" + }, + "model": "dojo.product_origin", + "pk": 5 + }, + { + "fields": { + "display_order": 60, + "icon": "globe", + "name": "Outsourced", + "value": "outsourced" + }, + "model": "dojo.product_origin", + "pk": 6 + }, { "fields": { "async_updating": false, diff --git a/unittests/test_sample_data.py b/unittests/test_sample_data.py index ee076b9561..b91e2ba1ac 100644 --- a/unittests/test_sample_data.py +++ b/unittests/test_sample_data.py @@ -1,6 +1,9 @@ from django.conf import settings from django.core.management import call_command +from dojo.models import Product +from dojo.product_attributes.models import Product_Lifecycle, Product_Origin, Product_Platform + from .dojo_test_case import DojoTestCase @@ -29,3 +32,27 @@ def test_loaddata(self): except Exception as e: self.assertEqual(False, True, e) self.assertEqual(True, True) + + # Regression: the sample-data fixtures referenced the Product_Platform / Product_Lifecycle / + # Product_Origin rows seeded by migration 0297 by pk without shipping the rows themselves, so + # loading them into a database whose tables had been emptied (``manage.py flush`` on the demo + # server) failed with "Product_Platform matching query does not exist". + def test_loaddata_is_self_contained_for_asset_attribute_options(self): + Product_Platform.objects.all().delete() + Product_Lifecycle.objects.all().delete() + Product_Origin.objects.all().delete() + + call_command("loaddata", self.get_fixture_file(), verbosity=0) + + expected = { + "BodgeIt": ("web", "production", "internal"), + "Internal CRM App": ("web", "construction", "internal"), + "Apple Accounting Software": ("web", "production", "purchased"), + } + for name, (platform, lifecycle, origin) in expected.items(): + product = Product.objects.get(name=name) + persisted = (product.platform.value, product.lifecycle.value, product.origin.value) + self.assertEqual( + persisted, (platform, lifecycle, origin), + msg=f"{name}: expected {(platform, lifecycle, origin)}, persisted={persisted}", + )