Skip to content

Commit

Permalink
Merge pull request #983 from alphagov/add-services-ab-2
Browse files Browse the repository at this point in the history
Setup Content Pages Taxonomy Navigation AB Test (with services)
  • Loading branch information
Vanita Barrett authored Jul 26, 2018
2 parents e66947f + 73d1fe0 commit 2356bcc
Show file tree
Hide file tree
Showing 21 changed files with 570 additions and 3 deletions.
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
@import 'helpers/add-title-margin';
@import "helpers/content-bottom-margin";
@import "helpers/publisher-metadata-with-logo";
@import "helpers/taxonomy-navigation";

// Components from this application
@import 'components/*';
Expand Down
19 changes: 19 additions & 0 deletions app/assets/stylesheets/helpers/_taxonomy-navigation.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.taxonomy-navigation {
border-top: 2px solid $govuk-blue;
padding-top: $gutter-half;
}

.taxonomy-navigation__title-link {
@include bold-24;
display: block;
}

.taxonomy-navigation__section {
padding: $gutter-one-third 0 $gutter-two-thirds 0;
margin-top: $gutter-half;
border-top: 1px solid $grey-2;
}

.taxonomy-navigation__section:first-of-type {
border-top: 0;
}
51 changes: 51 additions & 0 deletions app/controllers/concerns/content_pages_nav_ab_testable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
module ContentPagesNavAbTestable
CUSTOM_DIMENSION = 65

def self.included(base)
base.helper_method(
:content_pages_nav_test_variant,
:show_new_navigation?,
:page_in_scope?
)
base.after_action :set_test_response_header
end

def content_pages_nav_test
@content_pages_nav_test ||= GovukAbTesting::AbTest.new(
"ContentPagesNav",
dimension: CUSTOM_DIMENSION,
allowed_variants: %w(A B),
control_variant: "A"
)
end

def content_pages_nav_test_variant
@content_pages_nav_test_variant ||= content_pages_nav_test.requested_variant(request.headers)
end

def set_test_response_header
content_pages_nav_test_variant.configure_response(response) if page_in_scope?
end

def show_new_navigation?
content_pages_nav_test_variant.variant?("B") && page_in_scope?
end

def page_in_scope?
# Pages are in scope if:
# - They are not an out-of-scope format, e.g: html publications
# - They are tagged to the taxonomy
if @content_item
not_an_html_publication? && has_a_live_taxon?
end
end

def not_an_html_publication?
!@content_item.document_type.eql?("html_publication")
end

def has_a_live_taxon?
@content_item.taxons.present? &&
@content_item.taxons.detect { |taxon| taxon["phase"] == "live" }
end
end
26 changes: 25 additions & 1 deletion app/controllers/content_items_controller.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
class ContentItemsController < ApplicationController
include ContentPagesNavAbTestable

rescue_from GdsApi::HTTPForbidden, with: :error_403
rescue_from GdsApi::HTTPNotFound, with: :error_notfound
Expand All @@ -9,11 +10,13 @@ class ContentItemsController < ApplicationController
rescue_from PresenterBuilder::RedirectRouteReturned, with: :error_redirect
rescue_from PresenterBuilder::SpecialRouteReturned, with: :error_notfound

attr_accessor :content_item
attr_accessor :content_item, :taxonomy_navigation

def show
load_content_item

load_taxonomy_navigation if show_new_navigation?

set_expiry
set_access_control_allow_origin_header if request.format.atom?
set_guide_draft_access_token if @content_item.is_a?(GuidePresenter)
Expand Down Expand Up @@ -60,6 +63,27 @@ def load_content_item
@content_item = PresenterBuilder.new(content_item, content_item_path).presenter
end

def load_taxonomy_navigation
if @content_item.taxons.present?
taxons = @content_item.taxons.select { |taxon| taxon["phase"] == "live" }

taxon_ids = taxons.map { |taxon| taxon["content_id"] }
services = Supergroups::Services.new(taxon_ids)

@taxonomy_navigation = {
services: services.tagged_content,
}

@tagged_taxons = taxons.map do |taxon|
{
taxon_id: taxon["content_id"],
taxon_name: taxon["title"],
taxon_link: taxon["base_path"],
}
end
end
end

def content_item_template
@content_item.schema_name
end
Expand Down
5 changes: 5 additions & 0 deletions app/lib/services.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'gds_api/content_store'
require 'gds_api/rummager'

module Services
def self.content_store
Expand All @@ -10,4 +11,8 @@ def self.content_store
disable_cache: true,
)
end

def self.rummager
@rummager ||= GdsApi::Rummager.new(Plek.new.find("rummager"))
end
end
4 changes: 3 additions & 1 deletion app/presenters/content_item_presenter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ class ContentItemPresenter
:locale,
:phase,
:part_slug,
:document_type
:document_type,
:taxons

def initialize(content_item, requested_content_item_path = nil)
@content_item = content_item
Expand All @@ -22,6 +23,7 @@ def initialize(content_item, requested_content_item_path = nil)
@locale = content_item["locale"] || "en"
@phase = content_item["phase"]
@document_type = content_item["document_type"]
@taxons = content_item["links"]["taxons"] if content_item["links"]
@part_slug = requesting_a_part? ? requested_content_item_path.split('/').last : nil
end

Expand Down
29 changes: 29 additions & 0 deletions app/presenters/supergroups/services.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Supergroups
class Services
attr_reader :content

def initialize(taxon_ids)
@taxon_ids = taxon_ids
end

def tagged_content
@content = MostPopularContent.fetch(content_ids: @taxon_ids, filter_content_purpose_supergroup: "services")
format_document_data(@content)
end

private

