Skip to content

Commit

Permalink
Merge pull request #3829 from alphagov/dynamic_popular_browse_by_cont…
Browse files Browse the repository at this point in the history
…entid

Dynamic popular tasks - by content id
  • Loading branch information
beccapearce authored Nov 15, 2024
2 parents 79fa6f2 + 34e80a7 commit fe5b0da
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 64 deletions.
19 changes: 4 additions & 15 deletions app/helpers/browse_helper.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,10 @@
module BrowseHelper
def display_popular_links_for_slug?(slug)
popular_links_data(slug).present?
end

def popular_links_data(slug)
if I18n.exists?("browse.popular_links.#{slug}", :en)
I18n.t("browse.popular_links.#{slug}")
end
end

def popular_links_for_slug(slug)
links = popular_links_data(slug)
count = links.length
links.map.with_index(1) do |link, index|
def with_tracking_data(popular_content)
count = popular_content.length
popular_content.map.with_index(1) do |link, index|
{
text: link[:title],
href: link[:url],
href: link[:link],
data_attributes: {
module: "ga4-link-tracker",
ga4_track_links_only: "",
Expand Down
10 changes: 10 additions & 0 deletions app/models/mainstream_browse_page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,20 @@ def second_level_pages_curated?
details["second_level_ordering"] == "curated"
end

def top_level_browse_page?
top_level_browse_pages.any? { |page| page.base_path == base_path }
end

def lists
@lists ||= ListSet.new("section", @content_item.content_id, details["groups"])
end

def popular_list
return unless top_level_browse_page?

@popular_list ||= PopularListSet.fetch(@content_item)
end

def slug
base_path.sub(%r{\A/browse/}, "")
end
Expand Down
40 changes: 40 additions & 0 deletions app/models/popular_list_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class PopularListSet
def initialize(content_item)
@content_item = content_item
end

def self.fetch(content_item)
new(content_item).formatted_results
end

def formatted_results
if search_response["results"].present?
search_response["results"].map do |result|
{
title: result["title"],
link: result["link"],
}
end
end
end

private

attr_reader :content_item

def search_response
params = {
filter_any_mainstream_browse_page_content_ids: second_level_browse_content_ids,
count: 3,
order: "-popularity",
fields: SearchApiFields::POPULAR_BROWSE_SEARCH_FIELDS,
}
Services.cached_search(params)
end

def second_level_browse_content_ids
content_item
.linked_items("second_level_browse_pages")
.map { |content_item| content_item.content_item_data["content_id"] }
end
end
6 changes: 6 additions & 0 deletions app/services/search_api_fields.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,10 @@ module SearchApiFields
content_id
organisations
document_collections].freeze

POPULAR_BROWSE_SEARCH_FIELDS = %w[ title
link
public_timestamp
display_type
content_store_document_type].freeze
end
8 changes: 4 additions & 4 deletions app/views/browse/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
} %>
<% end %>

<% if display_popular_links_for_slug?(page.slug) %>
<% if page.popular_list %>
<div class="govuk-width-container">
<div class="browse__action-links">
<div class="govuk-grid-row">
Expand All @@ -45,7 +45,7 @@
font_size: "m"
} %>
<ul class="govuk-list govuk-!-margin-bottom-7">
<% popular_links_for_slug(page.slug).each do |link| %>
<% with_tracking_data(page.popular_list).each do |link| %>
<li>
<%= render partial: "shared/browse_action_link", locals: {link:} %>
</li>
Expand All @@ -68,7 +68,7 @@
<% total_links = page.second_level_browse_pages.count.to_s %>
<%= render "shared/browse_cards_container" do %>
<%= render "govuk_publishing_components/components/cards", {
heading: display_popular_links_for_slug?(page.slug) ? t("browse.topics") : nil,
heading: page.popular_list ? t("browse.topics") : nil,
items: page.second_level_browse_pages.map.with_index do |second_level_browse_page, index|
{
link: {
Expand All @@ -86,6 +86,6 @@
description: second_level_browse_page.description,
}
end,
sub_heading_level: display_popular_links_for_slug?(page.slug) ? 3 : 2,
sub_heading_level: page.popular_list ? 3 : 2,
} %>
<% end %>
6 changes: 6 additions & 0 deletions features/step_definitions/viewing_browse_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
],
page_size: SearchApiSearch::PAGE_SIZE_TO_GET_EVERYTHING,
)

content_ids = second_level_browse_pages.map { |link| link[:content_id] }
search_api_has_popular_documents_for_level_one_browse(content_ids)
end

Given(/^that there are curated second level browse pages$/) do
Expand All @@ -41,6 +44,9 @@
order_type: "curated",
)
add_second_level_browse_pages(second_level_browse_pages)

content_ids = second_level_browse_pages.map { |link| link[:content_id] }
search_api_has_popular_documents_for_level_one_browse(content_ids)
end

Then(/^I see the links tagged to the browse page/) do
Expand Down
15 changes: 13 additions & 2 deletions spec/controllers/browse_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
RSpec.describe BrowseController do
include GovukAbTesting::RspecHelpers
include SearchApiHelpers

render_views
describe "GET index" do
before do
Expand All @@ -21,15 +23,20 @@
describe "GET top_level_browse_page" do
describe "for a valid browse page" do
before do
stub_content_store_has_item(
"/browse/benefits",
content_item = {
base_path: "/browse/benefits",
title: "foo",
links: {
top_level_browse_pages:,
second_level_browse_pages:,
},
}
stub_content_store_has_item(
"/browse/benefits",
content_item,
)

search_api_has_popular_documents_for_level_one_browse(level_two_browse_content_ids)
end

it "sets correct expiry headers" do
Expand Down Expand Up @@ -75,4 +82,8 @@ def second_level_browse_pages
base_path: "/browse/benefits/entitlement",
}]
end

def level_two_browse_content_ids
second_level_browse_pages.map { |link| link[:content_id] }
end
end
54 changes: 32 additions & 22 deletions spec/features/mainstream_browsing_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,48 +23,58 @@
page_size: SearchApiSearch::PAGE_SIZE_TO_GET_EVERYTHING,
)

if content_item["links"]["second_level_browse_pages"].present?
content_ids = content_item["links"]["second_level_browse_pages"].map { |link| link["content_id"] }
search_api_has_popular_documents_for_level_one_browse(content_ids)
end

visit content_item["base_path"]

expect(page.status_code).to eq(200)
expect(page).to have_selector(".gem-c-breadcrumbs")
end
end

it "renders popular tasks on level 1 browse pages" do
level_one_browse_slugs = %w[ abroad
benefits
births-deaths-marriages
business
childcare-parenting
citizenship
disabilities
driving
education
employing-people
environment-countryside
housing-local-services
justice
tax
visas-immigration
working]

level_one_browse_slugs.each do |slug|
content_item = GovukSchemas::Example.find("mainstream_browse_page", example_name: "top_level_page").tap do |item|
item["base_path"] = "/browse/#{slug}"
end
describe "popular tasks" do
it "renders on level one browse pages" do
content_item = GovukSchemas::Example.find("mainstream_browse_page", example_name: "top_level_page")
stub_content_store_has_item(content_item["base_path"], content_item)
content_ids = content_item["links"]["second_level_browse_pages"].map { |link| link["content_id"] }
search_api_has_popular_documents_for_level_one_browse(content_ids)

visit content_item["base_path"]
expect(page).to have_css(".browse__action-links")
expect(page).to have_content("Popular tasks")
end
end

it "does not render on the root browse page" do
content_item = GovukSchemas::Example.find("mainstream_browse_page", example_name: "root_page")
stub_content_store_has_item(content_item["base_path"], content_item)

visit content_item["base_path"]
expect(page).not_to have_css(".browse__action-links")
expect(page).not_to have_content("Popular tasks")
end

it "does not render on level two browse pages" do
content_item = GovukSchemas::Example.find("mainstream_browse_page", example_name: "level_2_page")
stub_content_store_has_item(content_item["base_path"], content_item)
search_api_has_documents_for_browse_page(content_item["content_id"], %w[a-slug], page_size: 1000)

visit content_item["base_path"]
expect(page).not_to have_css(".browse__action-links")
expect(page).not_to have_content("Popular tasks")
end

it "renders the GOV.UK Chat promo" do
content_item = GovukSchemas::Example.find("mainstream_browse_page", example_name: "top_level_page").tap do |item|
item["base_path"] = GovukChatPromoHelper::GOVUK_CHAT_PROMO_BASE_PATHS.first
end

stub_content_store_has_item(content_item["base_path"], content_item)
content_ids = content_item["links"]["second_level_browse_pages"].map { |link| link["content_id"] }
search_api_has_popular_documents_for_level_one_browse(content_ids)

ClimateControl.modify GOVUK_CHAT_PROMO_ENABLED: "true" do
visit content_item["base_path"]
Expand Down
47 changes: 26 additions & 21 deletions spec/helpers/browse_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
RSpec.describe BrowseHelper do
describe "#display_popular_links_for_slug?" do
it "returns true if data exists" do
expect(helper.display_popular_links_for_slug?("business")).to be(true)
end

it "returns false if no data exists" do
expect(helper.display_popular_links_for_slug?("random12345")).to be(false)
end
end
describe "#with_tracking_data" do
it "returns formatted popular links" do
popular_content_from_search = [
{
'link': "/foo/policy_paper",
'title': "Policy on World Locations",
},
{
'link': "/foo/news_story",
'title': "PM attends summit on world location news pages",
},
{
'link': "/foo/anything",
'title': "Anything",
},
]

describe "#popular_links_for_slug" do
it "adds GA tracking data to links" do
expected_links = [
{
text: "HMRC online services: sign in or set up an account",
href: "/log-in-register-hmrc-online-services",
text: "Policy on World Locations",
href: "/foo/policy_paper",
data_attributes: {
module: "ga4-link-tracker",
ga4_track_links_only: "",
Expand All @@ -23,14 +28,14 @@
type: "action",
index_link: 1,
index_total: 3,
text: "HMRC online services: sign in or set up an account",
text: "Policy on World Locations",
section: "Popular tasks",
},
},
},
{
text: "Get information about a company",
href: "/get-information-about-a-company",
text: "PM attends summit on world location news pages",
href: "/foo/news_story",
data_attributes: {
module: "ga4-link-tracker",
ga4_track_links_only: "",
Expand All @@ -39,14 +44,14 @@
type: "action",
index_link: 2,
index_total: 3,
text: "Get information about a company",
text: "PM attends summit on world location news pages",
section: "Popular tasks",
},
},
},
{
text: "Find an energy certificate",
href: "/find-energy-certificate",
text: "Anything",
href: "/foo/anything",
data_attributes: {
module: "ga4-link-tracker",
ga4_track_links_only: "",
Expand All @@ -55,13 +60,13 @@
type: "action",
index_link: 3,
index_total: 3,
text: "Find an energy certificate",
text: "Anything",
section: "Popular tasks",
},
},
},
]
expect(helper.popular_links_for_slug("business")).to eq(expected_links)
expect(helper.with_tracking_data(popular_content_from_search)).to eq(expected_links)
end
end
end
Loading

0 comments on commit fe5b0da

Please sign in to comment.