Skip to content

Instantly share code, notes, and snippets.

@pixeltrix
Last active April 13, 2020 11:19
Show Gist options
  • Save pixeltrix/ccb6d060815851e7dac5057f7fb09999 to your computer and use it in GitHub Desktop.
Save pixeltrix/ccb6d060815851e7dac5057f7fb09999 to your computer and use it in GitHub Desktop.
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 = "[email protected]"
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

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