Move frontend cache purging to task

pull/12787/head
Jake Howard 2024-06-13 10:42:51 +01:00 zatwierdzone przez Matt Westcott
rodzic 65d3b34698
commit 79d129f8c2
8 zmienionych plików z 338 dodań i 282 usunięć

Wyświetl plik

@ -605,11 +605,13 @@ class TestDocumentCacheInvalidation(TestCase):
signal_handlers.unregister_signal_handlers()
def test_resave_document_purges(self, purge):
get_document_model().objects.get(id=5).save()
with self.captureOnCommitCallbacks(execute=True):
get_document_model().objects.get(id=5).save()
purge.assert_any_call("http://api.example.com/api/main/documents/5/")
def test_delete_document_purges(self, purge):
get_document_model().objects.get(id=5).delete()
with self.captureOnCommitCallbacks(execute=True):
get_document_model().objects.get(id=5).delete()
purge.assert_any_call("http://api.example.com/api/main/documents/5/")

Wyświetl plik

@ -597,11 +597,13 @@ class TestImageCacheInvalidation(TestCase):
signal_handlers.unregister_signal_handlers()
def test_resave_image_purges(self, purge):
get_image_model().objects.get(id=5).save()
with self.captureOnCommitCallbacks(execute=True):
get_image_model().objects.get(id=5).save()
purge.assert_any_call("http://api.example.com/api/main/images/5/")
def test_delete_image_purges(self, purge):
get_image_model().objects.get(id=5).delete()
with self.captureOnCommitCallbacks(execute=True):
get_image_model().objects.get(id=5).delete()
purge.assert_any_call("http://api.example.com/api/main/images/5/")

Wyświetl plik

@ -1886,22 +1886,26 @@ class TestPageCacheInvalidation(TestCase):
signal_handlers.unregister_signal_handlers()
def test_republish_page_purges(self, purge):
Page.objects.get(id=2).specific.save_revision().publish()
with self.captureOnCommitCallbacks(execute=True):
Page.objects.get(id=2).specific.save_revision().publish()
purge.assert_any_call("http://api.example.com/api/main/pages/2/")
def test_unpublish_page_purges(self, purge):
Page.objects.get(id=2).unpublish()
with self.captureOnCommitCallbacks(execute=True):
Page.objects.get(id=2).unpublish()
purge.assert_any_call("http://api.example.com/api/main/pages/2/")
def test_delete_page_purges(self, purge):
Page.objects.get(id=16).delete()
with self.captureOnCommitCallbacks(execute=True):
Page.objects.get(id=16).delete()
purge.assert_any_call("http://api.example.com/api/main/pages/16/")
def test_save_draft_doesnt_purge(self, purge):
Page.objects.get(id=2).specific.save_revision()
with self.captureOnCommitCallbacks(execute=True):
Page.objects.get(id=2).specific.save_revision()
purge.assert_not_called()

Wyświetl plik

@ -0,0 +1,83 @@
import logging
import re
from collections import defaultdict
from urllib.parse import urlsplit, urlunsplit
from django.conf import settings
from django_tasks import task
from wagtail.coreutils import get_content_languages
from .utils import get_backends
logger = logging.getLogger("wagtail.frontendcache")
@task()
def purge_urls_from_cache_task(urls, backend_settings=None, backends=None):
if not urls:
return
backends = get_backends(backend_settings, backends)
# If no backends are configured, there's nothing to do
if not backends:
return
# Convert each url to urls one for each managed language (WAGTAILFRONTENDCACHE_LANGUAGES setting).
# The managed languages are common to all the defined backends.
# This depends on settings.USE_I18N
# If WAGTAIL_I18N_ENABLED is True, this defaults to WAGTAIL_CONTENT_LANGUAGES
wagtail_i18n_enabled = getattr(settings, "WAGTAIL_I18N_ENABLED", False)
content_languages = get_content_languages() if wagtail_i18n_enabled else {}
languages = getattr(
settings, "WAGTAILFRONTENDCACHE_LANGUAGES", list(content_languages.keys())
)
if settings.USE_I18N and languages:
langs_regex = "^/(%s)/" % "|".join(languages)
new_urls = []
# Purge the given url for each managed language
for isocode in languages:
for url in urls:
up = urlsplit(url)
new_url = urlunsplit(
(
up.scheme,
up.netloc,
re.sub(langs_regex, "/%s/" % isocode, up.path),
up.query,
up.fragment,
)
)
# Check for best performance. True if re.sub found no match
# It happens when i18n_patterns was not used in urls.py to serve content for different languages from different URLs
if new_url in new_urls:
continue
new_urls.append(new_url)
urls = new_urls
urls_by_hostname = defaultdict(list)
for url in urls:
urls_by_hostname[urlsplit(url).netloc].append(url)
for hostname, urls in urls_by_hostname.items():
backends_for_hostname = {
backend_name: backend
for backend_name, backend in backends.items()
if backend.invalidates_hostname(hostname)
}
if not backends_for_hostname:
logger.info("Unable to find purge backend for %s", hostname)
continue
for backend_name, backend in backends_for_hostname.items():
for url in urls:
logger.info("[%s] Purging URL: %s", backend_name, url)
backend.purge_batch(urls)

