roadie 3.2.2 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -192,25 +192,6 @@ module Roadie
192
192
  expect(dom).to_not have_selector("link[href*=some]")
193
193
  expect(dom).to have_selector("link[href*=other]")
194
194
  end
195
-
196
- it "removes the data-roadie-ignore markers" do
197
- dom = dom_document <<-HTML
198
- <html>
199
- <head>
200
- <link rel="stylesheet" href="/cool.css" data-roadie-ignore id="first">
201
- </head>
202
- <body>
203
- <style data-roadie-ignore id="second">a { color: red; }</style>
204
- </body>
205
- </html>
206
- HTML
207
- scanner = AssetScanner.new dom, TestProvider.new, external_provider
208
-
209
- scanner.extract_css
210
-
211
- expect(dom.at_css("#first").attributes).to_not include("data-roadie-ignore")
212
- expect(dom.at_css("#second").attributes).to_not include("data-roadie-ignore")
213
- end
214
195
  end
215
196
  end
216
197
  end
@@ -35,6 +35,10 @@ module Roadie
35
35
  expect(provider).to be_instance_of(FilesystemProvider)
36
36
  end
37
37
 
38
+ it "defaults to HTML mode" do
39
+ expect(document.mode).to eq(:html)
40
+ end
41
+
38
42
  it "allows changes to the normal asset providers" do
39
43
  other_provider = double "Other proider"
40
44
  old_list = document.asset_providers
@@ -59,6 +63,20 @@ module Roadie
59
63
  expect(document.external_asset_providers).to eq(old_list)
60
64
  end
61
65
 
66
+ it "allows changes to the mode setting" do
67
+ document.mode = :xhtml
68
+ expect(document.mode).to eq(:xhtml)
69
+
70
+ document.mode = :html
71
+ expect(document.mode).to eq(:html)
72
+ end
73
+
74
+ it "does not allow unknown modes" do
75
+ expect {
76
+ document.mode = :other
77
+ }.to raise_error(ArgumentError, /:other/)
78
+ end
79
+
62
80
  it "can store callbacks for inlining" do
63
81
  callable = double "Callable"
64
82
 
@@ -98,6 +116,48 @@ module Roadie
98
116
  }
99
117
  expect { document.transform }.to_not raise_error
100
118
  end
119
+
120
+ context "in HTML mode" do
121
+ it "does not escape curly braces" do
122
+ document = Document.new "<body><a href='https://google.com/{{hello}}'>Hello</a></body>"
123
+ document.mode = :xhtml
124
+
125
+ expect(document.transform).to include("{{hello}}")
126
+ end
127
+ end
128
+ end
129
+
130
+ describe "partial transforming" do
131
+ it "runs the before and after callbacks" do
132
+ document = Document.new "<p></p>"
133
+ before = ->{}
134
+ after = ->{}
135
+ document.before_transformation = before
136
+ document.after_transformation = after
137
+
138
+ expect(before).to receive(:call).with(
139
+ instance_of(Nokogiri::HTML::DocumentFragment),
140
+ document,
141
+ ).ordered
142
+
143
+ expect(Inliner).to receive(:new).ordered.and_return double.as_null_object
144
+
145
+ expect(after).to receive(:call).with(
146
+ instance_of(Nokogiri::HTML::DocumentFragment),
147
+ document,
148
+ ).ordered
149
+
150
+ document.transform_partial
151
+ end
152
+
153
+ context "in HTML mode" do
154
+ it "does not escape curly braces" do
155
+ document = Document.new "<a href='https://google.com/{{hello}}'>Hello</a>"
156
+ document.mode = :xhtml
157
+
158
+ expect(document.transform_partial).to include("{{hello}}")
159
+ end
160
+ end
101
161
  end
102
162
  end
103
163
 
@@ -155,5 +215,27 @@ module Roadie
155
215
  %w[text-size 2em]
156
216
  ]).at_selector("p")
157
217
  end
218
+
219
+ it "removes data-roadie-ignore markers" do
220
+ document = Document.new <<-HTML
221
+ <html>
222
+ <head>
223
+ <link rel="stylesheet" href="/cool.css" data-roadie-ignore id="first">
224
+ </head>
225
+ <body>
226
+ <style data-roadie-ignore id="second">a { color: red; }</style>
227
+ <a href="#" data-roadie-ignore>
228
+ Hello world!
229
+ <span data-roadie-ignore></span>
230
+ </a>
231
+ </body>
232
+ </html>
233
+ HTML
234
+
235
+ result = Nokogiri::HTML.parse document.transform
236
+
237
+ expect(result).to have_selector("body > a > span")
238
+ expect(result).not_to have_selector("[data-roadie-ignore]")
239
+ end
158
240
  end
159
241
  end
@@ -219,9 +219,39 @@ module Roadie
219
219
  <body><p></p></body>
220
220
  </html>
221
221
  "
222
- Inliner.new([stylesheet], dom).inline(false)
222
+ Inliner.new([stylesheet], dom).inline(keep_uninlinable_css: false)
223
223
  expect(dom).to_not have_selector("head > style")
224
224
  end
