roadie-rails 1.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.travis.yml +15 -0
  4. data/Changelog.md +9 -0
  5. data/Gemfile +17 -0
  6. data/Guardfile +16 -0
  7. data/LICENSE.txt +22 -0
  8. data/README.md +317 -0
  9. data/Rakefile +14 -0
  10. data/Upgrading.md +70 -0
  11. data/lib/roadie-rails.rb +1 -0
  12. data/lib/roadie/rails.rb +21 -0
  13. data/lib/roadie/rails/asset_pipeline_provider.rb +24 -0
  14. data/lib/roadie/rails/automatic.rb +16 -0
  15. data/lib/roadie/rails/document_builder.rb +18 -0
  16. data/lib/roadie/rails/inline_on_delivery.rb +17 -0
  17. data/lib/roadie/rails/mail_inliner.rb +26 -0
  18. data/lib/roadie/rails/mailer.rb +14 -0
  19. data/lib/roadie/rails/options.rb +101 -0
  20. data/lib/roadie/rails/railtie.rb +22 -0
  21. data/lib/roadie/rails/version.rb +5 -0
  22. data/roadie-rails.gemspec +29 -0
  23. data/setup.sh +62 -0
  24. data/spec/integration_spec.rb +119 -0
  25. data/spec/lib/roadie/rails/asset_pipeline_provider_spec.rb +47 -0
  26. data/spec/lib/roadie/rails/automatic_spec.rb +44 -0
  27. data/spec/lib/roadie/rails/document_builder_spec.rb +20 -0
  28. data/spec/lib/roadie/rails/mail_inliner_spec.rb +57 -0
  29. data/spec/lib/roadie/rails/mailer_spec.rb +57 -0
  30. data/spec/lib/roadie/rails/options_spec.rb +136 -0
  31. data/spec/lib/roadie/rails/railtie_spec.rb +48 -0
  32. data/spec/railsapps/README.md +69 -0
  33. data/spec/railsapps/rails_30/.gitignore +2 -0
  34. data/spec/railsapps/rails_30/Gemfile +7 -0
  35. data/spec/railsapps/rails_30/app/mailers/auto_mailer.rb +17 -0
  36. data/spec/railsapps/rails_30/app/mailers/mailer.rb +17 -0
  37. data/spec/railsapps/rails_30/app/views/auto_mailer/normal_email.html.erb +11 -0
  38. data/spec/railsapps/rails_30/app/views/auto_mailer/normal_email.text +1 -0
  39. data/spec/railsapps/rails_30/app/views/mailer/normal_email.html.erb +11 -0
  40. data/spec/railsapps/rails_30/app/views/mailer/normal_email.text +1 -0
  41. data/spec/railsapps/rails_30/config/application.rb +19 -0
  42. data/spec/railsapps/rails_30/config/boot.rb +6 -0
  43. data/spec/railsapps/rails_30/config/environment.rb +5 -0
  44. data/spec/railsapps/rails_30/config/environments/development.rb +10 -0
  45. data/spec/railsapps/rails_30/config/initializers/secret_token.rb +1 -0
  46. data/spec/railsapps/rails_30/config/initializers/session_store.rb +1 -0
  47. data/spec/railsapps/rails_30/config/routes.rb +2 -0
  48. data/spec/railsapps/rails_30/public/images/rails.png +0 -0
  49. data/spec/railsapps/rails_30/public/stylesheets/email.css +2 -0
  50. data/spec/railsapps/rails_30/script/rails +6 -0
  51. data/spec/railsapps/rails_31/.gitignore +2 -0
  52. data/spec/railsapps/rails_31/Gemfile +11 -0
  53. data/spec/railsapps/rails_31/app/assets/images/rails.png +0 -0
  54. data/spec/railsapps/rails_31/app/assets/stylesheets/email.css.scss +2 -0
  55. data/spec/railsapps/rails_31/app/mailers/auto_mailer.rb +17 -0
  56. data/spec/railsapps/rails_31/app/mailers/mailer.rb +17 -0
  57. data/spec/railsapps/rails_31/app/views/auto_mailer/normal_email.html.erb +11 -0
  58. data/spec/railsapps/rails_31/app/views/auto_mailer/normal_email.text +1 -0
  59. data/spec/railsapps/rails_31/app/views/mailer/normal_email.html.erb +11 -0
  60. data/spec/railsapps/rails_31/app/views/mailer/normal_email.text +1 -0
  61. data/spec/railsapps/rails_31/config/application.rb +22 -0
  62. data/spec/railsapps/rails_31/config/boot.rb +6 -0
  63. data/spec/railsapps/rails_31/config/environment.rb +5 -0
  64. data/spec/railsapps/rails_31/config/environments/development.rb +11 -0
  65. data/spec/railsapps/rails_31/config/initializers/secret_token.rb +1 -0
  66. data/spec/railsapps/rails_31/config/initializers/session_store.rb +1 -0
  67. data/spec/railsapps/rails_31/config/initializers/wrap_parameters.rb +4 -0
  68. data/spec/railsapps/rails_31/config/routes.rb +2 -0
  69. data/spec/railsapps/rails_31/script/rails +6 -0
  70. data/spec/railsapps/rails_32/.gitignore +2 -0
  71. data/spec/railsapps/rails_32/Gemfile +11 -0
  72. data/spec/railsapps/rails_32/app/assets/images/rails.png +0 -0
  73. data/spec/railsapps/rails_32/app/assets/stylesheets/email.css.scss +2 -0
  74. data/spec/railsapps/rails_32/app/mailers/auto_mailer.rb +17 -0
  75. data/spec/railsapps/rails_32/app/mailers/mailer.rb +17 -0
  76. data/spec/railsapps/rails_32/app/views/auto_mailer/normal_email.html.erb +11 -0
  77. data/spec/railsapps/rails_32/app/views/auto_mailer/normal_email.text +1 -0
  78. data/spec/railsapps/rails_32/app/views/mailer/normal_email.html.erb +11 -0
  79. data/spec/railsapps/rails_32/app/views/mailer/normal_email.text +1 -0
  80. data/spec/railsapps/rails_32/config/application.rb +22 -0
  81. data/spec/railsapps/rails_32/config/boot.rb +6 -0
  82. data/spec/railsapps/rails_32/config/environment.rb +5 -0
  83. data/spec/railsapps/rails_32/config/environments/development.rb +11 -0
  84. data/spec/railsapps/rails_32/config/initializers/secret_token.rb +1 -0
  85. data/spec/railsapps/rails_32/config/initializers/session_store.rb +1 -0
  86. data/spec/railsapps/rails_32/config/initializers/wrap_parameters.rb +4 -0
  87. data/spec/railsapps/rails_32/config/routes.rb +2 -0
  88. data/spec/railsapps/rails_32/script/rails +6 -0
  89. data/spec/railsapps/rails_40/Gemfile +9 -0
  90. data/spec/railsapps/rails_40/app/assets/images/rails.png +0 -0
  91. data/spec/railsapps/rails_40/app/assets/stylesheets/email.css.scss +2 -0
  92. data/spec/railsapps/rails_40/app/mailers/auto_mailer.rb +17 -0
  93. data/spec/railsapps/rails_40/app/mailers/mailer.rb +17 -0
  94. data/spec/railsapps/rails_40/app/views/auto_mailer/normal_email.html.erb +11 -0
  95. data/spec/railsapps/rails_40/app/views/auto_mailer/normal_email.text +1 -0
  96. data/spec/railsapps/rails_40/app/views/mailer/normal_email.html.erb +11 -0
  97. data/spec/railsapps/rails_40/app/views/mailer/normal_email.text +1 -0
  98. data/spec/railsapps/rails_40/bin/rails +4 -0
  99. data/spec/railsapps/rails_40/config/application.rb +18 -0
  100. data/spec/railsapps/rails_40/config/boot.rb +4 -0
  101. data/spec/railsapps/rails_40/config/environment.rb +5 -0
  102. data/spec/railsapps/rails_40/config/environments/development.rb +9 -0
  103. data/spec/railsapps/rails_40/config/initializers/secret_token.rb +1 -0
  104. data/spec/railsapps/rails_40/config/initializers/session_store.rb +1 -0
  105. data/spec/railsapps/rails_40/config/routes.rb +2 -0
  106. data/spec/railsapps/rails_40_no_pipeline/Gemfile +9 -0
  107. data/spec/railsapps/rails_40_no_pipeline/app/mailers/auto_mailer.rb +17 -0
  108. data/spec/railsapps/rails_40_no_pipeline/app/mailers/mailer.rb +17 -0
  109. data/spec/railsapps/rails_40_no_pipeline/app/views/auto_mailer/normal_email.html.erb +11 -0
  110. data/spec/railsapps/rails_40_no_pipeline/app/views/auto_mailer/normal_email.text +1 -0
  111. data/spec/railsapps/rails_40_no_pipeline/app/views/mailer/normal_email.html.erb +11 -0
  112. data/spec/railsapps/rails_40_no_pipeline/app/views/mailer/normal_email.text +1 -0
  113. data/spec/railsapps/rails_40_no_pipeline/bin/rails +4 -0
  114. data/spec/railsapps/rails_40_no_pipeline/config/application.rb +19 -0
  115. data/spec/railsapps/rails_40_no_pipeline/config/boot.rb +4 -0
  116. data/spec/railsapps/rails_40_no_pipeline/config/environment.rb +5 -0
  117. data/spec/railsapps/rails_40_no_pipeline/config/environments/development.rb +9 -0
  118. data/spec/railsapps/rails_40_no_pipeline/config/initializers/secret_token.rb +1 -0
  119. data/spec/railsapps/rails_40_no_pipeline/config/initializers/session_store.rb +1 -0
  120. data/spec/railsapps/rails_40_no_pipeline/config/routes.rb +2 -0
  121. data/spec/railsapps/rails_40_no_pipeline/log/dee +0 -0
  122. data/spec/railsapps/rails_40_no_pipeline/public/images/rails.png +0 -0
  123. data/spec/railsapps/rails_40_no_pipeline/public/stylesheets/email.css +2 -0
  124. data/spec/railsapps/rails_40_precompiled/Gemfile +9 -0
  125. data/spec/railsapps/rails_40_precompiled/Rakefile +6 -0
  126. data/spec/railsapps/rails_40_precompiled/app/assets/images/rails.png +0 -0
  127. data/spec/railsapps/rails_40_precompiled/app/assets/stylesheets/email.css.scss +2 -0
  128. data/spec/railsapps/rails_40_precompiled/app/mailers/mailer.rb +17 -0
  129. data/spec/railsapps/rails_40_precompiled/app/views/mailer/normal_email.html.erb +11 -0
  130. data/spec/railsapps/rails_40_precompiled/app/views/mailer/normal_email.text +1 -0
  131. data/spec/railsapps/rails_40_precompiled/bin/rails +4 -0
  132. data/spec/railsapps/rails_40_precompiled/config/application.rb +18 -0
  133. data/spec/railsapps/rails_40_precompiled/config/boot.rb +4 -0
  134. data/spec/railsapps/rails_40_precompiled/config/environment.rb +5 -0
  135. data/spec/railsapps/rails_40_precompiled/config/environments/development.rb +14 -0
  136. data/spec/railsapps/rails_40_precompiled/config/initializers/secret_token.rb +1 -0
  137. data/spec/railsapps/rails_40_precompiled/config/initializers/session_store.rb +1 -0
  138. data/spec/railsapps/rails_40_precompiled/config/routes.rb +2 -0
  139. data/spec/railsapps/rails_40_precompiled/public/assets/email-fad0c62b8f82e2835c1d0bdc19894257.css +5 -0
  140. data/spec/railsapps/rails_40_precompiled/public/assets/email-fad0c62b8f82e2835c1d0bdc19894257.css.gz +0 -0
  141. data/spec/railsapps/rails_40_precompiled/public/assets/manifest-8a3d16aeb2a40fe5057dd998c3edab10.json +1 -0
  142. data/spec/railsapps/rails_40_precompiled/public/assets/rails-231a680f23887d9dd70710ea5efd3c62.png +0 -0
  143. data/spec/railsapps/rails_41/.gitignore +16 -0
  144. data/spec/railsapps/rails_41/Gemfile +8 -0
  145. data/spec/railsapps/rails_41/app/assets/images/rails.png +0 -0
  146. data/spec/railsapps/rails_41/app/assets/stylesheets/email.css.scss +2 -0
  147. data/spec/railsapps/rails_41/app/mailers/auto_mailer.rb +17 -0
  148. data/spec/railsapps/rails_41/app/mailers/mailer.rb +17 -0
  149. data/spec/railsapps/rails_41/app/views/auto_mailer/normal_email.html.erb +11 -0
  150. data/spec/railsapps/rails_41/app/views/auto_mailer/normal_email.text +1 -0
  151. data/spec/railsapps/rails_41/app/views/mailer/normal_email.html.erb +11 -0
  152. data/spec/railsapps/rails_41/app/views/mailer/normal_email.text +1 -0
  153. data/spec/railsapps/rails_41/bin/rails +4 -0
  154. data/spec/railsapps/rails_41/config.ru +4 -0
  155. data/spec/railsapps/rails_41/config/application.rb +13 -0
  156. data/spec/railsapps/rails_41/config/boot.rb +4 -0
  157. data/spec/railsapps/rails_41/config/environment.rb +5 -0
  158. data/spec/railsapps/rails_41/config/environments/development.rb +9 -0
  159. data/spec/railsapps/rails_41/config/initializers/secret_token.rb +1 -0
  160. data/spec/railsapps/rails_41/config/initializers/session_store.rb +1 -0
  161. data/spec/railsapps/rails_41/config/routes.rb +2 -0
  162. data/spec/spec_helper.rb +14 -0
  163. data/spec/support/have_selector_matcher.rb +3 -0
  164. data/spec/support/have_styling_matcher.rb +63 -0
  165. data/spec/support/rails_app.rb +70 -0
  166. metadata +443 -0
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+ require 'tempfile'
3
+ require 'mail'
4
+
5
+ describe "Integrations" do
6
+ def parse_html_in_email(mail)
7
+ Nokogiri::HTML.parse mail.html_part.body.decoded
8
+ end
9
+
10
+ [
11
+ RailsApp.new("Rails 3.0.x", 'rails_30', runner: :script, asset_pipeline: false),
12
+ ## We do not yet support live-compilation through asset pipeline
13
+ RailsApp.new("Rails 3.1.x", 'rails_31', runner: :script, asset_pipeline: true),
14
+ RailsApp.new("Rails 3.2.x", 'rails_32', runner: :script, asset_pipeline: true),
15
+ RailsApp.new("Rails 4.0.x", 'rails_40', runner: :bin, asset_pipeline: true),
16
+ RailsApp.new("Rails 4.0.x (without asset pipeline)", 'rails_40_no_pipeline', runner: :bin, asset_pipeline: false),
17
+ RailsApp.new("Rails 4.1.x", 'rails_41', runner: :bin, asset_pipeline: true),
18
+ ].each do |app|
19
+ describe "with #{app}" do
20
+ before { app.reset }
21
+
22
+ it "inlines styles for multipart emails" do
23
+ email = app.read_email(:normal_email)
24
+
25
+ expect(email.to).to eq(['example@example.org'])
26
+ expect(email.from).to eq(['john@example.com'])
27
+ expect(email).to have(2).parts
28
+
29
+ expect(email.text_part.body.decoded).not_to match(/<.*>/)
30
+
31
+ html = email.html_part.body.decoded
32
+ expect(html).to include '<!DOCTYPE'
33
+ expect(html).to include '<head'
34
+
35
+ document = parse_html_in_email(email)
36
+ expect(document).to have_selector('body h1')
37
+
38
+ if app.using_asset_pipeline?
39
+ expected_image_url = 'https://example.app.org/assets/rails.png'
40
+ else
41
+ expected_image_url = 'https://example.app.org/images/rails.png'
42
+ end
43
+ expect(document).to have_styling('background' => "url(#{expected_image_url})").at_selector('.image')
44
+
45
+ # If we deliver mails we can catch weird problems with headers being invalid
46
+ email.delivery_method :test
47
+ email.deliver
48
+ end
49
+
50
+ it "automatically inlines styles with automatic mailer" do
51
+ email = app.read_delivered_email(:normal_email)
52
+
53
+ expect(email.to).to eq(['example@example.org'])
54
+ expect(email.from).to eq(['john@example.com'])
55
+ expect(email).to have(2).parts
56
+
57
+ expect(email.text_part.body.decoded).not_to match(/<.*>/)
58
+
59
+ html = email.html_part.body.decoded
60
+ expect(html).to include '<!DOCTYPE'
61
+ expect(html).to include '<head'
62
+
63
+ document = parse_html_in_email(email)
64
+ expect(document).to have_selector('body h1')
65
+
66
+ if app.using_asset_pipeline?
67
+ expected_image_url = 'https://example.app.org/assets/rails.png'
68
+ else
69
+ expected_image_url = 'https://example.app.org/images/rails.png'
70
+ end
71
+ expect(document).to have_styling('background' => "url(#{expected_image_url})").at_selector('.image')
72
+
73
+ # If we deliver mails we can catch weird problems with headers being invalid
74
+ email.delivery_method :test
75
+ email.deliver
76
+ end
77
+
78
+ if app.using_asset_pipeline?
79
+ it "has a AssetPipelineProvider together with a FilesystemProvider" do
80
+ expect(app.read_providers).to eq(%w[Roadie::FilesystemProvider Roadie::Rails::AssetPipelineProvider])
81
+ end
82
+ else
83
+ it "only has a FilesystemProvider" do
84
+ expect(app.read_providers).to eq(["Roadie::FilesystemProvider"])
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ describe "with precompiled assets" do
91
+ let(:app) {
92
+ RailsApp.new("Rails 4.0.x (precompiled)", 'rails_40_precompiled', runner: :bin, asset_pipeline: false)
93
+ }
94
+
95
+ before { app.reset }
96
+
97
+ let(:document) do
98
+ parse_html_in_email app.read_email(:normal_email)
99
+ end
100
+
101
+ # It still has an AssetPipelineProvider in case some asset isn't
102
+ # precompiled, or the user want to combine. As long as the user is using
103
+ # the correct asset helpers a precompiled asset will be picked up by the
104
+ # FilesystemProvider.
105
+ it "has a AssetPipelineProvider together with a FilesystemProvider" do
106
+ expect(app.read_providers).to eq(%w[Roadie::FilesystemProvider Roadie::Rails::AssetPipelineProvider])
107
+ end
108
+
109
+ it "inlines the precompiled stylesheet" do
110
+ # Precompiled version has green color; the file in app/assets have red
111
+ expect(document).to have_styling('background-color' => 'green').at_selector('body')
112
+ end
113
+
114
+ it "inlines images with digests" do
115
+ image_url = "https://example.app.org/assets/rails-231a680f23887d9dd70710ea5efd3c62.png"
116
+ expect(document).to have_styling('background' => "url(#{image_url})").at_selector('.image')
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+ require 'roadie/rspec'
3
+
4
+ module Roadie
5
+ module Rails
6
+ describe AssetPipelineProvider do
7
+ let(:pipeline) { FakePipeline.new }
8
+
9
+ it_behaves_like "roadie asset provider", valid_name: "existing.css", invalid_name: "bad.css" do
10
+ subject { AssetPipelineProvider.new(pipeline) }
11
+ before do
12
+ pipeline.add_asset "existing.css", "existing.css", ""
13
+ end
14
+ end
15
+
16
+ describe "finding stylesheets" do
17
+ it "searches the asset pipeline" do
18
+ pipeline.add_asset "good.css", "/path/to/good.css.scss", "body { color: red; }"
19
+ provider = AssetPipelineProvider.new(pipeline)
20
+
21
+ stylesheet = provider.find_stylesheet("good.css")
22
+ expect(stylesheet.name).to eq("/path/to/good.css.scss (live compiled)")
23
+ expect(stylesheet.to_s).to eq("body{color:red}")
24
+ end
25
+
26
+ it "ignores query string and asset prefix" do
27
+ pipeline.add_asset "good.css", "good.css.scss", ""
28
+ provider = AssetPipelineProvider.new(pipeline)
29
+ expect(provider.find_stylesheet("/assets/good.css?body=1")).not_to be_nil
30
+ end
31
+ end
32
+
33
+ class FakePipeline
34
+ # Interface
35
+ def [](name)
36
+ @files.find { |file| file.matching_name == name }
37
+ end
38
+
39
+ # Test helpers
40
+ def initialize() @files = [] end
41
+ def add_asset(matching_name, path, content) @files << AssetFile.new(matching_name, path, content) end
42
+ private
43
+ AssetFile = Struct.new(:matching_name, :pathname, :to_s)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,44 @@
1
+ require 'spec_helper'
2
+ require 'mail'
3
+
4
+ module Roadie
5
+ module Rails
6
+ describe Automatic do
7
+ base_mailer = Class.new do
8
+ def initialize(email = nil)
9
+ @email = email
10
+ end
11
+
12
+ def mail(options = {})
13
+ @email
14
+ end
15
+ end
16
+
17
+ some_mailer = Class.new(base_mailer) do
18
+ include Automatic
19
+ end
20
+
21
+ describe "#roadie_options" do
22
+ it "returns Rails' roadie config" do
23
+ allow(::Rails).to receive_message_chain(:application, :config, :roadie).and_return "roadie config"
24
+ expect(some_mailer.new.roadie_options).to eq("roadie config")
25
+ end
26
+ end
27
+
28
+ describe "#mail" do
29
+ let(:email) { Mail.new(to: "foo@example.com", from: "me@example.com") }
30
+ let(:roadie_options) { Options.new(url_options: {host: "somehost.com"}) }
31
+ let(:instance) { some_mailer.new(email) }
32
+
33
+ before { allow(instance).to receive(:roadie_options).and_return roadie_options }
34
+
35
+ it "extends the email with InlineOnDelivery and assigns roadie options" do
36
+ email = instance.mail
37
+ expect(email).to be_kind_of(InlineOnDelivery)
38
+ expect(email.roadie_options).not_to be_nil
39
+ expect(email.roadie_options.url_options).to eq roadie_options.url_options
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,20 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ module Roadie
5
+ module Rails
6
+ describe DocumentBuilder do
7
+ it "builds documents with the given HTML" do
8
+ document = DocumentBuilder.build("foo", Options.new)
9
+ expect(document.html).to eq("foo")
10
+ end
11
+
12
+ it "applies the options to the document" do
13
+ options = Options.new
14
+ expect(options).to receive(:apply_to).with(instance_of Document).and_call_original
15
+
16
+ DocumentBuilder.build("", options)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,57 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+ require 'mail'
4
+
5
+ module Roadie
6
+ module Rails
7
+ describe MailInliner do
8
+ let(:email) { Mail.new }
9
+ let(:options) { Options.new }
10
+ subject(:inliner) { MailInliner.new(email, options) }
11
+
12
+ it "takes an email and options" do
13
+ inliner = MailInliner.new(email, options)
14
+ expect(inliner.email).to eq(email)
15
+ expect(inliner.options).to eq(options)
16
+ end
17
+
18
+ context "with an plaintext email" do
19
+ let(:email) do
20
+ Mail.new do
21
+ body "Hello world"
22
+ end
23
+ end
24
+
25
+ it "returns the email without doing anything" do
26
+ expect(inliner.execute).to eq(email)
27
+ expect(email.html_part).to be_nil
28
+ expect(email.body.decoded).to eq("Hello world")
29
+ end
30
+ end
31
+
32
+ context "with an multipart email" do
33
+ let(:html) { "<h1>Hello world!</h1>" }
34
+ let(:email) do
35
+ html_string = html
36
+ Mail.new do
37
+ text_part { body "Hello world" }
38
+ html_part { body html_string }
39
+ end
40
+ end
41
+
42
+ it "returns the email" do
43
+ expect(inliner.execute).to eq(email)
44
+ end
45
+
46
+ it "adjusts the html part using Roadie" do
47
+ document = double "A document", transform: "transformed HTML"
48
+ expect(DocumentBuilder).to receive(:build).with(html, instance_of(Options)).and_return document
49
+
50
+ inliner.execute
51
+
52
+ expect(email.html_part.body.decoded).to eq("transformed HTML")
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+ require 'mail'
3
+
4
+ module Roadie
5
+ module Rails
6
+ describe Mailer do
7
+ some_mailer = Class.new do
8
+ include Mailer
9
+
10
+ def initialize(email = nil)
11
+ @email = email
12
+ end
13
+
14
+ def mail(options = {})
15
+ @email
16
+ end
17
+ end
18
+
19
+ describe "#roadie_options" do
20
+ it "returns Rails' roadie config" do
21
+ allow(::Rails).to receive_message_chain(:application, :config, :roadie).and_return "roadie config"
22
+ expect(some_mailer.new.roadie_options).to eq("roadie config")
23
+ end
24
+ end
25
+
26
+ describe "#roadie_mail" do
27
+ let(:email) { Mail.new }
28
+ let(:instance) { some_mailer.new(email) }
29
+
30
+ before { allow(instance).to receive(:roadie_options).and_return(Options.new) }
31
+
32
+ before do
33
+ inliner = double "Mail inliner"
34
+ allow(inliner).to receive(:execute) { |email| email }
35
+ allow(MailInliner).to receive(:new).and_return(inliner)
36
+ end
37
+
38
+ it "calls the original mail method with all options and the block" do
39
+ expect(instance).to receive(:mail) do |options, &block|
40
+ expect(options).to eq({some: "option"})
41
+ expect(block).not_to be_nil
42
+ email
43
+ end
44
+
45
+ instance.roadie_mail(some: "option") { }
46
+ end
47
+
48
+ it "inlines the email" do
49
+ inliner = double "Inliner"
50
+ expect(MailInliner).to receive(:new).with(email, instance_of(Options)).and_return inliner
51
+ expect(inliner).to receive(:execute).and_return "inlined email"
52
+ expect(instance.roadie_mail).to eq("inlined email")
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,136 @@
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+ require 'ostruct'
4
+
5
+ module Roadie
6
+ module Rails
7
+ describe Options do
8
+ it "raises errors when constructed with unknown options" do
9
+ expect {
10
+ Options.new(unknown_option: "maybe a misspelling?")
11
+ }.to raise_error(ArgumentError, /unknown_option/)
12
+ end
13
+
14
+ shared_examples_for "attribute" do |name|
15
+ describe name do
16
+ it "defaults to nil" do
17
+ expect(Options.new.send(name)).to be_nil
18
+ end
19
+
20
+ it "can be set in the constructor" do
21
+ expect(Options.new(name => valid_value).send(name)).to eq(valid_value)
22
+ end
23
+
24
+ it "can be changed using setter" do
25
+ options = Options.new
26
+ options.send :"#{name}=", valid_value
27
+ expect(options.send(name)).to eq(valid_value)
28
+ end
29
+
30
+ it "can be applied to documents" do
31
+ fake_document = OpenStruct.new
32
+ options = Options.new(name => valid_value)
33
+ options.apply_to(fake_document)
34
+ expect(fake_document.send(name)).to eq(valid_value)
35
+ end
36
+
37
+ describe "merging" do
38
+ it "replaces values" do
39
+ options = Options.new(name => valid_value)
40
+ expect(options.merge(name => other_valid_value).send(name)).to eq(other_valid_value)
41
+ end
42
+
43
+ it "does not mutate instance" do
44
+ options = Options.new(name => valid_value)
45
+ options.merge(name => other_valid_value)
46
+ expect(options.send(name)).to eq(valid_value)
47
+ end
48
+ end
49
+
50
+ describe "destructive merging" do
51
+ it "replaces values" do
52
+ options = Options.new(name => valid_value)
53
+ expect(options.merge(name => other_valid_value).send(name)).to eq(other_valid_value)
54
+ end
55
+ end
56
+
57
+ describe "combining" do
58
+ it "combines the old and the new value" do
59
+ options = Options.new(name => valid_value)
60
+ combined = options.combine(name => other_valid_value)
61
+ expect_combinated_value combined.send(name)
62
+ end
63
+
64
+ it "does not mutate instance" do
65
+ options = Options.new(name => valid_value)
66
+ options.combine(name => other_valid_value)
67
+ expect(options.send(name)).to eq(valid_value)
68
+ end
69
+ end
70
+
71
+ describe "destructive combining" do
72
+ it "combines the old and the new value in the instance" do
73
+ options = Options.new(name => valid_value)
74
+ options.combine!(name => other_valid_value)
75
+ expect_combinated_value options.send(name)
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ it_behaves_like "attribute", :url_options do
82
+ let(:valid_value) { {host: "foo.com", port: 3000} }
83
+ let(:other_valid_value) { {host: "bar.com", scheme: "https"} }
84
+
85
+ def expect_combinated_value(value)
86
+ expect(value).to eq({host: "bar.com", port: 3000, scheme: "https"})
87
+ end
88
+ end
89
+
90
+ it_behaves_like "attribute", :before_transformation do
91
+ let(:valid_value) { Proc.new { } }
92
+ let(:other_valid_value) { Proc.new { } }
93
+
94
+ def expect_combinated_value(value)
95
+ expect(valid_value).to receive(:call).ordered.and_return 1
96
+ expect(other_valid_value).to receive(:call).ordered.and_return 2
97
+
98
+ expect(value.call).to eq(2)
99
+ end
100
+ end
101
+
102
+ it_behaves_like "attribute", :after_transformation do
103
+ let(:valid_value) { Proc.new { } }
104
+ let(:other_valid_value) { Proc.new { } }
105
+
106
+ def expect_combinated_value(value)
107
+ expect(valid_value).to receive(:call).ordered.and_return 1
108
+ expect(other_valid_value).to receive(:call).ordered.and_return 2
109
+ expect(value.call).to eq(2)
110
+ end
111
+ end
112
+
113
+ it_behaves_like "attribute", :asset_providers do
114
+ let(:provider1) { double "Asset provider 1" }
115
+ let(:provider2) { double "Asset provider 2" }
116
+
117
+ let(:valid_value) { ProviderList.new([provider1]) }
118
+ let(:other_valid_value) { ProviderList.new([provider2]) }
119
+
120
+ def expect_combinated_value(value)
121
+ expect(value).to be_instance_of(ProviderList)
122
+ expect(value.to_a).to eq([provider1, provider2])
123
+ end
124
+ end
125
+
126
+ describe "asset_providers" do
127
+ it "automatically wraps values in a ProviderList" do
128
+ provider = double "Asset provider"
129
+ options = Options.new(asset_providers: [provider])
130
+ expect(options.asset_providers).to be_instance_of(ProviderList)
131
+ expect(options.asset_providers.to_a).to eq([provider])
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end