diff --git a/CHANGELOG.md b/CHANGELOG.md index 948639f6..ed964099 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,8 +3,11 @@ ## Pre-release ### Implemented enhancements +- No ticket - Make teaser field optional in international articles - No ticket - Add featured industries to Invest home page - CI-321 - About UK landing page +- CI-276 - Added `CapitalInvestContactFormPage` and `CapitalInvestContactFormSuccessPage` +- CI-429 - Tree based breadcrumbs can now use `breadcrumbs_label` if available ### Fixed Bugs - CI-426 - Added pdf document upload to why choose uk page for ebook section diff --git a/core/serializer_mapping.py b/core/serializer_mapping.py index ec495443..e3b32ce8 100644 --- a/core/serializer_mapping.py +++ b/core/serializer_mapping.py @@ -59,6 +59,8 @@ great_international.models.capital_invest.CapitalInvestRegionPage: great_international.serializers.CapitalInvestRegionPageSerializer, # NOQA great_international.models.capital_invest.CapitalInvestOpportunityListingPage: great_international.serializers.CapitalInvestOpportunityListingSerializer, # NOQA great_international.models.capital_invest.CapitalInvestOpportunityPage: great_international.serializers.CapitalInvestOpportunityPageSerializer, # NOQA + great_international.models.capital_invest.CapitalInvestContactFormPage: great_international.serializers.CapitalInvestContactFormPageSerializer, # NOQA + great_international.models.capital_invest.CapitalInvestContactFormSuccessPage: great_international.serializers.CapitalInvestContactFormSuccessPageSerializer, # NOQA great_international.models.invest.InvestInternationalHomePage: great_international.serializers.InvestInternationalHomePageSerializer, # NOQA great_international.models.invest.InvestHighPotentialOpportunityFormSuccessPage: great_international.serializers.InvestHighPotentialOpportunityFormSuccessPageSerializer, # NOQA great_international.models.invest.InvestHighPotentialOpportunityFormPage: great_international.serializers.InvestHighPotentialOpportunityFormPageSerializer, # NOQA diff --git a/core/serializers.py b/core/serializers.py index a18caa0d..b972ea9c 100644 --- a/core/serializers.py +++ b/core/serializers.py @@ -10,6 +10,11 @@ class PageTitleAndUrlSerializer(serializers.Serializer): url = serializers.CharField() +class PageBreadcrumbsAndUrlSerializer(serializers.Serializer): + title = serializers.CharField(source='breadcrumbs_label') + url = serializers.CharField() + + class BasePageSerializer(serializers.Serializer): id = serializers.IntegerField() seo_title = serializers.CharField() @@ -27,7 +32,15 @@ def get_tree_based_breadcrumbs(self, instance): breadcrumbs = [ page.specific for page in instance.specific.ancestors_in_app] breadcrumbs.append(instance) - return PageTitleAndUrlSerializer(breadcrumbs, many=True).data + serialized = [] + + for crumb in breadcrumbs: + if hasattr(crumb, 'breadcrumbs_label'): + serialized.append(PageBreadcrumbsAndUrlSerializer(crumb).data) + else: + serialized.append(PageTitleAndUrlSerializer(crumb).data) + + return serialized def get_page_type(self, instance): return instance.__class__.__name__ diff --git a/db_template.sql b/db_template.sql index 59548abb..151211f5 100644 --- a/db_template.sql +++ b/db_template.sql @@ -2,8 +2,8 @@ -- PostgreSQL database dump -- --- Dumped from database version 10.6 (Ubuntu 10.6-0ubuntu0.18.04.1) --- Dumped by pg_dump version 10.6 (Ubuntu 10.6-0ubuntu0.18.04.1) +-- Dumped from database version 9.6.14 +-- Dumped by pg_dump version 11.3 SET statement_timeout = 0; SET lock_timeout = 0; @@ -12,23 +12,10 @@ SET client_encoding = 'UTF8'; SET standard_conforming_strings = on; SELECT pg_catalog.set_config('search_path', '', false); SET check_function_bodies = false; +SET xmloption = content; SET client_min_messages = warning; SET row_security = off; --- --- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: - --- - -CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog; - - --- --- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: - --- - -COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language'; - - SET default_tablespace = ''; SET default_with_oids = false; @@ -2988,6 +2975,82 @@ CREATE TABLE public.great_international_aboutukwhychoosetheukpage ( ); +-- +-- Name: great_international_capitalinvestcontactformpage; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.great_international_capitalinvestcontactformpage ( + page_ptr_id integer NOT NULL, + service_name character varying(100), + uses_tree_based_routing boolean NOT NULL, + breadcrumbs_label character varying(255) NOT NULL, + breadcrumbs_label_en_gb character varying(255), + breadcrumbs_label_de character varying(255), + breadcrumbs_label_ja character varying(255), + breadcrumbs_label_zh_hans character varying(255), + breadcrumbs_label_fr character varying(255), + breadcrumbs_label_es character varying(255), + breadcrumbs_label_pt character varying(255), + breadcrumbs_label_ar character varying(255), + heading character varying(255) NOT NULL, + heading_en_gb character varying(255), + heading_de character varying(255), + heading_ja character varying(255), + heading_zh_hans character varying(255), + heading_fr character varying(255), + heading_es character varying(255), + heading_pt character varying(255), + heading_ar character varying(255), + intro text NOT NULL, + intro_en_gb text, + intro_de text, + intro_ja text, + intro_zh_hans text, + intro_fr text, + intro_es text, + intro_pt text, + intro_ar text, + cta_text character varying(255) NOT NULL, + cta_text_en_gb character varying(255), + cta_text_de character varying(255), + cta_text_ja character varying(255), + cta_text_zh_hans character varying(255), + cta_text_fr character varying(255), + cta_text_es character varying(255), + cta_text_pt character varying(255), + cta_text_ar character varying(255) +); + + +-- +-- Name: great_international_capitalinvestcontactformsuccesspage; Type: TABLE; Schema: public; Owner: - +-- + +CREATE TABLE public.great_international_capitalinvestcontactformsuccesspage ( + page_ptr_id integer NOT NULL, + service_name character varying(100), + uses_tree_based_routing boolean NOT NULL, + large_text character varying(255) NOT NULL, + large_text_en_gb character varying(255), + large_text_de character varying(255), + large_text_ja character varying(255), + large_text_zh_hans character varying(255), + large_text_fr character varying(255), + large_text_es character varying(255), + large_text_pt character varying(255), + large_text_ar character varying(255), + small_text text NOT NULL, + small_text_en_gb text, + small_text_de text, + small_text_ja text, + small_text_zh_hans text, + small_text_fr text, + small_text_es text, + small_text_pt text, + small_text_ar text +); + + -- -- Name: great_international_capitalinvesthomesinenglandcardfieldssu8d44; Type: TABLE; Schema: public; Owner: - -- @@ -12566,6 +12629,14 @@ COPY public.auth_permission (id, name, content_type_id, codename) FROM stdin; 475 Can change invest region page 112 change_investregionpage 476 Can delete invest region page 112 delete_investregionpage 477 Can view invest region page 112 view_investregionpage +478 Can add capital invest contact form page 120 add_capitalinvestcontactformpage +479 Can change capital invest contact form page 120 change_capitalinvestcontactformpage +480 Can delete capital invest contact form page 120 delete_capitalinvestcontactformpage +481 Can view capital invest contact form page 120 view_capitalinvestcontactformpage +482 Can add capital invest contact form success page 121 add_capitalinvestcontactformsuccesspage +483 Can change capital invest contact form success page 121 change_capitalinvestcontactformsuccesspage +484 Can delete capital invest contact form success page 121 delete_capitalinvestcontactformsuccesspage +485 Can view capital invest contact form success page 121 view_capitalinvestcontactformsuccesspage \. @@ -12773,6 +12844,8 @@ COPY public.django_content_type (id, app_label, model) FROM stdin; 118 great_international aboutuklandingpage 119 great_international aboutukarticlesfields 112 great_international investregionpage +120 great_international capitalinvestcontactformpage +121 great_international capitalinvestcontactformsuccesspage \. @@ -13140,6 +13213,8 @@ COPY public.django_migrations (id, app, name, applied) FROM stdin; 357 great_international 0063_auto_20190807_1504 2019-08-08 10:30:16.491643+01 358 great_international 0064_merge_20190808_0928 2019-08-08 10:30:16.542222+01 359 great_international 0065_auto_20190808_1032 2019-08-08 11:37:15.180475+01 +360 great_international 0066_capitalinvestcontactformpage_capitalinvestcontactformsuccesspage 2019-08-09 09:15:15.500538+01 +361 great_international 0067_auto_20190814_0940 2019-08-14 10:42:44.256149+01 \. @@ -13495,6 +13570,22 @@ COPY public.great_international_aboutukwhychoosetheukpage (page_ptr_id, service_ \. +-- +-- Data for Name: great_international_capitalinvestcontactformpage; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY public.great_international_capitalinvestcontactformpage (page_ptr_id, service_name, uses_tree_based_routing, breadcrumbs_label, breadcrumbs_label_en_gb, breadcrumbs_label_de, breadcrumbs_label_ja, breadcrumbs_label_zh_hans, breadcrumbs_label_fr, breadcrumbs_label_es, breadcrumbs_label_pt, breadcrumbs_label_ar, heading, heading_en_gb, heading_de, heading_ja, heading_zh_hans, heading_fr, heading_es, heading_pt, heading_ar, intro, intro_en_gb, intro_de, intro_ja, intro_zh_hans, intro_fr, intro_es, intro_pt, intro_ar, cta_text, cta_text_en_gb, cta_text_de, cta_text_ja, cta_text_zh_hans, cta_text_fr, cta_text_es, cta_text_pt, cta_text_ar) FROM stdin; +\. + + +-- +-- Data for Name: great_international_capitalinvestcontactformsuccesspage; Type: TABLE DATA; Schema: public; Owner: - +-- + +COPY public.great_international_capitalinvestcontactformsuccesspage (page_ptr_id, service_name, uses_tree_based_routing, large_text, large_text_en_gb, large_text_de, large_text_ja, large_text_zh_hans, large_text_fr, large_text_es, large_text_pt, large_text_ar, small_text, small_text_en_gb, small_text_de, small_text_ja, small_text_zh_hans, small_text_fr, small_text_es, small_text_pt, small_text_ar) FROM stdin; +\. + + -- -- Data for Name: great_international_capitalinvesthomesinenglandcardfieldssu8d44; Type: TABLE DATA; Schema: public; Owner: - -- @@ -14153,7 +14244,7 @@ SELECT pg_catalog.setval('public.auth_group_permissions_id_seq', 20, true); -- Name: auth_permission_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - -- -SELECT pg_catalog.setval('public.auth_permission_id_seq', 477, true); +SELECT pg_catalog.setval('public.auth_permission_id_seq', 485, true); -- @@ -14216,14 +14307,14 @@ SELECT pg_catalog.setval('public.django_admin_log_id_seq', 1, false); -- Name: django_content_type_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - -- -SELECT pg_catalog.setval('public.django_content_type_id_seq', 119, true); +SELECT pg_catalog.setval('public.django_content_type_id_seq', 121, true); -- -- Name: django_migrations_id_seq; Type: SEQUENCE SET; Schema: public; Owner: - -- -SELECT pg_catalog.setval('public.django_migrations_id_seq', 359, true); +SELECT pg_catalog.setval('public.django_migrations_id_seq', 361, true); -- @@ -15124,6 +15215,22 @@ ALTER TABLE ONLY public.great_international_aboutukwhychoosetheukpage ADD CONSTRAINT great_international_aboutukwhychoosetheukpage_pkey PRIMARY KEY (page_ptr_id); +-- +-- Name: great_international_capitalinvestcontactformpage great_international_capitalinvestcontactformpage_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.great_international_capitalinvestcontactformpage + ADD CONSTRAINT great_international_capitalinvestcontactformpage_pkey PRIMARY KEY (page_ptr_id); + + +-- +-- Name: great_international_capitalinvestcontactformsuccesspage great_international_capitalinvestcontactformsuccesspage_pkey; Type: CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.great_international_capitalinvestcontactformsuccesspage + ADD CONSTRAINT great_international_capitalinvestcontactformsuccesspage_pkey PRIMARY KEY (page_ptr_id); + + -- -- Name: great_international_capitalinvesthomesinenglandcardfieldssu8d44 great_international_capitalinvesthomesinenglandcardfieldss_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- @@ -18635,6 +18742,20 @@ CREATE INDEX great_international_aboutuklandingpage_hero_image_id_6da7f8a1 ON pu CREATE INDEX great_international_aboutuklandingpage_service_name_441d14f1 ON public.great_international_aboutuklandingpage USING btree (service_name); +-- +-- Name: great_international_capi_service_name_04b98f69_like; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX great_international_capi_service_name_04b98f69_like ON public.great_international_capitalinvestcontactformsuccesspage USING btree (service_name varchar_pattern_ops); + + +-- +-- Name: great_international_capi_service_name_0867015e_like; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX great_international_capi_service_name_0867015e_like ON public.great_international_capitalinvestcontactformpage USING btree (service_name varchar_pattern_ops); + + -- -- Name: great_international_capi_service_name_a0c9c921_like; Type: INDEX; Schema: public; Owner: - -- @@ -19958,6 +20079,20 @@ CREATE INDEX great_international_capita_sector_icon_pt_id_bf4f43c2 ON public.gre CREATE INDEX great_international_capita_sector_icon_zh_hans_id_65d6dab1 ON public.great_international_capitalinvestopportunitypage USING btree (sector_icon_zh_hans_id); +-- +-- Name: great_international_capita_service_name_04b98f69; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX great_international_capita_service_name_04b98f69 ON public.great_international_capitalinvestcontactformsuccesspage USING btree (service_name); + + +-- +-- Name: great_international_capita_service_name_0867015e; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX great_international_capita_service_name_0867015e ON public.great_international_capitalinvestcontactformpage USING btree (service_name); + + -- -- Name: great_international_capita_service_name_a0c9c921; Type: INDEX; Schema: public; Owner: - -- @@ -39690,6 +39825,14 @@ ALTER TABLE ONLY public.great_international_investhighpotentialopportunityformsu ADD CONSTRAINT great_international__page_ptr_id_4e2e59c3_fk_wagtailco FOREIGN KEY (page_ptr_id) REFERENCES public.wagtailcore_page(id) DEFERRABLE INITIALLY DEFERRED; +-- +-- Name: great_international_capitalinvestcontactformpage great_international__page_ptr_id_4f703dde_fk_wagtailco; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.great_international_capitalinvestcontactformpage + ADD CONSTRAINT great_international__page_ptr_id_4f703dde_fk_wagtailco FOREIGN KEY (page_ptr_id) REFERENCES public.wagtailcore_page(id) DEFERRABLE INITIALLY DEFERRED; + + -- -- Name: great_international_internationaleuexitformpage great_international__page_ptr_id_6d7c3ad3_fk_wagtailco; Type: FK CONSTRAINT; Schema: public; Owner: - -- @@ -39866,6 +40009,14 @@ ALTER TABLE ONLY public.great_international_internationalhomepage ADD CONSTRAINT great_international__page_ptr_id_e94f663f_fk_wagtailco FOREIGN KEY (page_ptr_id) REFERENCES public.wagtailcore_page(id) DEFERRABLE INITIALLY DEFERRED; +-- +-- Name: great_international_capitalinvestcontactformsuccesspage great_international__page_ptr_id_f96df5cc_fk_wagtailco; Type: FK CONSTRAINT; Schema: public; Owner: - +-- + +ALTER TABLE ONLY public.great_international_capitalinvestcontactformsuccesspage + ADD CONSTRAINT great_international__page_ptr_id_f96df5cc_fk_wagtailco FOREIGN KEY (page_ptr_id) REFERENCES public.wagtailcore_page(id) DEFERRABLE INITIALLY DEFERRED; + + -- -- Name: great_international_capitalinvestregioncardfieldssummary great_international__page_zh_hans_id_0c11ab1c_fk_great_int; Type: FK CONSTRAINT; Schema: public; Owner: - -- diff --git a/great_international/apps.py b/great_international/apps.py index d0754d49..7397d24c 100644 --- a/great_international/apps.py +++ b/great_international/apps.py @@ -36,6 +36,8 @@ def ready(self): cache.AboutDitServicesPageSubscriber.subscribe() cache.AboutUkLandingPageSubscriber.subscribe() cache.AboutUkWhyChooseTheUkPageSubscriber.subscribe() + cache.CapitalInvestContactFormPageSubscriber.subscribe() + cache.CapitalInvestContactFormSuccessPageSubscriber.subscribe() # tags inheritance signals post_save.connect( receiver=signals.inherit_tags_from_parent, diff --git a/great_international/cache.py b/great_international/cache.py index 1a2bd147..60593149 100644 --- a/great_international/cache.py +++ b/great_international/cache.py @@ -48,7 +48,9 @@ class InternationalHomePageOldSubscriber(AbstractDatabaseCacheSubscriber): class InternationalArticlePageSubscriber(AbstractDatabaseCacheSubscriber): model = great_international.InternationalArticlePage - subscriptions = [] + subscriptions = [ + great_international.InternationalSectorPage + ] class InternationalCampaignPageSubscriber(AbstractDatabaseCacheSubscriber): @@ -239,3 +241,22 @@ class AboutUkWhyChooseTheUkPageSubscriber( ): model = great_international.AboutUkWhyChooseTheUkPage subscriptions = [] + + +class CapitalInvestContactFormPageSubscriber( + AbstractDatabaseCacheSubscriber +): + model = capital_invest.CapitalInvestContactFormPage + subscriptions = [ + capital_invest.InternationalCapitalInvestLandingPage + ] + + +class CapitalInvestContactFormSuccessPageSubscriber( + AbstractDatabaseCacheSubscriber +): + model = capital_invest.CapitalInvestContactFormSuccessPage + subscriptions = [ + capital_invest.InternationalCapitalInvestLandingPage, + capital_invest.CapitalInvestContactFormPage + ] diff --git a/great_international/migrations/0066_capitalinvestcontactformpage_capitalinvestcontactformsuccesspage.py b/great_international/migrations/0066_capitalinvestcontactformpage_capitalinvestcontactformsuccesspage.py new file mode 100644 index 00000000..acc8f491 --- /dev/null +++ b/great_international/migrations/0066_capitalinvestcontactformpage_capitalinvestcontactformsuccesspage.py @@ -0,0 +1,97 @@ +# Generated by Django 2.2.3 on 2019-08-08 14:51 + +import core.model_fields +import core.models +import core.validators +from django.db import migrations, models +import django.db.models.deletion +import great_international.panels.capital_invest + + +class Migration(migrations.Migration): + + dependencies = [ + ('wagtailcore', '0041_group_collection_permissions_verbose_name_plural'), + ('great_international', '0065_auto_20190808_1032'), + ] + + operations = [ + migrations.CreateModel( + name='CapitalInvestContactFormPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')), + ('service_name', models.CharField(choices=[('FIND_A_SUPPLIER', 'Find a Supplier'), ('EXPORT_READINESS', 'Export Readiness'), ('INVEST', 'Invest'), ('COMPONENTS', 'Components'), ('GREAT_INTERNATIONAL', 'Great International')], db_index=True, max_length=100, null=True)), + ('uses_tree_based_routing', models.BooleanField(default=False, help_text="Allow this page's URL to be determined by its slug, and the slugs of its ancestors in the page tree.", verbose_name='tree-based routing enabled')), + ('breadcrumbs_label', models.CharField(blank=True, max_length=255)), + ('breadcrumbs_label_en_gb', models.CharField(blank=True, max_length=255, null=True)), + ('breadcrumbs_label_de', models.CharField(blank=True, max_length=255, null=True)), + ('breadcrumbs_label_ja', models.CharField(blank=True, max_length=255, null=True)), + ('breadcrumbs_label_zh_hans', models.CharField(blank=True, max_length=255, null=True)), + ('breadcrumbs_label_fr', models.CharField(blank=True, max_length=255, null=True)), + ('breadcrumbs_label_es', models.CharField(blank=True, max_length=255, null=True)), + ('breadcrumbs_label_pt', models.CharField(blank=True, max_length=255, null=True)), + ('breadcrumbs_label_ar', models.CharField(blank=True, max_length=255, null=True)), + ('heading', models.CharField(max_length=255)), + ('heading_en_gb', models.CharField(max_length=255, null=True)), + ('heading_de', models.CharField(max_length=255, null=True)), + ('heading_ja', models.CharField(max_length=255, null=True)), + ('heading_zh_hans', models.CharField(max_length=255, null=True)), + ('heading_fr', models.CharField(max_length=255, null=True)), + ('heading_es', models.CharField(max_length=255, null=True)), + ('heading_pt', models.CharField(max_length=255, null=True)), + ('heading_ar', models.CharField(max_length=255, null=True)), + ('intro', core.model_fields.MarkdownField(blank=True, validators=[core.validators.slug_hyperlinks])), + ('intro_en_gb', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('intro_de', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('intro_ja', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('intro_zh_hans', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('intro_fr', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('intro_es', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('intro_pt', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('intro_ar', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('cta_text', models.CharField(max_length=255)), + ('cta_text_en_gb', models.CharField(max_length=255, null=True)), + ('cta_text_de', models.CharField(max_length=255, null=True)), + ('cta_text_ja', models.CharField(max_length=255, null=True)), + ('cta_text_zh_hans', models.CharField(max_length=255, null=True)), + ('cta_text_fr', models.CharField(max_length=255, null=True)), + ('cta_text_es', models.CharField(max_length=255, null=True)), + ('cta_text_pt', models.CharField(max_length=255, null=True)), + ('cta_text_ar', models.CharField(max_length=255, null=True)), + ], + options={ + 'abstract': False, + }, + bases=(great_international.panels.capital_invest.CapitalInvestContactFormPagePanels, core.models.WagtailAdminExclusivePageMixin, 'wagtailcore.page'), + ), + migrations.CreateModel( + name='CapitalInvestContactFormSuccessPage', + fields=[ + ('page_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='wagtailcore.Page')), + ('service_name', models.CharField(choices=[('FIND_A_SUPPLIER', 'Find a Supplier'), ('EXPORT_READINESS', 'Export Readiness'), ('INVEST', 'Invest'), ('COMPONENTS', 'Components'), ('GREAT_INTERNATIONAL', 'Great International')], db_index=True, max_length=100, null=True)), + ('uses_tree_based_routing', models.BooleanField(default=False, help_text="Allow this page's URL to be determined by its slug, and the slugs of its ancestors in the page tree.", verbose_name='tree-based routing enabled')), + ('large_text', models.CharField(max_length=255)), + ('large_text_en_gb', models.CharField(max_length=255, null=True)), + ('large_text_de', models.CharField(max_length=255, null=True)), + ('large_text_ja', models.CharField(max_length=255, null=True)), + ('large_text_zh_hans', models.CharField(max_length=255, null=True)), + ('large_text_fr', models.CharField(max_length=255, null=True)), + ('large_text_es', models.CharField(max_length=255, null=True)), + ('large_text_pt', models.CharField(max_length=255, null=True)), + ('large_text_ar', models.CharField(max_length=255, null=True)), + ('small_text', core.model_fields.MarkdownField(blank=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_en_gb', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_de', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_ja', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_zh_hans', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_fr', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_es', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_pt', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ('small_text_ar', core.model_fields.MarkdownField(blank=True, null=True, validators=[core.validators.slug_hyperlinks])), + ], + options={ + 'abstract': False, + }, + bases=(great_international.panels.capital_invest.CapitalInvestContactFormSuccessPagePanels, core.models.WagtailAdminExclusivePageMixin, 'wagtailcore.page'), + ), + ] diff --git a/great_international/migrations/0067_auto_20190814_0940.py b/great_international/migrations/0067_auto_20190814_0940.py new file mode 100644 index 00000000..48055ce4 --- /dev/null +++ b/great_international/migrations/0067_auto_20190814_0940.py @@ -0,0 +1,58 @@ +# Generated by Django 2.2.3 on 2019-08-14 09:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('great_international', '0066_capitalinvestcontactformpage_capitalinvestcontactformsuccesspage'), + ] + + operations = [ + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page'), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_ar', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_de', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_en_gb', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_es', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_fr', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_ja', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_pt', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + migrations.AlterField( + model_name='internationalarticlepage', + name='article_teaser_zh_hans', + field=models.TextField(blank=True, help_text='This is a subheading that displays when the article is featured on another page', null=True), + ), + ] diff --git a/great_international/models/capital_invest.py b/great_international/models/capital_invest.py index 71b87deb..b39e94e9 100644 --- a/great_international/models/capital_invest.py +++ b/great_international/models/capital_invest.py @@ -14,6 +14,7 @@ from great_international.models.base import BaseInternationalPage import great_international.panels.capital_invest as panels +from directory_constants import slugs class RegionCardField(models.Model): @@ -127,6 +128,12 @@ class InternationalCapitalInvestLandingPage( parent_page_types = ['great_international.InternationalHomePage'] + @classmethod + def allowed_subpage_models(cls): + return [ + CapitalInvestContactFormPage + ] + hero_title = models.CharField(max_length=255) hero_image = models.ForeignKey( 'wagtailimages.Image', @@ -686,3 +693,31 @@ class CapitalInvestOpportunityPage( contact_title = models.CharField(max_length=255, blank=True) contact_text = MarkdownField(blank=True) + + +class CapitalInvestContactFormPage( + panels.CapitalInvestContactFormPagePanels, WagtailAdminExclusivePageMixin, BaseInternationalPage +): + parent_page_types = ['great_international.InternationalCapitalInvestLandingPage'] + slug_identity = slugs.CONTACT_FORM_SLUG + + breadcrumbs_label = models.CharField(max_length=255, blank=True) + heading = models.CharField(max_length=255) + intro = MarkdownField(blank=True) + cta_text = models.CharField(max_length=255) + + @classmethod + def allowed_subpage_models(cls): + return [ + CapitalInvestContactFormSuccessPage + ] + + +class CapitalInvestContactFormSuccessPage( + panels.CapitalInvestContactFormSuccessPagePanels, WagtailAdminExclusivePageMixin, BaseInternationalPage +): + parent_page_types = ['great_international.CapitalInvestContactFormPage'] + slug_identity = slugs.FORM_SUCCESS_SLUG + + large_text = models.CharField(max_length=255) + small_text = MarkdownField(blank=True) diff --git a/great_international/models/great_international.py b/great_international/models/great_international.py index 13d054ba..e230e0ae 100644 --- a/great_international/models/great_international.py +++ b/great_international/models/great_international.py @@ -257,7 +257,8 @@ class Meta: @classmethod def allowed_subpage_models(cls): return [ - InternationalSubSectorPage + InternationalSubSectorPage, + InternationalArticlePage ] @@ -784,6 +785,7 @@ class InternationalArticlePage(panels.InternationalArticlePagePanels, BaseIntern 'great_international.InternationalCampaignPage', 'great_international.InternationalCuratedTopicLandingPage', 'great_international.InternationalGuideLandingPage', + 'great_international.InternationalSectorPage' ] subpage_types = [] @@ -794,6 +796,7 @@ class InternationalArticlePage(panels.InternationalArticlePagePanels, BaseIntern "below the main title on the article page" ) article_teaser = models.TextField( + blank=True, help_text="This is a subheading that displays when the article " "is featured on another page" ) diff --git a/great_international/panels/capital_invest.py b/great_international/panels/capital_invest.py index 7b2b66ac..7eeba479 100644 --- a/great_international/panels/capital_invest.py +++ b/great_international/panels/capital_invest.py @@ -505,3 +505,39 @@ class CapitalInvestOpportunityPagePanels: content_panels=content_panels, settings_panels=settings_panels, ) + + +class CapitalInvestContactFormPagePanels: + content_panels = [ + FieldPanel('breadcrumbs_label'), + FieldPanel('heading'), + FieldPanel('intro'), + FieldPanel('cta_text'), + ] + + settings_panels = [ + FieldPanel('title_en_gb'), + FieldPanel('slug'), + ] + + edit_handler = make_translated_interface( + content_panels=content_panels, + settings_panels=settings_panels, + ) + + +class CapitalInvestContactFormSuccessPagePanels: + content_panels = [ + FieldPanel('large_text'), + FieldPanel('small_text'), + ] + + settings_panels = [ + FieldPanel('title_en_gb'), + FieldPanel('slug'), + ] + + edit_handler = make_translated_interface( + content_panels=content_panels, + settings_panels=settings_panels, + ) diff --git a/great_international/serializers.py b/great_international/serializers.py index 1a35d17c..c3291889 100644 --- a/great_international/serializers.py +++ b/great_international/serializers.py @@ -657,6 +657,7 @@ class InternationalSectorPageSerializer( ChildPagesSerializerHelper ): child_sub_sectors = serializers.SerializerMethodField() + child_articles = serializers.SerializerMethodField() def get_child_sub_sectors(self, obj): return self.get_child_pages_data_for( @@ -665,6 +666,13 @@ def get_child_sub_sectors(self, obj): MinimalPageSerializer ) + def get_child_articles(self, obj): + return self.get_child_pages_data_for( + obj, + InternationalArticlePage, + RelatedArticlePageSerializer + ) + class InternationalArticlePageSerializer(PageWithRelatedPagesSerializer): article_title = serializers.CharField() @@ -2018,3 +2026,15 @@ def get_about_uk_articles_fields(self, instance): contact_us_section_summary = core_fields.MarkdownToHTMLField() contact_us_section_cta_text = serializers.CharField() contact_us_section_cta_link = serializers.CharField() + + +class CapitalInvestContactFormPageSerializer(BasePageSerializer): + breadcrumbs_label = serializers.CharField() + heading = serializers.CharField() + intro = core_fields.MarkdownToHTMLField() + cta_text = serializers.CharField() + + +class CapitalInvestContactFormSuccessPageSerializer(BasePageSerializer): + large_text = serializers.CharField() + small_text = core_fields.MarkdownToHTMLField() diff --git a/great_international/translation.py b/great_international/translation.py index ee62be09..b6bdb2c3 100644 --- a/great_international/translation.py +++ b/great_international/translation.py @@ -557,7 +557,7 @@ class CapitalInvestOpportunityPageTranslationOptions( @register(capital_invest.CapitalInvestRelatedRegions) -class RelatedRegionsSerializer( +class RelatedRegionsTranslationOptions( BaseTranslationOptions): fields = ( 'page', @@ -565,7 +565,7 @@ class RelatedRegionsSerializer( @register(capital_invest.CapitalInvestRelatedSectors) -class RelatedSectorsSerializer( +class RelatedSectorsTranslationOptions( BaseTranslationOptions): fields = ( 'page', @@ -573,7 +573,7 @@ class RelatedSectorsSerializer( @register(capital_invest.CapitalInvestRegionCardFieldsSummary) -class CapitalInvestRegionCardFieldSerializer( +class CapitalInvestRegionCardFieldTranslationOptions( BaseTranslationOptions): fields = ( 'page', @@ -581,7 +581,7 @@ class CapitalInvestRegionCardFieldSerializer( @register(capital_invest.CapitalInvestHomesInEnglandCardFieldsSummary) -class CapitalInvestHomesInEnglandCardFieldsSummarySerializer( +class CapitalInvestHomesInEnglandCardFieldsSummaryTranslationOptions( BaseTranslationOptions): fields = ( 'page', @@ -879,7 +879,7 @@ class AboutDitServicesPageTranslationOptions( @register(great_international.AboutDitServicesFields) -class AboutDitServicesFieldsSerializer( +class AboutDitServicesFieldsTranslationOptions( BaseTranslationOptions ): fields = ( @@ -986,9 +986,31 @@ class AboutUkWhyChooseTheUkPageTranslationOptions( @register(great_international.AboutUkArticlesFields) -class AboutUkArticlesFieldsSerializer( +class AboutUkArticlesFieldsTranslationOptions( BaseTranslationOptions ): fields = ( 'page', ) + + +@register(capital_invest.CapitalInvestContactFormPage) +class CapitalInvestContactFormPageTranslationOptions( + BaseTranslationOptions +): + fields = ( + 'breadcrumbs_label', + 'heading', + 'intro', + 'cta_text', + ) + + +@register(capital_invest.CapitalInvestContactFormSuccessPage) +class CapitalInvestContactFormSuccessPageTranslationOptions( + BaseTranslationOptions +): + fields = ( + 'large_text', + 'small_text', + ) diff --git a/tests/core/test_serializers.py b/tests/core/test_serializers.py index 9837c6c5..26e4df0d 100644 --- a/tests/core/test_serializers.py +++ b/tests/core/test_serializers.py @@ -1,5 +1,8 @@ import pytest from find_a_supplier.serializers import IndustryPageSerializer +from great_international.serializers import CapitalInvestContactFormSuccessPageSerializer +from tests.great_international.factories import CapitalInvestContactFormPageFactory, \ + CapitalInvestContactFormSuccessPageFactory @pytest.mark.django_db @@ -21,3 +24,29 @@ def test_base_page_serializer(page, rf): assert serializer.data['last_published_at'] == page.last_published_at assert serializer.data['title'] == page.title assert serializer.data['page_type'] == 'IndustryPage' + + +@pytest.mark.django_db +def test_tree_based_breadcrumbs_for_base_page_serializer( + rf, international_root_page +): + form_page = CapitalInvestContactFormPageFactory( + slug='contact', + title_en_gb='form-title', + breadcrumbs_label='breadcrumbs', + parent=international_root_page + ) + + success_page = CapitalInvestContactFormSuccessPageFactory( + slug='success', + title_en_gb="success-title", + parent=form_page + ) + + success_serializer = CapitalInvestContactFormSuccessPageSerializer( + instance=success_page, + context={'request': rf.get('/')} + ) + + assert success_serializer.data['tree_based_breadcrumbs'][0]['title'] == 'breadcrumbs' + assert success_serializer.data['tree_based_breadcrumbs'][1]['title'] == 'success-title' diff --git a/tests/great_international/factories.py b/tests/great_international/factories.py index 7b877511..7d31404a 100644 --- a/tests/great_international/factories.py +++ b/tests/great_international/factories.py @@ -738,3 +738,33 @@ class Meta: title_en_gb = factory.Sequence(lambda n: '123-555-{0}'.format(n)) last_published_at = timezone.now() parent = None + + +class CapitalInvestContactFormPageFactory( + wagtail_factories.PageFactory +): + + class Meta: + model = models.capital_invest.CapitalInvestContactFormPage + + heading = factory.fuzzy.FuzzyText(length=50) + intro = factory.fuzzy.FuzzyText(length=50) + cta_text = factory.fuzzy.FuzzyText(length=50) + slug = factory.Sequence(lambda n: '123-555-{0}'.format(n)) + title_en_gb = factory.Sequence(lambda n: '123-555-{0}'.format(n)) + last_published_at = timezone.now() + parent = None + + +class CapitalInvestContactFormSuccessPageFactory( + wagtail_factories.PageFactory +): + + class Meta: + model = models.capital_invest.CapitalInvestContactFormSuccessPage + + large_text = factory.fuzzy.FuzzyText(length=50) + slug = factory.Sequence(lambda n: '123-555-{0}'.format(n)) + title_en_gb = factory.Sequence(lambda n: '123-555-{0}'.format(n)) + last_published_at = timezone.now() + parent = None diff --git a/tests/great_international/test_models.py b/tests/great_international/test_models.py index 16ddd3e6..dd04fe1f 100644 --- a/tests/great_international/test_models.py +++ b/tests/great_international/test_models.py @@ -71,11 +71,19 @@ def test_models_hierarchy(): assert great_international.InternationalEUExitFormSuccessPage.allowed_parent_page_models() == [ great_international.InternationalEUExitFormPage, ] + assert capital_invest.InternationalCapitalInvestLandingPage.allowed_subpage_models() == [ + capital_invest.CapitalInvestContactFormPage, + ] assert capital_invest.CapitalInvestOpportunityListingPage.allowed_subpage_models() == [ capital_invest.CapitalInvestOpportunityPage, ] + assert capital_invest.CapitalInvestContactFormPage.allowed_subpage_models() == [ + capital_invest.CapitalInvestContactFormSuccessPage + ] + assert capital_invest.CapitalInvestContactFormSuccessPage.allowed_subpage_models() == [] assert great_international.InternationalSectorPage.allowed_subpage_models() == [ great_international.InternationalSubSectorPage, + great_international.InternationalArticlePage ] assert great_international.AboutDitLandingPage.allowed_subpage_models() == [ great_international.AboutDitServicesPage diff --git a/tests/great_international/test_views.py b/tests/great_international/test_views.py index 7e30e50e..547f4d01 100644 --- a/tests/great_international/test_views.py +++ b/tests/great_international/test_views.py @@ -307,3 +307,14 @@ def test_international_trade_home_page_exposes_industries( assert response.status_code == 200 assert len(response.json()['industries']) == 1 assert response.json()['industries'][0]['meta']['pk'] == industry.pk + + +def test_sector_page_exposes_articles_child_sub_pages(admin_client, international_root_page): + sector_page = factories.InternationalSectorPageFactory(parent=international_root_page, slug='sector-one') + factories.InternationalArticlePageFactory(parent=sector_page) + factories.InternationalArticlePageFactory(parent=sector_page) + url = reverse('api:api:pages:detail', kwargs={'pk': sector_page.pk}) + response = admin_client.get(url) + + assert response.status_code == 200 + assert len(response.json()['child_articles']) == 2