angrybeanie_wagtail/env/lib/python3.12/site-packages/wagtail/locales/tests.py

394 lines
13 KiB
Python
Raw Permalink Normal View History

2025-07-25 21:32:16 +10:00
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.contrib.messages import get_messages
from django.contrib.messages.constants import ERROR
from django.test import TestCase, override_settings
from django.urls import reverse
from wagtail import hooks
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.models import Locale, Page
from wagtail.test.utils import WagtailTestUtils
from wagtail.test.utils.template_tests import AdminTemplateTestUtils
class TestLocaleIndexView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
@classmethod
def setUpTestData(cls):
cls.user = cls.create_test_user()
cls.add_url = reverse("wagtaillocales:add")
def setUp(self):
self.login(user=self.user)
def get(self, params={}):
return self.client.get(reverse("wagtaillocales:index"), params)
def test_simple(self):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/index.html")
self.assertBreadcrumbsItemsRendered(
[{"url": "", "label": "Locales"}],
response.content,
)
self.assertContains(response, self.add_url)
@override_settings(WAGTAIL_CONTENT_LANGUAGES=[("en", "English")])
def test_index_view_doesnt_show_add_locale_button_if_all_locales_created(self):
self.assertNotContains(self.get(), self.add_url)
@override_settings(WAGTAIL_CONTENT_LANGUAGES=[("en", "English"), ("fr", "French")])
def test_index_view_shows_add_locale_button_with_stale_locales(self):
Locale.objects.create(language_code="de")
self.assertContains(self.get(), self.add_url)
class TestLocaleCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
def setUp(self):
self.login()
self.english = Locale.objects.get()
def get(self, params={}):
return self.client.get(reverse("wagtaillocales:add"), params)
def post(self, post_data={}):
return self.client.post(reverse("wagtaillocales:add"), post_data)
def test_default_language(self):
# we should have loaded with a single locale
self.assertEqual(self.english.language_code, "en")
self.assertEqual(self.english.get_display_name(), "English")
def test_simple(self):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtaillocales/create.html")
self.assertBreadcrumbsItemsRendered(
[
{"label": "Locales", "url": "/admin/locales/"},
{"label": "New: Locale", "url": ""},
],
response.content,
)
self.assertEqual(
response.context["form"].fields["language_code"].choices, [("fr", "French")]
)
def test_create(self):
response = self.post(
{
"language_code": "fr",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtaillocales:index"))
# Check that the locale was created
self.assertTrue(Locale.objects.filter(language_code="fr").exists())
def test_duplicate_not_allowed(self):
response = self.post(
{
"language_code": "en",
}
)
# Should return the form with errors
self.assertEqual(response.status_code, 200)
self.assertFormError(
response.context["form"],
"language_code",
["Select a valid choice. en is not one of the available choices."],
)
def test_language_code_must_be_in_settings(self):
response = self.post(
{
"language_code": "ja",
}
)
# Should return the form with errors
self.assertEqual(response.status_code, 200)
self.assertFormError(
response.context["form"],
"language_code",
["Select a valid choice. ja is not one of the available choices."],
)
@override_settings(WAGTAIL_CONTENT_LANGUAGES=[("en", "English")])
def test_create_view_no_access_if_all_locales_created(self):
response = self.get()
self.assertEqual(response.status_code, 302)
self.assertEqual(
response.context["message"],
"Sorry, you do not have permission to access this area.",
)
@override_settings(WAGTAIL_CONTENT_LANGUAGES=[("en", "English"), ("fr", "French")])
def test_create_view_can_access_with_stale_locales(self):
Locale.objects.create(language_code="de")
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtaillocales/create.html")
class TestLocaleEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
def setUp(self):
self.user = self.login()
self.english = Locale.objects.get()
def get(self, params=None, locale=None):
locale = locale or self.english
return self.client.get(
reverse("wagtaillocales:edit", args=[locale.id]), params or {}
)
def post(self, post_data=None, locale=None):
post_data = post_data or {}
locale = locale or self.english
post_data.setdefault("language_code", locale.language_code)
return self.client.post(
reverse("wagtaillocales:edit", args=[locale.id]), post_data
)
def test_simple(self):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtaillocales/edit.html")
self.assertBreadcrumbsItemsRendered(
[
{"url": "/admin/locales/", "label": "Locales"},
{"url": "", "label": str(self.english)},
],
response.content,
)
self.assertEqual(
response.context["form"].fields["language_code"].choices,
[
(
"en",
"English",
), # Note: Current value is displayed even though it's in use
("fr", "French"),
],
)
url_finder = AdminURLFinder(self.user)
expected_url = "/admin/locales/edit/%d/" % self.english.id
self.assertEqual(url_finder.get_edit_url(self.english), expected_url)
def test_invalid_language(self):
invalid = Locale.objects.create(language_code="foo")
response = self.get(locale=invalid)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtaillocales/edit.html")
self.assertEqual(
response.context["form"].fields["language_code"].choices,
[
(
None,
"Select a new language",
), # This is shown instead of the current value if invalid
("fr", "French"),
],
)
def test_edit(self):
response = self.post(
{
"language_code": "fr",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtaillocales:index"))
# Check that the locale was edited
self.english.refresh_from_db()
self.assertEqual(self.english.language_code, "fr")
def test_edit_duplicate_not_allowed(self):
french = Locale.objects.create(language_code="fr")
response = self.post(
{
"language_code": "en",
},
locale=french,
)
# Should return the form with errors
self.assertEqual(response.status_code, 200)
self.assertFormError(
response.context["form"],
"language_code",
["Select a valid choice. en is not one of the available choices."],
)
def test_edit_language_code_must_be_in_settings(self):
response = self.post(
{
"language_code": "ja",
}
)
# Should return the form with errors
self.assertEqual(response.status_code, 200)
self.assertFormError(
response.context["form"],
"language_code",
["Select a valid choice. ja is not one of the available choices."],
)
class TestLocaleDeleteView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
def setUp(self):
self.login()
self.english = Locale.objects.get()
def get(self, params={}, locale=None):
locale = locale or self.english
return self.client.get(
reverse("wagtaillocales:delete", args=[locale.id]), params
)
def post(self, post_data={}, locale=None):
locale = locale or self.english
return self.client.post(
reverse("wagtaillocales:delete", args=[locale.id]), post_data
)
def test_simple(self):
response = self.get()
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "wagtailadmin/generic/confirm_delete.html")
self.assertBreadcrumbsNotRendered(response.content)
def test_delete_locale(self):
french = Locale.objects.create(language_code="fr")
response = self.post(locale=french)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtaillocales:index"))
# Check that the locale was deleted
self.assertFalse(Locale.objects.filter(language_code="fr").exists())
def test_cannot_delete_locales_with_pages(self):
# create a French locale so that the deletion is not rejected on grounds of being the only
# existing locale
Locale.objects.create(language_code="fr")
response = self.post()
self.assertEqual(response.status_code, 200)
# Check error message
messages = list(get_messages(response.wsgi_request))
self.assertEqual(messages[0].level, ERROR)
self.assertEqual(
messages[0].message,
"This locale cannot be deleted because there are pages and/or other objects using it.\n\n\n\n\n",
)
# Check that the locale was not deleted
self.assertTrue(Locale.objects.filter(language_code="en").exists())
@override_settings(
LANGUAGE_CODE="de-at",
WAGTAIL_CONTENT_LANGUAGES=[
("en", "English"),
("fr", "French"),
("de", "German"),
("pl", "Polish"),
("ja", "Japanese"),
],
)
def test_can_delete_default_locale(self):
# The presence of the locale on the root page node (if that's the only thing using the
# locale) should not prevent deleting it
for lang in ("fr", "de", "pl", "ja"):
Locale.objects.create(language_code=lang)
self.assertEqual(Page.get_first_root_node().locale.language_code, "en")
Page.objects.filter(depth__gt=1).delete()
response = self.post()
# Should redirect back to index
self.assertRedirects(response, reverse("wagtaillocales:index"))
# Check that the locale was deleted
self.assertFalse(Locale.objects.filter(language_code="en").exists())
# root node's locale should now have been reassigned to the one matching the current
# LANGUAGE_CODE
self.assertEqual(Page.get_first_root_node().locale.language_code, "de")
@override_settings(
LANGUAGE_CODE="de-at",
WAGTAIL_CONTENT_LANGUAGES=[
("en", "English"),
("fr", "French"),
("de", "German"),
("pl", "Polish"),
("ja", "Japanese"),
],
)
def test_can_delete_default_locale_when_language_code_has_no_locale(self):
Locale.objects.create(language_code="fr")
self.assertEqual(Page.get_first_root_node().locale.language_code, "en")
Page.objects.filter(depth__gt=1).delete()
response = self.post()
# Should redirect back to index
self.assertRedirects(response, reverse("wagtaillocales:index"))
# Check that the locale was deleted
self.assertFalse(Locale.objects.filter(language_code="en").exists())
# root node's locale should now have been reassigned to 'fr' despite that not matching
# LANGUAGE_CODE (because it's the only remaining Locale record)
self.assertEqual(Page.get_first_root_node().locale.language_code, "fr")
def test_cannot_delete_last_remaining_locale(self):
Page.objects.filter(depth__gt=1).delete()
response = self.post()
self.assertEqual(response.status_code, 200)
# Check error message
messages = list(get_messages(response.wsgi_request))
self.assertEqual(messages[0].level, ERROR)
self.assertEqual(
messages[0].message,
"This locale cannot be deleted because there are no other locales.\n\n\n\n\n",
)
# Check that the locale was not deleted
self.assertTrue(Locale.objects.filter(language_code="en").exists())
class TestAdminPermissions(WagtailTestUtils, TestCase):
def test_registered_permissions(self):
locale_ct = ContentType.objects.get_for_model(Locale)
qs = Permission.objects.none()
for fn in hooks.get_hooks("register_permissions"):
qs |= fn()
registered_permissions = qs.filter(content_type=locale_ct)
self.assertEqual(
set(registered_permissions.values_list("codename", flat=True)),
{"add_locale", "change_locale", "delete_locale"},
)