def format_document_data(documents)
documents&.map do |document|
data = {
link: {
text: document["title"],
path: document["link"]
}
}

data
end
end
end
end
40 changes: 40 additions & 0 deletions app/services/most_popular_content.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'gds_api/rummager'

class MostPopularContent
include RummagerFields

attr_reader :content_ids, :filter_content_purpose_supergroup, :number_of_links

def initialize(content_ids:, filter_content_purpose_supergroup:, number_of_links: 5)
@content_ids = content_ids
@filter_content_purpose_supergroup = filter_content_purpose_supergroup
@number_of_links = number_of_links
end

def self.fetch(content_ids:, filter_content_purpose_supergroup:)
new(content_ids: content_ids, filter_content_purpose_supergroup: filter_content_purpose_supergroup).fetch
end

def fetch
search_response["results"]
end

private

def search_response
params = {
start: 0,
count: number_of_links,
fields: RummagerFields::TAXON_SEARCH_FIELDS,
filter_part_of_taxonomy_tree: content_ids,
order: '-popularity',
}
params[:filter_content_purpose_supergroup] = filter_content_purpose_supergroup if filter_content_purpose_supergroup.present?

search_result(params)
end

def search_result(params)
Services.rummager.search(params)
end
end
14 changes: 14 additions & 0 deletions app/services/rummager_fields.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module RummagerFields
TAXON_SEARCH_FIELDS = %w(title
link
description
content_store_document_type
public_timestamp
organisations).freeze

FEED_SEARCH_FIELDS = %w(title
link
description
display_type
public_timestamp).freeze
end
4 changes: 4 additions & 0 deletions app/views/layouts/application.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<% if @content_item.description %>
<meta name="description" content="<%= strip_tags(@content_item.description) %>" />
<% end %>
<%= content_pages_nav_test_variant.analytics_meta_tag.html_safe if page_in_scope? %>

<%= yield :extra_head_content %>
</head>
Expand All @@ -43,6 +44,9 @@

<main role="main" id="content" class="<%= @content_item.schema_name.dasherize %>" lang="<%= I18n.locale %>">
<%= yield %>
<% if show_new_navigation? && @taxonomy_navigation %>
<%= render 'shared/taxonomy_navigation', taxonomy_navigation: @taxonomy_navigation, tagged_taxons: @tagged_taxons %>
<% end %>
</main>
<%= render 'govuk_publishing_components/components/feedback' %>
</div>
Expand Down
25 changes: 25 additions & 0 deletions app/views/shared/_taxonomy_navigation.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<% if taxonomy_navigation.values().flatten.any? %>
<div class="taxonomy-navigation">
<h2>More in
<% tagged_taxons.each do |tagged_taxon| %>
<a class="taxonomy-navigation__title-link" href="<%= tagged_taxon[:taxon_link] %>"><%= tagged_taxon[:taxon_name] %></a>
<% end %>
</h2>

<% if taxonomy_navigation[:services].any? %>
<div class="taxonomy-navigation__section">
<%= render "govuk_publishing_components/components/heading", {
text: t('supergroups.services'),
heading_level: 3,
font_size: 24,
margin_bottom: 2
} %>

<%= render "govuk_publishing_components/components/highlight_boxes", {
inverse: true,
items: taxonomy_navigation[:services]
} %>
</div>
<% end %>
</div>
<% end %>
3 changes: 3 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ en:
last_updated: "Last updated %{date}"
published: "Published %{date}"
see_all_updates: "see all updates"
supergroups:
services: "Services"
see_more_supergroups: "See more %{supergroup}"
language_names:
ar: Arabic
de: German
Expand Down
2 changes: 2 additions & 0 deletions startup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ if [[ $1 == "--live" ]] ; then
PLEK_SERVICE_CONTENT_STORE_URI=${PLEK_SERVICE_CONTENT_STORE_URI-https://www.gov.uk/api} \
PLEK_SERVICE_STATIC_URI=${PLEK_SERVICE_STATIC_URI-assets.publishing.service.gov.uk} \
PLEK_SERVICE_RUMMAGER_URI=${PLEK_SERVICE_RUMMAGER_URI-https://www.gov.uk/api} \
PLEK_SERVICE_SEARCH_URI=${PLEK_SERVICE_SEARCH_URI-https://www.gov.uk/api} \
bundle exec rails s -p 3090
elif [[ $1 == "--dummy" ]] ; then
GOVUK_APP_DOMAIN=www.gov.uk \
GOVUK_WEBSITE_ROOT=https://www.gov.uk \
PLEK_SERVICE_CONTENT_STORE_URI=${PLEK_SERVICE_CONTENT_STORE_URI-https://govuk-content-store-examples.herokuapp.com/api} \
PLEK_SERVICE_STATIC_URI=${PLEK_SERVICE_STATIC_URI-assets.publishing.service.gov.uk} \
PLEK_SERVICE_RUMMAGER_URI=${PLEK_SERVICE_RUMMAGER_URI-https://www.gov.uk/api} \
PLEK_SERVICE_SEARCH_URI=${PLEK_SERVICE_SEARCH_URI-https://www.gov.uk/api} \
bundle exec rails s -p 3090
else
bundle exec rails s -p 3090
Expand Down
2 changes: 2 additions & 0 deletions test/controllers/content_items_controller_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ class ContentItemsControllerTest < ActionController::TestCase

stub_request(:get, %r{#{invalid_part_path}}).to_return(status: 200, body: content_item.to_json, headers: {})

@controller.stubs(:page_in_scope?).returns(false)

get :show, params: { path: invalid_part_path }

assert_response :redirect
Expand Down
Loading

0 comments on commit 2356bcc

Please sign in to comment.