Skip to content

Commit

Permalink
Merge pull request #822 from uktrade/develop
Browse files Browse the repository at this point in the history
Staging release
  • Loading branch information
richtier authored Apr 21, 2020
2 parents e21d35e + 9e9fe26 commit 238db45
Show file tree
Hide file tree
Showing 13 changed files with 152 additions and 23 deletions.
16 changes: 14 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
# Changelog

## Pre-release

### Implemented enhancements
- CI-677 - Add CTA link field to Capital Investment homepage hero
- no ticket - Add cache supoort to draft pages

## Hotfix
- No ticket - v3-cipipeline manifest.yml file fix

## [2020.03.23](https://github.com/uktrade/directory-cms/releases/tag/2020.03.23)
[Full Changelog](https://github.com/uktrade/directory-cms/compare/2020.03.06...2020.03.23)

### Implemented enhancements
- no ticket - Handle non-serializable page requested via /api/pages/<pk>/
- no ticket - Upgrade bleach to fix vulnerability
- no ticket - return only pks on /api/pages/
- no ticket - Add caching to /api/pages/<pk>/

## [2020.03.06](https://github.com/uktrade/directory-cms/releases/tag/2020.03.06)
[Full Changelog](https://github.com/uktrade/directory-cms/compare/2020.03.04...2020.03.06)

### Implemented enhancements
- CMS-1859 - Simplify caching system
- no ticket - return only pks on /api/pages/
- no ticket - Add caching to /api/pages/<pk>/
- no ticket - Remove region support

## [2020.03.04](https://github.com/uktrade/directory-cms/releases/tag/2020.03.04)
Expand Down
17 changes: 17 additions & 0 deletions core/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,18 @@ def populate_sync(cls, instance):
data=serializer.data,
lang=language_code,
)
if instance.has_unpublished_changes:
draft_instance = instance.get_latest_nested_revision_as_page()
draft_serializer = serializer_class(
instance=draft_instance,
context={'is_draft': True}
)
page_cache.set(
page_id=instance.id,
data=draft_serializer.data,
lang=language_code,
draft_version=True
)

@classmethod
def delete(cls, instance):
Expand All @@ -138,6 +150,11 @@ def delete(cls, instance):
page_id=instance.id,
lang=language_code,
)
page_cache.delete(
page_id=instance.id,
lang=language_code,
draft_version=True
)


class PageIDCache:
Expand Down
6 changes: 1 addition & 5 deletions core/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,13 @@ def to_representation(self, instance):
class MetaDictField(fields.DictField):

def get_attribute(self, instance):
if 'request' in self.context:
is_draft = helpers.is_draft_requested(self.context['request'])
else:
is_draft = False
return {
'languages': [
(code, label) for (code, label) in settings.LANGUAGES_LOCALIZED
if code in instance.specific.translated_languages
],
'url': instance.specific.get_url(
is_draft=is_draft,
is_draft=self.context.get('is_draft', False),
language_code=settings.LANGUAGE_CODE,
),
'slug': instance.slug,
Expand Down
21 changes: 16 additions & 5 deletions core/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from logging import getLogger

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.exceptions import ValidationError
from rest_framework.renderers import JSONRenderer
Expand All @@ -22,6 +24,9 @@
from core.serializer_mapping import MODELS_SERIALIZERS_MAPPING


logger = getLogger(__name__)


class PageNotSerializableError(NotImplementedError):
pass

Expand Down Expand Up @@ -89,14 +94,13 @@ def detail_view(self, request, **kwargs):
# Exit early if there are any issues
self.check_parameter_validity()

variation_kwargs = {'lang': translation.get_language()}

if helpers.is_draft_requested(request):
return super().detail_view(request, pk=None)
variation_kwargs['draft_version'] = True

# Return a cached response if one is available
cached_data = cache.PageCache.get(
page_id=self.object_id,
lang=translation.get_language(),
)
cached_data = cache.PageCache.get(page_id=self.object_id, **variation_kwargs)
if cached_data:
cached_response = helpers.CachedResponse(cached_data)
cached_response['etag'] = cached_data.get('etag', None)
Expand All @@ -108,15 +112,22 @@ def detail_view(self, request, **kwargs):

# No cached response available
response = super().detail_view(request, pk=None)

if response.status_code == 200:
# Reuse the already-fetched object to populate the cache
cache.CachePopulator.populate_async(self.get_object())

logger.warn(f'Page cache miss')
# No etag is set for this response because creating one is expensive.
# If API caching is enabled, one will be added to the cached version
# created above.
return response

def get_serializer_context(self):
context = super().get_serializer_context()
context['is_draft'] = helpers.is_draft_requested(self.request)
return context


class PagesOptionalDraftAPIEndpoint(APIEndpointBase):
def listing_view(self, request):
Expand Down
58 changes: 58 additions & 0 deletions great_international/migrations/0093_auto_20200414_1626.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Generated by Django 2.2.10 on 2020-04-14 16:26

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('great_international', '0092_auto_20200127_1223'),
]

operations = [
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link',
field=models.CharField(blank=True, max_length=255),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_ar',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_de',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_en_gb',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_es',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_fr',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_ja',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_pt',
field=models.CharField(blank=True, max_length=255, null=True),
),
migrations.AddField(
model_name='internationalcapitalinvestlandingpage',
name='hero_cta_link_zh_hans',
field=models.CharField(blank=True, max_length=255, null=True),
),
]
1 change: 1 addition & 0 deletions great_international/models/capital_invest.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ class InternationalCapitalInvestLandingPage(
)
hero_subtitle = models.CharField(max_length=255, blank=True)
hero_cta_text = models.CharField(max_length=255, blank=True)
hero_cta_link = models.CharField(max_length=255, blank=True)

featured_description = models.TextField(max_length=255, blank=True)

Expand Down
3 changes: 2 additions & 1 deletion great_international/panels/capital_invest.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ class InternationalCapitalInvestLandingPagePanels:
FieldPanel('hero_title'),
FieldPanel('hero_subheading'),
FieldPanel('hero_subtitle'),
FieldPanel('hero_cta_text')
FieldPanel('hero_cta_text'),
FieldPanel('hero_cta_link'),
]
),
MultiFieldPanel(
Expand Down
1 change: 1 addition & 0 deletions great_international/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1316,6 +1316,7 @@ class InternationalCapitalInvestLandingPageSerializer(BasePageSerializer, HeroSe
hero_subheading = serializers.CharField(max_length=255)
hero_subtitle = serializers.CharField(max_length=255)
hero_cta_text = serializers.CharField(max_length=255)
hero_cta_link = serializers.CharField(max_length=255)

reason_to_invest_section_title = serializers.CharField(max_length=255)
reason_to_invest_section_intro = serializers.CharField(max_length=255)
Expand Down
1 change: 1 addition & 0 deletions great_international/translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ class InternationalCapitalInvestLandingPageTranslationOptions(
'hero_subheading',
'hero_subtitle',
'hero_cta_text',
'hero_cta_link',

'reason_to_invest_section_title',
'reason_to_invest_section_intro',
Expand Down
3 changes: 2 additions & 1 deletion manifest.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
---
applications:
- buildpack: python_buildpack
- buildpacks:
- python_buildpack
timeout: 180
19 changes: 13 additions & 6 deletions tests/core/test_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,23 @@ class TestSubscriber(cache.DatabaseCacheSubscriber):
model_classes = [Page]

instance = mock.Mock(
id=1, slug='some-slug', service_name='thing',
id=2, slug='some-slug', service_name='thing',
translated_languages=['en-gb']
)
TestSubscriber.delete(sender=None, instance=instance)

assert mock_delete.call_count == 1
assert mock_delete.call_args == mock.call(
page_id=1,
lang='en-gb',
)
assert mock_delete.call_count == 2
assert mock_delete.call_args_list == [
mock.call(
page_id=2,
lang='en-gb',
),
mock.call(
page_id=2,
lang='en-gb',
draft_version=True,
)
]


@mock.patch('django.core.cache.cache.set')
Expand Down
4 changes: 1 addition & 3 deletions tests/core/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from wagtail.core.fields import StreamField

from core import fields
from core import permissions
from great_international.serializers import InternationalSectorPageSerializer, InternationalArticlePageSerializer
from tests.great_international.factories import InternationalSectorPageFactory

Expand Down Expand Up @@ -103,10 +102,9 @@ def test_meta_field_draft(international_root_page, rf):
parent=international_root_page,
slug='test-slug',
)
request = rf.get('/', {permissions.DraftTokenPermisison.TOKEN_PARAM: '1'})
serializer = InternationalSectorPageSerializer(
instance=sector_page,
context={'request': request}
context={'is_draft': True}
)

assert serializer.data['meta']['url'] == sector_page.get_url(is_draft=True)
Expand Down
25 changes: 25 additions & 0 deletions tests/great_international/test_serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,31 @@ def test_new_int_home_page_has_related_capital_invest(rf, international_root_pag
assert serializer.data['related_page_invest_capital']['meta']['slug'] == 'capital-invest'


@pytest.mark.django_db
def test_capital_invest_landing_page_has_cta(rf, international_root_page, image):
capital_invest_landing_page = InternationalCapitalInvestLandingPageFactory(
parent=international_root_page,
slug='capital-invest',
hero_title='Hero title',
hero_image=image,
hero_subheading='Hero subheading',
hero_subtitle='Hero subtitle',
hero_cta_text='click here',
hero_cta_link='/hero/cta/link',
)

serializer = InternationalCapitalInvestLandingPageSerializer(
instance=capital_invest_landing_page,
context={'request': rf.get('/')},
)

assert serializer.data['hero_title'] == 'Hero title'
assert serializer.data['hero_subheading'] == 'Hero subheading'
assert serializer.data['hero_subtitle'] == 'Hero subtitle'
assert serializer.data['hero_cta_text'] == 'click here'
assert serializer.data['hero_cta_link'] == '/hero/cta/link'


@pytest.mark.django_db
def test_new_int_home_page_has_related_trade(rf, international_root_page, image):
trade = InternationalTradeHomePageFactory(
Expand Down

0 comments on commit 238db45

Please sign in to comment.