225
+
226
+ it "puts the <style> element at the root when told so" do
227
+ stylesheet = use_css 'a:hover { color: red; }'
228
+ dom = Nokogiri::HTML.fragment("
229
+ <a></a>
230
+ ")
231
+
232
+ Inliner.new([stylesheet], dom).inline(
233
+ keep_uninlinable_css: true,
234
+ keep_uninlinable_in: :root,
235
+ )
236
+
237
+ expect(dom).to have_xpath("./a")
238
+ expect(dom).to have_xpath("./style")
239
+ end
240
+
241
+ it "raises error when told to save styles in an unknown place" do
242
+ stylesheet = use_css 'a:hover { color: red; }'
243
+ dom = Nokogiri::HTML.fragment("
244
+ <a></a>
245
+ ")
246
+
247
+ inliner = Inliner.new([stylesheet], dom)
248
+ expect {
249
+ inliner.inline(
250
+ keep_uninlinable_css: true,
251
+ keep_uninlinable_in: :unknown_place,
252
+ )
253
+ }.to raise_error(ArgumentError, /:unknown_place/)
254
+ end
225
255
  end
226
256
  end
227
257
  end
@@ -43,6 +43,41 @@ module Roadie
43
43
  }.to_not raise_error
44
44
  end
45
45
 
46
+ it "applies encoding from the response" do
47
+ # Net::HTTP always returns the body string as a byte-encoded string
48
+ # (US-ASCII). The headers will indicate what charset the client should
49
+ # use when trying to make sense of these bytes.
50
+ stub_request(:get, url).and_return(
51
+ body: %(p::before { content: "l\xF6ve" }).force_encoding("US-ASCII"),
52
+ headers: {"Content-Type" => "text/css;charset=ISO-8859-1"},
53
+ )
54
+
55
+ # Seems like CssParser strips out the non-ascii character for some
56
+ # reason.
57
+ # stylesheet = NetHttpProvider.new.find_stylesheet!(url)
58
+ # expect(stylesheet.to_s).to eq('p::before{content:"löve"}')
59
+
60
+ allow(Stylesheet).to receive(:new).and_return(instance_double(Stylesheet))
61
+ NetHttpProvider.new.find_stylesheet!(url)
62
+ expect(Stylesheet).to have_received(:new).with(url, 'p::before { content: "löve" }')
63
+ end
64
+
65
+ it "assumes UTF-8 encoding if server headers do not specify a charset" do
66
+ stub_request(:get, url).and_return(
67
+ body: %(p::before { content: "Åh nej" }).force_encoding("US-ASCII"),
68
+ headers: {"Content-Type" => "text/css"},
69
+ )
70
+
71
+ # Seems like CssParser strips out the non-ascii characters for some
72
+ # reason.
73
+ # stylesheet = NetHttpProvider.new.find_stylesheet!(url)
74
+ # expect(stylesheet.to_s).to eq('p::before{content:"Åh nej"}')
75
+
76
+ allow(Stylesheet).to receive(:new).and_return(instance_double(Stylesheet))
77
+ NetHttpProvider.new.find_stylesheet!(url)
78
+ expect(Stylesheet).to have_received(:new).with(url, 'p::before { content: "Åh nej" }')
79
+ end
80
+
46
81
  describe "error handling" do
47
82
  it "handles timeouts" do
48
83
  stub_request(:get, url).and_timeout
@@ -49,6 +49,22 @@ module Roadie
49
49
  rewriter.transform_dom dom
50
50
  }.to change { dom.at_css("div")["style"] }.to 'background-image: url("http://foo.com/image.jpg");'
51
51
  end
52
+
53
+ it "skips elements with data-roadie-ignore attributes" do
54
+ allow(generator).to receive(:generate_url).and_return("http://example.com")
55
+
56
+ dom = dom_document <<-HTML
57
+ <body>
58
+ <a href="some/path.jpg" data-roadie-ignore>Image</a>
59
+ <img src="some/path.jpg" data-roadie-ignore>
60
+ <div style="background-image: url(&quot;some/path.jpg&quot;);" data-roadie-ignore>
61
+ </body>
62
+ HTML
63
+
64
+ rewriter.transform_dom dom
65
+
66
+ expect(generator).not_to have_received(:generate_url)
67
+ end
52
68
  end
53
69
 
54
70
  describe "transforming css" do
@@ -1,6 +1,6 @@
1
1
  RSpec::Matchers.define :have_selector do |selector|
2
2
  match { |document| !document.css(selector).empty? }
3
- failure_message { "expected document to #{name_to_sentence}#{to_sentence selector}"}
4
- failure_message_when_negated { "expected document to not #{name_to_sentence}#{to_sentence selector}"}
3
+ failure_message { "expected document to have selector #{selector.inspect}"}
4
+ failure_message_when_negated { "expected document to not have selector #{selector.inspect}"}
5
5
  end
6
6
 
@@ -0,0 +1,6 @@
1
+ RSpec::Matchers.define :have_xpath do |xpath|
2
+ match { |document| !document.xpath(xpath).empty? }
3
+ failure_message { "expected document to have xpath #{xpath.inspect}"}
4
+ failure_message_when_negated { "expected document to not have xpath #{xpath.inspect}"}
5
+ end
6
+
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roadie
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.2
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Magnus Bergmark
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-13 00:00:00.000000000 Z
11
+ date: 2018-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -162,6 +162,7 @@ files:
162
162
  - spec/support/have_node_matcher.rb
163
163
  - spec/support/have_selector_matcher.rb
164
164
  - spec/support/have_styling_matcher.rb
165
+ - spec/support/have_xpath_matcher.rb
165
166
  - spec/support/test_provider.rb
166
167
  homepage: http://github.com/Mange/roadie
167
168
  licenses:
@@ -183,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
183
184
  version: '0'
184
185
  requirements: []
185
186
  rubyforge_project:
186
- rubygems_version: 2.6.12
187
+ rubygems_version: 2.6.14
187
188
  signing_key:
188
189
  specification_version: 4
189
190
  summary: Making HTML emails comfortable for the Ruby rockstars
@@ -221,4 +222,5 @@ test_files:
221
222
  - spec/support/have_node_matcher.rb
222
223
  - spec/support/have_selector_matcher.rb
223
224
  - spec/support/have_styling_matcher.rb
225
+ - spec/support/have_xpath_matcher.rb
224
226
  - spec/support/test_provider.rb