Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple calls to ActionMailer::Base#mail produces multiple Mail::Fields in the headers #162

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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
11 changes: 9 additions & 2 deletions lib/mail/notify/mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def template_mail(template_id, options)

message.personalisation = options[:personalisation] || {}

headers = options.except([:personalisation, :reply_to_id, :reference])
headers = options.except(:personalisation, :reply_to_id, :reference)

headers[:subject] = "Subject managed in Notify" unless options[:subject]

Expand Down Expand Up @@ -74,12 +74,19 @@ def view_mail(template_id, options)
message.reference = options[:reference]

subject = options[:subject]
headers = options.except([:personalisation, :reply_to_id, :reference])
headers = options.except(:personalisation, :reply_to_id, :reference)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is spot on and your tests demonstrate it nicely! 👌


# 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.
# Calling the #mail method is not idempotent. It modifies state by setting instance variables on the message. Specifically it sets @_message.
# mail generates message headers for the options passed in.
# each time it is called with the same headers it adds another header field.
#
# original_message = message.dup
body = mail(headers).body.raw_source
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we can just not pass headers to the call to mail here and leave it to the final call that will be returned.

Copy link
Contributor

Choose a reason for hiding this comment

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

Digging into it more, I can't see why we are handling headers other than to and subject at all, they will never be used as we cannot pass them onto Notify via the API.

I would be interested to know what headers are being duplicated for you and are showing up in your tests.

I've refactored the two methods to only use to and subject on the end of #165.


# @_message = original_message

# 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}
Expand Down
54 changes: 54 additions & 0 deletions spec/mail/notify/mailer_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,33 @@
expect(message.template_id).to eql("template-id")
end

it "does not set reply_to_id as a header" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk",
subject: "Test subject", reply_to_id: "123"}

message = TestMailer.with(message_params).test_view_mail

expect(message.header[:reply_to_id]).to be_nil
end

it "does not set reference as a header" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk",
subject: "Test subject", reference: "ref-123"}

message = TestMailer.with(message_params).test_view_mail

expect(message.header[:reference]).to be_nil
end

it "does not set personalisation as a header" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk",
subject: "Test subject", personalisation: "Dear sir"}

message = TestMailer.with(message_params).test_view_mail

expect(message.header[:personalisation]).to be_nil
end

it "sets the message subject" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk",
subject: "Test subject"}
Expand Down Expand Up @@ -131,6 +158,33 @@
expect(message.template_id).to eql("template-id")
end

it "does not set reply_to_id as a header" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk",
subject: "Test subject", reply_to_id: "123"}

message = TestMailer.with(message_params).test_template_mail

expect(message.header[:reply_to_id]).to be_nil
end

it "does not set reference as a header" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk",
subject: "Test subject", reference: "ref-123"}

message = TestMailer.with(message_params).test_template_mail

expect(message.header[:reference]).to be_nil
end

it "does not set personalisation as a header" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk",
subject: "Test subject", personalisation: "Dear sir"}

message = TestMailer.with(message_params).test_template_mail

expect(message.header[:personalisation]).to be_nil
end

it "sets the message to address" do
message_params = {template_id: "template-id", to: "test.name@email.co.uk"}

Expand Down