Initial commit
This commit is contained in:
509
env/lib/python3.10/site-packages/wagtail/snippets/tests/test_preview.py
vendored
Normal file
509
env/lib/python3.10/site-packages/wagtail/snippets/tests/test_preview.py
vendored
Normal file
@@ -0,0 +1,509 @@
|
||||
import datetime
|
||||
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from freezegun import freeze_time
|
||||
|
||||
from wagtail.admin.views.generic.preview import PreviewOnEdit
|
||||
from wagtail.test.testapp.models import (
|
||||
EventCategory,
|
||||
MultiPreviewModesModel,
|
||||
NonPreviewableModel,
|
||||
PreviewableModel,
|
||||
RevisableModel,
|
||||
)
|
||||
from wagtail.test.utils import WagtailTestUtils
|
||||
|
||||
|
||||
class TestPreview(WagtailTestUtils, TestCase):
|
||||
def setUp(self):
|
||||
self.user = self.login()
|
||||
|
||||
self.meetings_category = EventCategory.objects.create(name="Meetings")
|
||||
self.parties_category = EventCategory.objects.create(name="Parties")
|
||||
self.holidays_category = EventCategory.objects.create(name="Holidays")
|
||||
self.snippet = PreviewableModel.objects.create(text="A previewable snippet")
|
||||
|
||||
self.preview_on_add_url = reverse(
|
||||
"wagtailsnippets_tests_previewablemodel:preview_on_add"
|
||||
)
|
||||
self.preview_on_edit_url = reverse(
|
||||
"wagtailsnippets_tests_previewablemodel:preview_on_edit",
|
||||
args=(self.snippet.pk,),
|
||||
)
|
||||
self.session_key_prefix = "wagtail-preview-tests-previewablemodel"
|
||||
self.edit_session_key = f"{self.session_key_prefix}-{self.snippet.pk}"
|
||||
|
||||
self.post_data = {
|
||||
"text": "An edited previewable snippet",
|
||||
"categories": [self.parties_category.id, self.holidays_category.id],
|
||||
}
|
||||
|
||||
def test_preview_on_create_with_no_session_data(self):
|
||||
self.assertNotIn(self.session_key_prefix, self.client.session)
|
||||
|
||||
response = self.client.get(self.preview_on_add_url)
|
||||
|
||||
# The preview should be unavailable
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "wagtailadmin/generic/preview_error.html")
|
||||
self.assertContains(
|
||||
response,
|
||||
"<title>Preview not available - Wagtail</title>",
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h1 class="preview-error__title">Preview not available</h1>',
|
||||
html=True,
|
||||
)
|
||||
|
||||
def test_preview_on_create_with_invalid_data(self):
|
||||
self.assertNotIn(self.session_key_prefix, self.client.session)
|
||||
|
||||
response = self.client.post(self.preview_on_add_url, {"text": ""})
|
||||
|
||||
# Check the JSON response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{"is_valid": False, "is_available": False},
|
||||
)
|
||||
|
||||
# The invalid data should not be saved in the session
|
||||
self.assertNotIn(self.session_key_prefix, self.client.session)
|
||||
|
||||
response = self.client.get(self.preview_on_add_url)
|
||||
|
||||
# The preview should still be unavailable
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "wagtailadmin/generic/preview_error.html")
|
||||
self.assertContains(
|
||||
response,
|
||||
"<title>Preview not available - Wagtail</title>",
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h1 class="preview-error__title">Preview not available</h1>',
|
||||
html=True,
|
||||
)
|
||||
|
||||
def test_preview_on_create_with_m2m_field(self):
|
||||
response = self.client.post(self.preview_on_add_url, self.post_data)
|
||||
|
||||
# Check the JSON response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{"is_valid": True, "is_available": True},
|
||||
)
|
||||
|
||||
# Check the user can refresh the preview
|
||||
self.assertIn(self.session_key_prefix, self.client.session)
|
||||
|
||||
response = self.client.get(self.preview_on_add_url)
|
||||
|
||||
# Check the HTML response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "tests/previewable_model.html")
|
||||
self.assertContains(response, "An edited previewable snippet")
|
||||
self.assertContains(response, "<li>Parties</li>")
|
||||
self.assertContains(response, "<li>Holidays</li>")
|
||||
|
||||
def test_preview_on_edit_with_m2m_field(self):
|
||||
response = self.client.post(self.preview_on_edit_url, self.post_data)
|
||||
|
||||
# Check the JSON response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{"is_valid": True, "is_available": True},
|
||||
)
|
||||
|
||||
# Check the user can refresh the preview
|
||||
self.assertIn(self.edit_session_key, self.client.session)
|
||||
|
||||
response = self.client.get(self.preview_on_edit_url)
|
||||
|
||||
# Check the HTML response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "tests/previewable_model.html")
|
||||
self.assertContains(response, "An edited previewable snippet")
|
||||
self.assertContains(response, "<li>Parties</li>")
|
||||
self.assertContains(response, "<li>Holidays</li>")
|
||||
|
||||
def test_preview_on_edit_with_valid_then_invalid_data(self):
|
||||
response = self.client.post(self.preview_on_edit_url, self.post_data)
|
||||
|
||||
# Check the JSON response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{"is_valid": True, "is_available": True},
|
||||
)
|
||||
|
||||
# Send an invalid update request
|
||||
response = self.client.post(
|
||||
self.preview_on_edit_url, {**self.post_data, "text": ""}
|
||||
)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{"is_valid": False, "is_available": True},
|
||||
)
|
||||
|
||||
# Check the user can still see the preview with the last valid data
|
||||
self.assertIn(self.edit_session_key, self.client.session)
|
||||
|
||||
response = self.client.get(self.preview_on_edit_url)
|
||||
|
||||
# Check the HTML response
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "tests/previewable_model.html")
|
||||
self.assertContains(response, "An edited previewable snippet")
|
||||
self.assertContains(response, "<li>Parties</li>")
|
||||
self.assertContains(response, "<li>Holidays</li>")
|
||||
|
||||
def test_preview_on_edit_expiry(self):
|
||||
initial_datetime = timezone.now()
|
||||
expiry_datetime = initial_datetime + datetime.timedelta(
|
||||
seconds=PreviewOnEdit.preview_expiration_timeout + 1
|
||||
)
|
||||
|
||||
new_snippet = PreviewableModel.objects.create(text="A new previewable snippet")
|
||||
|
||||
with freeze_time(initial_datetime) as frozen_datetime:
|
||||
response = self.client.post(self.preview_on_edit_url, self.post_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(self.preview_on_edit_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
frozen_datetime.move_to(expiry_datetime)
|
||||
|
||||
preview_url = reverse(
|
||||
"wagtailsnippets_tests_previewablemodel:preview_on_edit",
|
||||
args=(new_snippet.pk,),
|
||||
)
|
||||
|
||||
response = self.client.post(preview_url, self.post_data)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
response = self.client.get(preview_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Stale preview data should be removed from the session
|
||||
self.assertNotIn(self.edit_session_key, self.client.session)
|
||||
self.assertIn(
|
||||
f"{self.session_key_prefix}-{new_snippet.pk}",
|
||||
self.client.session,
|
||||
)
|
||||
|
||||
def test_preview_on_create_clear_preview_data(self):
|
||||
# Set a fake preview session data for the page
|
||||
self.client.session[self.session_key_prefix] = "test data"
|
||||
|
||||
response = self.client.delete(self.preview_on_add_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{"success": True},
|
||||
)
|
||||
|
||||
# The data should no longer exist in the session
|
||||
self.assertNotIn(self.session_key_prefix, self.client.session)
|
||||
|
||||
response = self.client.get(self.preview_on_add_url)
|
||||
|
||||
# The preview should be unavailable
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "wagtailadmin/generic/preview_error.html")
|
||||
self.assertContains(
|
||||
response,
|
||||
"<title>Preview not available - Wagtail</title>",
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h1 class="preview-error__title">Preview not available</h1>',
|
||||
html=True,
|
||||
)
|
||||
|
||||
def test_preview_on_edit_clear_preview_data(self):
|
||||
# Set a fake preview session data for the page
|
||||
self.client.session[self.edit_session_key] = "test data"
|
||||
|
||||
response = self.client.delete(self.preview_on_edit_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertJSONEqual(
|
||||
response.content.decode(),
|
||||
{"success": True},
|
||||
)
|
||||
|
||||
# The data should no longer exist in the session
|
||||
self.assertNotIn(self.edit_session_key, self.client.session)
|
||||
|
||||
response = self.client.get(self.preview_on_edit_url)
|
||||
|
||||
# The preview should be unavailable
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, "wagtailadmin/generic/preview_error.html")
|
||||
self.assertContains(
|
||||
response,
|
||||
"<title>Preview not available - Wagtail</title>",
|
||||
html=True,
|
||||
)
|
||||
self.assertContains(
|
||||
response,
|
||||
'<h1 class="preview-error__title">Preview not available</h1>',
|
||||
html=True,
|
||||
)
|
||||
|
||||
def test_preview_revision(self):
|
||||
snippet = MultiPreviewModesModel.objects.create(text="Multiple modes")
|
||||
revision = snippet.save_revision(log_action=True)
|
||||
response = self.client.get(
|
||||
reverse(
|
||||
"wagtailsnippets_tests_multipreviewmodesmodel:revisions_view",
|
||||
args=(snippet.pk, revision.id),
|
||||
)
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Should respect the default_preview_mode
|
||||
self.assertTemplateUsed(response, "tests/previewable_model_alt.html")
|
||||
self.assertContains(response, "Multiple modes (Alternate Preview)")
|
||||
|
||||
|
||||
class TestEnablePreview(WagtailTestUtils, TestCase):
|
||||
def setUp(self):
|
||||
self.user = self.login()
|
||||
self.single = PreviewableModel.objects.create(text="Single preview mode")
|
||||
self.multiple = MultiPreviewModesModel.objects.create(
|
||||
text="Multiple preview modes"
|
||||
)
|
||||
|
||||
def get_url(self, snippet, name, args=None):
|
||||
model_name = type(snippet)._meta.model_name
|
||||
return reverse(f"wagtailsnippets_tests_{model_name}:{name}", args=args)
|
||||
|
||||
def test_show_preview_panel_on_create_with_single_mode(self):
|
||||
create_url = self.get_url(self.single, "add")
|
||||
preview_url = self.get_url(self.single, "preview_on_add")
|
||||
new_tab_url = preview_url + "?mode="
|
||||
response = self.client.get(create_url)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Should show the preview panel
|
||||
self.assertContains(response, 'data-side-panel="preview"')
|
||||
self.assertContains(response, 'data-action="%s"' % preview_url)
|
||||
|
||||
# Should have the preview side panel toggle button
|
||||
soup = self.get_soup(response.content)
|
||||
toggle_button = soup.find("button", {"data-side-panel-toggle": "preview"})
|
||||
self.assertIsNotNone(toggle_button)
|
||||
self.assertEqual("w-tooltip w-kbd", toggle_button["data-controller"])
|
||||
self.assertEqual("mod+p", toggle_button["data-w-kbd-key-value"])
|
||||
|
||||
# Should show the iframe
|
||||
self.assertContains(
|
||||
response,
|
||||
'<iframe id="preview-iframe" loading="lazy" title="Preview" class="preview-panel__iframe" data-preview-iframe aria-describedby="preview-panel-error-banner">',
|
||||
)
|
||||
|
||||
# Should show the new tab button with the default mode set
|
||||
self.assertContains(response, f'href="{new_tab_url}" target="_blank"')
|
||||
|
||||
# Should not show the preview mode selection
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<select id="id_preview_mode" name="preview_mode" class="preview-panel__mode-select" data-preview-mode-select>',
|
||||
)
|
||||
|
||||
def test_show_preview_panel_on_create_with_multiple_modes(self):
|
||||
create_url = self.get_url(self.multiple, "add")
|
||||
preview_url = self.get_url(self.multiple, "preview_on_add")
|
||||
new_tab_url = preview_url + "?mode=alt%231"
|
||||
response = self.client.get(create_url)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Should show the preview panel
|
||||
self.assertContains(response, 'data-side-panel-toggle="preview"')
|
||||
self.assertContains(response, 'data-side-panel="preview"')
|
||||
self.assertContains(response, 'data-action="%s"' % preview_url)
|
||||
|
||||
# Should show the iframe
|
||||
self.assertContains(
|
||||
response,
|
||||
'<iframe id="preview-iframe" loading="lazy" title="Preview" class="preview-panel__iframe" data-preview-iframe aria-describedby="preview-panel-error-banner">',
|
||||
)
|
||||
|
||||
# Should show the new tab button with the default mode set and correctly quoted
|
||||
self.assertContains(response, f'href="{new_tab_url}" target="_blank"')
|
||||
|
||||
# should show the preview mode selection
|
||||
self.assertContains(
|
||||
response,
|
||||
'<select id="id_preview_mode" name="preview_mode" class="preview-panel__mode-select" data-preview-mode-select>',
|
||||
)
|
||||
self.assertContains(response, '<option value="">Normal</option>')
|
||||
|
||||
# Should respect the default_preview_mode
|
||||
self.assertContains(
|
||||
response, '<option value="alt#1" selected>Alternate</option>'
|
||||
)
|
||||
|
||||
def test_show_preview_panel_on_edit_with_single_mode(self):
|
||||
edit_url = self.get_url(self.single, "edit", args=(self.single.pk,))
|
||||
preview_url = self.get_url(
|
||||
self.single, "preview_on_edit", args=(self.multiple.pk,)
|
||||
)
|
||||
new_tab_url = preview_url + "?mode="
|
||||
response = self.client.get(edit_url)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Should show the preview panel
|
||||
self.assertContains(response, 'data-side-panel-toggle="preview"')
|
||||
self.assertContains(response, 'data-side-panel="preview"')
|
||||
self.assertContains(response, 'data-action="%s"' % preview_url)
|
||||
|
||||
# Should show the iframe
|
||||
self.assertContains(
|
||||
response,
|
||||
'<iframe id="preview-iframe" loading="lazy" title="Preview" class="preview-panel__iframe" data-preview-iframe aria-describedby="preview-panel-error-banner">',
|
||||
)
|
||||
|
||||
# Should show the new tab button with the default mode set
|
||||
self.assertContains(response, f'href="{new_tab_url}" target="_blank"')
|
||||
|
||||
# Should not show the preview mode selection
|
||||
self.assertNotContains(
|
||||
response,
|
||||
'<select id="id_preview_mode" name="preview_mode" class="preview-panel__mode-select" data-preview-mode-select>',
|
||||
)
|
||||
|
||||
def test_show_preview_panel_on_edit_with_multiple_modes(self):
|
||||
edit_url = self.get_url(self.multiple, "edit", args=(self.multiple.pk,))
|
||||
preview_url = self.get_url(
|
||||
self.multiple, "preview_on_edit", args=(self.multiple.pk,)
|
||||
)
|
||||
new_tab_url = preview_url + "?mode=alt%231"
|
||||
response = self.client.get(edit_url)
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
# Should show the preview panel
|
||||
self.assertContains(response, 'data-side-panel-toggle="preview"')
|
||||
self.assertContains(response, 'data-side-panel="preview"')
|
||||
self.assertContains(response, 'data-action="%s"' % preview_url)
|
||||
|
||||
# Should show the iframe
|
||||
self.assertContains(
|
||||
response,
|
||||
'<iframe id="preview-iframe" loading="lazy" title="Preview" class="preview-panel__iframe" data-preview-iframe aria-describedby="preview-panel-error-banner">',
|
||||
)
|
||||
|
||||
# Should show the new tab button with the default mode set and correctly quoted
|
||||
self.assertContains(response, f'href="{new_tab_url}" target="_blank"')
|
||||
|
||||
# should show the preview mode selection
|
||||
self.assertContains(
|
||||
response,
|
||||
'<select id="id_preview_mode" name="preview_mode" class="preview-panel__mode-select" data-preview-mode-select>',
|
||||
)
|
||||
self.assertContains(response, '<option value="">Normal</option>')
|
||||
|
||||
# Should respect the default_preview_mode
|
||||
self.assertContains(
|
||||
response, '<option value="alt#1" selected>Alternate</option>'
|
||||
)
|
||||
|
||||
def test_show_preview_on_revisions_list(self):
|
||||
latest_revision = self.multiple.save_revision(log_action=True)
|
||||
history_url = self.get_url(self.multiple, "history", args=(self.multiple.pk,))
|
||||
preview_url = self.get_url(
|
||||
self.multiple,
|
||||
"revisions_view",
|
||||
args=(self.multiple.pk, latest_revision.id),
|
||||
)
|
||||
|
||||
response = self.client.get(history_url)
|
||||
self.assertContains(response, "Preview")
|
||||
self.assertContains(response, preview_url)
|
||||
|
||||
|
||||
class TestDisablePreviewWithEmptyModes(WagtailTestUtils, TestCase):
|
||||
"""
|
||||
Preview can be disabled by setting preview_modes to an empty list.
|
||||
"""
|
||||
|
||||
# NonPreviewableModel has preview_modes = []
|
||||
model = NonPreviewableModel
|
||||
|
||||
def setUp(self):
|
||||
self.user = self.login()
|
||||
self.snippet = self.model.objects.create(text="A non-previewable snippet")
|
||||
self.model_name = self.model._meta.model_name
|
||||
|
||||
def get_url(self, name, args=None):
|
||||
return reverse(f"wagtailsnippets_tests_{self.model_name}:{name}", args=args)
|
||||
|
||||
def test_disable_preview_on_create(self):
|
||||
response = self.client.get(self.get_url("add"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
preview_url = self.get_url("preview_on_add")
|
||||
self.assertNotContains(response, 'data-side-panel-toggle="preview"')
|
||||
self.assertNotContains(response, 'data-side-panel="preview"')
|
||||
self.assertNotContains(response, 'data-action="%s"' % preview_url)
|
||||
|
||||
def test_disable_preview_on_edit(self):
|
||||
response = self.client.get(self.get_url("edit", args=(self.snippet.pk,)))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
preview_url = self.get_url("preview_on_edit", args=(self.snippet.pk,))
|
||||
self.assertNotContains(response, 'data-side-panel-toggle="preview"')
|
||||
self.assertNotContains(response, 'data-side-panel="preview"')
|
||||
self.assertNotContains(response, 'data-action="%s"' % preview_url)
|
||||
|
||||
def test_disable_preview_on_revisions_list(self):
|
||||
latest_revision = self.snippet.save_revision(log_action=True)
|
||||
|
||||
response = self.client.get(self.get_url("history", args=(self.snippet.pk,)))
|
||||
preview_url = self.get_url(
|
||||
"revisions_view", args=(self.snippet.pk, latest_revision.id)
|
||||
)
|
||||
|
||||
self.assertNotContains(response, preview_url)
|
||||
|
||||
soup = self.get_soup(response.content)
|
||||
|
||||
preview_link = soup.find("a", {"href": preview_url})
|
||||
self.assertIsNone(preview_link)
|
||||
|
||||
|
||||
class TestDisablePreviewWithoutMixin(TestDisablePreviewWithEmptyModes):
|
||||
"""
|
||||
Preview can be disabled by not extending PreviewableMixin.
|
||||
"""
|
||||
|
||||
# RevisableModel does not extend PreviewableMixin
|
||||
model = RevisableModel
|
||||
|
||||
def get_url(self, name, args=None):
|
||||
# Cannot use reverse() as the urls are not registered
|
||||
# if the model does not extend PreviewableMixin
|
||||
if name == "preview_on_add":
|
||||
return f"/admin/snippets/tests/{self.model_name}/preview/"
|
||||
if name == "preview_on_edit":
|
||||
return f"/admin/snippets/tests/{self.model_name}/preview/{args[0]}/"
|
||||
if name == "revisions_view":
|
||||
return (
|
||||
f"/admin/snippets/tests/{self.model_name}/history/"
|
||||
f"{args[0]}/revisions/{args[1]}/view/"
|
||||
)
|
||||
return super().get_url(name, args)
|
||||
Reference in New Issue
Block a user