Skip to content

Commit

Permalink
Use breadcrumbs based on organisation if no parent
Browse files Browse the repository at this point in the history
Use breadcrumbs based on ancestors, if the document has a linked parent.
Otherwise use breadcrumbs based on the first normal
(non-world) organisation the page is linked to.
If there are no linked organisations use taxon based breadcrumbs,
or if taxons are also not linked to,
the default breadcrumbs pointing to the homepage.
  • Loading branch information
unoduetre committed Oct 15, 2024
1 parent 9ea8d10 commit 2768e72
Show file tree
Hide file tree
Showing 10 changed files with 260 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
useful summary for people upgrading their application, not a replication
of the commit log.

## Unreleased

* Use the first organisation to generate breadcrumbs, if no parent linked ([PR #4270](https://github.com/alphagov/govuk_publishing_components/pull/4270))

## 44.3.0

* Add variants required for square blue icon share links ([PR #4292](https://github.com/alphagov/govuk_publishing_components/pull/4292))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ body: |
This is a complex component that calls other components. For more accurate
preview with real data, see the [contextual navigation preview][preview].
There are 3 main variants of the component:
There are 4 main variants of the component:
- Step by step, which uses the [step by step header][header]
- Parent breadcrumb, which uses the `parent` link of the page with the [breadcrumbs component][breadcrumbs]
- Taxon breadcrumb, which uses the `taxons` link of the page with the [breadcrumbs component][breadcrumbs]
- Organisation breadcrumb, which uses the `organisations` link of the page with the [breadcrumbs component][breadcrumbs]
It must always used [together with the contextual sidebar][sidebar] and [footer].
Expand Down
1 change: 1 addition & 0 deletions lib/govuk_publishing_components.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
require "govuk_publishing_components/presenters/page_with_step_by_step_navigation"
require "govuk_publishing_components/presenters/public_layout_helper"
require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_ancestors"
require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_organisations"
require "govuk_publishing_components/presenters/content_breadcrumbs_based_on_taxons"
require "govuk_publishing_components/presenters/checkboxes_helper"
require "govuk_publishing_components/presenters/select_helper"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ def options(navigation)
step_by_step: false,
breadcrumbs: navigation.breadcrumbs,
}
elsif navigation.content_is_a_corporate_information_page? && navigation.content_has_related_organisations?
{
step_by_step: false,
breadcrumbs: navigation.organisation_breadcrumbs,
}
elsif navigation.use_taxon_breadcrumbs?
{
step_by_step: false,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module GovukPublishingComponents
module Presenters
# @private
class ContentBreadcrumbsBasedOnOrganisations
def self.call(content_item)
new(content_item).breadcrumbs
end

def initialize(content_item)
@content_item = ContentItem.new(content_item)
end

def breadcrumbs
[
{ title: "Home", url: "/" },
*organisation_breadcrumbs_items,
]
end

private

attr_reader :content_item

def organisation_breadcrumbs_items
first_related_organisation = ContentItem.new(content_item.related_organisations.first)
return [] unless first_related_organisation.present?

[{
title: first_related_organisation.title,
url: first_related_organisation.base_path,
}]
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ def taxon_breadcrumbs
@taxon_breadcrumbs ||= ContentBreadcrumbsBasedOnTaxons.call(content_item)
end

def organisation_breadcrumbs
@organisation_breadcrumbs ||= ContentBreadcrumbsBasedOnOrganisations.call(content_item)
end

def breadcrumbs
breadcrumbs_based_on_ancestors
end
Expand Down Expand Up @@ -72,6 +76,10 @@ def content_has_curated_related_items?
content_item.dig("links", "ordered_related_items").present? && content_item.dig("links", "parent").present?
end

def content_has_related_organisations?
ContentItem.new(content_item).related_organisations.present?
end

def content_is_tagged_to_a_live_taxon?
content_item.dig("links", "taxons").to_a.any? { |taxon| taxon["phase"] == "live" }
end
Expand All @@ -80,6 +88,10 @@ def content_is_a_specialist_document?
content_item["schema_name"] == "specialist_document"
end

def content_is_a_corporate_information_page?
content_item["schema_name"] == "corporate_information_page"
end

def content_is_a_html_publication?
content_item["document_type"] == "html_publication"
end
Expand Down
15 changes: 15 additions & 0 deletions spec/components/contextual_breadcrumbs_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,21 @@ def set_live_taxons(content_item)
assert_select ".gem-c-breadcrumbs.gem-c-breadcrumbs--inverse"
end

it "renders parent-based breadcrumbs if the content item is a corporate information page with a parent" do
content_item = example_document_for("corporate_information_page", "corporate_information_page_complaints")
render_component(content_item:)
assert_select "a", text: "Home"
assert_select "a", text: "Department of Health"
assert_select "a", text: "About us"
end

it "renders organisation breadcrumbs if the content item is a corporate information page with no parent but with a linked organisation" do
content_item = example_document_for("corporate_information_page", "best-practice-about-page")
render_component(content_item:)
assert_select "a", text: "Home"
assert_select "a", text: "Intellectual Property Office"
end

it "renders no taxon breadcrumbs if they are not live" do
content_item = example_document_for("guide", "guide")
content_item = remove_mainstream_browse(content_item)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
require "spec_helper"

RSpec.describe GovukPublishingComponents::Presenters::BreadcrumbSelector do
subject do
described_class.new(
content_item,
request,
prioritise_taxon_breadcrumbs,
disable_ga4,
)
end
let(:example) { %w[guide guide] }
let(:content_item) { example_document_for(example.first, example.second) }
let(:path) { content_item["base_path"] }
let(:query_parameters) { {} }
let(:request) { instance_double("ActionDispatch::Request", path:, query_parameters:) }
let(:prioritise_taxon_breadcrumbs) { false }
let(:disable_ga4) { false }

def example_document_for(schema_name, example_name)
GovukSchemas::Example.find(schema_name, example_name:)
end

describe "#initialize" do
it "does not raise exception" do
expect { subject }.not_to raise_error
end
end

describe "#breadcrumbs" do
context "when content item is corporate information page with parent" do
let(:example) { %w[corporate_information_page corporate_information_page_complaints] }

it "returns breadcrumbs based on ancestors" do
expect(subject.breadcrumbs).to eq([
{ title: "Home", url: "/" },
{ title: "Department of Health", url: "/government/organisations/department-of-health" },
{ title: "About us", url: "/government/organisations/department-of-health/about" },
])
end
end

context "when content item is corporate information page without parent but with organisation" do
let(:example) { %w[corporate_information_page best-practice-about-page] }

it "returns breadcrumbs based on organisation" do
expect(subject.breadcrumbs).to eq([
{ title: "Home", url: "/" },
{ title: "Intellectual Property Office", url: "/government/organisations/intellectual-property-office" },
])
end
end

context "when content item is corporate information page without parent, organisations but with taxon" do
let(:content_item) do
item = example_document_for("corporate_information_page", "best-practice-about-page")
item.dig("links", "organisations").clear
item["links"]["taxons"] = [{
"base_path" => "/corporate-information",
"title" => "Corporate information",
"phase" => "live",
}]
item
end

it "returns breadcrumbs based on taxons" do
expect(subject.breadcrumbs).to eq([
{ title: "Home", url: "/", is_page_parent: false },
{ title: "Corporate information", url: "/corporate-information", is_page_parent: true },
])
end
end

context "when content item is corporate information page without parent, organisations and taxons" do
let(:content_item) do
item = example_document_for("corporate_information_page", "best-practice-about-page")
item.dig("links", "organisations").clear
item
end

it "returns default breadcrumbs" do
expect(subject.breadcrumbs).to eq([
{ title: "Home", url: "/" },
])
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require "spec_helper"

RSpec.describe GovukPublishingComponents::Presenters::ContentBreadcrumbsBasedOnOrganisations do
subject { described_class.new(content_item) }
let(:content_item) { GovukSchemas::Example.find("document_collection", example_name: "document_collection") }

describe "#initialize" do
it "does not raise exception" do
expect { subject }.not_to raise_error
end
end

describe "#breadcrumbs" do
it "returns breadcrumbs based on organisation" do
expect(subject.breadcrumbs).to eq([
{ title: "Home", url: "/" },
{
title: "Driver and Vehicle Standards Agency",
url: "/government/organisations/driver-and-vehicle-standards-agency",
},
])
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
require "spec_helper"

RSpec.describe GovukPublishingComponents::Presenters::ContextualNavigation do
subject { described_class.new(content_item, request) }
let(:example) { %w[guide guide] }
let(:content_item) { example_document_for(example.first, example.second) }
let(:path) { content_item["base_path"] }
let(:query_parameters) { {} }
let(:request) { instance_double("ActionDispatch::Request", path:, query_parameters:) }

def example_document_for(schema_name, example_name)
GovukSchemas::Example.find(schema_name, example_name:)
end

describe "#initialize" do
it "does not raise exception" do
expect { subject }.not_to raise_error
end
end

describe "#organisation_breadcrumbs" do
it "calls ContentBreadcrumbsBasedOnOrganisation" do
called_class = GovukPublishingComponents::Presenters::ContentBreadcrumbsBasedOnOrganisations
expect(called_class).to receive(:call)
.with(content_item)
.and_return([])
subject.organisation_breadcrumbs
end
end

describe "#content_has_related_organisations?" do
context "when content item is linked to no organisations" do
let(:example) { %w[homepage homepage_with_popular_links_on_govuk] }

it "returns false" do
expect(subject.content_has_related_organisations?).to be(false)
end
end

context "when content item is only linked to world organisations" do
let(:example) { %w[worldwide_corporate_information_page worldwide_corporate_information_page] }

it "returns false" do
expect(subject.content_has_related_organisations?).to be(false)
end
end

context "when content item is linked to at least 1 normal organisation" do
let(:example) { %w[document_collection document_collection] }

it "returns true" do
expect(subject.content_has_related_organisations?).to be(true)
end
end
end

describe "#content_is_a_corporate_information_page?" do
context "when content item is corporate information page" do
let(:example) { %w[corporate_information_page corporate_information_page] }

it "returns true" do
expect(subject.content_is_a_corporate_information_page?).to be(true)
end
end

context "when content item is not corporate information page" do
let(:example) { %w[guide guide] }

it "returns false" do
expect(subject.content_is_a_corporate_information_page?).to be(false)
end
end
end
end

0 comments on commit 2768e72

Please sign in to comment.