Wyświetl plik

@ -447,32 +447,37 @@ class TestCachePurgingFunctions(TestCase):
PURGED_URLS.clear()
def test_purge_url_from_cache(self):
purge_url_from_cache("http://localhost/foo")
with self.captureOnCommitCallbacks(execute=True):
purge_url_from_cache("http://localhost/foo")
self.assertEqual(PURGED_URLS, {"http://localhost/foo"})
def test_purge_urls_from_cache(self):
purge_urls_from_cache(["http://localhost/foo", "http://localhost/bar"])
with self.captureOnCommitCallbacks(execute=True):
purge_urls_from_cache(["http://localhost/foo", "http://localhost/bar"])
self.assertEqual(PURGED_URLS, {"http://localhost/foo", "http://localhost/bar"})
def test_purge_page_from_cache(self):
page = EventIndex.objects.get(url_path="/home/events/")
purge_page_from_cache(page)
with self.captureOnCommitCallbacks(execute=True):
page = EventIndex.objects.get(url_path="/home/events/")
purge_page_from_cache(page)
self.assertEqual(
PURGED_URLS, {"http://localhost/events/", "http://localhost/events/past/"}
)
def test_purge_pages_from_cache(self):
purge_pages_from_cache(EventIndex.objects.all())
with self.captureOnCommitCallbacks(execute=True):
purge_pages_from_cache(EventIndex.objects.all())
self.assertEqual(
PURGED_URLS, {"http://localhost/events/", "http://localhost/events/past/"}
)
def test_purge_batch(self):
batch = PurgeBatch()
page = EventIndex.objects.get(url_path="/home/events/")
batch.add_page(page)
batch.add_url("http://localhost/foo")
batch.purge()
with self.captureOnCommitCallbacks(execute=True):
batch = PurgeBatch()
page = EventIndex.objects.get(url_path="/home/events/")
batch.add_page(page)
batch.add_url("http://localhost/foo")
batch.purge()
self.assertEqual(
PURGED_URLS,
@ -493,7 +498,8 @@ class TestCachePurgingFunctions(TestCase):
)
def test_invalidate_specific_location(self):
with self.assertLogs(level="INFO") as log_output:
purge_url_from_cache("http://localhost/foo")
with self.captureOnCommitCallbacks(execute=True):
purge_url_from_cache("http://localhost/foo")
self.assertEqual(PURGED_URLS, set())
self.assertIn(
@ -501,7 +507,8 @@ class TestCachePurgingFunctions(TestCase):
log_output.output[0],
)
purge_url_from_cache("http://example.com/foo")
with self.captureOnCommitCallbacks(execute=True):
purge_url_from_cache("http://example.com/foo")
self.assertEqual(PURGED_URLS, {"http://example.com/foo"})
@ -520,10 +527,11 @@ class TestCloudflareCachePurgingFunctions(TestCase):
PURGED_URLS.clear()
def test_cloudflare_purge_batch_chunked(self):
batch = PurgeBatch()
urls = [f"https://localhost/foo{i}" for i in range(1, 65)]
batch.add_urls(urls)
batch.purge()
with self.captureOnCommitCallbacks(execute=True):
batch = PurgeBatch()
urls = [f"https://localhost/foo{i}" for i in range(1, 65)]
batch.add_urls(urls)
batch.purge()
self.assertCountEqual(PURGED_URLS, set(urls))
@ -543,24 +551,27 @@ class TestCachePurgingSignals(TestCase):
PURGED_URLS.clear()
def test_purge_on_publish(self):
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
with self.captureOnCommitCallbacks(execute=True):
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
self.assertEqual(
PURGED_URLS, {"http://localhost/events/", "http://localhost/events/past/"}
)
def test_purge_on_unpublish(self):
page = EventIndex.objects.get(url_path="/home/events/")
page.unpublish()
with self.captureOnCommitCallbacks(execute=True):
page = EventIndex.objects.get(url_path="/home/events/")
page.unpublish()
self.assertEqual(
PURGED_URLS, {"http://localhost/events/", "http://localhost/events/past/"}
)
def test_purge_with_unroutable_page(self):
root = Page.objects.get(url_path="/")
page = EventIndex(title="new top-level page")
root.add_child(instance=page)
page.save_revision().publish()
with self.captureOnCommitCallbacks(execute=True):
root = Page.objects.get(url_path="/")
page = EventIndex(title="new top-level page")
root.add_child(instance=page)
page.save_revision().publish()
self.assertEqual(PURGED_URLS, set())
@override_settings(
@ -569,8 +580,9 @@ class TestCachePurgingSignals(TestCase):
WAGTAILFRONTENDCACHE_LANGUAGES=["en", "fr", "pt-br"],
)
def test_purge_on_publish_in_multilang_env(self):
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
with self.captureOnCommitCallbacks(execute=True):
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
self.assertEqual(
PURGED_URLS,
@ -591,8 +603,9 @@ class TestCachePurgingSignals(TestCase):
WAGTAIL_CONTENT_LANGUAGES=[("en", "English"), ("fr", "French")],
)
def test_purge_on_publish_with_i18n_enabled(self):
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
with self.captureOnCommitCallbacks(execute=True):
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
self.assertEqual(
PURGED_URLS,
@ -610,9 +623,10 @@ class TestCachePurgingSignals(TestCase):
WAGTAIL_CONTENT_LANGUAGES=[("en", "English"), ("fr", "French")],
)
def test_purge_on_publish_without_i18n_enabled(self):
# It should ignore WAGTAIL_CONTENT_LANGUAGES as WAGTAIL_I18N_ENABLED isn't set
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
with self.captureOnCommitCallbacks(execute=True):
# It should ignore WAGTAIL_CONTENT_LANGUAGES as WAGTAIL_I18N_ENABLED isn't set
page = EventIndex.objects.get(url_path="/home/events/")
page.save_revision().publish()
self.assertEqual(
PURGED_URLS,
{"http://localhost/en/events/", "http://localhost/en/events/past/"},
@ -696,7 +710,8 @@ class TestPurgeBatchClass(TestCase):
batch.add_url("http://localhost/events/")
with self.assertLogs(level="ERROR") as log_output:
batch.purge(backend_settings=backend_settings)
with self.captureOnCommitCallbacks(execute=True):
batch.purge(backend_settings=backend_settings)
self.assertIn(
"Couldn't purge 'http://localhost/events/' from Cloudflare. HTTPError: 500",

Wyświetl plik

@ -1,14 +1,9 @@
import logging
import re
from collections import defaultdict
from urllib.parse import urlsplit, urlunsplit
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.utils.module_loading import import_string
from wagtail.coreutils import get_content_languages
logger = logging.getLogger("wagtail.frontendcache")
@ -64,72 +59,9 @@ def purge_url_from_cache(url, backend_settings=None, backends=None):
def purge_urls_from_cache(urls, backend_settings=None, backends=None):
if not urls:
return
from .tasks import purge_urls_from_cache_task
backends = get_backends(backend_settings, backends)
# If no backends are configured, there's nothing to do
if not backends:
return
# Convert each url to urls one for each managed language (WAGTAILFRONTENDCACHE_LANGUAGES setting).
# The managed languages are common to all the defined backends.
# This depends on settings.USE_I18N
# If WAGTAIL_I18N_ENABLED is True, this defaults to WAGTAIL_CONTENT_LANGUAGES
wagtail_i18n_enabled = getattr(settings, "WAGTAIL_I18N_ENABLED", False)
content_languages = get_content_languages() if wagtail_i18n_enabled else {}
languages = getattr(
settings, "WAGTAILFRONTENDCACHE_LANGUAGES", list(content_languages.keys())
)
if settings.USE_I18N and languages:
langs_regex = "^/(%s)/" % "|".join(languages)
new_urls = []
# Purge the given url for each managed language
for isocode in languages:
for url in urls:
up = urlsplit(url)
new_url = urlunsplit(
(
up.scheme,
up.netloc,
re.sub(langs_regex, "/%s/" % isocode, up.path),
up.query,
up.fragment,
)
)
# Check for best performance. True if re.sub found no match
# It happens when i18n_patterns was not used in urls.py to serve content for different languages from different URLs
if new_url in new_urls:
continue
new_urls.append(new_url)
urls = new_urls
urls_by_hostname = defaultdict(list)
for url in urls:
urls_by_hostname[urlsplit(url).netloc].append(url)
for hostname, urls in urls_by_hostname.items():
backends_for_hostname = {
backend_name: backend
for backend_name, backend in backends.items()
if backend.invalidates_hostname(hostname)
}
if not backends_for_hostname:
logger.info("Unable to find purge backend for %s", hostname)
continue
for backend_name, backend in backends_for_hostname.items():
for url in urls:
logger.info("[%s] Purging URL: %s", backend_name, url)
backend.purge_batch(urls)
purge_urls_from_cache_task.enqueue(list(urls), backend_settings, backends)
def _get_page_cached_urls(page):

Wyświetl plik

@ -801,14 +801,15 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
self.assertTemplateUsed(response, "wagtailredirects/add.html")
def test_add(self):
response = self.post(
{
"old_path": "/test",
"site": "",
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
with self.captureOnCommitCallbacks(execute=True):
response = self.post(
{
"old_path": "/test",
"site": "",
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtailredirects:index"))
@ -827,15 +828,16 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
self.assertEqual(PURGED_URLS, {"http://localhost/test"})
def test_add_with_site(self):
localhost = Site.objects.get(hostname="localhost")
response = self.post(
{
"old_path": "/test",
"site": localhost.id,
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
with self.captureOnCommitCallbacks(execute=True):
localhost = Site.objects.get(hostname="localhost")
response = self.post(
{
"old_path": "/test",
"site": localhost.id,
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtailredirects:index"))
@ -849,72 +851,76 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
self.assertEqual(PURGED_URLS, {"http://localhost/test"})
def test_add_validation_error(self):
response = self.post(
{
"old_path": "",
"site": "",
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
with self.captureOnCommitCallbacks(execute=True):
response = self.post(
{
"old_path": "",
"site": "",
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
# Should not redirect to index
self.assertEqual(response.status_code, 200)
self.assertEqual(PURGED_URLS, set())
def test_cannot_add_duplicate_with_no_site(self):
models.Redirect.objects.create(
old_path="/test", site=None, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/test",
"site": "",
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
with self.captureOnCommitCallbacks(execute=True):
models.Redirect.objects.create(
old_path="/test", site=None, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/test",
"site": "",
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
# Should not redirect to index
self.assertEqual(response.status_code, 200)
self.assertEqual(PURGED_URLS, set())
def test_cannot_add_duplicate_on_same_site(self):
localhost = Site.objects.get(hostname="localhost")
models.Redirect.objects.create(
old_path="/test", site=localhost, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/test",
"site": localhost.pk,
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
with self.captureOnCommitCallbacks(execute=True):
localhost = Site.objects.get(hostname="localhost")
models.Redirect.objects.create(
old_path="/test", site=localhost, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/test",
"site": localhost.pk,
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
# Should not redirect to index
self.assertEqual(response.status_code, 200)
self.assertEqual(PURGED_URLS, set())
def test_can_reuse_path_on_other_site(self):
localhost = Site.objects.get(hostname="localhost")
contact_page = Page.objects.get(url_path="/home/contact-us/")
other_site = Site.objects.create(
hostname="other.example.com", port=80, root_page=contact_page
)
with self.captureOnCommitCallbacks(execute=True):
localhost = Site.objects.get(hostname="localhost")
contact_page = Page.objects.get(url_path="/home/contact-us/")
other_site = Site.objects.create(
hostname="other.example.com", port=80, root_page=contact_page
)
models.Redirect.objects.create(
old_path="/test", site=localhost, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/test",
"site": other_site.pk,
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
models.Redirect.objects.create(
old_path="/test", site=localhost, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/test",
"site": other_site.pk,
"is_permanent": "on",
"redirect_link": "http://www.test.com/",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtailredirects:index"))
@ -926,14 +932,15 @@ class TestRedirectsAddView(WagtailTestUtils, TestCase):
self.assertEqual(PURGED_URLS, redirects.get().old_links())
def test_add_long_redirect(self):
response = self.post(
{
"old_path": "/test",
"site": "",
"is_permanent": "on",
"redirect_link": "https://www.google.com/search?q=this+is+a+very+long+url+because+it+has+a+huge+search+term+appended+to+the+end+of+it+even+though+someone+should+really+not+be+doing+something+so+crazy+without+first+seeing+a+psychiatrist",
}
)
with self.captureOnCommitCallbacks(execute=True):
response = self.post(
{
"old_path": "/test",
"site": "",
"is_permanent": "on",
"redirect_link": "https://www.google.com/search?q=this+is+a+very+long+url+because+it+has+a+huge+search+term+appended+to+the+end+of+it+even+though+someone+should+really+not+be+doing+something+so+crazy+without+first+seeing+a+psychiatrist",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtailredirects:index"))
@ -1002,14 +1009,15 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
self.assertEqual(self.get(redirect_id=100000).status_code, 404)
def test_edit(self):
response = self.post(
{
"old_path": "/test",
"is_permanent": "on",
"site": "",
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
with self.captureOnCommitCallbacks(execute=True):
response = self.post(
{
"old_path": "/test",
"is_permanent": "on",
"site": "",
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtailredirects:index"))
@ -1025,16 +1033,17 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
self.assertEqual(PURGED_URLS, {"http://localhost/test"})
def test_edit_with_site(self):
localhost = Site.objects.get(hostname="localhost")
with self.captureOnCommitCallbacks(execute=True):
localhost = Site.objects.get(hostname="localhost")
response = self.post(
{
"old_path": "/test",
"is_permanent": "on",
"site": localhost.id,
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
response = self.post(
{
"old_path": "/test",
"is_permanent": "on",
"site": localhost.id,
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
# Should redirect back to index
self.assertRedirects(response, reverse("wagtailredirects:index"))
@ -1049,31 +1058,33 @@ class TestRedirectsEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase):
self.assertEqual(PURGED_URLS, {"http://localhost/test"})
def test_edit_validation_error(self):
response = self.post(
{
"old_path": "",
"is_permanent": "on",
"site": "",
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
with self.captureOnCommitCallbacks(execute=True):
response = self.post(
{
"old_path": "",
"is_permanent": "on",
"site": "",
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
# Should not redirect to index
self.assertEqual(response.status_code, 200)
self.assertEqual(PURGED_URLS, set())
def test_edit_duplicate(self):
models.Redirect.objects.create(
old_path="/othertest", site=None, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/othertest",
"is_permanent": "on",
"site": "",
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
with self.captureOnCommitCallbacks(execute=True):
models.Redirect.objects.create(
old_path="/othertest", site=None, redirect_link="http://elsewhere.com/"
)
response = self.post(
{
"old_path": "/othertest",
"is_permanent": "on",
"site": "",
"redirect_link": "http://www.test.com/ive-been-edited",
}
)
# Should not redirect to index
self.assertEqual(response.status_code, 200)
@ -1153,7 +1164,8 @@ class TestRedirectsDeleteView(WagtailTestUtils, TestCase):
self.assertEqual(self.get(redirect_id=100000).status_code, 404)
def test_delete(self):
response = self.post()
with self.captureOnCommitCallbacks(execute=True):
response = self.post()
# Should redirect back to index
self.assertRedirects(response, reverse("wagtailredirects:index"))

Wyświetl plik

@ -41,28 +41,29 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
page.save(log_action="wagtail.publish", user=self.user, clean=False)
def test_golden_path(self):
# the page we'll be triggering the change for here is...
test_subject = self.event_index
with self.captureOnCommitCallbacks(execute=True):
# the page we'll be triggering the change for here is...
test_subject = self.event_index
# identify 'draft' pages in this section
drafts = test_subject.get_descendants().not_live()
self.assertEqual(len(drafts), 4)
# identify 'draft' pages in this section
drafts = test_subject.get_descendants().not_live()
self.assertEqual(len(drafts), 4)
# gather urls for 'live' pages in this branch
request = get_dummy_request()
branch_urls = []
for page in (
test_subject.get_descendants(inclusive=True)
.live()
.specific(defer=True)
.iterator()
):
main_url = page.get_url(request).rstrip("/")
branch_urls.extend(
main_url + path.rstrip("/") for path in page.get_cached_paths()
)
# gather urls for 'live' pages in this branch
request = get_dummy_request()
branch_urls = []
for page in (
test_subject.get_descendants(inclusive=True)
.live()
.specific(defer=True)
.iterator()
):
main_url = page.get_url(request).rstrip("/")
branch_urls.extend(
main_url + path.rstrip("/") for path in page.get_cached_paths()
)
self.trigger_page_slug_changed_signal(test_subject)
self.trigger_page_slug_changed_signal(test_subject)
# gather all of the redirects that were created
redirects = Redirect.objects.all()
@ -97,32 +98,34 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
)
def test_no_redirects_created_when_page_is_root_for_all_sites_it_belongs_to(self):
self.trigger_page_slug_changed_signal(self.home_page)
with self.captureOnCommitCallbacks(execute=True):
self.trigger_page_slug_changed_signal(self.home_page)
self.assertFalse(Redirect.objects.exists())
self.assertEqual(len(PURGED_URLS), 0)
def test_handling_of_existing_redirects(self):
# the page we'll be triggering the change for here is...
test_subject = self.event_index
with self.captureOnCommitCallbacks(execute=True):
# the page we'll be triggering the change for here is...
test_subject = self.event_index
descendants = test_subject.get_descendants().live()
descendants = test_subject.get_descendants().live()
# but before we do, let's add some redirects that we'll expect to conflict
# with ones created by the signal handler
redirect1 = Redirect.objects.create(
old_path=Redirect.normalise_path(descendants.first().specific.url),
site=self.site,
redirect_link="/some-place",
automatically_created=False,
)
redirect2 = Redirect.objects.create(
old_path=Redirect.normalise_path(descendants.last().specific.url),
site=self.site,
redirect_link="/some-other-place",
automatically_created=True,
)
# but before we do, let's add some redirects that we'll expect to conflict
# with ones created by the signal handler
redirect1 = Redirect.objects.create(
old_path=Redirect.normalise_path(descendants.first().specific.url),
site=self.site,
redirect_link="/some-place",
automatically_created=False,
)
redirect2 = Redirect.objects.create(
old_path=Redirect.normalise_path(descendants.last().specific.url),
site=self.site,
redirect_link="/some-other-place",
automatically_created=True,
)
self.trigger_page_slug_changed_signal(test_subject)
self.trigger_page_slug_changed_signal(test_subject)
# pre-existing manually-created redirects should be preserved
from_db = Redirect.objects.get(id=redirect1.id)
@ -163,17 +166,18 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
)
def test_redirect_creation_for_custom_route_paths(self):
# Add a page that has overridden get_route_paths()
homepage = Page.objects.get(id=2)
routable_page = homepage.add_child(
instance=RoutablePageTest(
title="Routable Page",
live=True,
with self.captureOnCommitCallbacks(execute=True):
# Add a page that has overridden get_route_paths()
homepage = Page.objects.get(id=2)
routable_page = homepage.add_child(
instance=RoutablePageTest(
title="Routable Page",
live=True,
)
)
)
# Move from below the homepage to below the event index
routable_page.move(self.event_index, pos="last-child")
# Move from below the homepage to below the event index
routable_page.move(self.event_index, pos="last-child")
# Redirects should have been created for each path returned by get_route_paths()
self.assertEqual(
@ -206,23 +210,24 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
)
def test_no_redirects_created_when_pages_are_moved_to_a_different_site(self):
# Add a new home page
homepage_2 = Page(
title="Second home",
slug="second-home",
)
root_page = Page.objects.get(depth=1)
root_page.add_child(instance=homepage_2)
with self.captureOnCommitCallbacks(execute=True):
# Add a new home page
homepage_2 = Page(
title="Second home",
slug="second-home",
)
root_page = Page.objects.get(depth=1)
root_page.add_child(instance=homepage_2)
# Create a site with the above as the root_page
Site.objects.create(
root_page=homepage_2,
hostname="newsite.com",
port=80,
)
# Create a site with the above as the root_page
Site.objects.create(
root_page=homepage_2,
hostname="newsite.com",
port=80,
)
# Move the event index to the new site
self.event_index.move(homepage_2, pos="last-child")
# Move the event index to the new site
self.event_index.move(homepage_2, pos="last-child")
# No redirects should have been created
self.assertFalse(Redirect.objects.exists())
@ -230,6 +235,7 @@ class TestAutocreateRedirects(WagtailTestUtils, TestCase):
@override_settings(WAGTAILREDIRECTS_AUTO_CREATE=False)
def test_no_redirects_created_if_disabled(self):
self.trigger_page_slug_changed_signal(self.event_index)
with self.captureOnCommitCallbacks(execute=True):
self.trigger_page_slug_changed_signal(self.event_index)
self.assertFalse(Redirect.objects.exists())
self.assertEqual(len(PURGED_URLS), 0)