Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Stub out requests to GOV.UK Notify, convert them into Mail::Message instances and stash them into ActionMailer::Base.deliveries
# app/helpers/markdown_helper.rb
require "redcarpet/render_strip"
module MarkdownHelper
HTML_DEFAULTS = {
escape_html: false, filter_html: false,
hard_wrap: true, xhtml: true, safe_links_only: true,
no_styles: true, no_images: true, no_links: false,
with_toc_data: false, prettify: false, link_attributes: {}
}
PARSER_DEFAULTS = {
no_intra_emphasis: true, tables: false, fenced_code_blocks: false,
autolink: true, disable_indented_code_blocks: false, strikethrough: true,
lax_spacing: false, space_after_headers: true, superscript: true,
underline: false, highlight: false, quote: false, footnotes: false
}
def markdown_to_html(markup, options = {})
markdown_parser(html_renderer(options), options).render(markup).html_safe
end
def markdown_to_text(markup, options = {})
markdown_parser(text_renderer, options).render(markup).html_safe
end
private
def html_renderer(options)
Redcarpet::Render::HTML.new(options_for_renderer(options))
end
def text_renderer
Redcarpet::Render::StripDown.new
end
def markdown_parser(renderer, options)
Redcarpet::Markdown.new(renderer, options_for_parser(options))
end
def options_for_parser(options)
PARSER_DEFAULTS.merge(options.slice(*PARSER_DEFAULTS.keys))
end
def options_for_renderer(options)
HTML_DEFAULTS.merge(options.slice(*HTML_DEFAULTS.keys))
end
end
# lib/tasks/notify.rake
require "notifications/client"
require "fileutils"
namespace :notify do
task fetch_templates: :environment do
template_dir = Rails.root.join("spec", "fixtures", "notify")
client = Notifications::Client.new(ENV.fetch("NOTIFY_API_KEY"))
templates = client.get_all_templates(type: "email")
FileUtils.rm_rf template_dir
FileUtils.mkdir_p template_dir
templates.collection.each do |template|
template_path = template_dir.join("#{template.id}.json")
File.write(template_path, template.to_json)
end
rescue Notifications::Client::RequestError => e
puts e.message
end
end
# spec/support/notify.rb
RSpec.configure do |config|
NOTIFY_URL = "https://api.notifications.service.gov.uk/v2/notifications/email"
NOTIFY_APP = Module.new do
class << self
include MarkdownHelper
def call(env)
params = JSON.parse(env["rack.input"].read)
template = templates.fetch(params["template_id"])
message = Mail::Message.new
subject = template["subject"].dup
body = template["body"].dup
params["personalisation"].each do |key, value|
subject.gsub!("((#{key}))", value.to_s)
body.gsub!("((#{key}))", value.to_s)
end
text_part = markdown_to_text(body)
html_part = markdown_to_html(body)
message.message_id = "#{SecureRandom.uuid}@example.com"
message.from = "no-reply@example.com"
message.to = params["email_address"]
message.subject = subject
message.text_part = text_part
message.html_part = html_part
ActionMailer::Base.deliveries << message
[ 200, { "Content-Type" => "application/json" }, ["{}"] ]
end
private
def templates
@templates ||= load_templates
end
def load_templates
template_files.each_with_object({}) do |file, hash|
hash[File.basename(file, ".json")] = JSON.parse(File.read(file))
end
end
def template_files
Dir["#{template_dir}/*.json"]
end
def template_dir
Rails.root.join("spec", "fixtures", "notify")
end
end
end
config.before(:each) do |example|
unless example.metadata[:notify] == false
stub_request(:post, NOTIFY_URL).to_rack(NOTIFY_APP)
end
end
end
@pixeltrix
Copy link
Author

pixeltrix commented Apr 13, 2020

Actually extracted this out a bit so it could be used from Cucumber and RSpec. Also switched to using YAML for the templates so that they were more git diff friendly that one long string of JSON. You can see the final version here:

SeneddCymru/e-petitions@1256638

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment