diff --git a/app/controllers/content_items_controller.rb b/app/controllers/content_items_controller.rb index 5bacae228..778153000 100644 --- a/app/controllers/content_items_controller.rb +++ b/app/controllers/content_items_controller.rb @@ -65,23 +65,15 @@ def load_content_item def load_taxonomy_navigation if @content_item.taxons.present? - taxons = @content_item.taxons.select { |taxon| taxon["phase"] == "live" } current_base_path = @content_item.base_path - + taxons = @content_item.taxons.select { |taxon| taxon["phase"] == "live" } taxon_ids = taxons.map { |taxon| taxon["content_id"] } - services = Supergroups::Services.new(current_base_path, taxon_ids) - guidance_and_regulation = Supergroups::GuidanceAndRegulation.new(current_base_path, taxon_ids) - news = Supergroups::NewsAndCommunications.new(current_base_path, taxon_ids) - policy_and_engagement = Supergroups::PolicyAndEngagement.new(current_base_path, taxon_ids) - transparency = Supergroups::Transparency.new(current_base_path, taxon_ids) - - @taxonomy_navigation = { - services: (services.all_services if services.any_services?), - guidance_and_regulation: guidance_and_regulation.tagged_content, - news_and_communication: (news.all_news if news.any_news?), - policy_and_engagement: policy_and_engagement.tagged_content, - transparency: transparency.tagged_content, - } + + @taxonomy_navigation = {} + @content_item.links_out_supergroups.each do |supergroup| + supergroup_taxon_links = "Supergroups::#{supergroup.camelcase}".constantize.new(current_base_path, taxon_ids, filter_content_purpose_subgroup: @content_item.links_out_subgroups) + @taxonomy_navigation[supergroup.to_sym] = supergroup_taxon_links.tagged_content + end @tagged_taxons = taxons.map do |taxon| { diff --git a/app/presenters/content_item/links_out.rb b/app/presenters/content_item/links_out.rb new file mode 100644 index 000000000..67965755f --- /dev/null +++ b/app/presenters/content_item/links_out.rb @@ -0,0 +1,109 @@ +module ContentItem + module LinksOut + def links_out_supergroups + @links_out_supergroups ||= fetch_links_out_supergroups + end + + def links_out_subgroups + @links_out_subgroups ||= fetch_links_out_subgroups + end + + private + + def fetch_links_out_supergroups + links_out.map { |link| link["supergroup"] }.uniq + end + + def fetch_links_out_subgroups + subgroups = [] + links_out.each do |link| + if link["type"] == "content_purpose_subgroup" + subgroups << link["title"] + end + end + subgroups.uniq + end + + def links_out + @links_out ||= fetch_links_out + end + + def fetch_links_out + document_type_link_rule = DocumentTypeLinkRule.new(content_item) + return document_type_link_rule.links if document_type_link_rule.any? + subgroup_link_rule = SubgroupLinkRule.new(content_item) + return subgroup_link_rule.links if subgroup_link_rule.any? + SupergroupLinkRule.new(content_item).links + end + + class LinkRule + def initialize(content_item) + @content_item = content_item + @rules = load_rules + @links = fetch_links + end + + def any? + !@links.nil? + end + + def links + @links || [] + end + + private + + def fetch_links + if @content_item.dig(rule_level) && + @rules[rule_level] && + @rules[rule_level].dig(@content_item[rule_level]) + @rules[rule_level][@content_item[rule_level]] + end + end + + def load_rules + Rails.configuration.taxonomy_navigation_links_out + end + + def rule_level + NotImplementedError + end + end + + class DocumentTypeLinkRule < LinkRule + def initialize(content_item) + super + end + + private + + def rule_level + 'document_type' + end + end + + class SubgroupLinkRule < LinkRule + def initialize(content_item) + super + end + + private + + def rule_level + 'content_purpose_subgroup' + end + end + + class SupergroupLinkRule < LinkRule + def initialize(content_item) + super + end + + private + + def rule_level + 'content_purpose_supergroup' + end + end + end +end diff --git a/app/presenters/content_item_presenter.rb b/app/presenters/content_item_presenter.rb index daf799266..c121346ab 100644 --- a/app/presenters/content_item_presenter.rb +++ b/app/presenters/content_item_presenter.rb @@ -1,5 +1,6 @@ class ContentItemPresenter include ContentItem::Withdrawable + include ContentItem::LinksOut attr_reader :content_item, :requested_content_item_path, diff --git a/app/presenters/supergroups/guidance_and_regulation.rb b/app/presenters/supergroups/guidance_and_regulation.rb index 5ab8babe7..2df25efe2 100644 --- a/app/presenters/supergroups/guidance_and_regulation.rb +++ b/app/presenters/supergroups/guidance_and_regulation.rb @@ -1,20 +1,11 @@ module Supergroups class GuidanceAndRegulation < Supergroup - def initialize(current_path, taxon_ids) - @current_path = current_path - @taxon_ids = taxon_ids - @content = fetch_content + def initialize(current_path, taxon_ids, filters) + super(current_path, taxon_ids, filters, MostPopularContent) end def tagged_content format_document_data(@content, include_timestamp: false) end - - private - - def fetch_content - return [] unless @taxon_ids.any? - MostPopularContent.fetch(content_ids: @taxon_ids, current_path: @current_path, filter_content_purpose_supergroup: "guidance_and_regulation") - end end end diff --git a/app/presenters/supergroups/news_and_communications.rb b/app/presenters/supergroups/news_and_communications.rb index 2d7d1da6f..6a3b35295 100644 --- a/app/presenters/supergroups/news_and_communications.rb +++ b/app/presenters/supergroups/news_and_communications.rb @@ -2,56 +2,41 @@ module Supergroups class NewsAndCommunications < Supergroup attr_reader :content - def initialize(current_path, taxon_ids) - @taxon_ids = taxon_ids - @current_path = current_path - @content = fetch + def initialize(current_path, taxon_ids, filters) + super(current_path, taxon_ids, filters, MostRecentContent) end - def all_news + def tagged_content + return unless @content.any? { - documents: tagged_content, + documents: documents, promoted_content: promoted_content, } end - def any_news? - @content.any? - end + private - def tagged_content + def documents items = @content.drop(promoted_content_count) format_document_data(items) end def promoted_content - items = @content.shift(promoted_content_count) + items = @content.take(promoted_content_count) content = format_document_data(items, data_category: "ImageCardClicked") content.each do |document| document_image = news_item_photo(document[:link][:path]) document[:image] = { - url: document_image["url"], - alt: document_image["alt_text"], - context: document_image["context"] + url: document_image["url"], + alt: document_image["alt_text"], + context: document_image["context"] } end content end - private - - def fetch - return [] if @taxon_ids.empty? - - MostRecentContent.fetch( - content_ids: @taxon_ids, - current_path: @current_path, - filter_content_purpose_supergroup: "news_and_communications" - ) - end - def promoted_content_count 3 end diff --git a/app/presenters/supergroups/policy_and_engagement.rb b/app/presenters/supergroups/policy_and_engagement.rb index 5660f5381..f773c31da 100644 --- a/app/presenters/supergroups/policy_and_engagement.rb +++ b/app/presenters/supergroups/policy_and_engagement.rb @@ -1,20 +1,7 @@ module Supergroups class PolicyAndEngagement < Supergroup - def initialize(current_path, taxon_ids) - @current_path = current_path - @taxon_ids = taxon_ids - @content = fetch_content - end - - def tagged_content - format_document_data(@content) - end - - private - - def fetch_content - return [] unless @taxon_ids.any? - MostRecentContent.fetch(content_ids: @taxon_ids, current_path: @current_path, filter_content_purpose_supergroup: "policy_and_engagement") + def initialize(current_path, taxon_ids, filters) + super(current_path, taxon_ids, filters, MostRecentContent) end end end diff --git a/app/presenters/supergroups/services.rb b/app/presenters/supergroups/services.rb index d34422e53..3f6b5d670 100644 --- a/app/presenters/supergroups/services.rb +++ b/app/presenters/supergroups/services.rb @@ -1,46 +1,31 @@ module Supergroups - class Services + class Services < Supergroup attr_reader :content - def initialize(current_path, taxon_ids) - @taxon_ids = taxon_ids - @current_path = current_path - @content = fetch + def initialize(current_path, taxon_ids, filters) + super(current_path, taxon_ids, filters, MostPopularContent) end - def all_services + def tagged_content + return unless @content.any? { - documents: tagged_content, + documents: documents, promoted_content: promoted_content, } end - def any_services? - @content.any? - end + private - def tagged_content + def documents items = @content.drop(promoted_content_count) format_document_data(items) end def promoted_content - items = @content.shift(promoted_content_count) + items = @content.take(promoted_content_count) format_document_data(items, "HighlightBoxClicked") end - private - - def fetch - return [] if @taxon_ids.empty? - - MostPopularContent.fetch( - content_ids: @taxon_ids, - current_path: @current_path, - filter_content_purpose_supergroup: "services" - ) - end - def promoted_content_count 3 end diff --git a/app/presenters/supergroups/supergroup.rb b/app/presenters/supergroups/supergroup.rb index 5fbba0876..14e88678e 100644 --- a/app/presenters/supergroups/supergroup.rb +++ b/app/presenters/supergroups/supergroup.rb @@ -1,5 +1,16 @@ module Supergroups class Supergroup + def initialize(current_path, taxon_ids, filters, content_order_class) + @current_path = current_path + @taxon_ids = taxon_ids + @filters = default_filters.merge(filters) + @content = fetch_content(content_order_class) + end + + def tagged_content + format_document_data(@content) + end + private def format_document_data(documents, data_category: nil, include_timestamp: true) @@ -41,5 +52,14 @@ def data_attributes(base_path, link_text, index, data_category) def data_module_label self.class.name.demodulize.camelize(:lower) end + + def default_filters + { filter_content_purpose_supergroup: self.class.name.demodulize.underscore } + end + + def fetch_content(content_order_class) + return [] unless @taxon_ids.any? + content_order_class.fetch(content_ids: @taxon_ids, current_path: @current_path, filters: @filters) + end end end diff --git a/app/presenters/supergroups/transparency.rb b/app/presenters/supergroups/transparency.rb index f15ef45b7..f7afcbbd4 100644 --- a/app/presenters/supergroups/transparency.rb +++ b/app/presenters/supergroups/transparency.rb @@ -1,20 +1,7 @@ module Supergroups class Transparency < Supergroup - def initialize(current_path, taxon_ids) - @current_path = current_path - @taxon_ids = taxon_ids - @content = fetch_content - end - - def tagged_content - format_document_data(@content) - end - - private - - def fetch_content - return [] unless @taxon_ids.any? - MostRecentContent.fetch(content_ids: @taxon_ids, current_path: @current_path, filter_content_purpose_supergroup: "transparency") + def initialize(current_path, taxon_ids, filters) + super(current_path, taxon_ids, filters, MostRecentContent) end end end diff --git a/app/services/most_popular_content.rb b/app/services/most_popular_content.rb index 388400eba..3fd31a2c7 100644 --- a/app/services/most_popular_content.rb +++ b/app/services/most_popular_content.rb @@ -3,17 +3,17 @@ class MostPopularContent include RummagerFields - attr_reader :content_ids, :current_path, :filter_content_purpose_supergroup, :number_of_links + attr_reader :content_ids, :current_path, :filters, :number_of_links - def initialize(content_ids:, current_path:, filter_content_purpose_supergroup:, number_of_links: 3) + def initialize(content_ids:, current_path:, filters: {}, number_of_links: 3) @content_ids = content_ids @current_path = current_path - @filter_content_purpose_supergroup = filter_content_purpose_supergroup + @filters = filters @number_of_links = number_of_links end - def self.fetch(content_ids:, current_path:, filter_content_purpose_supergroup:) - new(content_ids: content_ids, current_path: current_path, filter_content_purpose_supergroup: filter_content_purpose_supergroup).fetch + def self.fetch(content_ids:, current_path:, filters:) + new(content_ids: content_ids, current_path: current_path, filters: filters).fetch end def fetch @@ -31,12 +31,9 @@ def search_response order: '-popularity', reject_link: current_path, } - params[:filter_content_purpose_supergroup] = filter_content_purpose_supergroup if filter_content_purpose_supergroup.present? + params[:filter_content_purpose_supergroup] = @filters[:filter_content_purpose_supergroup] if @filters[:filter_content_purpose_supergroup].present? + params[:filter_content_purpose_subgroup] = @filters[:filter_content_purpose_subgroup] if @filters[:filter_content_purpose_subgroup].present? - search_result(params) - end - - def search_result(params) Services.rummager.search(params) end end diff --git a/app/services/most_recent_content.rb b/app/services/most_recent_content.rb index 40c0fc243..1363b67a3 100644 --- a/app/services/most_recent_content.rb +++ b/app/services/most_recent_content.rb @@ -1,15 +1,15 @@ class MostRecentContent - attr_reader :content_id, :current_path, :filter_taxon, :number_of_links + attr_reader :content_id, :current_path, :filters, :number_of_links - def initialize(content_ids:, current_path:, filter_content_purpose_supergroup:, number_of_links: 3) + def initialize(content_ids:, current_path:, filters: {}, number_of_links: 3) @content_ids = content_ids @current_path = current_path - @filter_content_purpose_supergroup = filter_content_purpose_supergroup + @filters = filters @number_of_links = number_of_links end - def self.fetch(content_ids:, current_path:, filter_content_purpose_supergroup:) - new(content_ids: content_ids, current_path: current_path, filter_content_purpose_supergroup: filter_content_purpose_supergroup).fetch + def self.fetch(content_ids:, current_path:, filters:) + new(content_ids: content_ids, current_path: current_path, filters: filters).fetch end def fetch @@ -32,7 +32,9 @@ def search_response order: '-public_timestamp', reject_link: current_path, } - params[:filter_content_purpose_supergroup] = @filter_content_purpose_supergroup if @filter_content_purpose_supergroup.present? + params[:filter_content_purpose_supergroup] = @filters[:filter_content_purpose_supergroup] if @filters[:filter_content_purpose_supergroup].present? + params[:filter_content_purpose_subgroup] = @filters[:filter_content_purpose_subgroup] if @filters[:filter_content_purpose_subgroup].present? + Services.rummager.search(params) end end diff --git a/app/views/shared/_taxonomy_navigation.html.erb b/app/views/shared/_taxonomy_navigation.html.erb index ab7693467..78f071e94 100644 --- a/app/views/shared/_taxonomy_navigation.html.erb +++ b/app/views/shared/_taxonomy_navigation.html.erb @@ -63,7 +63,7 @@ <% end %> - <% if taxonomy_navigation[:news_and_communication].present? %> + <% if taxonomy_navigation[:news_and_communications].present? %>
<%= render "govuk_publishing_components/components/heading", { text: t('supergroups.news_and_communications'), @@ -72,7 +72,7 @@ margin_bottom: 2 } %> - <% taxonomy_navigation[:news_and_communication][:promoted_content].in_groups_of(3, false) do |promo_group| %> + <% taxonomy_navigation[:news_and_communications][:promoted_content].in_groups_of(3, false) do |promo_group| %>
<% promo_group.each do |promo| %>
@@ -89,6 +89,9 @@ <% end %>
<% end %> + <%= render "govuk_publishing_components/components/document_list", { + items: taxonomy_navigation[:news_and_communications][:documents] + } %>
<% end %> diff --git a/config/application.rb b/config/application.rb index 816d8582f..08773ca4a 100644 --- a/config/application.rb +++ b/config/application.rb @@ -49,5 +49,7 @@ class Application < Rails::Application # Do not swallow errors in after_commit/after_rollback callbacks. # config.active_record.raise_in_transactional_callbacks = true + + config.taxonomy_navigation_links_out = config_for(:taxonomy_navigation_links_out) end end diff --git a/config/taxonomy_navigation_links_out.yml b/config/taxonomy_navigation_links_out.yml new file mode 100644 index 000000000..18f6b5600 --- /dev/null +++ b/config/taxonomy_navigation_links_out.yml @@ -0,0 +1,104 @@ +default: &default + content_purpose_supergroup: + news_and_communications: + - title: policy_and_engagement + type: content_purpose_supergroup + supergroup: policy_and_engagement + - title: research_and_data + type: content_purpose_subgroup + supergroup: transparency + - title: guidance + type: content_purpose_subgroup + supergroup: guidance_and_regulation + - title: news + type: content_purpose_subgroup + supergroup: news_and_communications + - title: incidents + type: content_purpose_subgroup + supergroup: transparency + guidance_and_regulation: + - title: services + type: content_purpose_supergroup + supergroup: services + - title: guidance + type: content_purpose_subgroup + supergroup: guidance_and_regulation + - title: news + type: content_purpose_subgroup + supergroup: news_and_communications + - title: decisions + type: content_purpose_subgroup + supergroup: transparency + - title: step_by_step + type: document_type + supergroup: services + services: + - title: services + type: content_purpose_supergroup + supergroup: services + - title: guidance + type: content_purpose_subgroup + supergroup: guidance_and_regulation + content_purpose_subgroup: + policy: + - title: policy_and_engagement + type: content_purpose_supergroup + supergroup: policy_and_engagement + - title: policy + type: content_purpose_subgroup + supergroup: policy_and_engagement + incidents: + - title: incidents + type: content_purpose_subgroup + supergroup: transparency + - title: news + type: content_purpose_subgroup + supergroup: news_and_communications + - title: research_and_data + type: content_purpose_supergroup + supergroup: transparency + - title: guidance + type: content_purpose_subgroup + supergroup: guidance_and_regulation + research_and_data: + - title: research_and_data + type: content_purpose_supergroup + supergroup: transparency + decisions: + - title: news + type: content_purpose_subgroup + supergroup: news_and_communications + - title: guidance + type: content_purpose_subgroup + supergroup: guidance_and_regulation + document_type: + fatality_notice: [] + manual: [] + manual_section: [] + open_consultation: + - title: policy_and_engagement + type: content_purpose_supergroup + supergroup: policy_and_engagement + - title: decisions + type: content_purpose_subgroup + supergroup: transparency + closed_consultation: + - title: policy_and_engagement + type: content_purpose_supergroup + supergroup: policy_and_engagement + - title: decisions + type: content_purpose_subgroup + supergroup: transparency + consultation_outcome: + - title: decisions + type: content_purpose_subgroup + supergroup: transparency + +development: + <<: *default + +test: + <<: *default + +production: + <<: *default \ No newline at end of file diff --git a/test/integration/content_pages_navigation_test.rb b/test/integration/content_pages_navigation_test.rb index f965c515b..89da452f6 100644 --- a/test/integration/content_pages_navigation_test.rb +++ b/test/integration/content_pages_navigation_test.rb @@ -4,6 +4,10 @@ class ContentPagesNavigationTest < ActionDispatch::IntegrationTest include ContentPagesNavTestHelper include GdsApi::TestHelpers::Rummager + def setup + stub_links_out_supergroups_to_include_all + end + test "ContentPagesNav variant A does not show taxonomy navigation for single taxon" do setup_variant_a @@ -147,11 +151,7 @@ class ContentPagesNavigationTest < ActionDispatch::IntegrationTest setup_and_visit_content_item_with_taxons('guide', taxons) - assert page.has_css?('h3', text: "Guidance and regulation") - - assert page.has_css?('.gem-c-document-list__item a[data-track-category="guidanceAndRegulationDocumentListClicked"]', text: 'Free school meals form') - assert page.has_css?('.gem-c-document-list__item a[data-track-action="1"]', text: 'Free school meals form') - assert page.has_css?('.gem-c-document-list__item a[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + assert_has_guidance_and_regulation_section end test "does not show the Guidance section if there is no tagged content" do @@ -177,11 +177,7 @@ class ContentPagesNavigationTest < ActionDispatch::IntegrationTest setup_and_visit_content_item_with_taxons('guide', taxons) - assert page.has_css?('h3', text: "Transparency") - - assert page.has_css?('.gem-c-document-list__item a[data-track-category="transparencyDocumentListClicked"]', text: 'Free school meals form') - assert page.has_css?('.gem-c-document-list__item a[data-track-action="1"]', text: 'Free school meals form') - assert page.has_css?('.gem-c-document-list__item a[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + assert_has_transparency_section end test "does not show the Transparency section if there is no tagged content" do @@ -212,6 +208,7 @@ class ContentPagesNavigationTest < ActionDispatch::IntegrationTest assert page.has_css?('.gem-c-image-card__title-link[data-track-category="newsAndCommunicationsImageCardClicked"]', text: 'Free school meals form') assert page.has_css?('.gem-c-image-card__title-link[data-track-action="1"]', text: 'Free school meals form') assert page.has_css?('.gem-c-image-card__title-link[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + assert_has_news_and_communications_section end test "does not show the News and comms section if there is no tagged content" do @@ -266,6 +263,21 @@ class ContentPagesNavigationTest < ActionDispatch::IntegrationTest end end + test "links out will filter out supergroups not in the configuration" do + stub_rummager + setup_variant_b + taxons = THREE_TAXONS + supergroups.each do |supergroup_to_exclude| + supergroups_to_include = supergroups.delete_if { |supergroup| supergroup == supergroup_to_exclude } + stub_links_out_supergroups(supergroups_to_include) + setup_and_visit_content_item_with_taxons('guide', taxons) + supergroups_to_include.each do |included_supergroup| + send("assert_has_#{included_supergroup}_section") + end + refute page.has_css?('h3', text: supergroup_to_exclude.humanize) + end + end + test "ContentPagesNav variant B shows BETA phase message and survey link" do stub_rummager setup_variant_b @@ -283,7 +295,7 @@ class ContentPagesNavigationTest < ActionDispatch::IntegrationTest end def stub_empty_services - Supergroups::Services.any_instance.stubs(:all_services).returns({}) + Supergroups::Services.any_instance.stubs(:tagged_content).returns({}) end def stub_empty_guidance diff --git a/test/integration/content_pages_related_navigation_test.rb b/test/integration/content_pages_related_navigation_test.rb index 82fb18189..bf6641699 100644 --- a/test/integration/content_pages_related_navigation_test.rb +++ b/test/integration/content_pages_related_navigation_test.rb @@ -4,6 +4,10 @@ class ContentPagesRelatedNavigationTest < ActionDispatch::IntegrationTest include ContentPagesNavTestHelper include GdsApi::TestHelpers::Rummager + def setup + stub_links_out_supergroups_to_include_all + end + test "ContentPagesNav variant A shows related collections in the sidebar" do setup_variant_a diff --git a/test/integration/links_out_config_test.rb b/test/integration/links_out_config_test.rb new file mode 100644 index 000000000..af690aea7 --- /dev/null +++ b/test/integration/links_out_config_test.rb @@ -0,0 +1,66 @@ +require 'test_helper' + +class LinksOutConfigTest < ActionDispatch::IntegrationTest + include ContentPagesNavTestHelper + include GdsApi::TestHelpers::Rummager + + def schema_type + "guide" + end + + def setup_variant_b + ContentItemsController.any_instance.stubs(:show_new_navigation?).returns(true) + end + + def setup_and_visit_content_item_with_taxonomy_grouping(name, taxonomy_grouping) + taxonomy_grouping = default_taxonomy_grouping.merge(taxonomy_grouping) + @content_item = get_content_example(name).tap do |item| + item["links"]["taxons"] = SINGLE_TAXON + item["content_purpose_supergroup"] = taxonomy_grouping["content_purpose_supergroup"] + item["content_purpose_subgroup"] = taxonomy_grouping["content_purpose_subgroup"] + item["document_type"] = taxonomy_grouping["document_type"] + content_store_has_item(item["base_path"], item.to_json) + visit_with_cachebust(item["base_path"]) + end + end + + def default_taxonomy_grouping + { + "content_purpose_supergroup" => "guidance_and_regulation", + "content_purpose_subgroup" => "guidance", + "document_type" => "guide" + } + end + + def config + Rails.configuration.taxonomy_navigation_links_out + end + + def expected_supergroups(rule_level) + rule_level.map { |rules| rules["supergroup"].humanize } + end + + def assert_has_supergroup_navigation(expected_supergroups) + within('.taxonomy-navigation') do + expected_supergroups.each do |supergroup| + assert page.has_css?('.gem-c-heading', text: supergroup) + end + end + end + + test "links out configuration causes no errors and correct supergroups are displayed for each ruleset" do + stub_rummager + setup_variant_b + config.each_key do |taxonomy_rule_level| + config[taxonomy_rule_level].each_key do |rules_for_taxon| + setup_and_visit_content_item_with_taxonomy_grouping("guide", taxonomy_rule_level => rules_for_taxon) + expected_supergroups = expected_supergroups(config[taxonomy_rule_level][rules_for_taxon]) + if expected_supergroups.any? + assert_has_supergroup_navigation(expected_supergroups) + else + refute page.has_css?('taxonomy-navigation') + end + end + end + end +end diff --git a/test/presenters/content_item/links_out_test.rb b/test/presenters/content_item/links_out_test.rb new file mode 100644 index 000000000..651ef3d71 --- /dev/null +++ b/test/presenters/content_item/links_out_test.rb @@ -0,0 +1,242 @@ +require 'test_helper' + +class LinksOutTest < ActiveSupport::TestCase + def setup + @links_out = Object.new + @links_out.extend(ContentItem::LinksOut) + class << @links_out + def content_item + { + "content_purpose_supergroup" => "guidance_and_regulation", + "content_purpose_subgroup" => "guidance", + "document_type" => "guide" + } + end + end + end + + def rules + { + "content_purpose_supergroup" => { + "guidance_and_regulation" => [ + { + "title" => "link_to_guidance_and_regulation", + "type" => "content_purpose_supergroup", + "supergroup" => "services" + } + ] + }, + "content_purpose_subgroup" => { + "guidance" => [ + { + "title" => "link_to_guidance", + "type" => "content_purpose_subgroup", + "supergroup" => "transparency" + } + ] + }, + "document_type" => { + "guide" => [ + { + "title" => "link_to_guide", + "type" => "document_type", + "supergroup" => "guidance_and_regulation" + } + ] + } + } + end + + def other_rules + { + "content_purpose_supergroup" => { + "news_and_communications" => [ + { + "title" => "link_to_news_and_communications", + "type" => "content_purpose_supergroup", + "supergroup" => "news_and_communications" + } + ] + }, + "content_purpose_subgroup" => { + "news" => [ + { + "title" => "link_to_news", + "type" => "content_purpose_subgroup", + "supergroup" => "news_and_communications" + } + ] + }, + "document_type" => { + "article" => [ + { + "title" => "link_to_article", + "type" => "document_type", + "supergroup" => "news_and_communications" + } + ] + } + } + end + + def stub_load_rules(rules) + Rails.configuration.taxonomy_navigation_links_out = rules + end + + def assert_has_supergroup_rule(rule_set) + assert rule_set["content_purpose_supergroup"].has_key?("guidance_and_regulation") + end + + def assert_has_subgroup_rule(rule_set) + assert rule_set["content_purpose_subgroup"].has_key?("guidance") + end + + def assert_has_document_type_rule(rule_set) + assert rule_set["document_type"].has_key?("guide") + end + + def assert_returns_guide + assert_equal [{ "title" => "link_to_guide", "type" => "document_type", "supergroup" => "guidance_and_regulation" }], @links_out.links_out + end + + def assert_returns_guidance + assert_equal %w(guidance), @links_out.links_out_subgroups + end + + def assert_returns_guidance_and_regulation + assert_equal %w(guidance_and_regulation), @links_out.links_out_supergroups + end + + def news_and_communications_rule + { "title" => "link_to_news_and_communications", "type" => "content_purpose_supergroup", "supergroup" => "news_and_communications" } + end + + def news_rule + { "title" => "link_to_news", "type" => "content_purpose_subgroup", "supergroup" => "news_and_communications" } + end + + test 'links_out_supergroups returns empty array if the content_item is blank' do + class << @links_out + def content_item + {} + end + end + assert_equal [], @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns empty array if the link rules is blank' do + stub_load_rules({}) + assert_equal [], @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns empty array if the link does not contain any rules for this content_item' do + stub_load_rules(other_rules) + assert_equal [], @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns document type rule if it is defined within rule set' do + assert_has_supergroup_rule(rules) + assert_has_subgroup_rule(rules) + assert_has_document_type_rule(rules) + stub_load_rules(rules) + assert_equal %w(guidance_and_regulation), @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns subgroup rule if it is defined within rule set and document_type is not' do + amended_rules = rules + amended_rules["document_type"] = nil + assert_has_supergroup_rule(amended_rules) + assert_has_subgroup_rule(amended_rules) + stub_load_rules(amended_rules) + assert_equal %w(transparency), @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns supergroup rule if it is defined within rule set, document_type and supergroup are not' do + amended_rules = rules + amended_rules["content_purpose_subgroup"] = nil + amended_rules["document_type"] = nil + assert_has_supergroup_rule(amended_rules) + stub_load_rules(amended_rules) + assert_equal %w(services), @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns subgroup rule if it is defined within rule set and document_type does not match' do + amended_rules = rules + amended_rules["document_type"] = other_rules["document_type"] + assert_has_supergroup_rule(amended_rules) + assert_has_subgroup_rule(amended_rules) + stub_load_rules(amended_rules) + assert_equal %w(transparency), @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns supergroup rule if it is defined within rule set, document_type and supergroup do not match' do + amended_rules = rules + amended_rules["content_purpose_subgroup"] = other_rules["content_purpose_subgroup"] + amended_rules["document_type"] = other_rules["document_type"] + assert_has_supergroup_rule(amended_rules) + stub_load_rules(amended_rules) + assert_equal %w(services), @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns nothing if the document type is an empty array' do + amended_rules = rules + amended_rules["document_type"] = { "guide" => [] } + assert_has_supergroup_rule(amended_rules) + assert_has_subgroup_rule(amended_rules) + stub_load_rules(amended_rules) + assert_equal [], @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns correct supergroup names for content_purpose_supergroup rules' do + amended_rules = rules + amended_rules["content_purpose_supergroup"]["guidance_and_regulation"] << news_and_communications_rule + amended_rules["content_purpose_subgroup"] = nil + amended_rules["document_type"] = nil + + stub_load_rules(amended_rules) + assert_equal %w(services news_and_communications), @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns correct supergroup names for content_purpose_subgroup rules' do + amended_rules = rules + amended_rules["content_purpose_subgroup"]["guidance"] << news_and_communications_rule + amended_rules["document_type"] = nil + stub_load_rules(amended_rules) + assert_equal %w(transparency news_and_communications), @links_out.links_out_supergroups + end + + test 'links_out_supergroups returns correct supergroup names for document_type rules' do + amended_rules = rules + amended_rules["document_type"]["guide"] << news_and_communications_rule + + stub_load_rules(amended_rules) + assert_equal %w(guidance_and_regulation news_and_communications), @links_out.links_out_supergroups + end + + test 'links_out_subgroups returns correct subgroup names for content_purpose_supergroup rules' do + amended_rules = rules + amended_rules["content_purpose_supergroup"]["guidance_and_regulation"] << news_rule + amended_rules["content_purpose_subgroup"] = nil + amended_rules["document_type"] = nil + + stub_load_rules(amended_rules) + assert_equal %w(link_to_news), @links_out.links_out_subgroups + end + + test 'links_out_subgroups returns correct subgroup names for content_purpose_subgroup rules' do + amended_rules = rules + amended_rules["content_purpose_subgroup"]["guidance"] << news_rule + amended_rules["document_type"] = nil + + stub_load_rules(amended_rules) + assert_equal %w(link_to_guidance link_to_news), @links_out.links_out_subgroups + end + + test 'links_out_subgroups returns correct subgroup names for document_type rules' do + amended_rules = rules + amended_rules["document_type"]["guide"] << news_rule + + stub_load_rules(amended_rules) + assert_equal %w(link_to_news), @links_out.links_out_subgroups + end +end diff --git a/test/presenters/supergroups/guidance_and_regulation_test.rb b/test/presenters/supergroups/guidance_and_regulation_test.rb index 0d8833cfa..c2b6a2455 100644 --- a/test/presenters/supergroups/guidance_and_regulation_test.rb +++ b/test/presenters/supergroups/guidance_and_regulation_test.rb @@ -4,7 +4,7 @@ class GuidanceAndRegulationTest < ActiveSupport::TestCase include RummagerHelpers test "tagged_content returns empty array if taxon ids is a blank array" do - guidance_and_regulation = Supergroups::GuidanceAndRegulation.new("/no-particular-page", []) + guidance_and_regulation = Supergroups::GuidanceAndRegulation.new("/no-particular-page", [], {}) assert_equal [], guidance_and_regulation.tagged_content end @@ -12,7 +12,7 @@ class GuidanceAndRegulationTest < ActiveSupport::TestCase taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_popular_content("/no-particular-page", taxon_content_ids, 0, "guidance_and_regulation") - guidance_and_regulation = Supergroups::GuidanceAndRegulation.new("/no-particular-page", []) + guidance_and_regulation = Supergroups::GuidanceAndRegulation.new("/no-particular-page", [], {}) assert_equal [], guidance_and_regulation.tagged_content end @@ -20,7 +20,7 @@ class GuidanceAndRegulationTest < ActiveSupport::TestCase taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_popular_content("/no-particular-page", taxon_content_ids, 2, "guidance_and_regulation") - guidance_and_regulation = Supergroups::GuidanceAndRegulation.new("/no-particular-page", taxon_content_ids) + guidance_and_regulation = Supergroups::GuidanceAndRegulation.new("/no-particular-page", taxon_content_ids, {}) assert_equal 2, guidance_and_regulation.tagged_content.count end end diff --git a/test/presenters/supergroups/news_and_communications_test.rb b/test/presenters/supergroups/news_and_communications_test.rb index a5aa607e0..060d49839 100644 --- a/test/presenters/supergroups/news_and_communications_test.rb +++ b/test/presenters/supergroups/news_and_communications_test.rb @@ -4,16 +4,16 @@ class NewsAndCommunicationsTest < ActiveSupport::TestCase include RummagerHelpers test "finds no results if taxon ids is a blank array" do - news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", []) - refute news_and_comms.any_news? + news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", [], {}) + assert_nil news_and_comms.tagged_content end test "finds no results if there are taxon ids but no results" do taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_recent_content("/a-random-path", taxon_content_ids, 0, "news_and_communications") - news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids) - refute news_and_comms.any_news? + news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids, {}) + assert_nil news_and_comms.tagged_content end test "finds 2 featured items and 0 normal items with 2 results" do @@ -21,11 +21,10 @@ class NewsAndCommunicationsTest < ActiveSupport::TestCase stub_most_recent_content("/a-random-path", taxon_content_ids, 2, "news_and_communications") stub_content_store_items(2) - news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids) + news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids, {}) - assert news_and_comms.any_news? - assert_equal 0, news_and_comms.tagged_content.count - assert_equal 2, news_and_comms.promoted_content.count + assert_equal 0, news_and_comms.tagged_content[:documents].count + assert_equal 2, news_and_comms.tagged_content[:promoted_content].count end test "finds 3 promoted items and 2 normal items if there are enough results" do @@ -33,11 +32,10 @@ class NewsAndCommunicationsTest < ActiveSupport::TestCase stub_most_recent_content("/a-random-path", taxon_content_ids, 5, "news_and_communications") stub_content_store_items(3) - news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids) + news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids, {}) - news_and_comms.any_news? - assert_equal 2, news_and_comms.tagged_content.count - assert_equal 3, news_and_comms.promoted_content.count + assert_equal 2, news_and_comms.tagged_content[:documents].count + assert_equal 3, news_and_comms.tagged_content[:promoted_content].count end test "promoted content includes placeholder images if the content doesn't have one" do @@ -46,9 +44,9 @@ class NewsAndCommunicationsTest < ActiveSupport::TestCase stub_most_recent_content("/a-random-path", taxon_content_ids, 1, "news_and_communications") stub_content_store_items(1) - news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids) + news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids, {}) - news_item = news_and_comms.promoted_content.first + news_item = news_and_comms.tagged_content[:promoted_content].first assert_equal news_item[:image][:url], placeholder_image end @@ -67,9 +65,9 @@ class NewsAndCommunicationsTest < ActiveSupport::TestCase ) content_store_has_item("/content-item-0", content) - news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids) + news_and_comms = Supergroups::NewsAndCommunications.new("/a-random-path", taxon_content_ids, {}) - news_item = news_and_comms.promoted_content.first + news_item = news_and_comms.tagged_content[:promoted_content].first assert_equal news_item[:image][:url], "an/image/path" end diff --git a/test/presenters/supergroups/policy_and_engagement_test.rb b/test/presenters/supergroups/policy_and_engagement_test.rb index fe21edbe0..438ac74c6 100644 --- a/test/presenters/supergroups/policy_and_engagement_test.rb +++ b/test/presenters/supergroups/policy_and_engagement_test.rb @@ -4,7 +4,7 @@ class PolicyAndEngagementTest < ActiveSupport::TestCase include RummagerHelpers test "tagged_content returns empty array if taxon ids is a blank array" do - policy_and_engagement = Supergroups::PolicyAndEngagement.new("/a-random-path", []) + policy_and_engagement = Supergroups::PolicyAndEngagement.new("/a-random-path", [], {}) assert_equal [], policy_and_engagement.tagged_content end @@ -12,7 +12,7 @@ class PolicyAndEngagementTest < ActiveSupport::TestCase taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_recent_content("/a-random-path", taxon_content_ids, 0, "policy_and_engagement") - policy_and_engagement = Supergroups::PolicyAndEngagement.new("/a-random-path", []) + policy_and_engagement = Supergroups::PolicyAndEngagement.new("/a-random-path", [], {}) assert_equal [], policy_and_engagement.tagged_content end @@ -20,7 +20,7 @@ class PolicyAndEngagementTest < ActiveSupport::TestCase taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_recent_content("/a-random-path", taxon_content_ids, 2, "policy_and_engagement") - policy_and_engagement = Supergroups::PolicyAndEngagement.new("/a-random-path", taxon_content_ids) + policy_and_engagement = Supergroups::PolicyAndEngagement.new("/a-random-path", taxon_content_ids, {}) assert_equal 2, policy_and_engagement.tagged_content.count end end diff --git a/test/presenters/supergroups/services_test.rb b/test/presenters/supergroups/services_test.rb index 035040bc0..897a708cc 100644 --- a/test/presenters/supergroups/services_test.rb +++ b/test/presenters/supergroups/services_test.rb @@ -4,16 +4,16 @@ class ServicesTest < ActiveSupport::TestCase include RummagerHelpers test "services returns no results if taxon ids is a blank array" do - services = Supergroups::Services.new("/a-random-path", []) - refute services.any_services? + services = Supergroups::Services.new("/a-random-path", [], {}) + assert_nil services.tagged_content end test "services returns no results if there are taxon ids but no results" do taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_popular_content("/a-random-path", taxon_content_ids, 0, "services") - services = Supergroups::Services.new("/a-random-path", taxon_content_ids) - refute services.any_services? + services = Supergroups::Services.new("/a-random-path", taxon_content_ids, {}) + assert_nil services.tagged_content end test "tagged_content returns hash with with 2 featured items and 0 normal items with 2 results" do @@ -21,11 +21,10 @@ class ServicesTest < ActiveSupport::TestCase stub_most_popular_content("/a-random-path", taxon_content_ids, 2, "services") - services = Supergroups::Services.new("/a-random-path", taxon_content_ids) + services = Supergroups::Services.new("/a-random-path", taxon_content_ids, {}) - assert services.any_services? - assert_equal 0, services.tagged_content.count - assert_equal 2, services.promoted_content.count + assert_equal 0, services.tagged_content[:documents].count + assert_equal 2, services.tagged_content[:promoted_content].count end test "tagged_content returns hash with with 3 featured items and 2 normal items if there are enough results" do @@ -33,10 +32,9 @@ class ServicesTest < ActiveSupport::TestCase stub_most_popular_content("/a-random-path", taxon_content_ids, 5, "services") - services = Supergroups::Services.new("/a-random-path", taxon_content_ids) + services = Supergroups::Services.new("/a-random-path", taxon_content_ids, {}) - assert services.any_services? - assert_equal 2, services.tagged_content.count - assert_equal 3, services.promoted_content.count + assert_equal 2, services.tagged_content[:documents].count + assert_equal 3, services.tagged_content[:promoted_content].count end end diff --git a/test/presenters/supergroups/transparency_test.rb b/test/presenters/supergroups/transparency_test.rb index 683123e48..e8a1c668d 100644 --- a/test/presenters/supergroups/transparency_test.rb +++ b/test/presenters/supergroups/transparency_test.rb @@ -4,7 +4,7 @@ class TransparencyTest < ActiveSupport::TestCase include RummagerHelpers test "tagged_content returns empty array if taxon ids is a blank array" do - policy_and_engagement = Supergroups::Transparency.new("/a-random-path", []) + policy_and_engagement = Supergroups::Transparency.new("/a-random-path", [], {}) assert_equal [], policy_and_engagement.tagged_content end @@ -12,7 +12,7 @@ class TransparencyTest < ActiveSupport::TestCase taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_recent_content("/a-random-path", taxon_content_ids, 0, "transparency") - policy_and_engagement = Supergroups::Transparency.new("/a-random-path", []) + policy_and_engagement = Supergroups::Transparency.new("/a-random-path", [], {}) assert_equal [], policy_and_engagement.tagged_content end @@ -20,7 +20,7 @@ class TransparencyTest < ActiveSupport::TestCase taxon_content_ids = ['any-old-taxon', 'some-other-taxon-id'] stub_most_recent_content("/a-random-path", taxon_content_ids, 2, "transparency") - policy_and_engagement = Supergroups::Transparency.new("/a-random-path", taxon_content_ids) + policy_and_engagement = Supergroups::Transparency.new("/a-random-path", taxon_content_ids, {}) assert_equal 2, policy_and_engagement.tagged_content.count end end diff --git a/test/services/most_popular_content_test.rb b/test/services/most_popular_content_test.rb index 8888eafc0..848079f9e 100644 --- a/test/services/most_popular_content_test.rb +++ b/test/services/most_popular_content_test.rb @@ -8,7 +8,7 @@ def most_popular_content @most_popular_content ||= MostPopularContent.new( content_ids: taxon_content_ids, current_path: "/how-to-ride-a-bike", - filter_content_purpose_supergroup: 'guidance_and_regulation' + filters: { filter_content_purpose_supergroup: 'guidance_and_regulation', filter_content_purpose_subgroup: ['guidance'] } ) end @@ -64,12 +64,18 @@ def taxon_content_ids end end - test 'filters content by the requested filter_content_purpose_supergroup only' do + test 'filters content by the requested filter_content_purpose_supergroup' do assert_includes_params(filter_content_purpose_supergroup: 'guidance_and_regulation') do most_popular_content.fetch end end + test 'filters content by the requested filter_content_purpose_subgroups' do + assert_includes_params(filter_content_purpose_subgroup: ['guidance']) do + most_popular_content.fetch + end + end + test 'rejects the originating page from the results' do assert_includes_params(reject_link: '/how-to-ride-a-bike') do most_popular_content.fetch diff --git a/test/services/most_recent_content_test.rb b/test/services/most_recent_content_test.rb index 81446daaa..69a128ad5 100644 --- a/test/services/most_recent_content_test.rb +++ b/test/services/most_recent_content_test.rb @@ -8,7 +8,7 @@ def most_recent_content @most_recent_content ||= MostRecentContent.new( content_ids: taxon_content_ids, current_path: "/some-path", - filter_content_purpose_supergroup: "guidance_and_regulation", + filters: { filter_content_purpose_supergroup: 'guidance_and_regulation', filter_content_purpose_subgroup: ['guidance'] }, number_of_links: 6 ) end @@ -35,6 +35,12 @@ def taxon_content_ids end end + test "filters content by the requested filter_content_purpose_subgroups" do + assert_includes_params(filter_content_purpose_subgroup: ["guidance"]) do + most_recent_content.fetch + end + end + test "excludes current page" do assert_includes_params(reject_link: "/some-path") do most_recent_content.fetch diff --git a/test/support/content_pages_nav_test_helper.rb b/test/support/content_pages_nav_test_helper.rb index a222a78c1..47e306903 100644 --- a/test/support/content_pages_nav_test_helper.rb +++ b/test/support/content_pages_nav_test_helper.rb @@ -101,4 +101,60 @@ def setup_and_visit_content_from_publishing_app(publishing_app: nil) "phase" => "ethereal", } ].freeze + + def stub_links_out_supergroups(supergroups_to_include) + ContentItemPresenter.any_instance.stubs(:links_out_supergroups).returns(supergroups_to_include) + end + + def stub_links_out_supergroups_to_include_all + stub_links_out_supergroups(supergroups) + end + + def supergroups + %w(services guidance_and_regulation news_and_communications policy_and_engagement transparency) + end + + def assert_has_services_section + assert page.has_css?('h3', text: "Services") + assert page.has_css?('.gem-c-highlight-boxes__title', text: 'Free school meals form') + assert page.has_css?('.gem-c-highlight-boxes__title[data-track-category="ServicesHighlightBoxClicked"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-highlight-boxes__title[data-track-action="1"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-highlight-boxes__title[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + end + + def assert_has_policy_and_engagement_section + assert page.has_css?('h3', text: "Policy and engagement") + + assert page.has_css?('.gem-c-document-list__item a[data-track-category="policyAndEngagementDocumentListClicked"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-action="1"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + end + + def assert_has_guidance_and_regulation_section + assert page.has_css?('h3', text: "Guidance and regulation") + + assert page.has_css?('.gem-c-document-list__item a[data-track-category="guidanceAndRegulationDocumentListClicked"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-action="1"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + end + + def assert_has_transparency_section + assert page.has_css?('h3', text: "Transparency") + + assert page.has_css?('.gem-c-document-list__item a[data-track-category="transparencyDocumentListClicked"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-action="1"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + end + + def assert_has_news_and_communications_section + assert page.has_css?('h3', text: "News and communications") + assert page.has_css?('.gem-c-image-card__title', text: 'Free school meals form') + assert page.has_css?('.gem-c-image-card__title-link[data-track-category="newsAndCommunicationsImageCardClicked"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-image-card__title-link[data-track-action="1"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-image-card__title-link[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + + assert page.has_css?('.gem-c-document-list__item a[data-track-category="newsAndCommunicationsDocumentListClicked"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-action="1"]', text: 'Free school meals form') + assert page.has_css?('.gem-c-document-list__item a[data-track-label="/government/publications/meals"]', text: 'Free school meals form') + end end