-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Callbacks and deliver short circuiting (#72)
* allows the emails to have before/after callbacks. Fixes #65 * adds in functionality to stop an email from being delivered. Fixes #61
- Loading branch information
Showing
4 changed files
with
215 additions
and
1 deletion.
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 |
---|---|---|
@@ -0,0 +1,105 @@ | ||
require "./spec_helper" | ||
|
||
abstract class BaseTestEmail < Carbon::Email | ||
subject "My great subject" | ||
from Carbon::Address.new("[email protected]") | ||
to Carbon::Address.new("[email protected]") | ||
end | ||
|
||
BaseTestEmail.configure do |setting| | ||
setting.adapter = Carbon::DevAdapter.new | ||
end | ||
|
||
private class EmailWithBeforeCallbacks < BaseTestEmail | ||
property ran_before_callback : Bool = false | ||
|
||
before_send do | ||
self.ran_before_callback = true | ||
end | ||
end | ||
|
||
private class EmailWithAfterCallbacks < BaseTestEmail | ||
property ran_after_callback : Bool = false | ||
|
||
after_send do |_response| | ||
self.ran_after_callback = true | ||
end | ||
end | ||
|
||
private class EmailWithBothBeforeAndAfterCallbacks < BaseTestEmail | ||
property ran_before_callback : Bool = false | ||
property ran_after_callback : Bool = false | ||
|
||
before_send :mark_before_send | ||
after_send :mark_after_send | ||
|
||
private def mark_before_send | ||
self.ran_before_callback = true | ||
end | ||
|
||
private def mark_after_send(_response) | ||
self.ran_after_callback = true | ||
end | ||
end | ||
|
||
private class EmailUsingBeforeToStopSending < BaseTestEmail | ||
before_send :dont_actually_send | ||
after_send :never_actually_ran | ||
|
||
property ran_after_callback : Bool = false | ||
|
||
private def dont_actually_send | ||
@deliverable = false | ||
end | ||
|
||
private def never_actually_ran(_response) | ||
self.ran_after_callback = true | ||
end | ||
end | ||
|
||
describe "before/after callbacks" do | ||
context "before an email is sent" do | ||
it "runs the before_send callback" do | ||
email = EmailWithBeforeCallbacks.new | ||
email.ran_before_callback.should eq(false) | ||
email.deliver | ||
Carbon.should have_delivered_emails | ||
|
||
email.ran_before_callback.should eq(true) | ||
end | ||
end | ||
|
||
context "after an email is sent" do | ||
it "runs the after_send callback" do | ||
email = EmailWithAfterCallbacks.new | ||
email.ran_after_callback.should eq(false) | ||
email.deliver | ||
Carbon.should have_delivered_emails | ||
|
||
email.ran_after_callback.should eq(true) | ||
end | ||
end | ||
|
||
context "running both callbacks" do | ||
it "runs both callbacks" do | ||
email = EmailWithBothBeforeAndAfterCallbacks.new | ||
email.ran_before_callback.should eq(false) | ||
email.ran_after_callback.should eq(false) | ||
email.deliver | ||
Carbon.should have_delivered_emails | ||
|
||
email.ran_before_callback.should eq(true) | ||
email.ran_after_callback.should eq(true) | ||
end | ||
end | ||
|
||
context "Halting the deliver before it's sent" do | ||
it "never sends" do | ||
email = EmailUsingBeforeToStopSending.new | ||
email.deliver | ||
Carbon.should_not have_delivered_emails | ||
email.deliverable?.should eq(false) | ||
email.ran_after_callback.should eq(false) | ||
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 |
---|---|---|
|
@@ -78,6 +78,12 @@ private class EmailWithLayout < BareMinimumEmail | |
layout custom_layout | ||
end | ||
|
||
private class UndeliverableEmail < Carbon::Email | ||
subject "My great subject" | ||
from Carbon::Address.new("[email protected]") | ||
to Carbon::Address.new("[email protected]") | ||
end | ||
|
||
describe Carbon::Email do | ||
it "can build a bare minimum email" do | ||
email = BareMinimumEmail.new | ||
|
@@ -146,4 +152,12 @@ describe Carbon::Email do | |
email.html_body.should contain "Email Layout" | ||
email.html_body.should contain "Email body" | ||
end | ||
|
||
context "deliverable?" do | ||
it "is not delivery it is digiorno" do | ||
email = UndeliverableEmail.new | ||
email.deliverable = false | ||
email.deliverable?.should eq(false) | ||
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,81 @@ | ||
module Carbon::Callbacks | ||
# Runs the given method before the adapter calls `deliver_now` | ||
# | ||
# ``` | ||
# before_send :attach_metadata | ||
# | ||
# private def attach_metadata | ||
# # ... | ||
# end | ||
# ``` | ||
macro before_send(method_name) | ||
before_send do | ||
{{ method_name.id }} | ||
end | ||
end | ||
|
||
# Runs the block before the adapter calls `deliver_now` | ||
# | ||
# ``` | ||
# before_send do | ||
# # ... | ||
# end | ||
# ``` | ||
macro before_send | ||
def before_send | ||
{% if @type.methods.map(&.name).includes?(:before_send.id) %} | ||
previous_def | ||
{% else %} | ||
super | ||
{% end %} | ||
|
||
{{ yield }} | ||
end | ||
end | ||
|
||
# Runs the given method after the adapter calls `deliver_now`. | ||
# Passes in the return value of the adapter's `deliver_now` method. | ||
# | ||
# ``` | ||
# after_send :mark_email_as_sent | ||
# | ||
# private def mark_email_as_sent(response) | ||
# # ... | ||
# end | ||
# ``` | ||
macro after_send(method_name) | ||
after_send do |object| | ||
{{ method_name.id }}(object) | ||
end | ||
end | ||
|
||
# Runs the block after the adapter calls `deliver_now`, and passes the | ||
# return value of the adapter's `deliver_now` method to the block. | ||
# | ||
# ``` | ||
# after_send do |response| | ||
# # ... | ||
# end | ||
# ``` | ||
macro after_send(&block) | ||
{% | ||
if block.args.size != 1 | ||
raise <<-ERR | ||
The 'after_send' callback requires exactly 1 block arg to be passed. | ||
Example: | ||
after_send { |value| some_method(value) } | ||
ERR | ||
end | ||
%} | ||
def after_send(%object) | ||
{% if @type.methods.map(&.name).includes?(:after_send.id) %} | ||
previous_def | ||
{% else %} | ||
super | ||
{% end %} | ||
|
||
{{ block.args.first }} = %object | ||
{{ block.body }} | ||
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