roadie-rails 1.0.0.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/.travis.yml +15 -0
- data/Changelog.md +9 -0
- data/Gemfile +17 -0
- data/Guardfile +16 -0
- data/LICENSE.txt +22 -0
- data/README.md +317 -0
- data/Rakefile +14 -0
- data/Upgrading.md +70 -0
- data/lib/roadie-rails.rb +1 -0
- data/lib/roadie/rails.rb +21 -0
- data/lib/roadie/rails/asset_pipeline_provider.rb +24 -0
- data/lib/roadie/rails/automatic.rb +16 -0
- data/lib/roadie/rails/document_builder.rb +18 -0
- data/lib/roadie/rails/inline_on_delivery.rb +17 -0
- data/lib/roadie/rails/mail_inliner.rb +26 -0
- data/lib/roadie/rails/mailer.rb +14 -0
- data/lib/roadie/rails/options.rb +101 -0
- data/lib/roadie/rails/railtie.rb +22 -0
- data/lib/roadie/rails/version.rb +5 -0
- data/roadie-rails.gemspec +29 -0
- data/setup.sh +62 -0
- data/spec/integration_spec.rb +119 -0
- data/spec/lib/roadie/rails/asset_pipeline_provider_spec.rb +47 -0
- data/spec/lib/roadie/rails/automatic_spec.rb +44 -0
- data/spec/lib/roadie/rails/document_builder_spec.rb +20 -0
- data/spec/lib/roadie/rails/mail_inliner_spec.rb +57 -0
- data/spec/lib/roadie/rails/mailer_spec.rb +57 -0
- data/spec/lib/roadie/rails/options_spec.rb +136 -0
- data/spec/lib/roadie/rails/railtie_spec.rb +48 -0
- data/spec/railsapps/README.md +69 -0
- data/spec/railsapps/rails_30/.gitignore +2 -0
- data/spec/railsapps/rails_30/Gemfile +7 -0
- data/spec/railsapps/rails_30/app/mailers/auto_mailer.rb +17 -0
- data/spec/railsapps/rails_30/app/mailers/mailer.rb +17 -0
- data/spec/railsapps/rails_30/app/views/auto_mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_30/app/views/auto_mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_30/app/views/mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_30/app/views/mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_30/config/application.rb +19 -0
- data/spec/railsapps/rails_30/config/boot.rb +6 -0
- data/spec/railsapps/rails_30/config/environment.rb +5 -0
- data/spec/railsapps/rails_30/config/environments/development.rb +10 -0
- data/spec/railsapps/rails_30/config/initializers/secret_token.rb +1 -0
- data/spec/railsapps/rails_30/config/initializers/session_store.rb +1 -0
- data/spec/railsapps/rails_30/config/routes.rb +2 -0
- data/spec/railsapps/rails_30/public/images/rails.png +0 -0
- data/spec/railsapps/rails_30/public/stylesheets/email.css +2 -0
- data/spec/railsapps/rails_30/script/rails +6 -0
- data/spec/railsapps/rails_31/.gitignore +2 -0
- data/spec/railsapps/rails_31/Gemfile +11 -0
- data/spec/railsapps/rails_31/app/assets/images/rails.png +0 -0
- data/spec/railsapps/rails_31/app/assets/stylesheets/email.css.scss +2 -0
- data/spec/railsapps/rails_31/app/mailers/auto_mailer.rb +17 -0
- data/spec/railsapps/rails_31/app/mailers/mailer.rb +17 -0
- data/spec/railsapps/rails_31/app/views/auto_mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_31/app/views/auto_mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_31/app/views/mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_31/app/views/mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_31/config/application.rb +22 -0
- data/spec/railsapps/rails_31/config/boot.rb +6 -0
- data/spec/railsapps/rails_31/config/environment.rb +5 -0
- data/spec/railsapps/rails_31/config/environments/development.rb +11 -0
- data/spec/railsapps/rails_31/config/initializers/secret_token.rb +1 -0
- data/spec/railsapps/rails_31/config/initializers/session_store.rb +1 -0
- data/spec/railsapps/rails_31/config/initializers/wrap_parameters.rb +4 -0
- data/spec/railsapps/rails_31/config/routes.rb +2 -0
- data/spec/railsapps/rails_31/script/rails +6 -0
- data/spec/railsapps/rails_32/.gitignore +2 -0
- data/spec/railsapps/rails_32/Gemfile +11 -0
- data/spec/railsapps/rails_32/app/assets/images/rails.png +0 -0
- data/spec/railsapps/rails_32/app/assets/stylesheets/email.css.scss +2 -0
- data/spec/railsapps/rails_32/app/mailers/auto_mailer.rb +17 -0
- data/spec/railsapps/rails_32/app/mailers/mailer.rb +17 -0
- data/spec/railsapps/rails_32/app/views/auto_mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_32/app/views/auto_mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_32/app/views/mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_32/app/views/mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_32/config/application.rb +22 -0
- data/spec/railsapps/rails_32/config/boot.rb +6 -0
- data/spec/railsapps/rails_32/config/environment.rb +5 -0
- data/spec/railsapps/rails_32/config/environments/development.rb +11 -0
- data/spec/railsapps/rails_32/config/initializers/secret_token.rb +1 -0
- data/spec/railsapps/rails_32/config/initializers/session_store.rb +1 -0
- data/spec/railsapps/rails_32/config/initializers/wrap_parameters.rb +4 -0
- data/spec/railsapps/rails_32/config/routes.rb +2 -0
- data/spec/railsapps/rails_32/script/rails +6 -0
- data/spec/railsapps/rails_40/Gemfile +9 -0
- data/spec/railsapps/rails_40/app/assets/images/rails.png +0 -0
- data/spec/railsapps/rails_40/app/assets/stylesheets/email.css.scss +2 -0
- data/spec/railsapps/rails_40/app/mailers/auto_mailer.rb +17 -0
- data/spec/railsapps/rails_40/app/mailers/mailer.rb +17 -0
- data/spec/railsapps/rails_40/app/views/auto_mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_40/app/views/auto_mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_40/app/views/mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_40/app/views/mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_40/bin/rails +4 -0
- data/spec/railsapps/rails_40/config/application.rb +18 -0
- data/spec/railsapps/rails_40/config/boot.rb +4 -0
- data/spec/railsapps/rails_40/config/environment.rb +5 -0
- data/spec/railsapps/rails_40/config/environments/development.rb +9 -0
- data/spec/railsapps/rails_40/config/initializers/secret_token.rb +1 -0
- data/spec/railsapps/rails_40/config/initializers/session_store.rb +1 -0
- data/spec/railsapps/rails_40/config/routes.rb +2 -0
- data/spec/railsapps/rails_40_no_pipeline/Gemfile +9 -0
- data/spec/railsapps/rails_40_no_pipeline/app/mailers/auto_mailer.rb +17 -0
- data/spec/railsapps/rails_40_no_pipeline/app/mailers/mailer.rb +17 -0
- data/spec/railsapps/rails_40_no_pipeline/app/views/auto_mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_40_no_pipeline/app/views/auto_mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_40_no_pipeline/app/views/mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_40_no_pipeline/app/views/mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_40_no_pipeline/bin/rails +4 -0
- data/spec/railsapps/rails_40_no_pipeline/config/application.rb +19 -0
- data/spec/railsapps/rails_40_no_pipeline/config/boot.rb +4 -0
- data/spec/railsapps/rails_40_no_pipeline/config/environment.rb +5 -0
- data/spec/railsapps/rails_40_no_pipeline/config/environments/development.rb +9 -0
- data/spec/railsapps/rails_40_no_pipeline/config/initializers/secret_token.rb +1 -0
- data/spec/railsapps/rails_40_no_pipeline/config/initializers/session_store.rb +1 -0
- data/spec/railsapps/rails_40_no_pipeline/config/routes.rb +2 -0
- data/spec/railsapps/rails_40_no_pipeline/log/dee +0 -0
- data/spec/railsapps/rails_40_no_pipeline/public/images/rails.png +0 -0
- data/spec/railsapps/rails_40_no_pipeline/public/stylesheets/email.css +2 -0
- data/spec/railsapps/rails_40_precompiled/Gemfile +9 -0
- data/spec/railsapps/rails_40_precompiled/Rakefile +6 -0
- data/spec/railsapps/rails_40_precompiled/app/assets/images/rails.png +0 -0
- data/spec/railsapps/rails_40_precompiled/app/assets/stylesheets/email.css.scss +2 -0
- data/spec/railsapps/rails_40_precompiled/app/mailers/mailer.rb +17 -0
- data/spec/railsapps/rails_40_precompiled/app/views/mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_40_precompiled/app/views/mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_40_precompiled/bin/rails +4 -0
- data/spec/railsapps/rails_40_precompiled/config/application.rb +18 -0
- data/spec/railsapps/rails_40_precompiled/config/boot.rb +4 -0
- data/spec/railsapps/rails_40_precompiled/config/environment.rb +5 -0
- data/spec/railsapps/rails_40_precompiled/config/environments/development.rb +14 -0
- data/spec/railsapps/rails_40_precompiled/config/initializers/secret_token.rb +1 -0
- data/spec/railsapps/rails_40_precompiled/config/initializers/session_store.rb +1 -0
- data/spec/railsapps/rails_40_precompiled/config/routes.rb +2 -0
- data/spec/railsapps/rails_40_precompiled/public/assets/email-fad0c62b8f82e2835c1d0bdc19894257.css +5 -0
- data/spec/railsapps/rails_40_precompiled/public/assets/email-fad0c62b8f82e2835c1d0bdc19894257.css.gz +0 -0
- data/spec/railsapps/rails_40_precompiled/public/assets/manifest-8a3d16aeb2a40fe5057dd998c3edab10.json +1 -0
- data/spec/railsapps/rails_40_precompiled/public/assets/rails-231a680f23887d9dd70710ea5efd3c62.png +0 -0
- data/spec/railsapps/rails_41/.gitignore +16 -0
- data/spec/railsapps/rails_41/Gemfile +8 -0
- data/spec/railsapps/rails_41/app/assets/images/rails.png +0 -0
- data/spec/railsapps/rails_41/app/assets/stylesheets/email.css.scss +2 -0
- data/spec/railsapps/rails_41/app/mailers/auto_mailer.rb +17 -0
- data/spec/railsapps/rails_41/app/mailers/mailer.rb +17 -0
- data/spec/railsapps/rails_41/app/views/auto_mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_41/app/views/auto_mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_41/app/views/mailer/normal_email.html.erb +11 -0
- data/spec/railsapps/rails_41/app/views/mailer/normal_email.text +1 -0
- data/spec/railsapps/rails_41/bin/rails +4 -0
- data/spec/railsapps/rails_41/config.ru +4 -0
- data/spec/railsapps/rails_41/config/application.rb +13 -0
- data/spec/railsapps/rails_41/config/boot.rb +4 -0
- data/spec/railsapps/rails_41/config/environment.rb +5 -0
- data/spec/railsapps/rails_41/config/environments/development.rb +9 -0
- data/spec/railsapps/rails_41/config/initializers/secret_token.rb +1 -0
- data/spec/railsapps/rails_41/config/initializers/session_store.rb +1 -0
- data/spec/railsapps/rails_41/config/routes.rb +2 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/have_selector_matcher.rb +3 -0
- data/spec/support/have_styling_matcher.rb +63 -0
- data/spec/support/rails_app.rb +70 -0
- 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
|