From 89e7756c11ba901cbd04599901cf4b936828b593 Mon Sep 17 00:00:00 2001 From: Bruce Bolt Date: Thu, 15 Feb 2024 10:04:49 +0000 Subject: [PATCH 1/2] Use details for contacts in Worldwide Organisation pages We are changing the content item for Worldwide Organisations and Worldwide Offices to be a single piece of content, with all sub-pages included in a single Worldwide Organisation content item. Therefore switching the Worldwide Organisation page to get the office information from the `details`, rather than `links`. --- .../worldwide_organisation_presenter.rb | 24 +++++++------------ .../worldwide_organisation_presenter_test.rb | 4 ++-- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/app/presenters/worldwide_organisation_presenter.rb b/app/presenters/worldwide_organisation_presenter.rb index 1f27b60a2..950a2f1de 100644 --- a/app/presenters/worldwide_organisation_presenter.rb +++ b/app/presenters/worldwide_organisation_presenter.rb @@ -77,25 +77,25 @@ def people_in_non_primary_roles end def main_office - return unless (office_item = content_item.dig("links", "main_office")&.first) + return unless (office_item = content_item.dig("details", "main_office_parts")&.first) - office_contact_item = contact_for_office(office_item["content_id"]) + office_contact_item = linked_contact(office_item["contact_content_id"]) return unless office_contact_item WorldwideOffice.new( contact: WorldwideOrganisation::LinkedContactPresenter.new(office_contact_item), - has_access_and_opening_times?: office_item.dig("details", "access_and_opening_times").present?, - public_url: office_item.fetch("web_url"), + has_access_and_opening_times?: office_item["access_and_opening_times"].present?, + public_url: "#{content_item['base_path']}/#{office_item['slug']}", ) end WorldwideOffice = Struct.new(:contact, :has_access_and_opening_times?, :public_url, keyword_init: true) def home_page_offices - return [] unless content_item.dig("links", "home_page_offices") + return [] unless content_item.dig("details", "home_page_office_parts") - content_item.dig("links", "home_page_offices").map { |office| - contact = contact_for_office(office["content_id"]) + content_item.dig("details", "home_page_office_parts").map { |office| + contact = linked_contact(office["contact_content_id"]) next unless contact WorldwideOrganisation::LinkedContactPresenter.new(contact) @@ -131,15 +131,9 @@ def sponsoring_organisations private - def contact_for_office(office_content_id) - contact_mapping = content_item.dig("details", "office_contact_associations").select { |office_contact_association| - office_contact_association["office_content_id"] == office_content_id - }.first - - return unless contact_mapping - + def linked_contact(contact_content_id) content_item.dig("links", "contacts").select { |contact| - contact["content_id"] == contact_mapping["contact_content_id"] + contact["content_id"] == contact_content_id }.first end diff --git a/test/presenters/worldwide_organisation_presenter_test.rb b/test/presenters/worldwide_organisation_presenter_test.rb index cad961b01..2cd5f8d84 100644 --- a/test/presenters/worldwide_organisation_presenter_test.rb +++ b/test/presenters/worldwide_organisation_presenter_test.rb @@ -157,7 +157,7 @@ def schema_name test "#main_office returns nil when there is no main office" do without_main_office = schema_item - without_main_office["links"].delete("main_office") + without_main_office["details"].delete("main_office_parts") presented = create_presenter(WorldwideOrganisationPresenter, content_item: without_main_office) @@ -166,7 +166,7 @@ def schema_name test "#home_page_offices returns an empty array when there are no home page offices" do without_home_page_offices = schema_item - without_home_page_offices["links"].delete("home_page_offices") + without_home_page_offices["details"].delete("home_page_office_parts") presented = create_presenter(WorldwideOrganisationPresenter, content_item: without_home_page_offices) From 0c88e1184c08cabedb941df8f5cc69141a6c7aaf Mon Sep 17 00:00:00 2001 From: Bruce Bolt Date: Thu, 15 Feb 2024 11:21:23 +0000 Subject: [PATCH 2/2] Add support for worldwide offices embedded in worldwide organisations As part of the switch to Worldwide Organisation content items containing the content for their offices, we need to switch the rendering of the office pages to use these parts. This makes that switch in a backward compatible way, so we can continue rendering office pages under the existing content items until the office routes are updated to point to the organisation's content item. In a later PR, we will remove `WorldwideOfficePresenter` and it's associated view. --- app/controllers/content_items_controller.rb | 1 + app/presenters/content_item_presenter.rb | 4 ++ ...worldwide_organisation_office_presenter.rb | 46 ++++++++++++ app/services/presenter_builder.rb | 5 ++ .../worldwide_organisation_office.html.erb | 35 ++++++++++ .../worldwide_organisation_test.rb | 6 +- ...wide_organisation_office_presenter_test.rb | 70 +++++++++++++++++++ 7 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 app/presenters/worldwide_organisation_office_presenter.rb create mode 100644 app/views/content_items/worldwide_organisation_office.html.erb create mode 100644 test/presenters/worldwide_organisation_office_presenter_test.rb diff --git a/app/controllers/content_items_controller.rb b/app/controllers/content_items_controller.rb index 46362e95c..06cd56d6a 100644 --- a/app/controllers/content_items_controller.rb +++ b/app/controllers/content_items_controller.rb @@ -178,6 +178,7 @@ def content_item_template return "guide_single" if @content_item.render_guide_as_single_page? return "manual_updates" if @content_item.manual_updates? return "hmrc_manual_updates" if @content_item.hmrc_manual_updates? + return "worldwide_organisation_office" if @content_item.worldwide_organisation_office? @content_item.schema_name end diff --git a/app/presenters/content_item_presenter.rb b/app/presenters/content_item_presenter.rb index 850db6aa7..0354e9cd3 100644 --- a/app/presenters/content_item_presenter.rb +++ b/app/presenters/content_item_presenter.rb @@ -110,6 +110,10 @@ def hmrc_manual_updates? view_context.request.path =~ /^\/hmrc-internal-manuals\/.*\/updates$/ && content_item["schema_name"] == "hmrc_manual" end + def worldwide_organisation_office? + view_context.request.path =~ /^\/world\/.*\/office\/.*$/ && content_item["schema_name"] == "worldwide_organisation" + end + def show_default_breadcrumbs? true end diff --git a/app/presenters/worldwide_organisation_office_presenter.rb b/app/presenters/worldwide_organisation_office_presenter.rb new file mode 100644 index 000000000..07b7f9500 --- /dev/null +++ b/app/presenters/worldwide_organisation_office_presenter.rb @@ -0,0 +1,46 @@ +class WorldwideOrganisationOfficePresenter < ContentItemPresenter + include ContentItem::ContentsList + include WorldwideOrganisation::Branding + + def formatted_title + worldwide_organisation&.formatted_title + end + + def body + office["access_and_opening_times"] + end + + def contact + associated_contact = content_item.dig("links", "contacts").select { |contact| + contact["content_id"] == office["contact_content_id"] + }.first + + WorldwideOrganisation::LinkedContactPresenter.new(associated_contact) + end + + def show_default_breadcrumbs? + false + end + + def office + all_offices = content_item.dig("details", "main_office_parts") + content_item.dig("details", "home_page_office_parts") + + all_offices.select { |office| + office["slug"] == requested_path.gsub("#{content_item['base_path']}/", "") + }.first + end + + def worldwide_organisation + WorldwideOrganisationPresenter.new(content_item, requested_path, view_context) + end + + def sponsoring_organisations + worldwide_organisation&.sponsoring_organisations + end + +private + + def show_contents_list? + true + end +end diff --git a/app/services/presenter_builder.rb b/app/services/presenter_builder.rb index 6ea7ef3a4..7bf130752 100644 --- a/app/services/presenter_builder.rb +++ b/app/services/presenter_builder.rb @@ -37,6 +37,7 @@ def presenter_name return service_sign_in_presenter_name if service_sign_in_format? return "ManualUpdatesPresenter" if manual_updates? return "HmrcManualUpdatesPresenter" if hmrc_manual_updates? + return "WorldwideOrganisationOfficePresenter" if worldwide_organisation_office? "#{content_item['schema_name'].classify}Presenter" end @@ -49,6 +50,10 @@ def hmrc_manual_updates? view_context.request.path =~ /^\/hmrc-internal-manuals\/.*\/updates$/ && content_item["schema_name"] == "hmrc_manual" end + def worldwide_organisation_office? + view_context.request.path =~ /^\/world\/.*\/office\/.*$/ && content_item["schema_name"] == "worldwide_organisation" + end + def service_sign_in_format? content_item["schema_name"] == "service_sign_in" end diff --git a/app/views/content_items/worldwide_organisation_office.html.erb b/app/views/content_items/worldwide_organisation_office.html.erb new file mode 100644 index 000000000..eac88d649 --- /dev/null +++ b/app/views/content_items/worldwide_organisation_office.html.erb @@ -0,0 +1,35 @@ +<%= render partial: "content_items/worldwide_organisation/header", locals: { + worldwide_organisation: @content_item.worldwide_organisation, +} %> + +
+
+ <%= render "govuk_publishing_components/components/contents_list", + contents: @content_item.contents, + underline_links: true + %> +
+ +
+
+ <%= render "govuk_publishing_components/components/heading", { + text: sanitize("About #{@content_item.contact.title}"), + heading_level: 2, + font_size: "xl", + margin_bottom: 4, + } %> + +
+
+ <%= render partial: "content_items/worldwide_organisation/contact", locals: { + contact: @content_item.contact, + hide_title: true, + } %> +
+ + <%= render "govuk_publishing_components/components/govspeak", {} do + raw(@content_item.body) + end %> +
+
+
diff --git a/test/integration/worldwide_organisation_test.rb b/test/integration/worldwide_organisation_test.rb index c4b956380..4e6bdcbe9 100644 --- a/test/integration/worldwide_organisation_test.rb +++ b/test/integration/worldwide_organisation_test.rb @@ -107,7 +107,7 @@ class WorldwideOrganisationTest < ActionDispatch::IntegrationTest within("#contact-us") do assert page.has_text?("Contact us") assert page.has_content?("Torre Emperador Castellana") - assert page.has_link?(I18n.t("contact.access_and_opening_times"), href: "https://www.integration.publishing.service.gov.uk/world/organisations/british-embassy-madrid/office/british-embassy") + assert page.has_link?(I18n.t("contact.access_and_opening_times"), href: "/world/uk-embassy-in-country/office/british-embassy") end end @@ -116,7 +116,7 @@ class WorldwideOrganisationTest < ActionDispatch::IntegrationTest within("#contact-us") do assert page.has_content?("Department for Business and Trade Dusseldorf") - assert_not page.has_link?(I18n.t("contact.access_and_opening_times"), href: "https://www.integration.publishing.service.gov.uk/world/organisations/department-for-business-and-trade-germany/office/uk-trade-investment-duesseldorf") + assert_not page.has_link?(I18n.t("contact.access_and_opening_times"), href: "/world/uk-embassy-in-country/office/uk-trade-investment-duesseldorf") end end @@ -124,7 +124,7 @@ class WorldwideOrganisationTest < ActionDispatch::IntegrationTest setup_and_visit_content_item( "worldwide_organisation", { - "links" => { "main_office" => nil }, + "details" => { "main_office_parts" => nil }, }, ) assert_not page.has_text?("Contact us") diff --git a/test/presenters/worldwide_organisation_office_presenter_test.rb b/test/presenters/worldwide_organisation_office_presenter_test.rb new file mode 100644 index 000000000..ce029e323 --- /dev/null +++ b/test/presenters/worldwide_organisation_office_presenter_test.rb @@ -0,0 +1,70 @@ +require "presenter_test_helper" + +class WorldwideOrganisationOfficePresenterTest < PresenterTestCase + def schema_name + "worldwide_organisation" + end + + def requested_path + "#{schema_item['base_path']}/#{schema_item.dig('details', 'main_office_parts', 0, 'slug')}" + end + + def present_example(example) + create_presenter( + "WorldwideOrganisationOfficePresenter".safe_constantize, + content_item: example, + requested_path:, + ) + end + + test "#title returns the title of the schema item" do + assert_equal schema_item["title"], presented_item.title + end + + test "#body returns the access and opening times of the schema item" do + assert_equal schema_item.dig("details", "main_office_parts", 0, "access_and_opening_times"), presented_item.body + end + + test "#contact returns the contact as an instance of #{WorldwideOrganisation::LinkedContactPresenter}" do + assert presented_item.contact.is_a?(WorldwideOrganisation::LinkedContactPresenter) + end + + test "#sponsoring_organisation_logo returns the logo details of the item" do + with_non_default_crest = schema_item + sponsoring_organisation = first_sponsoring_organisation(with_non_default_crest) + sponsoring_organisation["details"]["logo"]["crest"] = "dbt" + + presented = present_example(with_non_default_crest) + + expected = { name: "British Deputy High Commission
Hyderabad", url: "/world/uk-embassy-in-country", crest: "dbt", brand: "foreign-commonwealth-development-office" } + assert_equal expected, presented.organisation_logo + end + + test "#sponsoring_organisation_logo returns default values when the crest and brand of the first sponsoring organisation are blank" do + with_empty_logo = schema_item + sponsoring_organisation = first_sponsoring_organisation(with_empty_logo) + sponsoring_organisation["details"]["logo"]["crest"] = nil + sponsoring_organisation["details"]["brand"] = nil + + presented = present_example(with_empty_logo) + + expected = { name: "British Deputy High Commission
Hyderabad", url: "/world/uk-embassy-in-country", crest: "single-identity", brand: "single-identity" } + assert_equal expected, presented.organisation_logo + end + + test "#sponsoring_organisation_logo returns default values when the sponsoring organisations are nil" do + without_sponsoring_organisations = schema_item + without_sponsoring_organisations["links"].delete("sponsoring_organisations") + + presented = present_example(without_sponsoring_organisations) + + expected = { name: "British Deputy High Commission
Hyderabad", url: "/world/uk-embassy-in-country", crest: "single-identity", brand: "single-identity" } + assert_equal expected, presented.organisation_logo + end + +private + + def first_sponsoring_organisation(item) + item["links"]["sponsoring_organisations"][0] + end +end