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
19 changes: 19 additions & 0 deletions drivers/place/template_mailer.cr
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,13 @@ class Place::TemplateMailer < PlaceOS::Driver
reply_to = metadata_template["reply_to"].to_s if (reply_to_template = metadata_template["reply_to"]?) && reply_to_template.to_s.presence
reply_to = @reply_to if @reply_to

# a template's `to` replaces the recipient the driver chose; its `cc` and
# `bcc` are added to whatever the driver passed
template_to = addresses(metadata_template["to"]?)
to = template_to unless template_to.empty?
cc = merge_addresses(cc, metadata_template["cc"]?)
bcc = merge_addresses(bcc, metadata_template["bcc"]?)

mailer.send_mail(to, subject, text, html, resource_attachments, attachments, cc, bcc, from, reply_to)
else
logger.info { "unable to find template #{template.join(SEPERATOR)} from zones #{zone_ids} metadata, forwarding to Mailer_2" }
Expand All @@ -270,6 +277,18 @@ class Place::TemplateMailer < PlaceOS::Driver
end
end

# Splits a template's address list; commas, semicolons and whitespace all separate
protected def addresses(value : String | Int64 | Nil) : Array(String)
value.to_s.split(/[,;\s]+/).map(&.strip).reject(&.empty?)
end

protected def merge_addresses(existing : String | Array(String), extra : String | Int64 | Nil) : String | Array(String)
additional = addresses(extra)
return existing if additional.empty?
current = existing.is_a?(String) ? (existing.presence ? [existing] : [] of String) : existing
(current + additional).uniq(&.downcase)
end

alias Template = Hash(String, String | Int64)

# zone_id, timeout, templates
Expand Down
43 changes: 43 additions & 0 deletions drivers/place/template_mailer_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ class StaffAPI < DriverSpecs::MockDriver
from: "noreply@org.com",
reply_to: "template-reply@org.com",
},
# a template that names its own recipients
{
id: "template-2",
trigger: "test.reception",
subject: "Arrival",
html: "<p>%{name} has arrived</p>",
to: "reception@org.com, security@org.com",
cc: "manager@org.com",
bcc: "audit@org.com; Reception@org.com",
},
]

def zones(q : String? = nil,
Expand Down Expand Up @@ -91,6 +101,9 @@ class Mailer < DriverSpecs::MockDriver
)
self[:sent] = self[:sent].as_i + 1
self[:reply_to] = reply_to
self[:to] = to
self[:cc] = cc
self[:bcc] = bcc
true
end

Expand All @@ -108,6 +121,9 @@ class Mailer < DriverSpecs::MockDriver
) : Bool
self[:sent] = self[:sent].as_i + 1
self[:reply_to] = reply_to
self[:to] = to
self[:cc] = cc
self[:bcc] = bcc
true
end
end
Expand Down Expand Up @@ -157,4 +173,31 @@ DriverSpecs.mock_driver "Place::TemplateMailer" do
reply_to: "host@org.com",
).get
system(:Mailer_2)[:reply_to].should eq "tenant@org.com"

# 4. A template with no recipients of its own leaves the caller's To, CC and
# BCC untouched.
exec(
:send_template,
to: "steve@org.com",
template: {"test", "welcome"},
args: {name: "Bob"},
cc: ["assistant@org.com"],
).get
system(:Mailer_2)[:to].should eq "steve@org.com"
system(:Mailer_2)[:cc].should eq ["assistant@org.com"]
system(:Mailer_2)[:bcc].should eq [] of String

# 5. A template's `to` replaces the recipient the driver chose, and its `cc`
# and `bcc` are added to the caller's, without duplicates.
exec(
:send_template,
to: "host@org.com",
template: {"test", "reception"},
args: {name: "Bob"},
cc: ["assistant@org.com"],
bcc: "reception@org.com",
).get
system(:Mailer_2)[:to].should eq ["reception@org.com", "security@org.com"]
system(:Mailer_2)[:cc].should eq ["assistant@org.com", "manager@org.com"]
system(:Mailer_2)[:bcc].should eq ["reception@org.com", "audit@org.com"]
end
Loading