-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
876feb2
commit 9604478
Showing
30 changed files
with
1,083 additions
and
315 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,70 +1,22 @@ | ||
import requests | ||
import logging | ||
|
||
from cms.components.sites.models import VercelFrontendSettings | ||
from cms.components.page.tasks import revalidate_vercel_frontend_task | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
def revalidate_vercel_frontend(sender, **kwargs): | ||
instance = kwargs["instance"] | ||
|
||
site = kwargs["instance"].get_site() | ||
site = instance.get_site() | ||
if not site: | ||
# page doesn't belong to any site | ||
return | ||
|
||
site_name = site.site_name | ||
hostname = site.hostname | ||
settings = VercelFrontendSettings.for_site(site) | ||
|
||
if not settings: | ||
# not configured for this site | ||
if not settings.revalidate_url: | ||
return | ||
|
||
url = settings.revalidate_url | ||
secret = settings.revalidate_secret | ||
|
||
if not url or not secret: | ||
# not configured for this site | ||
return | ||
|
||
language_code = instance.locale.language_code | ||
|
||
if language_code != "en": | ||
# we need to get the original slug | ||
# as we use the english slugs for the frontend | ||
english_page = ( | ||
instance.get_translations(inclusive=True) | ||
.filter(locale__language_code="en") | ||
.first() | ||
) | ||
|
||
slug = english_page.slug | ||
_, _, page_path = english_page.get_url_parts() | ||
else: | ||
slug = instance.slug | ||
_, _, page_path = instance.get_url_parts() | ||
|
||
page_path = page_path[:-1] | ||
|
||
if slug == hostname: | ||
path = f"/{language_code}" | ||
else: | ||
path = f"/{language_code}{page_path}" | ||
|
||
try: | ||
response = requests.post( | ||
url, | ||
timeout=None, | ||
json={ | ||
"secret": secret, | ||
"path": path, | ||
}, | ||
) | ||
response.raise_for_status() | ||
except Exception as e: | ||
logger.error(f"Error while revalidating {path} on {site_name}: {e}") | ||
return | ||
|
||
logger.info(f"Revalidated {path} on {site_name}") | ||
revalidate_vercel_frontend_task.delay(page_id=instance.id) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import requests | ||
import logging | ||
from pycon.celery import app | ||
from wagtail.models import Page | ||
from cms.components.sites.models import VercelFrontendSettings | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
@app.task | ||
def revalidate_vercel_frontend_task(page_id): | ||
page = Page.objects.get(id=page_id) | ||
site = page.get_site() | ||
|
||
settings = VercelFrontendSettings.for_site(site) | ||
|
||
site_name = site.site_name | ||
hostname = site.hostname | ||
|
||
url = settings.revalidate_url | ||
secret = settings.revalidate_secret | ||
|
||
if not url or not secret: | ||
# not configured for this site | ||
return | ||
|
||
language_code = page.locale.language_code | ||
|
||
if language_code != "en": | ||
# we need to get the original slug | ||
# as we use the english slugs for the frontend | ||
english_page = ( | ||
page.get_translations(inclusive=True) | ||
.filter(locale__language_code="en") | ||
.first() | ||
) | ||
|
||
slug = english_page.slug | ||
_, _, page_path = english_page.get_url_parts() | ||
else: | ||
slug = page.slug | ||
_, _, page_path = page.get_url_parts() | ||
|
||
page_path = page_path[:-1] | ||
|
||
if slug == hostname: | ||
path = f"/{language_code}" | ||
else: | ||
path = f"/{language_code}{page_path}" | ||
|
||
try: | ||
response = requests.post( | ||
url, | ||
timeout=None, | ||
json={ | ||
"secret": secret, | ||
"path": path, | ||
}, | ||
) | ||
response.raise_for_status() | ||
except Exception as e: | ||
logger.error(f"Error while revalidating {path} on {site_name}: {e}") | ||
return | ||
|
||
logger.info(f"Revalidated {path} on {site_name}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,119 +1,35 @@ | ||
from cms.components.sites.tests.factories import VercelFrontendSettingsFactory | ||
from unittest import mock | ||
import pytest | ||
from cms.components.page.signals import revalidate_vercel_frontend | ||
from cms.components.sites.tests.factories import VercelFrontendSettingsFactory | ||
from wagtail_factories import PageFactory, SiteFactory | ||
|
||
pytestmark = pytest.mark.django_db | ||
|
||
|
||
def test_revalidate_vercel_frontend_disabled_if_not_configured(requests_mock): | ||
mock_call = requests_mock.post("https://test.com", status_code=200) | ||
|
||
@mock.patch("cms.components.page.signals.revalidate_vercel_frontend_task") | ||
def test_revalidate_vercel_frontend_disabled_if_not_configured(mock_task): | ||
site = SiteFactory() | ||
page = PageFactory() | ||
site.root_page = page | ||
site.save() | ||
revalidate_vercel_frontend("test_revalidate_vercel_frontend", instance=page) | ||
|
||
assert not mock_call.called | ||
|
||
|
||
def test_revalidate_vercel_frontend( | ||
requests_mock, | ||
): | ||
site = SiteFactory() | ||
parent = PageFactory() | ||
page = PageFactory(slug="test-page123") | ||
page.set_url_path(parent) | ||
|
||
site.root_page = parent | ||
site.save() | ||
|
||
settings = VercelFrontendSettingsFactory( | ||
revalidate_url="https://test.com", revalidate_secret="test", site=site | ||
) | ||
mock_call = requests_mock.post(settings.revalidate_url, status_code=200) | ||
|
||
revalidate_vercel_frontend("test_revalidate_vercel_frontend", instance=page) | ||
|
||
assert mock_call.called | ||
body = mock_call.last_request.json() | ||
assert body["secret"] == "test" | ||
assert body["path"] == "/en/test-page123" | ||
mock_task.delay.assert_not_called() | ||
|
||
|
||
def test_revalidate_vercel_frontend_special_case_for_landing_page( | ||
requests_mock, | ||
): | ||
@mock.patch("cms.components.page.signals.revalidate_vercel_frontend_task") | ||
def test_revalidate_vercel_frontend(mock_task): | ||
site = SiteFactory() | ||
|
||
parent = PageFactory() | ||
page = PageFactory(slug=site.hostname) | ||
page.set_url_path(parent) | ||
site.root_page = parent | ||
|
||
page = PageFactory() | ||
site.root_page = page | ||
site.save() | ||
|
||
settings = VercelFrontendSettingsFactory( | ||
VercelFrontendSettingsFactory( | ||
revalidate_url="https://test.com", revalidate_secret="test", site=site | ||
) | ||
mock_call = requests_mock.post(settings.revalidate_url, status_code=200) | ||
|
||
revalidate_vercel_frontend("test_revalidate_vercel_frontend", instance=page) | ||
|
||
assert mock_call.called | ||
|
||
body = mock_call.last_request.json() | ||
assert body["secret"] == "test" | ||
assert body["path"] == "/en" | ||
|
||
|
||
def test_revalidate_vercel_frontend_for_different_language(requests_mock, locale): | ||
parent = PageFactory() | ||
site = SiteFactory(hostname="pycon", root_page=parent) | ||
|
||
page = PageFactory(slug="test123", locale=locale("en"), parent=parent) | ||
page.set_url_path(parent) | ||
|
||
italian_page = page.copy_for_translation(locale=locale("it")) | ||
italian_page.slug = "something-else" | ||
italian_page.save() | ||
italian_page.set_url_path(parent) | ||
|
||
settings = VercelFrontendSettingsFactory( | ||
revalidate_url="https://test.com", revalidate_secret="test", site=site | ||
) | ||
mock_call = requests_mock.post(settings.revalidate_url, status_code=200) | ||
|
||
revalidate_vercel_frontend("test_revalidate_vercel_frontend", instance=italian_page) | ||
|
||
assert mock_call.called | ||
|
||
body = mock_call.last_request.json() | ||
assert body["secret"] == "test" | ||
assert body["path"] == "/it/test123" | ||
|
||
|
||
def test_revalidate_vercel_frontend_when_vercel_is_down_doesnt_crash( | ||
caplog, | ||
requests_mock, | ||
locale, | ||
): | ||
parent = PageFactory() | ||
|
||
page = PageFactory(slug="test123", locale=locale("en"), parent=parent) | ||
site = SiteFactory(hostname="pycon", root_page=page) | ||
|
||
italian_page = page.copy_for_translation(locale=locale("it")) | ||
italian_page.slug = "something-else" | ||
italian_page.save() | ||
|
||
settings = VercelFrontendSettingsFactory( | ||
revalidate_url="https://test.com", revalidate_secret="test", site=site | ||
) | ||
mock_call = requests_mock.post(settings.revalidate_url, status_code=500) | ||
|
||
revalidate_vercel_frontend("test_revalidate_vercel_frontend", instance=italian_page) | ||
|
||
assert mock_call.called | ||
assert "Error while revalidating" in caplog.records[0].message | ||
mock_task.delay.assert_called_with(page_id=page.id) |
Oops, something went wrong.
9604478
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
pycon – ./
www.pycon.it
pycon-python-italia.vercel.app
pycon.it
pycon-git-main-python-italia.vercel.app
2024.pycon.it