Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these numbers based on anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's very much a finger-in-air estimate. This is the same as our estimates for taxonomy emails (which may now be wrong).

This is the explanation in the commit (d4a97b2#diff-5c90fde72d5dd7ed3acd972c5bc07f58) where the taxonomy estimate was added:

These figures are based on analysis of historical email volume.

Perhaps we could make a request to email-alert-api to figure out the exact volume.


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