Skip to content

Commit

Permalink
Merge pull request #451 from alphagov/generalize-taxonomy-signup
Browse files Browse the repository at this point in the history
Enable users to signup to all content by organisation
  • Loading branch information
bilbof authored Apr 18, 2019
2 parents 4cf20a7 + fa627c7 commit 6fdfc68
Show file tree
Hide file tree
Showing 20 changed files with 410 additions and 223 deletions.
67 changes: 67 additions & 0 deletions app/controllers/content_item_signups_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# This controller takes any content item and makes it possible to subscribe
# to alerts when documents linked to them are changed (taxons, orgs etc).
# This is in contrast to EmailAlertSignupsController, which takes a
# finder_email_signup content item.
class ContentItemSignupsController < ApplicationController
protect_from_forgery except: [:create]
before_action :require_content_item_param
before_action :validate_document_type
helper_method :estimated_email_frequency

def new
@subscription = ContentItemSubscriptionPresenter.new(@content_item)
end

def confirm; end

def create
signup = ContentItemSubscriberList.new(content_item.to_h)

if signup.has_content_item?
redirect_to signup.subscription_management_url
else
redirect_to confirm_content_item_signup_path(link: content_item_path)
end
end

private

PERMITTED_CONTENT_ITEMS = %w(taxon organisation).freeze

def require_content_item_param
unless valid_content_item_param?
redirect_to '/'
false
end
end

def valid_content_item_param?
content_item_path.to_s.starts_with?('/') && URI.parse(content_item_path).relative?
rescue URI::InvalidURIError
false
end

def content_item_path
# Topic param left in for backwards compatibility.
# Topic is the user-facing terminology for taxons. Expect the taxon base
# path to be provided in a param of this name.
params[:link] || params[:topic]
end

def content_item
@content_item ||= EmailAlertFrontend
.services(:content_store)
.content_item(content_item_path)
end

def validate_document_type
unless PERMITTED_CONTENT_ITEMS.include?(content_item['document_type'])
redirect_to '/'
false
end
end

def estimated_email_frequency
EmailVolume::WeeklyEmailVolume.new(content_item).estimate
end
end
66 changes: 0 additions & 66 deletions app/controllers/taxonomy_signups_controller.rb

This file was deleted.

4 changes: 2 additions & 2 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def title(text, params = {})
render 'govuk_publishing_components/components/title', { title: text }.merge(params)
end

def live_taxon?(taxon)
taxon['phase'] == 'live'
def live_content_item?(content_item)
content_item['phase'] == 'live'
end
end
61 changes: 61 additions & 0 deletions app/models/content_item_subscriber_list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
class ContentItemSubscriberList
def initialize(content_item)
@content_item = content_item
end

def subscription_management_url
subscriber_list.dig('subscriber_list', 'subscription_url')
end

def has_content_item?
content_item.present?
end

private

attr_accessor :content_item

class UnsupportedContentItemError < StandardError; end

def subscriber_list
EmailAlertFrontend.services(:email_alert_api)
.find_or_create_subscriber_list(subscription_params)
end

def subscription_params
{
'title' => content_item['title'],
'links' => link_hash
}
end

def link_hash
case content_item_type
when 'taxon'
taxon_links
when 'organisation'
organisation_links
else
message = "No link hash available for content items of type #{content_item_type}!"
raise UnsupportedContentItemError, message
end
end

def taxon_links
{
# 'taxon_tree' is the key used in email-alert-service for
# notifications, so create a subscriber list with this key.
'taxon_tree' => [content_item['content_id']]
}
end

def organisation_links
{
'organisations' => [content_item['content_id']]
}
end

def content_item_type
content_item.dig('document_type')
end
end
37 changes: 37 additions & 0 deletions app/models/email_volume/organisation_weekly_email_volume.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module EmailVolume
class OrganisationWeeklyEmailVolume
HIGH = '40 - 60'.freeze
MEDIUM = '0 - 20'.freeze
LOW = '0 - 5'.freeze

def initialize(organisation)
@organisation = organisation
end

def estimate
parent_organisation = extract_parent_from(@organisation)

# It's a top-level organisation like HM Treasury
return HIGH if parent_organisation.blank?

# Is a 2nd level organisation like UK Debt Management Office
grandparent_organisation = extract_parent_from(
fetch_content_item(parent_organisation.fetch('base_path'))
)
return MEDIUM if grandparent_organisation.blank?

# Is a 3rd level organisation
LOW
end

private

def extract_parent_from(content_item)
Array(content_item.dig('links', 'ordered_parent_organisations')).first
end

def fetch_content_item(base_path)
EmailAlertFrontend.services(:content_store).content_item(base_path)
end
end
end
37 changes: 37 additions & 0 deletions app/models/email_volume/taxon_weekly_email_volume.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module EmailVolume
class TaxonWeeklyEmailVolume
HIGH = '40 - 60'.freeze
MEDIUM = '0 - 20'.freeze
LOW = '0 - 5'.freeze

def initialize(taxon)
@taxon = taxon
end

def estimate
parent_taxon = extract_parent_from(@taxon)

# Is at the top of the taxonomy
return HIGH if parent_taxon.blank?

# Is a 2nd level taxon
grandparent_taxon = extract_parent_from(
fetch_content_item(parent_taxon.fetch('base_path'))
)
return MEDIUM if grandparent_taxon.blank?

# Is a 3rd level taxon or below
LOW
end

private

def extract_parent_from(content_item)
Array(content_item.dig('links', 'parent_taxons')).first
end

def fetch_content_item(base_path)
EmailAlertFrontend.services(:content_store).content_item(base_path)
end
end
end
31 changes: 31 additions & 0 deletions app/models/email_volume/weekly_email_volume.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module EmailVolume
class WeeklyEmailVolume
def initialize(content_item)
@content_item = content_item
end

def estimate
volume_estimator.estimate
end

private

class ContentItemNotEstimatableError < StandardError; end

def volume_estimator
case content_item_type
when 'taxon'
TaxonWeeklyEmailVolume.new(@content_item)
when 'organisation'
OrganisationWeeklyEmailVolume.new(@content_item)
else
error_message = "Volume estimate not possible for content items of type #{content_item_type}!"
raise ContentItemNotEstimatableError, error_message
end
end

def content_item_type
@content_item.dig('document_type')
end
end
end
34 changes: 0 additions & 34 deletions app/models/taxonomy_signup.rb

This file was deleted.

35 changes: 0 additions & 35 deletions app/models/weekly_email_volume.rb

This file was deleted.

Loading

0 comments on commit 6fdfc68

Please sign in to comment.