test: cover MailerBaseTest, welcome and MailerDeliveryJobTest
This commit is contained in:
1 parent
10cabe922d
commit
ebd0b88bd6
2 files changed
+194
No files matched your search
@@ -0,0 +1,108 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
require 'tmpdir'
|
||||||
|
require 'fileutils'
|
||||||
|
|
||||||
|
class MailerBaseTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@dir = Dir.mktmpdir('prism-mailer-base')
|
||||||
|
FileUtils.mkdir_p(File.join(@dir, 'user'))
|
||||||
|
Prism::Mailer.deliveries.clear
|
||||||
|
Prism::Mailer.delivery_method = :test
|
||||||
|
|
||||||
|
write('user/welcome.text.erb', "Hi <%= name %>, welcome!\n")
|
||||||
|
write('user/welcome.html.erb', "<p>Hi <%= name %>, welcome!</p>\n")
|
||||||
|
write('user/text_only.text.erb', "plain only for <%= name %>\n")
|
||||||
|
|
||||||
|
mailer_dir = @dir
|
||||||
|
@mailer_class = Class.new(Prism::Mailer::Base) do
|
||||||
|
self.template_roots = [mailer_dir]
|
||||||
|
default from: 'noreply@example.com'
|
||||||
|
|
||||||
|
def welcome(user)
|
||||||
|
@name = user[:name]
|
||||||
|
mail(to: user[:email], subject: 'Welcome!')
|
||||||
|
end
|
||||||
|
|
||||||
|
def text_only(user)
|
||||||
|
@name = user[:name]
|
||||||
|
mail(to: user[:email], subject: 'Plain', template: 'text_only')
|
||||||
|
end
|
||||||
|
|
||||||
|
def missing_template(user)
|
||||||
|
mail(to: user[:email], subject: 'Nope', template: 'does_not_exist')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Object.const_set(:UserMailer, @mailer_class)
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
Object.send(:remove_const, :UserMailer) if Object.const_defined?(:UserMailer)
|
||||||
|
FileUtils.remove_entry(@dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def write(relative, source)
|
||||||
|
File.write(File.join(@dir, relative), source)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_mailer_name_strips_the_mailer_suffix_and_underscores
|
||||||
|
assert_equal 'user', UserMailer.mailer_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_calling_an_action_as_a_class_method_renders_both_bodies_with_auto_locals
|
||||||
|
delivery = UserMailer.welcome(name: 'Ada', email: 'ada@example.com')
|
||||||
|
message = delivery.message
|
||||||
|
assert_equal ['ada@example.com'], message.to
|
||||||
|
assert_equal 'Welcome!', message.subject
|
||||||
|
assert_equal 'noreply@example.com', message.from
|
||||||
|
assert_equal "Hi Ada, welcome!\n", message.text_body
|
||||||
|
assert_equal "<p>Hi Ada, welcome!</p>\n", message.html_body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_default_options_apply_before_the_action_runs
|
||||||
|
delivery = UserMailer.welcome(name: 'Bob', email: 'bob@example.com')
|
||||||
|
assert_equal 'noreply@example.com', delivery.message.from
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_deliver_now_hands_the_message_to_prism_mailer
|
||||||
|
UserMailer.welcome(name: 'Cleo', email: 'cleo@example.com').deliver_now
|
||||||
|
assert_equal 1, Prism::Mailer.deliveries.size
|
||||||
|
assert_includes Prism::Mailer.deliveries.last.to_s, 'Cleo'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_deliver_now_publishes_deliver_mail_instrumentation_event
|
||||||
|
events = []
|
||||||
|
subscriber = Prism::Instrumentation.subscribe('deliver_mail.prism') { |event| events << event }
|
||||||
|
|
||||||
|
UserMailer.welcome(name: 'Eve', email: 'eve@example.com').deliver_now
|
||||||
|
|
||||||
|
assert_equal 1, events.size
|
||||||
|
assert_equal 'Welcome!', events.first.payload[:subject]
|
||||||
|
assert_equal ['eve@example.com'], events.first.payload[:to]
|
||||||
|
assert_equal :test, events.first.payload[:delivery_method]
|
||||||
|
assert_kind_of Float, events.first.duration
|
||||||
|
ensure
|
||||||
|
Prism::Instrumentation.unsubscribe(subscriber)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_explicit_template_option_overrides_the_action_name
|
||||||
|
delivery = UserMailer.text_only(name: 'Dee', email: 'dee@example.com')
|
||||||
|
assert_equal "plain only for Dee\n", delivery.message.text_body
|
||||||
|
assert_nil delivery.message.html_body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_missing_template_for_both_variants_raises_template_not_found
|
||||||
|
assert_raises(Prism::View::TemplateNotFound) do
|
||||||
|
UserMailer.missing_template(email: 'nobody@example.com')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_unknown_class_method_still_raises_no_method_error
|
||||||
|
assert_raises(NoMethodError) { UserMailer.does_not_exist_at_all }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_responds_to_defined_actions_but_not_arbitrary_names
|
||||||
|
assert UserMailer.respond_to?(:welcome)
|
||||||
|
refute UserMailer.respond_to?(:not_a_real_action)
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
require 'tmpdir'
|
||||||
|
require 'fileutils'
|
||||||
|
|
||||||
|
class MailerDeliveryJobTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@dir = Dir.mktmpdir('prism-mailer-delivery-job')
|
||||||
|
FileUtils.mkdir_p(File.join(@dir, 'templates', 'ping'))
|
||||||
|
File.write(File.join(@dir, 'templates', 'ping', 'ping.text.erb'), "ping <%= name %>\n")
|
||||||
|
|
||||||
|
Prism::Mailer.deliveries.clear
|
||||||
|
Prism::Mailer.delivery_method = :test
|
||||||
|
|
||||||
|
template_dir = File.join(@dir, 'templates')
|
||||||
|
@mailer_class = Class.new(Prism::Mailer::Base) do
|
||||||
|
self.template_roots = [template_dir]
|
||||||
|
default from: 'jobs@example.com'
|
||||||
|
|
||||||
|
def ping(user)
|
||||||
|
@name = user[:name]
|
||||||
|
mail(to: user[:email], subject: 'Ping')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Object.const_set(:PingMailer, @mailer_class)
|
||||||
|
|
||||||
|
@queue = Prism::Jobs::Queue.new(File.join(@dir, 'jobs.pstore'))
|
||||||
|
@previous_queue = Prism::Jobs.default_queue
|
||||||
|
Prism::Jobs.default_queue = @queue
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
Prism::Jobs.default_queue = @previous_queue
|
||||||
|
Object.send(:remove_const, :PingMailer) if Object.const_defined?(:PingMailer)
|
||||||
|
FileUtils.remove_entry(@dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_deliver_later_enqueues_a_real_job_that_a_worker_can_process
|
||||||
|
PingMailer.ping(name: 'Finn', email: 'finn@example.com').deliver_later
|
||||||
|
assert_equal 1, @queue.size
|
||||||
|
|
||||||
|
worker = Prism::Jobs::Worker.new(@queue)
|
||||||
|
processed = worker.work_off
|
||||||
|
|
||||||
|
assert_equal 1, processed
|
||||||
|
assert_equal 0, @queue.size
|
||||||
|
assert_equal 1, Prism::Mailer.deliveries.size
|
||||||
|
assert_includes Prism::Mailer.deliveries.last.to_s, 'ping Finn'
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_deliver_later_job_survives_reading_back_from_a_freshly_opened_queue
|
||||||
|
PingMailer.ping(name: 'Gwen', email: 'gwen@example.com').deliver_later
|
||||||
|
|
||||||
|
reopened = Prism::Jobs::Queue.new(File.join(@dir, 'jobs.pstore'))
|
||||||
|
worker = Prism::Jobs::Worker.new(reopened)
|
||||||
|
assert_equal 1, worker.work_off
|
||||||
|
assert_equal 1, Prism::Mailer.deliveries.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_failed_delivery_is_retried_then_dead_lettered_like_any_other_job
|
||||||
|
PingMailer.ping(name: 'Hana', email: 'hana@example.com').deliver_later(queue: 'mailers')
|
||||||
|
Prism::Mailer.delivery_method = :smtp
|
||||||
|
Prism::Mailer.smtp_settings = { address: '127.0.0.1', port: 1 }
|
||||||
|
|
||||||
|
worker = Prism::Jobs::Worker.new(@queue, queue_name: 'mailers')
|
||||||
|
5.times do
|
||||||
|
worker.work_off
|
||||||
|
force_all_due
|
||||||
|
end
|
||||||
|
|
||||||
|
assert_equal 1, @queue.dead_letter_size
|
||||||
|
assert_equal 0, Prism::Mailer.deliveries.size
|
||||||
|
ensure
|
||||||
|
Prism::Mailer.delivery_method = :test
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Same trick as test_jobs_worker.rb: retries are scheduled with real
|
||||||
|
# backoff into the future, so tests pull run_at back into the past
|
||||||
|
# instead of sleeping for it.
|
||||||
|
def force_all_due
|
||||||
|
pstore = @queue.instance_variable_get(:@pstore)
|
||||||
|
pstore.transaction { pstore[:jobs].each_value { |job| job[:run_at] = Time.now - 1 } }
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in new issue
Block a user