diff --git a/src/oscar/apps/catalogue/apps.py b/src/oscar/apps/catalogue/apps.py index a3eb1e68286..d58341dd698 100644 --- a/src/oscar/apps/catalogue/apps.py +++ b/src/oscar/apps/catalogue/apps.py @@ -38,7 +38,9 @@ def get_urls(self): self.category_view.as_view(), name="category", ), - path("ranges//", self.range_view.as_view(), name="range"), + re_path( + r"^ranges/(?P[\w-]+)/$", self.range_view.as_view(), name="range" + ), ] return self.post_process_urls(urls) diff --git a/src/oscar/apps/dashboard/catalogue/apps.py b/src/oscar/apps/dashboard/catalogue/apps.py index 513e1386e46..b332c0d60ad 100644 --- a/src/oscar/apps/dashboard/catalogue/apps.py +++ b/src/oscar/apps/dashboard/catalogue/apps.py @@ -1,4 +1,4 @@ -from django.urls import path +from django.urls import path, re_path from django.utils.translation import gettext_lazy as _ from oscar.core.application import OscarDashboardConfig @@ -108,8 +108,8 @@ def get_urls(self): self.product_create_redirect_view.as_view(), name="catalogue-product-create", ), - path( - "products/create//", + re_path( + r"^products/create/(?P[\w-]+)/$", self.product_createupdate_view.as_view(), name="catalogue-product-create", ), diff --git a/src/oscar/apps/dashboard/communications/apps.py b/src/oscar/apps/dashboard/communications/apps.py index 692b8f40659..77e4e50ef96 100644 --- a/src/oscar/apps/dashboard/communications/apps.py +++ b/src/oscar/apps/dashboard/communications/apps.py @@ -1,4 +1,4 @@ -from django.urls import path +from django.urls import path, re_path from django.utils.translation import gettext_lazy as _ from oscar.core.application import OscarDashboardConfig @@ -22,6 +22,8 @@ def ready(self): def get_urls(self): urls = [ path("", self.list_view.as_view(), name="comms-list"), - path("/", self.update_view.as_view(), name="comms-update"), + re_path( + r"^(?P[\w-]+)/$", self.update_view.as_view(), name="comms-update" + ), ] return self.post_process_urls(urls) diff --git a/src/oscar/apps/offer/apps.py b/src/oscar/apps/offer/apps.py index 7689fe80505..4a4e8aff573 100644 --- a/src/oscar/apps/offer/apps.py +++ b/src/oscar/apps/offer/apps.py @@ -1,4 +1,4 @@ -from django.urls import path +from django.urls import path, re_path from django.utils.translation import gettext_lazy as _ from oscar.core.application import OscarConfig @@ -22,6 +22,6 @@ def ready(self): def get_urls(self): urls = [ path("", self.list_view.as_view(), name="list"), - path("/", self.detail_view.as_view(), name="detail"), + re_path(r"^(?P[\w-]+)/$", self.detail_view.as_view(), name="detail"), ] return self.post_process_urls(urls) diff --git a/tests/functional/dashboard/test_catalogue.py b/tests/functional/dashboard/test_catalogue.py index abe6a1a7023..1be98924c7a 100644 --- a/tests/functional/dashboard/test_catalogue.py +++ b/tests/functional/dashboard/test_catalogue.py @@ -1,7 +1,9 @@ from http import client as http_client from django.urls import reverse +from django.test import TestCase +from oscar.core.compat import get_user_model from oscar.core.loading import get_class, get_model from oscar.test.factories import ( CategoryFactory, @@ -12,6 +14,7 @@ ) from oscar.test.testcases import WebTestCase, add_permissions +User = get_user_model() Product = get_model("catalogue", "Product") ProductClass = get_model("catalogue", "ProductClass") ProductCategory = get_model("catalogue", "ProductCategory") @@ -317,3 +320,15 @@ def test_can_create_a_child_product(self): def test_cant_create_child_product_for_invalid_parents(self): pass + + +class TestProductCreatePageWithUnicodeSlug(TestCase): + def setUp(self): + self.slug = "Ûul-wįth-weird-chars" + ProductClass.objects.create(name="Book", slug=self.slug) + self.user = User.objects.create(is_staff=True) + self.client.force_login(self.user) + + def test_url_with_unicode_characters(self): + response = self.client.get(f"/dashboard/catalogue/products/create/{self.slug}/") + self.assertEqual(200, response.status_code) diff --git a/tests/functional/dashboard/test_communication.py b/tests/functional/dashboard/test_communication.py index ea3a94874c7..6d8bdaa1c9f 100644 --- a/tests/functional/dashboard/test_communication.py +++ b/tests/functional/dashboard/test_communication.py @@ -1,11 +1,14 @@ from django.core import mail from django.urls import reverse +from django.test import TestCase +from oscar.core.compat import get_user_model from oscar.core.loading import get_model from oscar.test.factories import UserFactory from oscar.test.testcases import WebTestCase CommunicationEventType = get_model("communication", "CommunicationEventType") +User = get_user_model() class TestAnAdmin(WebTestCase): @@ -36,3 +39,19 @@ def test_can_send_a_preview_email(self): form.submit("send_preview") assert len(mail.outbox) == 1 + + +class TestCommsUpdatePageWithUnicodeSlug(TestCase): + def setUp(self): + self.slug = "Ûul-wįth-weird-chars" + self.commtype = CommunicationEventType.objects.create( + name="comm-event", + category=CommunicationEventType.USER_RELATED, + code="Ûul-wįth-weird-chars", + ) + self.user = User.objects.create(is_staff=True) + self.client.force_login(self.user) + + def test_url_with_unicode_characters(self): + response = self.client.get(f"/dashboard/comms/{self.slug}/") + self.assertEqual(200, response.status_code) diff --git a/tests/functional/test_offer.py b/tests/functional/test_offer.py index 380c2c220fe..d79ad1ea400 100644 --- a/tests/functional/test_offer.py +++ b/tests/functional/test_offer.py @@ -1,3 +1,11 @@ +from django.test import TestCase + +from oscar.test.factories.offer import ( + BenefitFactory, + ConditionalOfferFactory, + ConditionFactory, + RangeFactory, +) from oscar.test.testcases import WebTestCase @@ -5,3 +13,25 @@ class TestTheOfferListPage(WebTestCase): def test_exists(self): response = self.app.get("/offers/") self.assertEqual(200, response.status_code) + + +class TestOfferDetailsPageWithUnicodeSlug(TestCase): + def setUp(self): + self.slug = "Ûul-wįth-weird-chars" + self.offer = ConditionalOfferFactory( + condition=ConditionFactory(), benefit=BenefitFactory(), slug=self.slug + ) + + def test_url_with_unicode_characters(self): + response = self.client.get(f"/offers/{self.slug}/") + self.assertEqual(200, response.status_code) + + +class TestRangeDetailsPageWithUnicodeSlug(TestCase): + def setUp(self): + self.slug = "Ûul-wįth-weird-chars" + self.range = RangeFactory(slug=self.slug, is_public=True) + + def test_url_with_unicode_characters(self): + response = self.client.get(f"/catalogue/ranges/{self.slug}/") + self.assertEqual(200, response.status_code)