diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fe8d439b..fcaa3249 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: matrix: python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] django-version: ["3.2", "4.2", "5.2"] - oscar-version: ["3.2", "4.0"] + oscar-version: ["3.2", "4.0", "4.1"] exclude: - python-version: "3.13" django-version: "3.2" @@ -59,6 +59,8 @@ jobs: django-version: "5.2" - python-version: "3.8" oscar-version: "4.0" + - python-version: "3.8" + oscar-version: "4.1" steps: - name: Download src dir uses: actions/download-artifact@v4 diff --git a/oscarapi/fixtures/product.xml b/oscarapi/fixtures/product.xml index 5828a55a..1b69caa7 100644 --- a/oscarapi/fixtures/product.xml +++ b/oscarapi/fixtures/product.xml @@ -1,7 +1,7 @@ - parent + standalone 1234 @@ -18,10 +18,28 @@ True + + parent + parent-1234 + + + + Oscar T-shirt + parent-1234 + Hank + 1 + + + + 2013-12-12T16:33:57.426000+00:00 + 2013-12-12T16:33:57.426000+00:00 + True + + child child-1234 - 1 + 5 oscar-t-shirt-child diff --git a/oscarapi/serializers/admin/product.py b/oscarapi/serializers/admin/product.py index 43049f3c..b569b862 100644 --- a/oscarapi/serializers/admin/product.py +++ b/oscarapi/serializers/admin/product.py @@ -93,10 +93,14 @@ def update(self, instance, validated_data): categories = validated_data.pop("categories", None) recommended_products = validated_data.pop("recommended_products", None) children = validated_data.pop("children", None) + structure = validated_data.get("structure", instance.structure) # Child products are not supposed to have a product class, their product # class comes from the parent product. - if instance.is_child: - validated_data.pop("product_class", None) + if structure == Product.CHILD: + validated_data["product_class"] = None + else: + # Parent and standalone products are not supposed to have a parent + validated_data["parent"] = None with transaction.atomic(): # it is all or nothing! # update instance @@ -118,6 +122,9 @@ def update(self, instance, validated_data): else: _categories.set(categories) + if instance.is_child: + instance.categories.all().delete() + if recommended_products is not None: with fake_autocreated( instance.recommended_products @@ -148,11 +155,17 @@ def update(self, instance, validated_data): self.update_relation("options", _product_options, new_options) self.update_relation("images", instance.images, images) - self.update_relation("stockrecords", instance.stockrecords, stockrecords) self.update_relation( "attributes", instance.attribute_values, attribute_values ) + if instance.is_parent: + instance.stockrecords.all().delete() + else: + self.update_relation( + "stockrecords", instance.stockrecords, stockrecords + ) + if ( self.partial ): # we need to clean up all the attributes with wrong product class diff --git a/oscarapi/serializers/product.py b/oscarapi/serializers/product.py index 7a5188cc..f12b3efa 100644 --- a/oscarapi/serializers/product.py +++ b/oscarapi/serializers/product.py @@ -460,15 +460,30 @@ class BaseProductSerializer(OscarModelSerializer): ) def validate(self, attrs): - if "structure" in attrs and "parent" in attrs: + structure = attrs.get("structure", None) + if structure and "parent" in attrs: if attrs["structure"] == Product.CHILD and attrs["parent"] is None: raise serializers.ValidationError(_("child without parent")) - if "structure" in attrs and "product_class" in attrs: + if structure and "product_class" in attrs: if attrs["product_class"] is None and attrs["structure"] != Product.CHILD: raise serializers.ValidationError( _("product_class can not be empty for structure %(structure)s") % attrs ) + if ( + self.instance + and structure + and structure != Product.PARENT + and self.instance.structure == Product.PARENT + and self.instance.children.exists() + ): + raise serializers.ValidationError( + { + "structure": _( + "Cannot convert parent product with children to a non-parent" + ) + } + ) return super(BaseProductSerializer, self).validate(attrs) diff --git a/oscarapi/tests/unit/testproduct.py b/oscarapi/tests/unit/testproduct.py index ededa998..6a845f86 100644 --- a/oscarapi/tests/unit/testproduct.py +++ b/oscarapi/tests/unit/testproduct.py @@ -15,7 +15,9 @@ from django.test import TestCase, RequestFactory, override_settings from django.utils.timezone import make_aware +from oscar import VERSION as OSCAR_VERSION from oscar.core.loading import get_model +from oscar.test.factories import ProductFactory from rest_framework import exceptions @@ -84,7 +86,7 @@ def test_product_list(self): self.response = self.get("product-list") self.response.assertStatusEqual(200) # we should have four products - self.assertEqual(len(self.response.body), 4) + self.assertEqual(len(self.response.body), 5) # default we have 3 fields product = self.response.body[0] default_fields = ["id", "url"] @@ -95,7 +97,7 @@ def test_product_list_filter(self): standalone_products_url = "%s?structure=standalone" % reverse("product-list") self.response = self.get(standalone_products_url) self.response.assertStatusEqual(200) - self.assertEqual(len(self.response.body), 2) + self.assertEqual(len(self.response.body), 3) parent_products_url = "%s?structure=parent" % reverse("product-list") self.response = self.get(parent_products_url) @@ -882,7 +884,7 @@ def test_create_product(self): ) self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) obj = ser.save() - self.assertEqual(obj.pk, 5, "Should be new object, with a high pk") + self.assertEqual(obj.pk, 6, "Should be new object, with a high pk") self.assertEqual(obj.product_class.slug, "testtype") self.assertEqual(obj.slug, "new-product") @@ -899,7 +901,7 @@ def test_create_child_product(self): ) self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) obj = ser.save() - self.assertEqual(obj.pk, 5, "Should be new object, with a high pk") + self.assertEqual(obj.pk, 6, "Should be new object, with a high pk") self.assertEqual(obj.product_class, None) self.assertFalse(obj.categories.exists()) self.assertEqual(obj.slug, "new-product") @@ -1499,7 +1501,7 @@ def test_update_child_with_attributes(self): 0, "The child has no attributes", ) - self.assertEqual(child_product.parent_id, 1) + self.assertEqual(child_product.parent_id, 5) self.assertIsNone(child_product.product_class) self.assertEqual(child_product.upc, "child-1234") self.assertEqual(child_product.slug, "oscar-t-shirt-child") @@ -1635,6 +1637,193 @@ def test_update_attributes_to_parent_and_child(self): ) +@skipIf(settings.OSCARAPI_BLOCK_ADMIN_API_ACCESS, "Admin API is not enabled") +class AdminProductSerializerStructureUpdateTest(_ProductSerializerTest): + def test_parent_with_children_to_child(self): + product = Product.objects.get(pk=5) + new_parent = ProductFactory(structure="parent", categories=[]) + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "new-shirt", + "structure": "child", + "parent": new_parent.pk, + }, + instance=product, + ) + self.assertFalse(ser.is_valid(), "Should fail because parent has children") + self.assertEqual(len(ser.errors), 1) + self.assertIn("structure", ser.errors) + + def test_parent_without_children_to_child(self): + product = Product.objects.get(pk=5) + product.children.all().delete() + new_parent = ProductFactory(structure="parent") + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "new-shirt", + "structure": "child", + "categories": ["Clothing"], + "stockrecords": [ + { + "partner_sku": "henk-het-kind", + "price_currency": "EUR", + "price": "110.00", + "partner": "http://127.0.0.1:8000/api/admin/partners/1/", + } + ], + "parent": new_parent.pk, + }, + instance=product, + ) + self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) + new_product = ser.save() + self.assertEqual(new_product.structure, "child") + self.assertEqual(new_product.slug, "new-shirt") + self.assertEqual( + new_product.product_class, None, "Child products have no product class" + ) + self.assertEqual(new_product.parent.pk, new_parent.pk) + self.assertFalse( + new_product.categories.exists(), "Child products cannot have categories" + ) + self.assertTrue(new_product.stockrecords.exists()) + + def test_standalone_to_child(self): + product = Product.objects.get(pk=1) + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "1234", + "structure": "child", + "parent": 5, + }, + instance=product, + ) + self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) + new_product = ser.save() + self.assertEqual(new_product.structure, "child") + self.assertEqual(new_product.slug, "1234") + self.assertEqual( + new_product.product_class, None, "Child products have no product class" + ) + self.assertEqual(new_product.parent.pk, 5) + self.assertFalse( + new_product.categories.exists(), "Child products cannot have categories" + ) + self.assertTrue(new_product.stockrecords.exists()) + + def test_parent_with_children_to_standalone(self): + product = Product.objects.get(pk=5) + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "standalone-1234", + "structure": "standalone", + }, + instance=product, + ) + self.assertFalse(ser.is_valid(), "Should fail because parent has children") + self.assertEqual(len(ser.errors), 1) + self.assertIn("structure", ser.errors) + + def test_parent_without_children_to_standalone(self): + product = Product.objects.get(pk=5) + product.children.all().delete() + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "standalone-1234", + "structure": "standalone", + "categories": ["Clothing"], + "stockrecords": [ + { + "partner_sku": "henk-het-kind", + "price_currency": "EUR", + "price": "110.00", + "partner": "http://127.0.0.1:8000/api/admin/partners/1/", + } + ], + }, + instance=product, + ) + self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) + new_product = ser.save() + self.assertEqual(new_product.structure, "standalone") + self.assertEqual(new_product.slug, "standalone-1234") + self.assertEqual(new_product.product_class.pk, 1) + self.assertEqual(new_product.parent, None) + self.assertTrue(new_product.categories.exists()) + self.assertTrue(new_product.stockrecords.exists()) + + def test_child_to_standalone(self): + product = Product.objects.get(pk=2) + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "standalone-1234", + "structure": "standalone", + "categories": ["Clothing"], + }, + instance=product, + ) + self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) + new_product = ser.save() + self.assertEqual(new_product.structure, "standalone") + self.assertEqual(new_product.slug, "standalone-1234") + self.assertEqual(new_product.product_class.pk, 1) + self.assertEqual(new_product.parent, None) + self.assertTrue(new_product.categories.exists()) + self.assertTrue(new_product.stockrecords.exists()) + + def test_child_to_parent(self): + product = Product.objects.get(pk=2) + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "new-parent-1234", + "structure": "parent", + "categories": ["Clothing"], + }, + instance=product, + ) + self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) + new_product = ser.save() + self.assertEqual(new_product.structure, "parent") + self.assertEqual(new_product.slug, "new-parent-1234") + self.assertEqual(new_product.product_class.pk, 1) + self.assertEqual(new_product.parent, None, "Parent products have no parent") + self.assertTrue(new_product.categories.exists()) + self.assertFalse( + new_product.stockrecords.exists(), + "Parent products cannot have stockrecords", + ) + + def test_standalone_to_parent(self): + product = Product.objects.get(pk=1) + ser = AdminProductSerializer( + data={ + "product_class": "t-shirt", + "slug": "new-parent-1234", + "structure": "parent", + "categories": ["Clothing"], + }, + instance=product, + ) + self.assertTrue(ser.is_valid(), "Something wrong %s" % ser.errors) + new_product = ser.save() + self.assertEqual(new_product.structure, "parent") + self.assertEqual(new_product.slug, "new-parent-1234") + self.assertEqual(new_product.product_class.pk, 1) + self.assertEqual(new_product.parent, None) + self.assertTrue(new_product.categories.exists()) + self.assertFalse( + new_product.stockrecords.exists(), + "Parent products cannot have stockrecords", + ) + + @skipIf(settings.OSCARAPI_BLOCK_ADMIN_API_ACCESS, "Admin API is not enabled") class TestProductAdmin(APITest): fixtures = [ @@ -1681,14 +1870,14 @@ def test_staff_has_no_access_by_default(self): self.response.assertStatusEqual(403) def test_post_product(self): - self.assertEqual(Product.objects.count(), 4) + self.assertEqual(Product.objects.count(), 5) self.login("admin", "admin") data = deepcopy(self.attributes) data["slug"] = "keikeikke" data["upc"] = "roekoekoe" self.response = self.post("admin-product-list", **data) self.response.assertStatusEqual(201) - self.assertEqual(Product.objects.count(), 5) + self.assertEqual(Product.objects.count(), 6) data = deepcopy(self.tshirt) data["slug"] = "hoelahoepie" @@ -1696,7 +1885,7 @@ def test_post_product(self): data["stockrecords"][0]["partner_sku"] = "kjdfshkshjfkh" self.response = self.post("admin-product-list", **data) self.response.assertStatusEqual(201) - self.assertEqual(Product.objects.count(), 6) + self.assertEqual(Product.objects.count(), 7) def test_put_product(self): self.login("admin", "admin") @@ -2231,6 +2420,13 @@ def test_create_category_tree(self): }, ] + if OSCAR_VERSION[0] >= 4 and OSCAR_VERSION[1] >= 1: + long_description = {"long_description": ""} + exclude_from_menu = {"exclude_from_menu": False} + else: + long_description = {} + exclude_from_menu = {} + self.response = self.post("admin-category-bulk", manual_data=data) self.assertEqual(Category.objects.count(), 4) @@ -2248,11 +2444,13 @@ def test_create_category_tree(self): "name": "Henk", "code": "henk", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "henk", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 1, @@ -2262,11 +2460,13 @@ def test_create_category_tree(self): "name": "Klaas", "code": "klaas", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 2, @@ -2276,11 +2476,13 @@ def test_create_category_tree(self): "name": "Klaas 2", "code": "klaas2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 3, @@ -2292,11 +2494,13 @@ def test_create_category_tree(self): "name": "Harrie", "code": "harrie", "description": "Dit is de description", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "harrie", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 4, @@ -2341,11 +2545,13 @@ def test_create_category_tree(self): "name": "Henk nieuw", "code": "henk", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "henk", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 1, @@ -2355,11 +2561,13 @@ def test_create_category_tree(self): "name": "Klaas", "code": "klaas", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 2, @@ -2371,11 +2579,13 @@ def test_create_category_tree(self): "name": "Harrie", "code": "harrie", "description": "Dit is de description", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "harrie", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 4, @@ -2385,11 +2595,13 @@ def test_create_category_tree(self): "name": "Klaas 2", "code": "klaas2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 3, @@ -2434,11 +2646,13 @@ def test_create_category_tree(self): "name": "Harrie", "code": "harrie", "description": "Dit is de description", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "harrie", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 4, @@ -2448,11 +2662,13 @@ def test_create_category_tree(self): "name": "Henk nieuw", "code": "henk", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "henk", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 1, @@ -2462,11 +2678,13 @@ def test_create_category_tree(self): "name": "Klaas", "code": "klaas", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 2, @@ -2476,11 +2694,13 @@ def test_create_category_tree(self): "name": "Klaas 2", "code": "klaas2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 3, @@ -2521,6 +2741,13 @@ def test_crazy_stuff(self): }, ] + if OSCAR_VERSION[0] >= 4 and OSCAR_VERSION[1] >= 1: + long_description = {"long_description": ""} + exclude_from_menu = {"exclude_from_menu": False} + else: + long_description = {} + exclude_from_menu = {} + self.response = self.post("admin-category-bulk", manual_data=data) self.assertEqual(Category.objects.count(), 14) @@ -2533,11 +2760,13 @@ def test_crazy_stuff(self): "name": "Henk", "code": "henk", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "henk", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 1, @@ -2547,11 +2776,13 @@ def test_crazy_stuff(self): "name": "Klaas", "code": "klaas", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 2, @@ -2561,11 +2792,13 @@ def test_crazy_stuff(self): "name": "Klaas 2", "code": "klaas2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 3, @@ -2575,11 +2808,13 @@ def test_crazy_stuff(self): "name": "Klaas 3", "code": "klaas3", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-3", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 4, @@ -2589,11 +2824,13 @@ def test_crazy_stuff(self): "name": "Klaas 4", "code": "klaas4", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-4", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 5, @@ -2603,11 +2840,13 @@ def test_crazy_stuff(self): "name": "Klaas 5", "code": "klaas5", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-5", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 6, @@ -2617,11 +2856,13 @@ def test_crazy_stuff(self): "name": "Klaas 6", "code": "klaas6", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-6", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 7, @@ -2633,11 +2874,13 @@ def test_crazy_stuff(self): "name": "Harrie", "code": "harrie", "description": "Dit is de description", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "harrie", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 8, @@ -2647,11 +2890,13 @@ def test_crazy_stuff(self): "name": "Koe", "code": "koe", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 9, @@ -2661,11 +2906,13 @@ def test_crazy_stuff(self): "name": "Koe 2", "code": "koe2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 10, @@ -2675,11 +2922,13 @@ def test_crazy_stuff(self): "name": "Koe 3", "code": "koe3", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-3", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 11, @@ -2689,11 +2938,13 @@ def test_crazy_stuff(self): "name": "Koe 4", "code": "koe4", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-4", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 12, @@ -2703,11 +2954,13 @@ def test_crazy_stuff(self): "name": "Koe 5", "code": "koe5", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-5", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 13, @@ -2717,11 +2970,13 @@ def test_crazy_stuff(self): "name": "Koe 6", "code": "koe6", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-6", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 14, @@ -2788,11 +3043,13 @@ def test_crazy_stuff(self): "name": "Henk", "code": "henk", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "henk", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 1, @@ -2802,11 +3059,13 @@ def test_crazy_stuff(self): "name": "Harrie", "code": "harrie", "description": "Dit is de description", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "harrie", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 8, @@ -2816,11 +3075,13 @@ def test_crazy_stuff(self): "name": "Nieuwe 1", "code": "nieuwe1", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "nieuwe-1", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 15, @@ -2830,11 +3091,13 @@ def test_crazy_stuff(self): "name": "Klaas", "code": "klaas", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 2, @@ -2844,11 +3107,13 @@ def test_crazy_stuff(self): "name": "Klaas 2", "code": "klaas2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 3, @@ -2860,11 +3125,13 @@ def test_crazy_stuff(self): "name": "Nieuwe 2", "code": "nieuwe2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "nieuwe-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 16, @@ -2874,11 +3141,13 @@ def test_crazy_stuff(self): "name": "Klaas 3", "code": "klaas3", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-3", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 4, @@ -2888,11 +3157,13 @@ def test_crazy_stuff(self): "name": "Klaas 4", "code": "klaas4", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-4", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 5, @@ -2904,11 +3175,13 @@ def test_crazy_stuff(self): "name": "Nieuwe 3", "code": "nieuwe3", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "nieuwe-3", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 17, @@ -2918,11 +3191,13 @@ def test_crazy_stuff(self): "name": "Klaas 5", "code": "klaas5", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-5", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 6, @@ -2932,11 +3207,13 @@ def test_crazy_stuff(self): "name": "Klaas 6", "code": "klaas6", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "klaas-6", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 7, @@ -2948,11 +3225,13 @@ def test_crazy_stuff(self): "name": "Gekke 1", "code": "gekke1", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "gekke-1", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 18, @@ -2962,11 +3241,13 @@ def test_crazy_stuff(self): "name": "Koe", "code": "koe", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 9, @@ -2976,11 +3257,13 @@ def test_crazy_stuff(self): "name": "Koe 2", "code": "koe2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 10, @@ -2992,11 +3275,13 @@ def test_crazy_stuff(self): "name": "Gekke 2", "code": "gekke2", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "gekke-2", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 19, @@ -3006,11 +3291,13 @@ def test_crazy_stuff(self): "name": "Koe 3", "code": "koe3", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-3", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 11, @@ -3020,11 +3307,13 @@ def test_crazy_stuff(self): "name": "Koe 4", "code": "koe4", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-4", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 12, @@ -3036,11 +3325,13 @@ def test_crazy_stuff(self): "name": "Gekke 3", "code": "gekke3", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "gekke-3", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 20, @@ -3050,11 +3341,13 @@ def test_crazy_stuff(self): "name": "Koe 5", "code": "koe5", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-5", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 13, @@ -3064,11 +3357,13 @@ def test_crazy_stuff(self): "name": "Koe 6", "code": "koe6", "description": "", + **long_description, "meta_title": None, "meta_description": None, "image": "", "slug": "koe-6", "is_public": True, + **exclude_from_menu, "ancestors_are_public": True, }, "id": 14, diff --git a/oscarapi/tests/unit/testutils.py b/oscarapi/tests/unit/testutils.py index 28e09ba8..81793cf7 100644 --- a/oscarapi/tests/unit/testutils.py +++ b/oscarapi/tests/unit/testutils.py @@ -39,7 +39,7 @@ def test_category_construct_id_filter_pk(self): self.assertEqual(c.id, 1) def test_product_construct_id_filter_upc(self): - for upc in ["1234", "child-1234", "attrtypestest", "entity"]: + for upc in ["1234", "parent-1234", "child-1234", "attrtypestest", "entity"]: p = self._test_construct_id_filter(Product, {"upc": upc, "title": "henk"}) self.assertEqual(p.upc, upc)