-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The Mailer is what is used to provide applcations with Notify emails. This class is used as the parent for new subclasses that provide the application specific emails. Like a module, we have to test this by creating a new TestMailer that inherits from our updated class. The main thing to notice here is that we have to prevent Rails from carrying out the default behaviour of looking for views to provide the parts of the email (the html and plain text content), we do so by calling `mail` with a block that sets the parts to empty object - these are then replaced later with the actual content.
- Loading branch information
Showing
8 changed files
with
294 additions
and
64 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,19 +2,94 @@ | |
|
||
module Mail | ||
module Notify | ||
## | ||
# The Mail Notify base Mailer class, overridden in Rails applications to provide the additional | ||
# Notify behaviour along with the application behaviour. | ||
|
||
class Mailer < ActionMailer::Base | ||
def view_mail(template_id, headers) | ||
raise ArgumentError, "You must specify a template ID" if template_id.blank? | ||
## | ||
# Set a default from address, will only be used in previews if a from address is not supplied | ||
# by subclasses | ||
|
||
default from: "[email protected]" | ||
|
||
## | ||
# Send an email where the content is managed in the Notify template. | ||
# | ||
# The required arguments are: | ||
# | ||
# - template_id | ||
# - to address | ||
# | ||
# Can include personalisation. | ||
# | ||
# Add any additional headers in the options hash. | ||
# | ||
# A default subject is supplied as ActionMailer requires one, however it will never be used as | ||
# the subject is assumed to be managed in the Notify template. | ||
|
||
def template_mail(template_id, options) | ||
raise ArgumentError, "You must specify a Notify template ID" if template_id.blank? | ||
raise ArgumentError, "You must specify a to address" if options[:to].nil? || options[:to].blank? | ||
|
||
message.template_id = template_id | ||
message.reply_to_id = options[:reply_to_id] | ||
message.reference = options[:reference] | ||
|
||
message.personalisation = options[:personalisation] || {} | ||
|
||
headers = options.except([:personalisation, :reply_to_id, :reference]) | ||
|
||
mail(headers.merge(template_id: template_id)) | ||
headers[:subject] = "Subject managed in Notify" unless options[:subject] | ||
|
||
mail(headers) do |format| | ||
format.text { nil } | ||
format.html { nil } | ||
end | ||
end | ||
|
||
def template_mail(template_id, headers) | ||
raise ArgumentError, "You must specify a template ID" if template_id.blank? | ||
## | ||
# Send an email where the content is managed in the Rails application. | ||
# | ||
# The required arguments are: | ||
# | ||
# - template_id | ||
# - to address | ||
# - subject | ||
# | ||
# Personalisation will dropped as all content comes from the view provided by Rails. | ||
# | ||
# Add any additional headers in the options hash. | ||
|
||
def view_mail(template_id, options) | ||
raise ArgumentError, "You must specify a Notify template ID" if template_id.blank? | ||
raise ArgumentError, "You must supply a to address" unless options[:to] | ||
raise ArgumentError, "You must specify a subject" if options[:subject].blank? | ||
|
||
message.template_id = template_id | ||
message.reply_to_id = options[:reply_to_id] | ||
message.reference = options[:reference] | ||
|
||
subject = options[:subject] | ||
headers = options.except([:personalisation, :reply_to_id, :reference]) | ||
|
||
mail(headers.merge(body: "", subject: "", template_id: template_id)) | ||
# we have to render the view for the message and grab the raw source, then we set that as the | ||
# body in the personalisation for sending to the Notify API. | ||
body = mail(headers).body.raw_source | ||
|
||
# The 'view mail' works by sending a subject and body as personalisation options, these are | ||
# then used in the Notify template to provide content. | ||
message.personalisation = {subject: subject, body: body} | ||
|
||
mail(headers) do |format| | ||
format.text { nil } | ||
format.html { nil } | ||
end | ||
end | ||
|
||
## | ||
# allows blank personalisation options | ||
|
||
def blank_allowed(value) | ||
value.presence || Personalisation::BLANK | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,53 +1,219 @@ | ||
# frozen_string_literal: true | ||
|
||
require "spec_helper" | ||
require "mailers/test_mailer" | ||
|
||
RSpec.describe Mail::Notify::Mailer do | ||
let(:mailer) { Mail::Notify::Mailer.new } | ||
describe "#view_mail" do | ||
it "sets the message template id" do | ||
message_params = {template_id: "template-id", to: "[email protected]", subject: "Test subject"} | ||
|
||
context "with a view" do | ||
it "sends the template" do | ||
expect(mailer).to receive(:mail).with({template_id: "foo", bar: "baz"}) | ||
mailer.view_mail("foo", bar: "baz") | ||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.template_id).to eql("template-id") | ||
end | ||
|
||
it "sets the message subject" do | ||
message_params = {template_id: "template-id", to: "[email protected]", subject: "Test subject"} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.header[:subject]).to be_a Mail::Field | ||
expect(message.header[:subject].value).to eql("Test subject") | ||
end | ||
|
||
it "raises an error if the template ID is blank" do | ||
expect { mailer.view_mail("", bar: "baz") }.to raise_error( | ||
ArgumentError, | ||
"You must specify a template ID" | ||
it "sets the message to address" do | ||
message_params = {template_id: "template-id", to: "[email protected]", subject: "Test subject"} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.header[:to]).to be_a Mail::Field | ||
expect(message.header[:to].value).to eql("[email protected]") | ||
end | ||
|
||
it "sets the subject on personalisation" do | ||
message_params = {template_id: "template-id", to: "[email protected]", subject: "Test subject"} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.personalisation[:subject]).to eql("Test subject") | ||
end | ||
|
||
it "sets the body on personalisation" do | ||
message_params = {template_id: "template-id", to: "[email protected]", subject: "Test subject"} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.personalisation[:body]).to eql("This is the body from the mailers view.\r\n") | ||
end | ||
|
||
it "drops any further personalisation" do | ||
message_params = { | ||
template_id: "template-id", | ||
to: "[email protected]", | ||
subject: "Test subject", | ||
personalisation: {name: "Test Name"} | ||
} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.personalisation.key?(:name)).to be false | ||
end | ||
|
||
it "sets the reply_to_id" do | ||
message_params = { | ||
template_id: "template-id", | ||
to: "[email protected]", | ||
subject: "Test subject", | ||
reply_to_id: "test-reply-to-id" | ||
} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.reply_to_id).to eql("test-reply-to-id") | ||
end | ||
|
||
it "sets the reference" do | ||
message_params = { | ||
template_id: "template-id", | ||
to: "[email protected]", | ||
subject: "Test subject", | ||
reply_to_id: "test-reference" | ||
} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect(message.reply_to_id).to eql("test-reference") | ||
end | ||
|
||
it "requires template id to be set" do | ||
message_params = {to: "[email protected]", subject: "Test subject"} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect { message.template_id }.to raise_error( | ||
ArgumentError, "You must specify a Notify template ID" | ||
) | ||
end | ||
|
||
it "requires to address to be set" do | ||
message_params = {template_id: "template-id", subject: "Test subject"} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect { message.header[:to] }.to raise_error( | ||
ArgumentError, "You must supply a to address" | ||
) | ||
end | ||
end | ||
|
||
context "with a template" do | ||
it "sends a blank body and subject" do | ||
expect(mailer).to receive(:mail).with({ | ||
template_id: "foo", | ||
bar: "baz", | ||
body: "", | ||
subject: "" | ||
}) | ||
mailer.template_mail("foo", bar: "baz") | ||
end | ||
|
||
it "raises an error if the template ID is blank" do | ||
expect { mailer.template_mail("", bar: "baz") }.to raise_error( | ||
ArgumentError, | ||
"You must specify a template ID" | ||
it "requires subject to be set" do | ||
message_params = {template_id: "template-id", to: "Test subject"} | ||
|
||
message = TestMailer.with(message_params).test_view_mail | ||
|
||
expect { message.header[:subject] }.to raise_error( | ||
ArgumentError, "You must specify a subject" | ||
) | ||
end | ||
end | ||
|
||
describe "#template_email" do | ||
it "sets the message template id" do | ||
message_params = {template_id: "template-id", to: "[email protected]"} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.template_id).to eql("template-id") | ||
end | ||
|
||
it "sets the message to address" do | ||
message_params = {template_id: "template-id", to: "[email protected]"} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.header[:to]).to be_a Mail::Field | ||
expect(message.header[:to].value).to eql("[email protected]") | ||
end | ||
|
||
it "sets the subject as ActionMailer requires one" do | ||
message_params = {template_id: "template-id", to: "[email protected]"} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.header[:subject]).to be_a Mail::Field | ||
expect(message.header[:subject].value).to eql("Subject managed in Notify") | ||
end | ||
|
||
it "sets the subject if one is passed, even though it will not be used" do | ||
message_params = {template_id: "template-id", to: "[email protected]", subject: "My subject"} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.header[:subject]).to be_a Mail::Field | ||
expect(message.header[:subject].value).to eql("My subject") | ||
end | ||
|
||
context "without personalisation" do | ||
it "sets the personalisation of the message to an empty hash" do | ||
message_params = {template_id: "template-id", to: "[email protected]"} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.personalisation).to eql({}) | ||
end | ||
end | ||
|
||
context "with personalisation" do | ||
it "sets the personalisation of the message" do | ||
message_params = { | ||
template_id: "template-id", | ||
to: "[email protected]", | ||
personalisation: {name: "Name", age: "25"} | ||
} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.personalisation).to eql({name: "Name", age: "25"}) | ||
end | ||
end | ||
|
||
it "sets the reply_to_id" do | ||
message_params = { | ||
template_id: "template-id", | ||
to: "[email protected]", | ||
subject: "Test subject", | ||
reply_to_id: "test-reply-to-id" | ||
} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.reply_to_id).to eql("test-reply-to-id") | ||
end | ||
|
||
it "sets the reference" do | ||
message_params = { | ||
template_id: "template-id", | ||
to: "[email protected]", | ||
subject: "Test subject", | ||
reply_to_id: "test-reference" | ||
} | ||
|
||
message = TestMailer.with(message_params).test_template_mail | ||
|
||
expect(message.reply_to_id).to eql("test-reference") | ||
end | ||
end | ||
|
||
describe "#blank_allowed" do | ||
context "when given a non-blank value" do | ||
it "returns the given value" do | ||
expect(mailer.blank_allowed("foo")).to eq "foo" | ||
expect(TestMailer.new.blank_allowed("foo")).to eq "foo" | ||
end | ||
end | ||
|
||
context "when given a blank value" do | ||
it "returns explicitly blank personalisation" do | ||
expect(mailer.blank_allowed("")).to be Mail::Notify::Personalisation::BLANK | ||
expect(TestMailer.new.blank_allowed("")).to be Mail::Notify::Personalisation::BLANK | ||
end | ||
end | ||
end | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
# frozen_string_literal: true | ||
|
||
class TestMailer < Mail::Notify::Mailer | ||
def test_view_mail | ||
template_id = params[:template_id] | ||
options = params.except(:template_id) | ||
|
||
view_mail(template_id, options) | ||
end | ||
|
||
def test_template_mail | ||
template_id = params[:template_id] | ||
options = params.except(:template_id) | ||
|
||
template_mail(template_id, options) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
1 change: 0 additions & 1 deletion
1
spec/support/templates/test_mailer/my_mail_optional_fields.text.erb
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
This is the body from the mailers view. |
Oops, something went wrong.