From 9401af90330ae2f5becba013af7ae8773b819cc2 Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Fri, 12 Jan 2024 19:02:56 +0000
Subject: [PATCH 01/12] Added editable cta to UKEA article page.
---
core/components/static/icons/event-icon.jpeg | Bin 0 -> 742 bytes
core/components/static/icons/series-icon.jpeg | Bin 0 -> 684 bytes
...etailpage_call_to_action_eventorderable.py | 98 ++++++++++++++++++
core/models.py | 68 ++++++++++++
.../learn/includes/article_page_cta.html | 6 +-
learn/templatetags/helpers.py | 63 ++++++++++-
tests/unit/learn/factories.py | 10 ++
tests/unit/learn/test_templatetags.py | 60 ++++++++++-
8 files changed, 300 insertions(+), 5 deletions(-)
create mode 100644 core/components/static/icons/event-icon.jpeg
create mode 100644 core/components/static/icons/series-icon.jpeg
create mode 100644 core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py
diff --git a/core/components/static/icons/event-icon.jpeg b/core/components/static/icons/event-icon.jpeg
new file mode 100644
index 0000000000000000000000000000000000000000..85cc7e57c7ac74df407926392dfabbb19086e65c
GIT binary patch
literal 742
zcmex=5A1R0qH8UG()kYr$BVrFDO0&MIIEUX+rDH8z(CI(g}CRQ$Xs5B!J12YS&Ae#`o
zqOgczV4}E^xnoGJnoF0wm)YfTl46#gzmZn3x!uS(xE+Ak!2D
zg#%ec3>`(4g8tuP-~qaXNsw8P!JfhPlGyHLo3>rMm%Y`tRx+wRETl*qESGG^;g?f>6wkMM*`hsrlS@((rzX5{lzn`@XKwtGcU9T`S7V=M
z&7SjpnTE@@GKP1had(gJ${EkL_qj01)(7Op*4%g#n_c#9@~XKv-=BN){FvUI9q}d0*Ug!ftufE<
zz2V$BhH`6qm(Sm)U1_?f+IRos`p=T8rHvg`D;K(7lgW(JxqLnJ)RH|xUGB3Eij{0X
zm1q0lGxO&8b~h9s{byLbd;OQcS6XYgw|@8PdKvUQ^rFg~XUWPt6ZY-lT|9q}^X8Dq
z)K}ahzjJ=B*NS;Gd#0NQ*Q-1GWE|gwxU)Exa>s_P^eeV>Qz5A1R0qH8UG()kYHe7W@KbQ0?aII?5sc;69EQBW@aWPRxWm^EF%*$&?ABj>_Upd
zBI1sTVoHWa<{^cXH(pY9Dk*K8v=FFEl97Rl8O=NfMkbJfN`eebK)?VqjsYmnAjmAF
zs3f9n=vcULJV3ong3N*p_6)byd(YGL&(jv=u1hRX^hnq-WhINy7FNCl`Ox}z
zOBd(f-EnuR(9Y1gL8;r7O@1Hc_T<#&Jjc#xacb+Sh1G&P>SOv>OKsa>+rIgCN&X^}
z3#=Bw@2yM3U7=AS(CZdwD0};Lui)C3pDs*)
zwDjo8t4w}j3;P`SPnp=R|Fq;v=XT?(MOFnL{_sCPe(}Zg<>faXz3ZGGy<)MwoVkhX
z?OM+rhw^qdS?4Ie%~*ftW_9a~wVKy`4lHQlnIwE+#it+4%OAf}-L>0IRcJNal2_7w
zm-$%~6*Ly8Ti7H#Rz4j3A+PG#eOs$eK>>NM6wRZ$M|386c)SaE$GqFOY=1%ZQvIiv
z-(Q&-c|HnGELXYOy+3Md!1tt^t&-c6g0pxwH6EH`b~=Ia?^nUfGsOjZVo#$tq*=8k
yE#0~_Ly|?)-7ZsEuHf?C_1FJin*M3d@2~rK5{j-#pEQpz;JGK-oPGYx|C<0+B;Q&9
literal 0
HcmV?d00001
diff --git a/core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py b/core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py
new file mode 100644
index 0000000000..0452dbc209
--- /dev/null
+++ b/core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py
@@ -0,0 +1,98 @@
+# Generated by Django 4.1.13 on 2024-01-12 17:57
+
+import core.blocks
+from django.db import migrations, models
+import django.db.models.deletion
+import modelcluster.fields
+import wagtail.blocks
+import wagtail.fields
+import wagtail.snippets.blocks
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('export_academy', '0033_alter_coursepage_metadata_alter_coursepage_reviews'),
+ ('core', '0129_alter_greatmedia_subtitles_en_and_more'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='UKEACTA',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ (
+ 'image',
+ wagtail.fields.StreamField(
+ [
+ (
+ 'media',
+ wagtail.blocks.StreamBlock([('image', core.blocks.ImageBlock())], max_num=1, min_num=1),
+ )
+ ],
+ blank=True,
+ null=True,
+ use_json_field=True,
+ ),
+ ),
+ ('name', models.CharField(help_text='Snippet name', max_length=50)),
+ ],
+ options={
+ 'verbose_name': 'UKEA CTA',
+ 'verbose_name_plural': "UKEA CTA's",
+ },
+ ),
+ migrations.AddField(
+ model_name='detailpage',
+ name='call_to_action',
+ field=wagtail.fields.StreamField(
+ [
+ (
+ 'ukea_article_cta',
+ wagtail.blocks.ListBlock(
+ wagtail.snippets.blocks.SnippetChooserBlock('core.UKEACTA'),
+ icon='link',
+ label='UKEA Call to action',
+ max_num=1,
+ template='learn/includes/article_page_cta.html',
+ ),
+ )
+ ],
+ blank=True,
+ null=True,
+ use_json_field=True,
+ ),
+ ),
+ migrations.CreateModel(
+ name='EventOrderable',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('sort_order', models.IntegerField(blank=True, editable=False, null=True)),
+ (
+ 'event',
+ models.ForeignKey(
+ blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='export_academy.event'
+ ),
+ ),
+ (
+ 'page',
+ modelcluster.fields.ParentalKey(
+ on_delete=django.db.models.deletion.CASCADE, related_name='ukea_cta_links', to='core.ukeacta'
+ ),
+ ),
+ (
+ 'series',
+ models.ForeignKey(
+ blank=True,
+ null=True,
+ on_delete=django.db.models.deletion.SET_NULL,
+ to='export_academy.coursepage',
+ ),
+ ),
+ ],
+ options={
+ 'ordering': ['sort_order'],
+ 'abstract': False,
+ },
+ ),
+ ]
diff --git a/core/models.py b/core/models.py
index 1fb80f81a7..b1a9e1d40f 100644
--- a/core/models.py
+++ b/core/models.py
@@ -906,6 +906,24 @@ class Meta:
use_json_field=True,
)
+ call_to_action = StreamField(
+ [
+ (
+ 'ukea_article_cta',
+ blocks.ListBlock(
+ SnippetChooserBlock('core.UKEACTA'),
+ template='learn/includes/article_page_cta.html',
+ label='UKEA Call to action',
+ max_num=1,
+ icon='link',
+ ),
+ )
+ ],
+ use_json_field=True,
+ null=True,
+ blank=True,
+ )
+
def get_steps(self):
topics = CuratedListPage.objects.live()
return [{'text': page.title, 'url': page.url} for page in topics]
@@ -1042,6 +1060,56 @@ def get_context(self, request, *args, **kwargs):
return context
+class EventOrderable(Orderable):
+ """
+ This allows us to either series or multiple events
+ """
+
+ page = ParentalKey('core.UKEACTA', related_name='ukea_cta_links')
+ event = models.ForeignKey('export_academy.Event', on_delete=models.SET_NULL, null=True, blank=True)
+ series = models.ForeignKey('export_academy.CoursePage', on_delete=models.SET_NULL, null=True, blank=True)
+
+ panels = [FieldPanel('event'), FieldPanel('series')]
+
+
+@register_snippet
+class UKEACTA(ClusterableModel):
+
+ image = StreamField(
+ [
+ (
+ 'media',
+ blocks.StreamBlock(
+ [
+ ('image', core_blocks.ImageBlock()),
+ ],
+ min_num=1,
+ max_num=1,
+ ),
+ ),
+ ],
+ use_json_field=True,
+ blank=True,
+ null=True,
+ )
+ name = models.CharField(max_length=50, help_text='Snippet name')
+ panels = [
+ FieldPanel('image'),
+ FieldPanel('name'),
+ MultiFieldPanel(
+ [InlinePanel('ukea_cta_links', label='Link')],
+ heading='Link(s)',
+ icon='link',
+ ),
+ ]
+
+ class Meta:
+ verbose_name = 'UKEA CTA'
+ verbose_name_plural = "UKEA CTA's"
+
+ def __str__(self):
+ return self.name
+
@register_snippet
class RelatedContentCTA(models.Model):
type_choices = [
diff --git a/learn/templates/learn/includes/article_page_cta.html b/learn/templates/learn/includes/article_page_cta.html
index 330ab14d2a..712cc26c4b 100644
--- a/learn/templates/learn/includes/article_page_cta.html
+++ b/learn/templates/learn/includes/article_page_cta.html
@@ -1,4 +1,6 @@
+{% load get_article_cta_attributes from helpers %}
Learn more with free training
- {% include 'components/great/card.html' with heading_class="great-card__link--heading--18" heading_level="h3" tag_container_inner_class="article-page-cta-container-inner-container" container_class="article-page-cta-container-title-container" classes="great-card--cta great-card--cta-with-content govuk-!-margin-bottom-8" title="Join the UK Export Academy" content="Free training with Q&A, helping you learn to sell confidently to overseas customers" content_tag="p" image_src="/static/images/ukea-landing.png" is_svg_image=False url="/export-academy" show_title_link=True tag="Service" tag_icon="/static/icons/hand.svg" %}
-
+ {% get_article_cta_attributes page.call_to_action.0.value.0 as cta_attrs %}
+ {% include 'components/great/card.html' with heading_class="great-card__link--heading--18" heading_level="h3" tag_container_inner_class="article-page-cta-container-inner-container" container_class="article-page-cta-container-title-container" classes="great-card--cta great-card--cta-with-content govuk-!-margin-bottom-8" title=cta_attrs.title content=cta_attrs.description content_tag="p" image_src=cta_attrs.image is_svg_image=False url=cta_attrs.link show_title_link=True tag=cta_attrs.type tag_icon=cta_attrs.icon %}
+
\ No newline at end of file
diff --git a/learn/templatetags/helpers.py b/learn/templatetags/helpers.py
index 5347a0c65b..b7ea35eded 100644
--- a/learn/templatetags/helpers.py
+++ b/learn/templatetags/helpers.py
@@ -1,7 +1,10 @@
from django import template
+from django.urls import reverse
+from django.utils import timezone
from wagtail.models import Page
-from core.models import RelatedContentCTA
+from core.models import UKEACTA, RelatedContentCTA
+from export_academy.models import Event
register = template.Library()
@@ -18,3 +21,61 @@ def get_cta_attributes(cta: RelatedContentCTA):
result['tag_description'] = dict(RelatedContentCTA.type_choices)[cta.type]
result['tag_icon'] = '/static/icons/hand.svg' if 'service' in cta.type.lower() else '/static/icons/guidance.svg'
return result
+
+
+def get_first_available_event(event_ids: list):
+ first_available_event = None
+ for event in Event.objects.filter(id__in=event_ids):
+ if event.start_date > timezone.now() and event.live:
+ if first_available_event:
+ if event.start_date < first_available_event.start_date:
+ first_available_event = event
+ else:
+ first_available_event = event
+ return first_available_event
+
+
+@register.simple_tag
+def get_article_cta_attributes(cta: UKEACTA) -> dict:
+ default_data = {
+ 'link': '/export-academy',
+ 'image': '/static/images/ukea-landing.png',
+ 'icon': '/static/icons/hand.svg',
+ 'title': 'Join the UK Export Academy',
+ 'description': 'Free training with Q&A, helping you learn to sell confidently to overseas customers',
+ 'type': 'Series',
+ }
+ if not cta:
+ return default_data
+
+ links = cta.ukea_cta_links.all()
+ series = [
+ {
+ 'title': link.series.title,
+ 'description': link.series.summary,
+ 'icon': '/static/icons/series-icon.jpeg',
+ 'type': 'Series',
+ 'image': cta.image[0].value[0].value.file.url if cta.image else default_data['image'],
+ 'link': reverse('export_academy:course', kwargs={'slug': link.series.slug}),
+ }
+ for link in links
+ if link.series
+ ]
+ # We want pass through the first available event to the CTA
+ # The default result will be used if first_available_event is None
+ first_available_event = get_first_available_event([link.event.id for link in links if link.event])
+
+ if first_available_event:
+ return {
+ 'title': first_available_event.name,
+ 'description': first_available_event.description,
+ 'icon': '/static/icons/event-icon.jpeg',
+ 'type': 'Event',
+ 'image': cta.image[0].value[0].value.file.url if cta.image else default_data['image'],
+ 'link': first_available_event.get_absolute_url(),
+ }
+ elif series:
+ return series[0]
+ else:
+ # the default CTA will be displayed if series and first available_event are None
+ return default_data
\ No newline at end of file
diff --git a/tests/unit/learn/factories.py b/tests/unit/learn/factories.py
index b33dbc0d3b..136220d705 100644
--- a/tests/unit/learn/factories.py
+++ b/tests/unit/learn/factories.py
@@ -15,3 +15,13 @@ class Meta:
class RelatedContentCTASnippetFactory(DjangoModelFactory):
class Meta:
model = models.RelatedContentCTA
+
+
+class UKEACTASnippetFactory(DjangoModelFactory):
+ class Meta:
+ model = models.UKEACTA
+
+
+class EventOrderableFactory(DjangoModelFactory):
+ class Meta:
+ model = models.EventOrderable
\ No newline at end of file
diff --git a/tests/unit/learn/test_templatetags.py b/tests/unit/learn/test_templatetags.py
index 28b8f7db16..b25a4dd7dc 100644
--- a/tests/unit/learn/test_templatetags.py
+++ b/tests/unit/learn/test_templatetags.py
@@ -1,9 +1,15 @@
import pytest
+from django.utils import timezone
from wagtail.models import Page
from wagtail_factories import PageChooserBlockFactory
-from learn.templatetags.helpers import get_cta_attributes
-from .factories import RelatedContentCTASnippetFactory
+from learn.templatetags.helpers import get_article_cta_attributes, get_cta_attributes
+from tests.unit.export_academy.factories import EventFactory
+from .factories import (
+ EventOrderableFactory,
+ RelatedContentCTASnippetFactory,
+ UKEACTASnippetFactory,
+)
@pytest.mark.parametrize(
@@ -67,3 +73,53 @@ def test_get_cta_attributes(domestic_site, link_text, type, url, expected):
cta_attrs = get_cta_attributes(cta)
assert cta_attrs == expected
+
+
+@pytest.mark.parametrize(
+ 'name, events, expected',
+ (
+ (
+ 'test',
+ None,
+ {
+ 'image': '/static/images/ukea-landing.png',
+ 'icon': '/static/icons/hand.svg',
+ 'type': 'Series',
+ },
+ ),
+ (
+ 'test',
+ 1,
+ {
+ 'image': '/static/images/ukea-landing.png',
+ 'icon': '/static/icons/event-icon.jpeg',
+ 'type': 'Event',
+ },
+ ),
+ (
+ 'test',
+ 2,
+ {
+ 'image': '/static/images/ukea-landing.png',
+ 'icon': '/static/icons/event-icon.jpeg',
+ 'type': 'Event',
+ },
+ ),
+ ),
+)
+@pytest.mark.django_db
+def test_get_article_cta_attributes(root_page, name, events, expected):
+
+ cta = UKEACTASnippetFactory(name=name)
+
+ if events:
+ for loop in range(events):
+ delta = timezone.now() + timezone.timedelta(days=1 + loop)
+ event_obj = EventFactory(start_date=delta, live=delta)
+ EventOrderableFactory(page=cta, event=event_obj)
+
+ cta_attrs = get_article_cta_attributes(cta)
+
+ assert cta_attrs['image'] == expected['image']
+ assert cta_attrs['icon'] == expected['icon']
+ assert cta_attrs['type'] == expected['type']
\ No newline at end of file
From 625c8cbdd5cf72dcd98a7705b661945914a0a52c Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Fri, 12 Jan 2024 19:56:08 +0000
Subject: [PATCH 02/12] Formatted code
---
activitystream/serializers.py | 8 +++---
config/wsgi.py | 1 +
contact/models.py | 22 +++++++--------
...etailpage_call_to_action_eventorderable.py | 5 ++--
core/models.py | 2 +-
core/templatetags/content_tags.py | 12 +++-----
core/templatetags/progress_bar.py | 6 ++--
core/templatetags/video_tags.py | 6 ++--
core/wagtail_hooks.py | 6 ++--
export_academy/helpers.py | 14 ++++++----
exportplan/context.py | 16 +++++------
exportplan/forms.py | 28 +++++++++----------
learn/templatetags/helpers.py | 2 +-
sso_profile/business_profile/forms.py | 2 +-
sso_profile/enrolment/views.py | 4 +--
tests/unit/contact/test_helpers.py | 2 +-
tests/unit/contact/test_views.py | 6 ++--
tests/unit/core/test_wagtail_hooks.py | 6 ++--
.../test_organise_country_guide_ctas.py | 11 +++++---
.../test_update_factsheets_cta_links.py | 6 ++--
tests/unit/domestic/test_models.py | 8 ++++--
tests/unit/learn/factories.py | 2 +-
tests/unit/learn/test_templatetags.py | 2 +-
.../sso_profile/enrolment/test_helpers.py | 2 +-
.../sso_profile/enrolment/test_widgets.py | 4 +--
25 files changed, 91 insertions(+), 92 deletions(-)
diff --git a/activitystream/serializers.py b/activitystream/serializers.py
index d995ccf4e1..dec269c9da 100644
--- a/activitystream/serializers.py
+++ b/activitystream/serializers.py
@@ -30,7 +30,7 @@ def _prep_richtext_for_indexing(self, rich_text_value: str) -> str:
def to_representation(self, obj):
return {
- 'id': ('dit:greatCms:Article:' + str(obj.id) + ':Update'),
+ 'id': 'dit:greatCms:Article:' + str(obj.id) + ':Update',
'type': 'Update',
'published': obj.last_published_at.isoformat('T'),
'object': {
@@ -77,7 +77,7 @@ def _get_article_body_content_for_search(self, obj: ArticlePage) -> str:
def to_representation(self, obj):
return {
- 'id': ('dit:greatCms:Article:' + str(obj.id) + ':Update'),
+ 'id': 'dit:greatCms:Article:' + str(obj.id) + ':Update',
'type': 'Update',
'published': obj.last_published_at.isoformat('T'),
'object': {
@@ -134,7 +134,7 @@ def _get_microsite_body_content_for_search(self, obj: MicrositePage) -> str:
def to_representation(self, obj):
return {
- 'id': ('dit:greatCms:Microsite:' + str(obj.id) + ':Update'),
+ 'id': 'dit:greatCms:Microsite:' + str(obj.id) + ':Update',
'type': 'Update',
'published': obj.last_published_at.isoformat('T'),
'object': {
@@ -144,7 +144,7 @@ def to_representation(self, obj):
'summary': obj.page_teaser,
'content': self._get_microsite_body_content_for_search(obj),
'url': f'https://www.great.gov.uk{obj.get_url()}',
- 'locale_id': obj.locale_id
+ 'locale_id': obj.locale_id,
# 'keywords': ' '.join(obj.tags.all().values_list('name', flat=True)),
},
}
diff --git a/config/wsgi.py b/config/wsgi.py
index 98730e9605..a544518541 100644
--- a/config/wsgi.py
+++ b/config/wsgi.py
@@ -6,6 +6,7 @@
For more information on this file, see
https://docs.djangoproject.com/en/2.2/howto/deployment/wsgi/
"""
+
import os
from django.core.wsgi import get_wsgi_application
diff --git a/contact/models.py b/contact/models.py
index 319b9b4889..040dcdc81b 100644
--- a/contact/models.py
+++ b/contact/models.py
@@ -22,44 +22,44 @@ class ContactUsGuidanceSnippet(
# if we need to trace through where content goes)
snippet_slugs.HELP_EXOPP_ALERTS_IRRELEVANT: {
'title': 'Guidance - Daily alerts are not relevant',
- 'page_path': ('/contact/triage/export-opportunities/alerts-not-relevant/'),
+ 'page_path': '/contact/triage/export-opportunities/alerts-not-relevant/',
},
snippet_slugs.HELP_EXOPPS_NO_RESPONSE: {
'title': 'Guidance - Export Opportunity application no response',
- 'page_path': ('/contact/triage/export-opportunities/opportunity-no-response/'),
+ 'page_path': '/contact/triage/export-opportunities/opportunity-no-response/',
},
snippet_slugs.HELP_MISSING_VERIFY_EMAIL: {
'title': 'Guidance - Email verification missing',
- 'page_path': ('/contact/triage/great-account/no-verification-email/'),
+ 'page_path': '/contact/triage/great-account/no-verification-email/',
},
snippet_slugs.HELP_PASSWORD_RESET: {
'title': 'Guidance - Missing password reset link',
- 'page_path': ('/contact/triage/great-account/password-reset/'),
+ 'page_path': '/contact/triage/great-account/password-reset/',
},
snippet_slugs.HELP_COMPANIES_HOUSE_LOGIN: {
'title': 'Guidance - Companies House login not working',
- 'page_path': ('/contact/triage/great-account/companies-house-login/'),
+ 'page_path': '/contact/triage/great-account/companies-house-login/',
},
snippet_slugs.HELP_VERIFICATION_CODE_ENTER: {
'title': 'Guidance - Where to enter letter verification code',
- 'page_path': ('/contact/triage/great-account/verification-letter-code/'),
+ 'page_path': '/contact/triage/great-account/verification-letter-code/',
},
snippet_slugs.HELP_VERIFICATION_CODE_LETTER: {
'title': 'Guidance - Verification letter not delivered',
- 'page_path': ('/contact/triage/great-account/no-verification-letter/'),
+ 'page_path': '/contact/triage/great-account/no-verification-letter/',
},
snippet_slugs.HELP_VERIFICATION_CODE_MISSING: {
'title': 'Guidance - Verification code not delivered',
- 'page_path': ('/contact/triage/great-account/verification-missing/'),
+ 'page_path': '/contact/triage/great-account/verification-missing/',
},
snippet_slugs.HELP_ACCOUNT_COMPANY_NOT_FOUND: {
'title': 'Guidance - Company not found',
- 'page_path': ('/contact/triage/great-account/company-not-found/'),
+ 'page_path': '/contact/triage/great-account/company-not-found/',
},
snippet_slugs.HELP_EXPORTING_TO_UK: {
# NB snippet_slugs.HELP_EXPORTING_TO_UK is NOT bootstrapped via data migration
'title': 'Guidance - Exporting to the UK',
- 'page_path': ('contact/triage/international/exporting-to-the-uk/'),
+ 'page_path': 'contact/triage/international/exporting-to-the-uk/',
},
}
@@ -119,7 +119,7 @@ class ContactSuccessSnippet(
},
snippet_slugs.HELP_FORM_SUCCESS_DSO: {
'title': 'Contact Defence and Security Organisation form success page content',
- 'page_path': ('/contact/defence-and-security-organisation/success/'),
+ 'page_path': '/contact/defence-and-security-organisation/success/',
},
snippet_slugs.HELP_FORM_SUCCESS_EXPORT_ADVICE: {
'title': 'Contact exporting from the UK form success page content',
diff --git a/core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py b/core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py
index 0452dbc209..a210cf73a7 100644
--- a/core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py
+++ b/core/migrations/0130_ukeacta_detailpage_call_to_action_eventorderable.py
@@ -1,12 +1,13 @@
# Generated by Django 4.1.13 on 2024-01-12 17:57
-import core.blocks
-from django.db import migrations, models
import django.db.models.deletion
import modelcluster.fields
import wagtail.blocks
import wagtail.fields
import wagtail.snippets.blocks
+from django.db import migrations, models
+
+import core.blocks
class Migration(migrations.Migration):
diff --git a/core/models.py b/core/models.py
index b1a9e1d40f..45dca8cea5 100644
--- a/core/models.py
+++ b/core/models.py
@@ -723,7 +723,6 @@ def is_lesson_page(self, page):
class LessonPlaceholderPage(Page, mixins.AuthenticatedUserRequired if not settings.FEATURE_DEA_V2 else object):
-
"""Structural page to allow for configuring and representing very simple
to modules (`CuratedListPage`s).
@@ -1110,6 +1109,7 @@ class Meta:
def __str__(self):
return self.name
+
@register_snippet
class RelatedContentCTA(models.Model):
type_choices = [
diff --git a/core/templatetags/content_tags.py b/core/templatetags/content_tags.py
index 943c5a7cb5..d0da024a2b 100644
--- a/core/templatetags/content_tags.py
+++ b/core/templatetags/content_tags.py
@@ -441,8 +441,7 @@ def render_automated_list_page_card_content(page, request, module_completion_dat
completion_percentage = module_completion_data.get('completion_percentage', 0)
completion_count = module_completion_data.get('completion_count', 0)
total_pages = module_completion_data.get('total_pages', 0)
- html_content = format_html(
- f"""
+ html_content = format_html(f"""
{ page.heading}
@@ -459,16 +458,13 @@ def render_automated_list_page_card_content(page, request, module_completion_dat
- """
- )
+ """)
else:
- html_content = format_html(
- f"""
+ html_content = format_html(f"""
{ page.heading}
- """
- )
+ """)
return html_content
diff --git a/core/templatetags/progress_bar.py b/core/templatetags/progress_bar.py
index b7d3fea0bd..70a59287ec 100644
--- a/core/templatetags/progress_bar.py
+++ b/core/templatetags/progress_bar.py
@@ -12,10 +12,8 @@ def progress_bar(total, complete):
percentage = int((complete / total) * 100) if (total or 0) > 0 else 0
- return format_html(
- f"""
+ return format_html(f"""
- """
- )
+ """)
diff --git a/core/templatetags/video_tags.py b/core/templatetags/video_tags.py
index cb7067c24a..b537df8937 100644
--- a/core/templatetags/video_tags.py
+++ b/core/templatetags/video_tags.py
@@ -74,8 +74,7 @@ def render_video(block):
"""
- rendered = format_html(
- f"""
+ rendered = format_html(f"""
{transcript_container}
- """
- )
+ """)
return rendered
diff --git a/core/wagtail_hooks.py b/core/wagtail_hooks.py
index 568ea96480..ab8ae1ad5f 100644
--- a/core/wagtail_hooks.py
+++ b/core/wagtail_hooks.py
@@ -506,15 +506,13 @@ def get_related_link_conversion(item):
@hooks.register('insert_editor_js')
def toolbar_sticky_by_default():
- return mark_safe(
- """
+ return mark_safe("""
- """
- )
+ """)
@hooks.register('register_help_menu_item')
diff --git a/export_academy/helpers.py b/export_academy/helpers.py
index a93a7742e5..53fece3971 100644
--- a/export_academy/helpers.py
+++ b/export_academy/helpers.py
@@ -135,13 +135,17 @@ def get_event_join_button(event):
def get_ics_button(event, on_confirmation):
return {
- 'label': f'Add to calendar{event.name}',
+ 'label': (
+ f'Add to calendar{event.name}'
+ ),
'value': 'Confirmed',
'type': 'submit',
- 'classname': 'govuk-button ukea-ga-tracking govuk-!-margin-bottom-0'
- if on_confirmation
- else 'govuk-button govuk-button--secondary ukea-ga-tracking govuk-!-margin-bottom-0',
+ 'classname': (
+ 'govuk-button ukea-ga-tracking govuk-!-margin-bottom-0'
+ if on_confirmation
+ else 'govuk-button govuk-button--secondary ukea-ga-tracking govuk-!-margin-bottom-0'
+ ),
}
diff --git a/exportplan/context.py b/exportplan/context.py
index 7b2c1dc429..df08a43055 100644
--- a/exportplan/context.py
+++ b/exportplan/context.py
@@ -75,15 +75,15 @@ def get_context_provider_data(self, request, **kwargs):
age_group_population_data[section] = {}
age_groups = self.export_plan.data['ui_options'].get(section, {}).get('target_ages', [])
age_group_population_data[section]['target_ages'] = age_groups
- age_group_population_data[section][
- 'male_target_age_population'
- ] = helpers.total_population_by_gender_age(
- dataset=population_dataset, age_filter=age_groups, gender='male'
+ age_group_population_data[section]['male_target_age_population'] = (
+ helpers.total_population_by_gender_age(
+ dataset=population_dataset, age_filter=age_groups, gender='male'
+ )
)
- age_group_population_data[section][
- 'female_target_age_population'
- ] = helpers.total_population_by_gender_age(
- dataset=population_dataset, age_filter=age_groups, gender='female'
+ age_group_population_data[section]['female_target_age_population'] = (
+ helpers.total_population_by_gender_age(
+ dataset=population_dataset, age_filter=age_groups, gender='female'
+ )
)
age_group_population_data[section]['total_target_age_population'] = int(
age_group_population_data[section]['male_target_age_population']
diff --git a/exportplan/forms.py b/exportplan/forms.py
index a7c858a70a..5a46313fb5 100644
--- a/exportplan/forms.py
+++ b/exportplan/forms.py
@@ -30,7 +30,7 @@ class ExportPlanAdaptingYourProductForm(forms.Form):
'research what the requirements are so your products have the correct labels for your '
'target market.'
),
- 'placeholder': ('Describe alterations'),
+ 'placeholder': 'Describe alterations',
}
),
)
@@ -45,7 +45,7 @@ class ExportPlanAdaptingYourProductForm(forms.Form):
'on the market.You will have to research packaging requirements for your target market to avoid '
'your products becoming damaged, lost or rejected.'
),
- 'placeholder': ('Describe alterations'),
+ 'placeholder': 'Describe alterations',
}
),
)
@@ -60,7 +60,7 @@ class ExportPlanAdaptingYourProductForm(forms.Form):
'shopping trips. You will have to research the size of products sold in this market so '
'you meet customer needs for your target market.'
),
- 'placeholder': ('Describe alterations'),
+ 'placeholder': 'Describe alterations',
}
),
)
@@ -75,39 +75,39 @@ class ExportPlanAdaptingYourProductForm(forms.Form):
'in order to comply with safety regulations in that market. You will have to research '
'standards relevant to your product to make sure they are compliant.'
),
- 'placeholder': ('Describe alterations'),
+ 'placeholder': 'Describe alterations',
}
),
)
translations = forms.CharField(
label='Translations',
required=False,
- widget=Textarea(attrs={'tooltip': ('Translations'), 'placeholder': ('Describe alterations')}),
+ widget=Textarea(attrs={'tooltip': 'Translations', 'placeholder': 'Describe alterations'}),
)
other_changes = forms.CharField(
label='Other changes',
required=False,
- widget=Textarea(attrs={'tooltip': ('Other changes'), 'placeholder': ('Describe alterations')}),
+ widget=Textarea(attrs={'tooltip': 'Other changes', 'placeholder': 'Describe alterations'}),
)
certificate_of_origin = forms.CharField(
label='Certificate of origin',
required=False,
- widget=Textarea(attrs={'tooltip': ('Certificate of origin'), 'placeholder': ('Add notes')}),
+ widget=Textarea(attrs={'tooltip': 'Certificate of origin', 'placeholder': 'Add notes'}),
)
insurance_certificate = forms.CharField(
label='Insurance certificate',
required=False,
- widget=Textarea(attrs={'tooltip': ('Insurance certificate'), 'placeholder': ('Add note')}),
+ widget=Textarea(attrs={'tooltip': 'Insurance certificate', 'placeholder': 'Add note'}),
)
commercial_invoice = forms.CharField(
label='Commercial invoice',
required=False,
- widget=Textarea(attrs={'tooltip': ('Commercial invoice'), 'placeholder': ('Add note')}),
+ widget=Textarea(attrs={'tooltip': 'Commercial invoice', 'placeholder': 'Add note'}),
)
uk_customs_declaration = forms.CharField(
label='UK customs declaration',
required=False,
- widget=Textarea(attrs={'tooltip': ('UK customs declaration'), 'placeholder': ('Add note')}),
+ widget=Textarea(attrs={'tooltip': 'UK customs declaration', 'placeholder': 'Add note'}),
)
@@ -122,9 +122,9 @@ def set_country_specific_text(self, country_name):
self.fields['demand'].label = f'Describe the consumer demand for your product in the {country_name}'
self.fields['competitors'].label = f'Who are your competitors in the {country_name}?'
self.fields['trend'].label = f'What are the product trends in the {country_name}?'
- self.fields[
- 'unqiue_selling_proposition'
- ].label = f'What’s your unique selling proposition for the {country_name}?'
+ self.fields['unqiue_selling_proposition'].label = (
+ f'What’s your unique selling proposition for the {country_name}?'
+ )
self.fields['average_price'].label = f'What’s the avg price for your product in the {country_name}?'
self.fields['trend'].widget.attrs['description'] = (
f'Describe what you know about the product market in the {country_name}. '
@@ -203,7 +203,7 @@ def set_country_specific_text(self, country_name):
average_price = forms.CharField(
required=False,
widget=NumberInput(
- attrs={'placeholder': ('0.00'), 'currency': ('GBP')},
+ attrs={'placeholder': '0.00', 'currency': 'GBP'},
),
)
diff --git a/learn/templatetags/helpers.py b/learn/templatetags/helpers.py
index b7ea35eded..6fac9e52a7 100644
--- a/learn/templatetags/helpers.py
+++ b/learn/templatetags/helpers.py
@@ -78,4 +78,4 @@ def get_article_cta_attributes(cta: UKEACTA) -> dict:
return series[0]
else:
# the default CTA will be displayed if series and first available_event are None
- return default_data
\ No newline at end of file
+ return default_data
diff --git a/sso_profile/business_profile/forms.py b/sso_profile/business_profile/forms.py
index e1cfaff375..946da3b5ce 100644
--- a/sso_profile/business_profile/forms.py
+++ b/sso_profile/business_profile/forms.py
@@ -166,7 +166,7 @@ class CaseStudyRichMediaForm(DynamicHelptextFieldsMixin, forms.Form):
'create_help_text': image_help_text_create,
'update_help_text': image_help_text_update,
'create_label': 'Upload a main image for this case study',
- 'update_label': ('Replace the main image for this case study (optional)'),
+ 'update_label': 'Replace the main image for this case study (optional)',
},
{
'field_name': 'image_two',
diff --git a/sso_profile/enrolment/views.py b/sso_profile/enrolment/views.py
index b81ea929dc..771df99df2 100644
--- a/sso_profile/enrolment/views.py
+++ b/sso_profile/enrolment/views.py
@@ -279,8 +279,8 @@ def done(self, form_list, form_dict, **kwargs):
'company_name': data['company_name'],
'name': self.request.user.full_name,
'email': self.request.user.email,
- 'profile_remove_member_url': (
- self.request.build_absolute_uri(reverse('sso_profile:business-profile-admin-tools'))
+ 'profile_remove_member_url': self.request.build_absolute_uri(
+ reverse('sso_profile:business-profile-admin-tools')
),
'report_abuse_url': urls.domestic.FEEDBACK,
},
diff --git a/tests/unit/contact/test_helpers.py b/tests/unit/contact/test_helpers.py
index 7a5734c0ae..f75a87073f 100644
--- a/tests/unit/contact/test_helpers.py
+++ b/tests/unit/contact/test_helpers.py
@@ -42,7 +42,7 @@ def all_offices():
'is_match': True,
'region_id': 'east_midlands',
'name': 'DIT East Midlands',
- 'address_street': ('The International Trade Centre, ' '5 Merus Court, ' 'Meridian Business Park'),
+ 'address_street': 'The International Trade Centre, ' '5 Merus Court, ' 'Meridian Business Park',
'address_city': 'Leicester',
'address_postcode': 'LE19 1RJ',
'email': 'test+east_midlands@examoke.com',
diff --git a/tests/unit/contact/test_views.py b/tests/unit/contact/test_views.py
index 1dbef940d8..ddfc59bb38 100644
--- a/tests/unit/contact/test_views.py
+++ b/tests/unit/contact/test_views.py
@@ -679,7 +679,7 @@ def test_office_finder_valid(all_office_details, client):
'is_match': True,
'region_id': 'east_midlands',
'name': 'DIT East Midlands',
- 'address_street': ('The International Trade Centre, ' '5 Merus Court, ' 'Meridian Business Park'),
+ 'address_street': 'The International Trade Centre, ' '5 Merus Court, ' 'Meridian Business Park',
'address_city': 'Leicester',
'address_postcode': 'LE19 1RJ',
'email': 'test+east_midlands@examoke.com',
@@ -697,7 +697,7 @@ def test_office_finder_valid(all_office_details, client):
'is_match': False,
'region_id': 'west_midlands',
'name': 'DIT West Midlands',
- 'address_street': ('The International Trade Centre, ' '10 New Street, ' 'Midlands Business Park'),
+ 'address_street': 'The International Trade Centre, ' '10 New Street, ' 'Midlands Business Park',
'address_city': 'Birmingham',
'address_postcode': 'B20 1RJ',
'email': 'test+west_midlands@examoke.com',
@@ -1844,7 +1844,7 @@ def test_regional_office_not_displayed_on_confirmation_page(
'is_match': True,
'region_id': 'east_midlands',
'name': 'DIT East Midlands',
- 'address_street': ('The International Trade Centre, ' '5 Merus Court, ' 'Meridian Business Park'),
+ 'address_street': 'The International Trade Centre, ' '5 Merus Court, ' 'Meridian Business Park',
'address_city': 'Leicester',
'address_postcode': 'LE19 1RJ',
'email': 'test+east_midlands@examoke.com',
diff --git a/tests/unit/core/test_wagtail_hooks.py b/tests/unit/core/test_wagtail_hooks.py
index 1ecc60cc49..0d960625da 100644
--- a/tests/unit/core/test_wagtail_hooks.py
+++ b/tests/unit/core/test_wagtail_hooks.py
@@ -1200,15 +1200,13 @@ def test_migrate_article_page(self):
class WagtailInsertEditorJsTestCase(TestCase):
def test_toolbar_sticky_by_default(self):
return_value = toolbar_sticky_by_default()
- expected_value = mark_safe(
- """
+ expected_value = mark_safe("""
- """
- )
+ """)
assert return_value == expected_value
diff --git a/tests/unit/domestic/management/commands/test_organise_country_guide_ctas.py b/tests/unit/domestic/management/commands/test_organise_country_guide_ctas.py
index e7bad06ab3..b3a945d40d 100644
--- a/tests/unit/domestic/management/commands/test_organise_country_guide_ctas.py
+++ b/tests/unit/domestic/management/commands/test_organise_country_guide_ctas.py
@@ -11,11 +11,14 @@
def test_organise_ctas(domestic_homepage):
ctas = {
'intro_cta_one_title': 'View live export opportunities for Antigua and Barbuda',
- 'intro_cta_one_link': 'https://www.great.gov.uk/export-opportunities/opportunities?s=&areas%5B%5D=antigua-and'
- '-barbuda&commit=Find+opportunities',
+ 'intro_cta_one_link': (
+ 'https://www.great.gov.uk/export-opportunities/opportunities?s=&areas%5B%5D=antigua-and'
+ '-barbuda&commit=Find+opportunities'
+ ),
'intro_cta_two_title': 'Find an online marketplace in Antigua and Barbuda',
- 'intro_cta_two_link': 'https://www.great.gov.uk/selling-online-overseas/markets/results/?category_id'
- '=&country_id=344&commit=',
+ 'intro_cta_two_link': (
+ 'https://www.great.gov.uk/selling-online-overseas/markets/results/?category_id' '=&country_id=344&commit='
+ ),
'intro_cta_three_title': 'Find export events for Antigua and Barbuda',
'intro_cta_three_link': 'https://www.events.great.gov.uk/ehome/index.php?eventid=200183029&',
'intro_cta_four_title': '',
diff --git a/tests/unit/domestic/management/commands/test_update_factsheets_cta_links.py b/tests/unit/domestic/management/commands/test_update_factsheets_cta_links.py
index 421f9c6b5a..f53c1f708a 100644
--- a/tests/unit/domestic/management/commands/test_update_factsheets_cta_links.py
+++ b/tests/unit/domestic/management/commands/test_update_factsheets_cta_links.py
@@ -37,8 +37,10 @@
'title': 'Trade and investment factsheets: Ivory Coast',
},
{
- 'url': 'https://assets.publishing.service.gov.uk/127'
- '/british-indian-ocean-territory-factsheet-2022-02-18.pdf',
+ 'url': (
+ 'https://assets.publishing.service.gov.uk/127'
+ '/british-indian-ocean-territory-factsheet-2022-02-18.pdf'
+ ),
'title': 'Trade and investment factsheets: British Indian Ocean Territory',
},
{
diff --git a/tests/unit/domestic/test_models.py b/tests/unit/domestic/test_models.py
index 3820aaff2c..eb4998bbb6 100644
--- a/tests/unit/domestic/test_models.py
+++ b/tests/unit/domestic/test_models.py
@@ -371,8 +371,10 @@ def test_fact_sheet_columns(
},
{
'title': 'Check for trade barriers',
- 'link': 'https://www.check-international-trade-barriers.service.gov.uk/barriers/'
- '?resolved=0&location=fr',
+ 'link': (
+ 'https://www.check-international-trade-barriers.service.gov.uk/barriers/'
+ '?resolved=0&location=fr'
+ ),
},
],
),
@@ -768,7 +770,7 @@ def test_base_content_page__get_breadcrumbs(
{
'title': article_page.title,
'url': article_page.url,
- }
+ },
# NB: article_page IS in this list
]
diff --git a/tests/unit/learn/factories.py b/tests/unit/learn/factories.py
index 136220d705..ae3e778ab2 100644
--- a/tests/unit/learn/factories.py
+++ b/tests/unit/learn/factories.py
@@ -24,4 +24,4 @@ class Meta:
class EventOrderableFactory(DjangoModelFactory):
class Meta:
- model = models.EventOrderable
\ No newline at end of file
+ model = models.EventOrderable
diff --git a/tests/unit/learn/test_templatetags.py b/tests/unit/learn/test_templatetags.py
index b25a4dd7dc..7c4a74e213 100644
--- a/tests/unit/learn/test_templatetags.py
+++ b/tests/unit/learn/test_templatetags.py
@@ -122,4 +122,4 @@ def test_get_article_cta_attributes(root_page, name, events, expected):
assert cta_attrs['image'] == expected['image']
assert cta_attrs['icon'] == expected['icon']
- assert cta_attrs['type'] == expected['type']
\ No newline at end of file
+ assert cta_attrs['type'] == expected['type']
diff --git a/tests/unit/sso_profile/enrolment/test_helpers.py b/tests/unit/sso_profile/enrolment/test_helpers.py
index bc308391c1..8a34d2d342 100644
--- a/tests/unit/sso_profile/enrolment/test_helpers.py
+++ b/tests/unit/sso_profile/enrolment/test_helpers.py
@@ -145,7 +145,7 @@ def test_notify_company_admins_member_joined_ok(mock_submit):
'form_url': 'the/form/url',
'sender': {},
'spam_control': {},
- 'template_id': (settings.GOV_NOTIFY_NEW_MEMBER_REGISTERED_TEMPLATE_ID),
+ 'template_id': settings.GOV_NOTIFY_NEW_MEMBER_REGISTERED_TEMPLATE_ID,
'email_address': 'admin@xyzcorp.com',
},
}
diff --git a/tests/unit/sso_profile/enrolment/test_widgets.py b/tests/unit/sso_profile/enrolment/test_widgets.py
index 15f38f13f1..eb5d17257a 100644
--- a/tests/unit/sso_profile/enrolment/test_widgets.py
+++ b/tests/unit/sso_profile/enrolment/test_widgets.py
@@ -54,8 +54,6 @@ class Form(forms.Form):
- """.format(
- span_class=span_class
- )
+ """.format(span_class=span_class)
assert_html_equal(expected_html=expected, actual_html=Form().as_p())
From 3e56e2b704d38949f20060d4274247826925a8e1 Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Tue, 16 Jan 2024 10:36:42 +0000
Subject: [PATCH 03/12] Added cta to DetailPage
---
core/models.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/core/models.py b/core/models.py
index 45dca8cea5..f3f5696ef5 100644
--- a/core/models.py
+++ b/core/models.py
@@ -946,6 +946,7 @@ def get_current_module(self):
FieldPanel('objective'),
FieldPanel('body'),
FieldPanel('recap'),
+ FieldPanel('call_to_action')
]
@cached_classmethod
From a51bc371c442694b8663be73247c7d3d787fa486 Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Tue, 16 Jan 2024 14:56:26 +0000
Subject: [PATCH 04/12] Fixed default CTS icon to series and adjusted test
---
learn/templatetags/helpers.py | 2 +-
tests/unit/learn/test_templatetags.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/learn/templatetags/helpers.py b/learn/templatetags/helpers.py
index 6fac9e52a7..0a97c7bd5e 100644
--- a/learn/templatetags/helpers.py
+++ b/learn/templatetags/helpers.py
@@ -43,7 +43,7 @@ def get_article_cta_attributes(cta: UKEACTA) -> dict:
'icon': '/static/icons/hand.svg',
'title': 'Join the UK Export Academy',
'description': 'Free training with Q&A, helping you learn to sell confidently to overseas customers',
- 'type': 'Series',
+ 'type': 'Service',
}
if not cta:
return default_data
diff --git a/tests/unit/learn/test_templatetags.py b/tests/unit/learn/test_templatetags.py
index 7c4a74e213..575f949636 100644
--- a/tests/unit/learn/test_templatetags.py
+++ b/tests/unit/learn/test_templatetags.py
@@ -84,7 +84,7 @@ def test_get_cta_attributes(domestic_site, link_text, type, url, expected):
{
'image': '/static/images/ukea-landing.png',
'icon': '/static/icons/hand.svg',
- 'type': 'Series',
+ 'type': 'Service',
},
),
(
From acf2cc9e30016472944cc88d130a99c00d0d6b21 Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Tue, 16 Jan 2024 15:11:15 +0000
Subject: [PATCH 05/12] Added new helper condition to exclude completed events
---
learn/templatetags/helpers.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/learn/templatetags/helpers.py b/learn/templatetags/helpers.py
index 0a97c7bd5e..8f093dab77 100644
--- a/learn/templatetags/helpers.py
+++ b/learn/templatetags/helpers.py
@@ -26,7 +26,7 @@ def get_cta_attributes(cta: RelatedContentCTA):
def get_first_available_event(event_ids: list):
first_available_event = None
for event in Event.objects.filter(id__in=event_ids):
- if event.start_date > timezone.now() and event.live:
+ if event.start_date > timezone.now() and event.live and not event.completed:
if first_available_event:
if event.start_date < first_available_event.start_date:
first_available_event = event
From c1b76fa9fc72e202bb15acf0ccff159f049b98ca Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Wed, 17 Jan 2024 13:55:35 +0000
Subject: [PATCH 06/12] Fixed templatetag test case
---
core/models.py | 2 +-
tests/unit/learn/test_templatetags.py | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/core/models.py b/core/models.py
index f3f5696ef5..58a844e69a 100644
--- a/core/models.py
+++ b/core/models.py
@@ -946,7 +946,7 @@ def get_current_module(self):
FieldPanel('objective'),
FieldPanel('body'),
FieldPanel('recap'),
- FieldPanel('call_to_action')
+ FieldPanel('call_to_action'),
]
@cached_classmethod
diff --git a/tests/unit/learn/test_templatetags.py b/tests/unit/learn/test_templatetags.py
index 575f949636..1262a57bdd 100644
--- a/tests/unit/learn/test_templatetags.py
+++ b/tests/unit/learn/test_templatetags.py
@@ -115,7 +115,7 @@ def test_get_article_cta_attributes(root_page, name, events, expected):
if events:
for loop in range(events):
delta = timezone.now() + timezone.timedelta(days=1 + loop)
- event_obj = EventFactory(start_date=delta, live=delta)
+ event_obj = EventFactory(start_date=delta, live=delta, completed=None)
EventOrderableFactory(page=cta, event=event_obj)
cta_attrs = get_article_cta_attributes(cta)
From 31441d6a734ca4358061dcca1148913bd14d4aaf Mon Sep 17 00:00:00 2001
From: davidu1975
Date: Wed, 17 Jan 2024 15:55:22 +0000
Subject: [PATCH 07/12] build requirements
---
requirements.txt | 4 ++--
requirements_test.txt | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/requirements.txt b/requirements.txt
index c1b92c5487..106243a93f 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -257,7 +257,7 @@ jsonschema==3.2.0
# directory-components
# drf-spectacular
# great-components
-kombu==5.3.4
+kombu==5.3.5
# via celery
l18n==2021.3
# via wagtail
@@ -418,7 +418,7 @@ soupsieve==2.5
# via beautifulsoup4
sphinx==1.8.6
# via -r requirements.in
-sphinxcontrib-serializinghtml==1.1.5
+sphinxcontrib-serializinghtml==1.1.10
# via sphinxcontrib-websupport
sphinxcontrib-websupport==1.2.4
# via sphinx
diff --git a/requirements_test.txt b/requirements_test.txt
index 66a0f03d21..97a9c2f97f 100644
--- a/requirements_test.txt
+++ b/requirements_test.txt
@@ -426,7 +426,7 @@ jsonschema==3.2.0
# directory-components
# drf-spectacular
# great-components
-kombu==5.3.4
+kombu==5.3.5
# via celery
l18n==2021.3
# via wagtail
@@ -734,7 +734,7 @@ soupsieve==2.5
# via beautifulsoup4
sphinx==1.8.6
# via -r requirements.in
-sphinxcontrib-serializinghtml==1.1.5
+sphinxcontrib-serializinghtml==1.1.10
# via sphinxcontrib-websupport
sphinxcontrib-websupport==1.2.4
# via sphinx
From 66d6b02b122d14ba4d3e490e2c8e0d2f858c2ee4 Mon Sep 17 00:00:00 2001
From: davidu1975
Date: Wed, 17 Jan 2024 16:02:44 +0000
Subject: [PATCH 08/12] build requirements
---
requirements_test.in | 2 +-
requirements_test.txt | 22 ++--------------------
2 files changed, 3 insertions(+), 21 deletions(-)
diff --git a/requirements_test.in b/requirements_test.in
index 6ab07889c6..0466697af4 100644
--- a/requirements_test.in
+++ b/requirements_test.in
@@ -25,7 +25,7 @@ browserstack-sdk==1.12.0
# Code quality
# -------------
-black
+black==23.12.1
blacken-docs==1.6.0
isort==5.12.0
flake8==6.1.0
diff --git a/requirements_test.txt b/requirements_test.txt
index 97a9c2f97f..66e15bb6a6 100644
--- a/requirements_test.txt
+++ b/requirements_test.txt
@@ -6,10 +6,6 @@
#
--no-binary psycopg2
-aiohttp==3.9.1
- # via black
-aiosignal==1.3.1
- # via aiohttp
airtable-python-wrapper==0.13.0
# via -r requirements.in
alabaster==0.7.16
@@ -36,12 +32,9 @@ astroid==3.0.2
asttokens==2.4.1
# via stack-data
async-timeout==4.0.3
- # via
- # aiohttp
- # redis
+ # via redis
attrs==23.2.0
# via
- # aiohttp
# allure-python-commons
# jsonschema
# outcome
@@ -59,7 +52,7 @@ beautifulsoup4==4.11.2
# wagtail
billiard==3.6.4.0
# via celery
-black==24.1a1
+black==23.12.1
# via
# -r requirements_test.in
# blacken-docs
@@ -340,10 +333,6 @@ freetype-py==2.3.0
# rlpycairo
freezegun==1.1.0
# via -r requirements_test.in
-frozenlist==1.4.1
- # via
- # aiohttp
- # aiosignal
geoip2==2.9.0
# via -r requirements.in
gevent==23.9.1
@@ -382,7 +371,6 @@ idna==3.6
# via
# requests
# trio
- # yarl
imagesize==1.4.1
# via sphinx
importlib-metadata==7.0.1
@@ -461,10 +449,6 @@ monotonic==1.6
# directory-client-core
msgpack==1.0.7
# via locust
-multidict==6.0.4
- # via
- # aiohttp
- # yarl
mypy-extensions==1.0.0
# via black
nodeenv==1.8.0
@@ -880,8 +864,6 @@ wsproto==1.2.0
# via trio-websocket
xhtml2pdf==0.2.13
# via -r requirements.in
-yarl==1.9.4
- # via aiohttp
zipp==3.17.0
# via importlib-metadata
zope-event==5.0
From 8ec617b5027da5f7db92e7c53ca579145e2b16f6 Mon Sep 17 00:00:00 2001
From: davidu1975
Date: Wed, 17 Jan 2024 16:04:38 +0000
Subject: [PATCH 09/12] updated black
---
core/models.py | 1 -
core/templatetags/content_tags.py | 12 ++++++++----
core/templatetags/progress_bar.py | 6 ++++--
core/templatetags/video_tags.py | 6 ++++--
core/wagtail_hooks.py | 6 ++++--
exportplan/context.py | 16 ++++++++--------
exportplan/forms.py | 6 +++---
tests/unit/core/test_wagtail_hooks.py | 6 ++++--
tests/unit/learn/test_templatetags.py | 1 -
tests/unit/sso_profile/enrolment/test_widgets.py | 4 +++-
10 files changed, 38 insertions(+), 26 deletions(-)
diff --git a/core/models.py b/core/models.py
index 58a844e69a..ae3bbc89d9 100644
--- a/core/models.py
+++ b/core/models.py
@@ -1074,7 +1074,6 @@ class EventOrderable(Orderable):
@register_snippet
class UKEACTA(ClusterableModel):
-
image = StreamField(
[
(
diff --git a/core/templatetags/content_tags.py b/core/templatetags/content_tags.py
index d0da024a2b..943c5a7cb5 100644
--- a/core/templatetags/content_tags.py
+++ b/core/templatetags/content_tags.py
@@ -441,7 +441,8 @@ def render_automated_list_page_card_content(page, request, module_completion_dat
completion_percentage = module_completion_data.get('completion_percentage', 0)
completion_count = module_completion_data.get('completion_count', 0)
total_pages = module_completion_data.get('total_pages', 0)
- html_content = format_html(f"""
+ html_content = format_html(
+ f"""
{ page.heading}
@@ -458,13 +459,16 @@ def render_automated_list_page_card_content(page, request, module_completion_dat
- """)
+ """
+ )
else:
- html_content = format_html(f"""
+ html_content = format_html(
+ f"""
{ page.heading}
- """)
+ """
+ )
return html_content
diff --git a/core/templatetags/progress_bar.py b/core/templatetags/progress_bar.py
index 70a59287ec..b7d3fea0bd 100644
--- a/core/templatetags/progress_bar.py
+++ b/core/templatetags/progress_bar.py
@@ -12,8 +12,10 @@ def progress_bar(total, complete):
percentage = int((complete / total) * 100) if (total or 0) > 0 else 0
- return format_html(f"""
+ return format_html(
+ f"""
- """)
+ """
+ )
diff --git a/core/templatetags/video_tags.py b/core/templatetags/video_tags.py
index b537df8937..cb7067c24a 100644
--- a/core/templatetags/video_tags.py
+++ b/core/templatetags/video_tags.py
@@ -74,7 +74,8 @@ def render_video(block):
"""
- rendered = format_html(f"""
+ rendered = format_html(
+ f"""
{transcript_container}
- """)
+ """
+ )
return rendered
diff --git a/core/wagtail_hooks.py b/core/wagtail_hooks.py
index ab8ae1ad5f..568ea96480 100644
--- a/core/wagtail_hooks.py
+++ b/core/wagtail_hooks.py
@@ -506,13 +506,15 @@ def get_related_link_conversion(item):
@hooks.register('insert_editor_js')
def toolbar_sticky_by_default():
- return mark_safe("""
+ return mark_safe(
+ """
- """)
+ """
+ )
@hooks.register('register_help_menu_item')
diff --git a/exportplan/context.py b/exportplan/context.py
index df08a43055..7b2c1dc429 100644
--- a/exportplan/context.py
+++ b/exportplan/context.py
@@ -75,15 +75,15 @@ def get_context_provider_data(self, request, **kwargs):
age_group_population_data[section] = {}
age_groups = self.export_plan.data['ui_options'].get(section, {}).get('target_ages', [])
age_group_population_data[section]['target_ages'] = age_groups
- age_group_population_data[section]['male_target_age_population'] = (
- helpers.total_population_by_gender_age(
- dataset=population_dataset, age_filter=age_groups, gender='male'
- )
+ age_group_population_data[section][
+ 'male_target_age_population'
+ ] = helpers.total_population_by_gender_age(
+ dataset=population_dataset, age_filter=age_groups, gender='male'
)
- age_group_population_data[section]['female_target_age_population'] = (
- helpers.total_population_by_gender_age(
- dataset=population_dataset, age_filter=age_groups, gender='female'
- )
+ age_group_population_data[section][
+ 'female_target_age_population'
+ ] = helpers.total_population_by_gender_age(
+ dataset=population_dataset, age_filter=age_groups, gender='female'
)
age_group_population_data[section]['total_target_age_population'] = int(
age_group_population_data[section]['male_target_age_population']
diff --git a/exportplan/forms.py b/exportplan/forms.py
index 5a46313fb5..bfdc35093d 100644
--- a/exportplan/forms.py
+++ b/exportplan/forms.py
@@ -122,9 +122,9 @@ def set_country_specific_text(self, country_name):
self.fields['demand'].label = f'Describe the consumer demand for your product in the {country_name}'
self.fields['competitors'].label = f'Who are your competitors in the {country_name}?'
self.fields['trend'].label = f'What are the product trends in the {country_name}?'
- self.fields['unqiue_selling_proposition'].label = (
- f'What’s your unique selling proposition for the {country_name}?'
- )
+ self.fields[
+ 'unqiue_selling_proposition'
+ ].label = f'What’s your unique selling proposition for the {country_name}?'
self.fields['average_price'].label = f'What’s the avg price for your product in the {country_name}?'
self.fields['trend'].widget.attrs['description'] = (
f'Describe what you know about the product market in the {country_name}. '
diff --git a/tests/unit/core/test_wagtail_hooks.py b/tests/unit/core/test_wagtail_hooks.py
index 0d960625da..1ecc60cc49 100644
--- a/tests/unit/core/test_wagtail_hooks.py
+++ b/tests/unit/core/test_wagtail_hooks.py
@@ -1200,13 +1200,15 @@ def test_migrate_article_page(self):
class WagtailInsertEditorJsTestCase(TestCase):
def test_toolbar_sticky_by_default(self):
return_value = toolbar_sticky_by_default()
- expected_value = mark_safe("""
+ expected_value = mark_safe(
+ """
- """)
+ """
+ )
assert return_value == expected_value
diff --git a/tests/unit/learn/test_templatetags.py b/tests/unit/learn/test_templatetags.py
index 1262a57bdd..29f039d339 100644
--- a/tests/unit/learn/test_templatetags.py
+++ b/tests/unit/learn/test_templatetags.py
@@ -109,7 +109,6 @@ def test_get_cta_attributes(domestic_site, link_text, type, url, expected):
)
@pytest.mark.django_db
def test_get_article_cta_attributes(root_page, name, events, expected):
-
cta = UKEACTASnippetFactory(name=name)
if events:
diff --git a/tests/unit/sso_profile/enrolment/test_widgets.py b/tests/unit/sso_profile/enrolment/test_widgets.py
index eb5d17257a..15f38f13f1 100644
--- a/tests/unit/sso_profile/enrolment/test_widgets.py
+++ b/tests/unit/sso_profile/enrolment/test_widgets.py
@@ -54,6 +54,8 @@ class Form(forms.Form):
- """.format(span_class=span_class)
+ """.format(
+ span_class=span_class
+ )
assert_html_equal(expected_html=expected, actual_html=Form().as_p())
From 937f408ea0c16be3a3f6ca458dab2eda47e29251 Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Fri, 19 Jan 2024 11:45:26 +0000
Subject: [PATCH 10/12] improved get_first_available_event function
---
learn/templatetags/helpers.py | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/learn/templatetags/helpers.py b/learn/templatetags/helpers.py
index 8f093dab77..b758c954cf 100644
--- a/learn/templatetags/helpers.py
+++ b/learn/templatetags/helpers.py
@@ -22,16 +22,12 @@ def get_cta_attributes(cta: RelatedContentCTA):
result['tag_icon'] = '/static/icons/hand.svg' if 'service' in cta.type.lower() else '/static/icons/guidance.svg'
return result
-
def get_first_available_event(event_ids: list):
first_available_event = None
- for event in Event.objects.filter(id__in=event_ids):
+ for event in Event.objects.filter(id__in=event_ids).order_by("start_date"):
+ print(event.start_date)
if event.start_date > timezone.now() and event.live and not event.completed:
- if first_available_event:
- if event.start_date < first_available_event.start_date:
- first_available_event = event
- else:
- first_available_event = event
+ return event
return first_available_event
From f0799b0280915af623dff2daf058dae8afb812e3 Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Fri, 19 Jan 2024 11:48:02 +0000
Subject: [PATCH 11/12] formatted helpers
---
learn/templatetags/helpers.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/learn/templatetags/helpers.py b/learn/templatetags/helpers.py
index b758c954cf..d335fcdb7f 100644
--- a/learn/templatetags/helpers.py
+++ b/learn/templatetags/helpers.py
@@ -22,6 +22,7 @@ def get_cta_attributes(cta: RelatedContentCTA):
result['tag_icon'] = '/static/icons/hand.svg' if 'service' in cta.type.lower() else '/static/icons/guidance.svg'
return result
+
def get_first_available_event(event_ids: list):
first_available_event = None
for event in Event.objects.filter(id__in=event_ids).order_by("start_date"):
From dc798c6b53db97b303f54d0a6bf9b3107093c5ad Mon Sep 17 00:00:00 2001
From: bobby-didcoding
Date: Fri, 19 Jan 2024 12:10:45 +0000
Subject: [PATCH 12/12] formatted helpers
---
learn/templatetags/helpers.py | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/learn/templatetags/helpers.py b/learn/templatetags/helpers.py
index d335fcdb7f..73e8a9acfb 100644
--- a/learn/templatetags/helpers.py
+++ b/learn/templatetags/helpers.py
@@ -25,8 +25,7 @@ def get_cta_attributes(cta: RelatedContentCTA):
def get_first_available_event(event_ids: list):
first_available_event = None
- for event in Event.objects.filter(id__in=event_ids).order_by("start_date"):
- print(event.start_date)
+ for event in Event.objects.filter(id__in=event_ids).order_by('start_date'):
if event.start_date > timezone.now() and event.live and not event.completed:
return event
return first_available_event