Add tests for ModelViewSet's usage view

pull/10930/head
Sage Abdullah 2023-09-26 17:29:06 +01:00
rodzic 41abe3342c
commit 2eaa59da24
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: EB1A33CC51CC0217
3 zmienionych plików z 206 dodań i 1 usunięć

Wyświetl plik

@ -3,6 +3,7 @@ from io import BytesIO
from django.conf import settings
from django.contrib.admin.utils import quote
from django.contrib.auth.models import Permission
from django.contrib.contenttypes.models import ContentType
from django.test import TestCase
from django.urls import reverse
@ -10,8 +11,13 @@ from django.utils.formats import date_format
from django.utils.timezone import make_aware
from openpyxl import load_workbook
from wagtail.admin.admin_url_finder import AdminURLFinder
from wagtail.models import ModelLogEntry
from wagtail.test.testapp.models import FeatureCompleteToy, JSONStreamModel
from wagtail.test.testapp.models import (
FeatureCompleteToy,
JSONStreamModel,
VariousOnDeleteModel,
)
from wagtail.test.utils.template_tests import AdminTemplateTestUtils
from wagtail.test.utils.wagtail_tests import WagtailTestUtils
from wagtail.utils.deprecation import RemovedInWagtail60Warning
@ -731,6 +737,30 @@ class TestBreadcrumbs(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
]
self.assertBreadcrumbsItemsRendered(items, response.content)
def test_usage_view(self):
usage_url = reverse(
"feature_complete_toy:usage",
args=(quote(self.object.pk),),
)
response = self.client.get(usage_url)
items = [
{
"url": reverse("feature_complete_toy:index"),
"label": "Feature complete toys",
},
{
"url": reverse(
"feature_complete_toy:edit", args=(quote(self.object.pk),)
),
"label": str(self.object),
},
{
"url": "",
"label": "Usage",
},
]
self.assertBreadcrumbsItemsRendered(items, response.content)
class TestLegacyPatterns(WagtailTestUtils, TestCase):
# RemovedInWagtail60Warning: legacy integer pk-based URLs will be removed
@ -862,3 +892,145 @@ class TestHistoryView(WagtailTestUtils, TestCase):
header = soup.select_one(".w-slim-header")
history_link = header.find("a", attrs={"href": self.url})
self.assertIsNotNone(history_link)
class TestUsageView(WagtailTestUtils, TestCase):
@classmethod
def setUpTestData(cls):
cls.user = cls.create_test_user()
cls.object = FeatureCompleteToy.objects.create(name="Buzz")
cls.url = reverse(
"feature_complete_toy:usage",
args=(quote(cls.object.pk),),
)
cls.tbx = VariousOnDeleteModel.objects.create(
text="Toybox", cascading_toy=cls.object
)
def setUp(self):
self.user = self.login(self.user)
def test_simple(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
soup = self.get_soup(response.content)
h1 = soup.select_one("h1")
self.assertEqual(h1.text.strip(), f"Usage of {self.object}")
tds = soup.select("tbody tr td")
self.assertEqual(len(tds), 3)
self.assertEqual(tds[0].text.strip(), str(self.tbx))
self.assertEqual(tds[1].text.strip(), "Various on delete model")
self.assertEqual(tds[2].text.strip(), "Cascading toy")
tbx_edit_url = AdminURLFinder(self.user).get_edit_url(self.tbx)
# Link to referrer's edit view
link = tds[0].select_one("a")
self.assertIsNotNone(link)
self.assertEqual(link.attrs.get("href"), tbx_edit_url)
# Link to referrer's edit view with parameters for the specific field
link = tds[2].select_one("a")
self.assertIsNotNone(link)
self.assertIn(tbx_edit_url, link.attrs.get("href"))
def test_usage_without_permission(self):
self.user.is_superuser = False
self.user.save()
admin_permission = Permission.objects.get(
content_type__app_label="wagtailadmin", codename="access_admin"
)
self.user.user_permissions.add(admin_permission)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, reverse("wagtailadmin_home"))
def test_usage_without_permission_on_referrer(self):
self.user.is_superuser = False
self.user.save()
admin_permission = Permission.objects.get(
content_type__app_label="wagtailadmin", codename="access_admin"
)
toy_edit_permission = Permission.objects.get(
content_type__app_label="tests", codename="change_featurecompletetoy"
)
self.user.user_permissions.add(admin_permission, toy_edit_permission)
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
soup = self.get_soup(response.content)
h1 = soup.select_one("h1")
self.assertEqual(h1.text.strip(), f"Usage of {self.object}")
tds = soup.select("tbody tr td")
self.assertEqual(len(tds), 3)
self.assertEqual(tds[0].text.strip(), "(Private various on delete model)")
self.assertEqual(tds[1].text.strip(), "Various on delete model")
self.assertEqual(tds[2].text.strip(), "Cascading toy")
# Not link to referrer's edit view
link = tds[0].select_one("a")
self.assertIsNone(link)
# Not link to referrer's edit view
link = tds[2].select_one("a")
self.assertIsNone(link)
def test_usage_with_describe_on_delete(self):
response = self.client.get(self.url + "?describe_on_delete=1")
self.assertEqual(response.status_code, 200)
soup = self.get_soup(response.content)
h1 = soup.select_one("h1")
self.assertEqual(h1.text.strip(), f"Usage of {self.object}")
tds = soup.select("tbody tr td")
self.assertEqual(len(tds), 3)
self.assertEqual(tds[0].text.strip(), str(self.tbx))
self.assertEqual(tds[1].text.strip(), "Various on delete model")
self.assertEqual(
tds[2].text.strip(),
"Cascading toy: the various on delete model will also be deleted",
)
tbx_edit_url = AdminURLFinder(self.user).get_edit_url(self.tbx)
# Link to referrer's edit view
link = tds[0].select_one("a")
self.assertIsNotNone(link)
self.assertEqual(link.attrs.get("href"), tbx_edit_url)
# Link to referrer's edit view with parameters for the specific field
link = tds[2].select_one("a")
self.assertIsNotNone(link)
self.assertIn(tbx_edit_url, link.attrs.get("href"))
def test_empty(self):
self.tbx.delete()
response = self.client.get(self.url)
soup = self.get_soup(response.content)
results = soup.select_one("#listing-results")
table = soup.select_one("table")
self.assertEqual(response.status_code, 200)
self.assertIsNotNone(results)
self.assertEqual(results.text.strip(), "There are no results.")
self.assertIsNone(table)
def test_edit_view_links_to_usage_view(self):
edit_url = reverse("feature_complete_toy:edit", args=(quote(self.object.pk),))
response = self.client.get(edit_url)
soup = self.get_soup(response.content)
side_panel = soup.select_one("[data-side-panel='status']")
usage_link = side_panel.find("a", attrs={"href": self.url})
self.assertIsNotNone(usage_link)
def test_delete_view_links_to_usage_view(self):
edit_url = reverse("feature_complete_toy:delete", args=(quote(self.object.pk),))
response = self.client.get(edit_url)
soup = self.get_soup(response.content)
usage_link = soup.find("a", attrs={"href": self.url + "?describe_on_delete=1"})
self.assertIsNotNone(usage_link)

Wyświetl plik

@ -0,0 +1,25 @@
# Generated by Django 4.2.5 on 2023-09-26 09:29
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("tests", "0028_fullfeaturedsnippet_some_number"),
]
operations = [
migrations.AddField(
model_name="variousondeletemodel",
name="cascading_toy",
field=models.ForeignKey(
blank=True,
null=True,
on_delete=django.db.models.deletion.CASCADE,
related_name="+",
to="tests.featurecompletetoy",
),
),
]

Wyświetl plik

@ -1205,6 +1205,14 @@ class VariousOnDeleteModel(models.Model):
related_name="+",
)
cascading_toy = models.ForeignKey(
"tests.FeatureCompleteToy",
on_delete=models.CASCADE,
null=True,
blank=True,
related_name="+",
)
content_type = models.ForeignKey(
ContentType, on_delete=models.CASCADE, null=True, blank=True
)