Skip to content

Commit

Permalink
Merge pull request #4653 from alphagov/model-organisations
Browse files Browse the repository at this point in the history
Model organisations
  • Loading branch information
KludgeKML authored Mar 3, 2025
2 parents 0ada15c + 4bc7fa8 commit c31c82b
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 49 deletions.
5 changes: 3 additions & 2 deletions app/models/case_study.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
class CaseStudy < ContentItem
include EmphasisedOrganisations
include Updatable
include WorldwideOrganisations
include Organisations

def contributors
(organisations_ordered_by_emphasis + worldwide_organisations).uniq
contributors_list = (organisations_ordered_by_emphasis + worldwide_organisations).uniq
super(contributors_list)
end
end
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
module Organisations
module EmphasisedOrganisations
extend ActiveSupport::Concern

included do
def organisations_ordered_by_emphasis
organisations.sort_by { |organisation| emphasised?(organisation) ? -1 : 1 }
end

def organisations
(content_store_hash.dig("links", "organisations") || []).map do |organisation|
{ "title" => organisation["title"], "base_path" => organisation["base_path"], "content_id" => organisation["content_id"] }
end
end
end

private

def emphasised?(organisation)
organisation["content_id"].in?(emphasised_organisations)
organisation.content_id.in?(emphasised_organisations)
end

def emphasised_organisations
Expand Down
4 changes: 1 addition & 3 deletions app/models/concerns/worldwide_organisations.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ module WorldwideOrganisations

included do
def worldwide_organisations
(content_store_hash.dig("links", "worldwide_organisations") || []).map do |organisation|
{ "title" => organisation["title"], "base_path" => organisation["base_path"], "content_id" => organisation["content_id"] }
end
linked("worldwide_organisations")
end
end
end
21 changes: 16 additions & 5 deletions app/models/content_item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

class ContentItem
include Withdrawable
include Organisations

attr_reader :attachments, :base_path, :body, :content_store_hash,
attr_reader :attachments, :base_path, :body, :content_id, :content_store_hash,
:content_store_response, :description, :document_type, :first_public_at,
:first_published_at, :image, :links, :locale, :phase, :public_updated_at,
:schema_name, :title
Expand All @@ -16,6 +14,7 @@ def initialize(content_store_response, override_content_store_hash: nil)
@content_store_hash = override_content_store_hash || content_store_response.to_hash

@body = content_store_hash.dig("details", "body")
@content_id = content_store_hash["content_id"]
@image = content_store_hash.dig("details", "image")
@description = content_store_hash["description"]
@document_type = content_store_hash["document_type"]
Expand All @@ -39,6 +38,10 @@ def initialize(content_store_response, override_content_store_hash: nil)

REGEX_IS_A = /is_an?_(.*)\?/

def organisations
linked("organisations")
end

def respond_to_missing?(method_name, _include_private = false)
method_name.to_s =~ REGEX_IS_A ? true : super
end
Expand Down Expand Up @@ -67,12 +70,20 @@ def meta_section
)&.downcase
end

def contributors
organisations
def contributors(content_items = organisations)
content_items.map do |content_item|
{ "title" => content_item.title, "base_path" => content_item.base_path }
end
end

private

def linked(type)
return [] if content_store_hash.dig("links", type).blank?

content_store_hash.dig("links", type).map { |hash| ContentItemFactory.build(hash) }
end

def get_attachments(attachment_hash)
return [] unless attachment_hash

Expand Down
18 changes: 18 additions & 0 deletions app/models/logo.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
class Logo
attr_reader :crest, :formatted_title, :image

def initialize(logo)
@image = get_image(logo["image"])
@crest = logo["crest"]
@formatted_title = logo["formatted_title"]
end

def get_image(logo_image)
return unless logo_image

OpenStruct.new(
alt_text: logo_image["alt_text"],
url: logo_image["url"],
)
end
end
17 changes: 17 additions & 0 deletions app/models/organisation.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Organisation < ContentItem
attr_reader :logo

def initialize(organisation_data)
super(organisation_data)
@logo = Logo.new(organisation_data.dig("details", "logo"))
@organisation_data = organisation_data
end

def brand
organisation_data.dig("details", "brand")
end

private

attr_reader :organisation_data
end
31 changes: 25 additions & 6 deletions spec/models/case_study_spec.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
RSpec.describe CaseStudy do
subject(:case_study) { described_class.new(content_store_response) }

let(:content_store_response) do
GovukSchemas::Example.find("case_study", example_name: "doing-business-in-spain")
end
Expand All @@ -10,18 +12,35 @@

describe "#contributors" do
it "returns the organisations ordered by emphasis followed by worldwide organisations" do
content_item = described_class.new(content_store_response)

worldwide_organisations = content_store_response.dig("links", "worldwide_organisations")
organisations = content_store_response.dig("links", "organisations")

expected_contributors = [
{ "title" => organisations[1]["title"], "base_path" => organisations[1]["base_path"], "content_id" => organisations[1]["content_id"] },
{ "title" => organisations[0]["title"], "base_path" => organisations[0]["base_path"], "content_id" => organisations[0]["content_id"] },
{ "title" => worldwide_organisations[0]["title"], "base_path" => worldwide_organisations[0]["base_path"], "content_id" => worldwide_organisations[0]["content_id"] },
{ "title" => organisations[1]["title"], "base_path" => organisations[1]["base_path"] },
{ "title" => organisations[0]["title"], "base_path" => organisations[0]["base_path"] },
{ "title" => worldwide_organisations[0]["title"], "base_path" => worldwide_organisations[0]["base_path"] },
]

expect(content_item.contributors).to eq(expected_contributors)
expect(case_study.contributors).to eq(expected_contributors)
end

context "with no worldwide organisations" do
let(:content_store_response) do
example = GovukSchemas::Example.find("case_study", example_name: "doing-business-in-spain")
example["links"].delete("worldwide_organisations")
example
end

it "returns just the organisations ordered by emphasis" do
organisations = content_store_response.dig("links", "organisations")

expected_contributors = [
{ "title" => organisations[1]["title"], "base_path" => organisations[1]["base_path"] },
{ "title" => organisations[0]["title"], "base_path" => organisations[0]["base_path"] },
]

expect(case_study.contributors).to eq(expected_contributors)
end
end
end
end
44 changes: 20 additions & 24 deletions spec/models/content_item_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,33 +154,15 @@
end

describe "#contributors" do
subject(:content_item) do
described_class.new(
{
"links" => {
"organisations" => [
{
"analytics_identifier" => "8888",
"content_id" => "11234500",
"api_path" => "/api/content/government/organisations/uk-health-security-agency",
"api_url" => "https://www.gov.uk/api/content/government/organisations/uk-health-security-agency",
"base_path" => "/government/organisations/uk-health-security-agency",
"document_type" => "organisation",
"title" => "UK Health Security Agency",
"web_url" => "https://www.gov.uk/government/organisations/uk-health-security-agency",
},
],
},
},
)
end
subject(:content_item) { described_class.new(content_store_response) }

let(:content_store_response) { GovukSchemas::Example.find("answer", example_name: "answer") }

it "returns the organisations content_id, base_path and title" do
it "returns the organisations base_path and title" do
expect(content_item.contributors).to eq([
{
"content_id" => "11234500",
"base_path" => "/government/organisations/uk-health-security-agency",
"title" => "UK Health Security Agency",
"base_path" => content_store_response.dig("links", "organisations", 0, "base_path"),
"title" => content_store_response.dig("links", "organisations", 0, "title"),
},
])
end
Expand Down Expand Up @@ -212,4 +194,18 @@
expect(content_item.meta_section).to eq("title of the parent's parent link")
end
end

describe "#organisations" do
subject(:content_item) { described_class.new(content_store_response) }

let(:content_store_response) do
GovukSchemas::Example.find("answer", example_name: "answer")
end

it "gets all organisations linked to the content item" do
expect(content_item.organisations.count).to eq(content_store_response.dig("links", "organisations").count)
expect(content_item.organisations.first.title)
.to eq(content_store_response.dig("links", "organisations", 0, "title"))
end
end
end
50 changes: 50 additions & 0 deletions spec/models/logo_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
RSpec.describe Logo do
let(:logo) do
{
"crest" => "dbt",
"formatted_title" => "Department for<br/>Business &amp; Trade",
}
end

describe "#crest" do
it "gets the crest" do
expect(described_class.new(logo).crest)
.to eq(logo["crest"])
end
end

describe "#formatted_title" do
it "gets the formatted title" do
expect(described_class.new(logo).formatted_title)
.to eq(logo["formatted_title"])
end
end

describe "#image" do
context "when there is an image" do
let(:logo) do
{
"formatted_title" => "Forensic Science <br/>Regulator",
"image" => {
"alt_text" => "Forensic Science Regulator",
"url" => "https://example.com/sample.png",
},
}
end

it "gets the image alt_text" do
expect(described_class.new(logo).image.alt_text).to eq(logo["image"]["alt_text"])
end

it "gets the image url" do
expect(described_class.new(logo).image.url).to eq(logo["image"]["url"])
end
end

context "when there is no image" do
it "returns nil" do
expect(described_class.new(logo).image).to be_nil
end
end
end
end
18 changes: 18 additions & 0 deletions spec/models/organisation_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
RSpec.describe Organisation do
let(:content_store_response) do
GovukSchemas::Example.find("organisation", example_name: "organisation")
end

describe "#brand" do
it "gets the brand" do
expect(described_class.new(content_store_response).brand).not_to be_nil
expect(described_class.new(content_store_response).brand).to eq(content_store_response.dig("details", "brand"))
end
end

describe "#logo" do
it "gets the logo" do
expect(described_class.new(content_store_response).logo).to be_instance_of(Logo)
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
let(:content_store_response) { GovukSchemas::Example.find(schema, example_name: schema) }

it "knows it has emphasised organisations" do
expect(described_class.new(content_store_response).contributors.first["content_id"]).to eq(content_store_response["details"]["emphasised_organisations"].first)
first_organisation = content_store_response["links"]["organisations"].find do |link|
link["content_id"] == content_store_response["details"]["emphasised_organisations"].first
end

expect(described_class.new(content_store_response).organisations_ordered_by_emphasis.first.title).to eq(first_organisation["title"])
end
end

Expand Down

0 comments on commit c31c82b

Please sign in to comment.