Skip to content

Commit 9522842

Browse files
committed
Expose broken ActionMailer preview setup.
This fixes the spec suite to expose issues with `ActionMailer` being configured incorrectly when previews are not available. This addresses several issues: - The incorrect configuration options are only exposed once `ActionMailer::Base` is loaded; this forces the class to load in the mailer initializer and at the end of our script - This adds specs specifically for the "development" environment which were missing before; it appeared that by not setting the environment it would default to "development" per the script, however, when the command shells out the `RAILS_ENV` is already set to "test" from rspec running. To be certain we cover the other possible edge cases we specifically add more tests for `ActionMailer` not being available, and for a custom configuration being set after `rspec-rails` is loaded. - Despite us asking Rails to turn off eager loading in our custom script, several files were still getting eager loaded; this explicitly clears the eager load paths to stop this - This fixes how the mailer script is shelled out in Ruby 1.8.7; now the environment variables are properly formatted and standard error is piped to standard out Exposes the regression issue in #1386
1 parent 7bb6ea4 commit 9522842

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed

example_app_generator/generate_action_mailer_specs.rb

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,25 @@ def comment_lines(path, flag, *args)
1414

1515
initializer 'action_mailer.rb', <<-CODE
1616
if ENV['DEFAULT_URL']
17-
Rails.application.configure do
18-
config.action_mailer.default_url_options = { :host => ENV['DEFAULT_URL'] }
17+
if ::Rails::VERSION::STRING < '4.1'
18+
ExampleApp::Application.configure do
19+
config.action_mailer.default_url_options = { :host => ENV['DEFAULT_URL'] }
20+
end
21+
else
22+
Rails.application.configure do
23+
config.action_mailer.default_url_options = { :host => ENV['DEFAULT_URL'] }
24+
end
1925
end
2026
end
27+
28+
if defined?(ActionMailer)
29+
# This will force the loading of ActionMailer settings
30+
ActionMailer::Base.smtp_settings
31+
end
2132
CODE
33+
gsub_file 'config/initializers/action_mailer.rb',
34+
/ExampleApp/,
35+
Rails.application.class.parent.to_s
2236

2337
copy_file 'spec/support/default_preview_path'
2438
chmod 'spec/support/default_preview_path', 0755

example_app_generator/spec/support/default_preview_path

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require_file_stub 'config/environment' do
3232
module ExampleApp
3333
class Application < Rails::Application
3434
config.eager_load = false
35+
config.eager_load_paths.clear
3536

3637
# Don't care if the mailer can't send.
3738
config.action_mailer.raise_delivery_errors = false unless ENV['NO_ACTION_MAILER']
@@ -58,3 +59,7 @@ if ENV['DEFAULT_URL']
5859
elsif defined?(::ActionMailer::Preview)
5960
puts Rails.application.config.action_mailer.preview_path
6061
end
62+
63+
# This will force the loading of ActionMailer settings to ensure we do not
64+
# accicentally set something we should not
65+
ActionMailer::Base.smtp_settings

example_app_generator/spec/verify_mailer_preview_path_spec.rb

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,25 @@ def ==(str)
88
end
99
end
1010

11+
def as_commandline(ops)
12+
cmd, ops = ops.reverse
13+
ops ||= {}
14+
cmd_parts = ops.map { |k, v| "#{k}=#{v}" } << cmd << '2>&1'
15+
cmd_parts.join(' ')
16+
end
17+
1118
def capture_exec(*ops)
1219
io = if RUBY_VERSION.to_f < 1.9
13-
IO.popen(ops.join(' '))
20+
IO.popen(as_commandline(ops))
1421
else
1522
ops << { :err => [:child, :out] }
1623
IO.popen(ops)
1724
end
1825
# Necessary to ignore warnings from Rails code base
19-
out = io.readlines.reject { |line|
20-
line =~ /warning: circular argument reference/
21-
}.join.chomp
26+
out = io.readlines.
27+
reject { |line| line =~ /warning: circular argument reference/ }.
28+
join.
29+
chomp
2230
CaptureExec.new(out, $?.exitstatus)
2331
end
2432

@@ -176,8 +184,58 @@ def have_no_preview
176184
end
177185
end
178186
else
179-
it 'handles no action mailer preview' do
180-
expect(capture_exec(exec_script)).to have_no_preview
187+
context 'in the development environment' do
188+
let(:custom_env) { { 'RAILS_ENV' => rails_env } }
189+
let(:rails_env) { 'development' }
190+
191+
it 'handles no action mailer preview' do
192+
expect(capture_exec(custom_env, exec_script)).to have_no_preview
193+
end
194+
195+
it 'allows initializers to set options' do
196+
expect(
197+
capture_exec(
198+
custom_env.merge('DEFAULT_URL' => 'test-host'),
199+
exec_script
200+
)
201+
).to eq('test-host')
202+
end
203+
204+
it 'handles action mailer not being available' do
205+
expect(
206+
capture_exec(
207+
custom_env.merge('NO_ACTION_MAILER' => 'true'),
208+
exec_script
209+
)
210+
).to have_no_preview
211+
end
212+
end
213+
214+
context 'in a non-development environment' do
215+
let(:custom_env) { { 'RAILS_ENV' => rails_env } }
216+
let(:rails_env) { 'test' }
217+
218+
it 'handles no action mailer preview' do
219+
expect(capture_exec(custom_env, exec_script)).to have_no_preview
220+
end
221+
222+
it 'allows initializers to set options' do
223+
expect(
224+
capture_exec(
225+
custom_env.merge('DEFAULT_URL' => 'test-host'),
226+
exec_script
227+
)
228+
).to eq('test-host')
229+
end
230+
231+
it 'handles action mailer not being available' do
232+
expect(
233+
capture_exec(
234+
custom_env.merge('NO_ACTION_MAILER' => 'true'),
235+
exec_script
236+
)
237+
).to have_no_preview
238+
end
181239
end
182240
end
183241
end

0 commit comments

Comments
 (0)