pdfkit 0.8.0 → 0.8.7.1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pdfkit might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/.github/workflows/release-drafter.yml +19 -0
- data/.github/workflows/stale.yml +19 -0
- data/.github/workflows/test.yml +59 -0
- data/.ruby-version +1 -1
- data/.travis.yml +42 -8
- data/CHANGELOG.md +71 -1
- data/Gemfile +1 -1
- data/README.md +36 -10
- data/lib/pdfkit/configuration.rb +38 -3
- data/lib/pdfkit/html_preprocessor.rb +25 -0
- data/lib/pdfkit/middleware.rb +53 -43
- data/lib/pdfkit/os.rb +21 -0
- data/lib/pdfkit/pdfkit.rb +55 -96
- data/lib/pdfkit/source.rb +36 -7
- data/lib/pdfkit/version.rb +3 -1
- data/lib/pdfkit/wkhtmltopdf.rb +82 -0
- data/lib/pdfkit.rb +6 -0
- data/pdfkit.gemspec +9 -7
- data/spec/configuration_spec.rb +85 -12
- data/spec/html_preprocessor_spec.rb +71 -0
- data/spec/middleware_spec.rb +240 -107
- data/spec/os_spec.rb +67 -0
- data/spec/pdfkit_spec.rb +132 -52
- data/spec/source_spec.rb +67 -13
- data/spec/spec_helper.rb +5 -1
- metadata +45 -48
data/spec/middleware_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
def app; Rack::Lint.new(@app); end
|
@@ -17,43 +19,72 @@ end
|
|
17
19
|
|
18
20
|
describe PDFKit::Middleware do
|
19
21
|
let(:headers) do
|
20
|
-
{'
|
22
|
+
{'content-type' => "text/html"}
|
21
23
|
end
|
22
24
|
|
23
25
|
describe "#call" do
|
26
|
+
|
27
|
+
describe 'threadsafety' do
|
28
|
+
before { mock_app }
|
29
|
+
it 'is threadsafe' do
|
30
|
+
n = 30
|
31
|
+
extensions = Array.new(n) { rand > 0.5 ? 'html' : 'pdf' }
|
32
|
+
actual_content_types = Hash.new
|
33
|
+
|
34
|
+
threads = (0...n).map { |i|
|
35
|
+
Thread.new do
|
36
|
+
resp = get("http://www.example.org/public/test.#{extensions[i]}")
|
37
|
+
actual_content_types[i] = resp.content_type
|
38
|
+
end
|
39
|
+
}
|
40
|
+
|
41
|
+
threads.each(&:join)
|
42
|
+
|
43
|
+
extensions.each_with_index do |extension, index|
|
44
|
+
result = actual_content_types[index]
|
45
|
+
case extension
|
46
|
+
when 'html', 'txt', 'csv'
|
47
|
+
expect(result).to eq("text/#{extension}")
|
48
|
+
when 'pdf'
|
49
|
+
expect(result).to eq('application/pdf')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
24
55
|
describe "caching" do
|
25
56
|
let(:headers) do
|
26
57
|
{
|
27
|
-
'
|
28
|
-
'
|
29
|
-
'
|
58
|
+
'content-type' => "text/html",
|
59
|
+
'etag' => 'foo',
|
60
|
+
'cache-control' => 'max-age=2592000, public'
|
30
61
|
}
|
31
62
|
end
|
32
63
|
|
33
64
|
context "by default" do
|
34
65
|
before { mock_app }
|
35
66
|
|
36
|
-
it "deletes
|
67
|
+
it "deletes etag" do
|
37
68
|
get 'http://www.example.org/public/test.pdf'
|
38
|
-
expect(last_response.headers["
|
69
|
+
expect(last_response.headers["etag"]).to be_nil
|
39
70
|
end
|
40
|
-
it "deletes
|
71
|
+
it "deletes cache-control" do
|
41
72
|
get 'http://www.example.org/public/test.pdf'
|
42
|
-
expect(last_response.headers["
|
73
|
+
expect(last_response.headers["cache-control"]).to be_nil
|
43
74
|
end
|
44
75
|
end
|
45
76
|
|
46
77
|
context "when on" do
|
47
78
|
before { mock_app({}, :caching => true) }
|
48
79
|
|
49
|
-
it "preserves
|
80
|
+
it "preserves etag" do
|
50
81
|
get 'http://www.example.org/public/test.pdf'
|
51
|
-
expect(last_response.headers["
|
82
|
+
expect(last_response.headers["etag"]).not_to be_nil
|
52
83
|
end
|
53
84
|
|
54
|
-
it "preserves
|
85
|
+
it "preserves cache-control" do
|
55
86
|
get 'http://www.example.org/public/test.pdf'
|
56
|
-
expect(last_response.headers["
|
87
|
+
expect(last_response.headers["cache-control"]).not_to be_nil
|
57
88
|
end
|
58
89
|
end
|
59
90
|
end
|
@@ -68,7 +99,7 @@ describe PDFKit::Middleware do
|
|
68
99
|
context "matching" do
|
69
100
|
specify do
|
70
101
|
get 'http://www.example.org/public/test.pdf'
|
71
|
-
expect(last_response.headers["
|
102
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
72
103
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
73
104
|
end
|
74
105
|
end
|
@@ -76,7 +107,7 @@ describe PDFKit::Middleware do
|
|
76
107
|
context "not matching" do
|
77
108
|
specify do
|
78
109
|
get 'http://www.example.org/secret/test.pdf'
|
79
|
-
expect(last_response.headers["
|
110
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
80
111
|
expect(last_response.body).to eq("Hello world!")
|
81
112
|
end
|
82
113
|
end
|
@@ -88,7 +119,7 @@ describe PDFKit::Middleware do
|
|
88
119
|
context "matching" do
|
89
120
|
specify do
|
90
121
|
get 'http://www.example.org/public/test.pdf'
|
91
|
-
expect(last_response.headers["
|
122
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
92
123
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
93
124
|
end
|
94
125
|
end
|
@@ -96,7 +127,7 @@ describe PDFKit::Middleware do
|
|
96
127
|
context "not matching" do
|
97
128
|
specify do
|
98
129
|
get 'http://www.example.org/secret/test.pdf'
|
99
|
-
expect(last_response.headers["
|
130
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
100
131
|
expect(last_response.body).to eq("Hello world!")
|
101
132
|
end
|
102
133
|
end
|
@@ -110,7 +141,7 @@ describe PDFKit::Middleware do
|
|
110
141
|
context "matching" do
|
111
142
|
specify do
|
112
143
|
get 'http://www.example.org/public/test.pdf'
|
113
|
-
expect(last_response.headers["
|
144
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
114
145
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
115
146
|
end
|
116
147
|
end
|
@@ -118,7 +149,7 @@ describe PDFKit::Middleware do
|
|
118
149
|
context "not matching" do
|
119
150
|
specify do
|
120
151
|
get 'http://www.example.org/secret/test.pdf'
|
121
|
-
expect(last_response.headers["
|
152
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
122
153
|
expect(last_response.body).to eq("Hello world!")
|
123
154
|
end
|
124
155
|
end
|
@@ -130,7 +161,7 @@ describe PDFKit::Middleware do
|
|
130
161
|
context "matching" do
|
131
162
|
specify do
|
132
163
|
get 'http://www.example.org/public/test.pdf'
|
133
|
-
expect(last_response.headers["
|
164
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
134
165
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
135
166
|
end
|
136
167
|
end
|
@@ -138,7 +169,7 @@ describe PDFKit::Middleware do
|
|
138
169
|
context "not matching" do
|
139
170
|
specify do
|
140
171
|
get 'http://www.example.org/secret/test.pdf'
|
141
|
-
expect(last_response.headers["
|
172
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
142
173
|
expect(last_response.body).to eq("Hello world!")
|
143
174
|
end
|
144
175
|
end
|
@@ -156,7 +187,7 @@ describe PDFKit::Middleware do
|
|
156
187
|
context "matching" do
|
157
188
|
specify do
|
158
189
|
get 'http://www.example.org/public/test.pdf'
|
159
|
-
expect(last_response.headers["
|
190
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
160
191
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
161
192
|
end
|
162
193
|
end
|
@@ -164,7 +195,7 @@ describe PDFKit::Middleware do
|
|
164
195
|
context "not matching" do
|
165
196
|
specify do
|
166
197
|
get 'http://www.example.org/secret/test.pdf'
|
167
|
-
expect(last_response.headers["
|
198
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
168
199
|
expect(last_response.body).to eq("Hello world!")
|
169
200
|
end
|
170
201
|
end
|
@@ -176,7 +207,7 @@ describe PDFKit::Middleware do
|
|
176
207
|
context "matching" do
|
177
208
|
specify do
|
178
209
|
get 'http://www.example.org/public/test.pdf'
|
179
|
-
expect(last_response.headers["
|
210
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
180
211
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
181
212
|
end
|
182
213
|
end
|
@@ -184,7 +215,7 @@ describe PDFKit::Middleware do
|
|
184
215
|
context "not matching" do
|
185
216
|
specify do
|
186
217
|
get 'http://www.example.org/secret/test.pdf'
|
187
|
-
expect(last_response.headers["
|
218
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
188
219
|
expect(last_response.body).to eq("Hello world!")
|
189
220
|
end
|
190
221
|
end
|
@@ -198,7 +229,7 @@ describe PDFKit::Middleware do
|
|
198
229
|
context "matching" do
|
199
230
|
specify do
|
200
231
|
get 'http://www.example.org/public/test.pdf'
|
201
|
-
expect(last_response.headers["
|
232
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
202
233
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
203
234
|
end
|
204
235
|
end
|
@@ -206,7 +237,7 @@ describe PDFKit::Middleware do
|
|
206
237
|
context "not matching" do
|
207
238
|
specify do
|
208
239
|
get 'http://www.example.org/secret/test.pdf'
|
209
|
-
expect(last_response.headers["
|
240
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
210
241
|
expect(last_response.body).to eq("Hello world!")
|
211
242
|
end
|
212
243
|
end
|
@@ -218,7 +249,7 @@ describe PDFKit::Middleware do
|
|
218
249
|
context "matching" do
|
219
250
|
specify do
|
220
251
|
get 'http://www.example.org/public/test.pdf'
|
221
|
-
expect(last_response.headers["
|
252
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
222
253
|
expect(last_response.body.bytesize).to eq(PDFKit.new("Hello world!").to_pdf.bytesize)
|
223
254
|
end
|
224
255
|
end
|
@@ -226,7 +257,7 @@ describe PDFKit::Middleware do
|
|
226
257
|
context "not matching" do
|
227
258
|
specify do
|
228
259
|
get 'http://www.example.org/secret/test.pdf'
|
229
|
-
expect(last_response.headers["
|
260
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
230
261
|
expect(last_response.body).to eq("Hello world!")
|
231
262
|
end
|
232
263
|
end
|
@@ -236,22 +267,22 @@ describe PDFKit::Middleware do
|
|
236
267
|
end
|
237
268
|
|
238
269
|
describe "saving generated pdf to disk" do
|
239
|
-
|
270
|
+
before do
|
240
271
|
#make sure tests don't find an old test_save.pdf
|
241
|
-
File.delete('spec/test_save.pdf') if File.
|
242
|
-
expect(File.
|
243
|
-
|
272
|
+
File.delete('spec/test_save.pdf') if File.exist?('spec/test_save.pdf')
|
273
|
+
expect(File.exist?('spec/test_save.pdf')).to eq(false)
|
274
|
+
end
|
244
275
|
|
245
276
|
context "when header PDFKit-save-pdf is present" do
|
246
|
-
it "
|
247
|
-
|
277
|
+
it "saves the .pdf to disk" do
|
278
|
+
headers = { 'PDFKit-save-pdf' => 'spec/test_save.pdf' }
|
248
279
|
mock_app({}, {only: '/public'}, headers)
|
249
|
-
|
250
|
-
expect(File.
|
251
|
-
|
280
|
+
get 'http://www.example.org/public/test_save.pdf'
|
281
|
+
expect(File.exist?('spec/test_save.pdf')).to eq(true)
|
282
|
+
end
|
252
283
|
|
253
|
-
it "
|
254
|
-
|
284
|
+
it "does not raise when target directory does not exist" do
|
285
|
+
headers = { 'PDFKit-save-pdf' => '/this/dir/does/not/exist/spec/test_save.pdf' }
|
255
286
|
mock_app({}, {only: '/public'}, headers)
|
256
287
|
expect {
|
257
288
|
get 'http://www.example.com/public/test_save.pdf'
|
@@ -260,17 +291,162 @@ describe PDFKit::Middleware do
|
|
260
291
|
end
|
261
292
|
|
262
293
|
context "when header PDFKit-save-pdf is not present" do
|
263
|
-
it "
|
294
|
+
it "does not saved the .pdf to disk" do
|
264
295
|
mock_app({}, {only: '/public'}, {} )
|
265
|
-
|
266
|
-
expect(File.
|
296
|
+
get 'http://www.example.org/public/test_save.pdf'
|
297
|
+
expect(File.exist?('spec/test_save.pdf')).to eq(false)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
describe 'javascript delay' do
|
303
|
+
context 'when header PDFKit-javascript-delay is present' do
|
304
|
+
it 'passes header value through to PDFKit initialiser' do
|
305
|
+
expect(PDFKit).to receive(:new).with('Hello world!', {
|
306
|
+
root_url: 'http://www.example.com/', protocol: 'http', javascript_delay: 4321
|
307
|
+
}).and_call_original
|
308
|
+
|
309
|
+
headers = { 'PDFKit-javascript-delay' => '4321' }
|
310
|
+
mock_app({}, { only: '/public' }, headers)
|
311
|
+
get 'http://www.example.com/public/test_save.pdf'
|
312
|
+
end
|
313
|
+
|
314
|
+
it 'handles invalid content in header' do
|
315
|
+
expect(PDFKit).to receive(:new).with('Hello world!', {
|
316
|
+
root_url: 'http://www.example.com/', protocol: 'http', javascript_delay: 0
|
317
|
+
}).and_call_original
|
318
|
+
|
319
|
+
headers = { 'PDFKit-javascript-delay' => 'invalid' }
|
320
|
+
mock_app({}, { only: '/public' }, headers)
|
321
|
+
get 'http://www.example.com/public/test_save.pdf'
|
322
|
+
end
|
323
|
+
|
324
|
+
it 'overrides default option' do
|
325
|
+
expect(PDFKit).to receive(:new).with('Hello world!', {
|
326
|
+
root_url: 'http://www.example.com/', protocol: 'http', javascript_delay: 4321
|
327
|
+
}).and_call_original
|
328
|
+
|
329
|
+
headers = { 'PDFKit-javascript-delay' => '4321' }
|
330
|
+
mock_app({ javascript_delay: 1234 }, { only: '/public' }, headers)
|
331
|
+
get 'http://www.example.com/public/test_save.pdf'
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context 'when header PDFKit-javascript-delay is not present' do
|
336
|
+
it 'passes through default option' do
|
337
|
+
expect(PDFKit).to receive(:new).with('Hello world!', {
|
338
|
+
root_url: 'http://www.example.com/', protocol: 'http', javascript_delay: 1234
|
339
|
+
}).and_call_original
|
340
|
+
|
341
|
+
mock_app({ javascript_delay: 1234 }, { only: '/public' }, { })
|
342
|
+
get 'http://www.example.com/public/test_save.pdf'
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
|
347
|
+
describe ":disposition" do
|
348
|
+
describe "doesn't overwrite existing value" do
|
349
|
+
let(:headers) do
|
350
|
+
super().merge({
|
351
|
+
'content-disposition' => 'attachment; filename=report-20200101.pdf'
|
352
|
+
})
|
353
|
+
end
|
354
|
+
|
355
|
+
specify do
|
356
|
+
mock_app({}, { :disposition => 'inline' })
|
357
|
+
get 'http://www.example.org/public/test.pdf'
|
358
|
+
expect(last_response.headers["content-disposition"]).to eq('attachment; filename=report-20200101.pdf')
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
describe "inline or blank" do
|
363
|
+
context "default" do
|
364
|
+
specify do
|
365
|
+
mock_app
|
366
|
+
get 'http://www.example.org/public/test.pdf'
|
367
|
+
expect(last_response.headers["content-disposition"]).to eq("inline")
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
context "inline" do
|
372
|
+
specify do
|
373
|
+
mock_app({}, { :disposition => 'inline' })
|
374
|
+
get 'http://www.example.org/public/test.pdf'
|
375
|
+
expect(last_response.headers["content-disposition"]).to eq("inline")
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
describe "attachment" do
|
381
|
+
context "attachment" do
|
382
|
+
specify do
|
383
|
+
mock_app({}, { :disposition => 'attachment' })
|
384
|
+
get 'http://www.example.org/public/test.pdf'
|
385
|
+
expect(last_response.headers["content-disposition"]).to eq("attachment")
|
386
|
+
end
|
387
|
+
end
|
388
|
+
|
389
|
+
context "attachment with filename" do
|
390
|
+
specify do
|
391
|
+
mock_app({}, { :disposition => 'attachment; filename=report.pdf' })
|
392
|
+
get 'http://www.example.org/public/test.pdf'
|
393
|
+
expect(last_response.headers["content-disposition"]).to eq("attachment; filename=report.pdf")
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
describe "error handling" do
|
400
|
+
let(:error) { StandardError.new("Something went wrong") }
|
401
|
+
|
402
|
+
context "errors raised by PDF generation" do
|
403
|
+
specify do
|
404
|
+
mock_app
|
405
|
+
allow(PDFKit).to receive(:new).and_raise(error)
|
406
|
+
get 'http://www.example.org/public/test.pdf'
|
407
|
+
expect(last_response.status).to eq(500)
|
408
|
+
expect(last_response.body).to eq(error.message)
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
context "errors raised upstream" do
|
413
|
+
specify do
|
414
|
+
mock_app
|
415
|
+
allow(@app).to receive(:call).and_raise(error)
|
416
|
+
|
417
|
+
expect {
|
418
|
+
get 'http://www.example.org/public/test.pdf'
|
419
|
+
}.to raise_error(error)
|
267
420
|
end
|
268
421
|
end
|
269
422
|
end
|
270
423
|
end
|
271
424
|
|
272
|
-
|
273
|
-
|
425
|
+
describe "content type header" do
|
426
|
+
before { mock_app }
|
427
|
+
|
428
|
+
context "lower case" do
|
429
|
+
specify "header gets correctly updated" do
|
430
|
+
get 'http://www.example.org/public/test.pdf'
|
431
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
432
|
+
end
|
433
|
+
end
|
434
|
+
|
435
|
+
context "mixed case" do
|
436
|
+
let(:headers) do
|
437
|
+
{'Content-Type' => "text/html"}
|
438
|
+
end
|
439
|
+
|
440
|
+
specify "header gets correctly updated" do
|
441
|
+
pending("this test only applies to rack 2.x and is rejected by rack 3.x") if Rack.release >= "3.0.0"
|
442
|
+
get 'http://www.example.org/public/test.pdf'
|
443
|
+
expect(last_response.headers["Content-Type"]).to eq("application/pdf")
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
describe "remove .pdf from PATH_INFO and REQUEST_URI" do
|
449
|
+
before { mock_app }
|
274
450
|
|
275
451
|
context "matching" do
|
276
452
|
|
@@ -293,7 +469,7 @@ describe PDFKit::Middleware do
|
|
293
469
|
main_app = lambda { |env|
|
294
470
|
@env = env
|
295
471
|
@env['SCRIPT_NAME'] = '/example.org'
|
296
|
-
headers = {'
|
472
|
+
headers = {'content-type' => "text/html"}
|
297
473
|
[200, headers, @body || ['Hello world!']]
|
298
474
|
}
|
299
475
|
|
@@ -319,80 +495,37 @@ describe PDFKit::Middleware do
|
|
319
495
|
end
|
320
496
|
end
|
321
497
|
|
322
|
-
describe "#
|
498
|
+
describe "#root_url and #protocol" do
|
323
499
|
before do
|
324
500
|
@pdf = PDFKit::Middleware.new({})
|
325
501
|
@env = { 'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com' }
|
326
502
|
end
|
327
503
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
end
|
333
|
-
|
334
|
-
it "should correctly parse relative url with double quotes" do
|
335
|
-
@body = %{<link href="/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />}
|
336
|
-
body = @pdf.send :translate_paths, @body, @env
|
337
|
-
expect(body).to eq("<link href=\"http://example.com/stylesheets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />")
|
338
|
-
end
|
504
|
+
context 'when root_url is not configured' do
|
505
|
+
it "infers the root_url and protocol from the environment" do
|
506
|
+
root_url = @pdf.send(:root_url, @env)
|
507
|
+
protocol = @pdf.send(:protocol, @env)
|
339
508
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
expect(body).to eq("<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,600' rel='stylesheet' type='text/css'>")
|
344
|
-
end
|
345
|
-
|
346
|
-
it "should correctly parse multiple tags where first one is root url" do
|
347
|
-
@body = %{<a href='/'><img src='/logo.jpg' ></a>}
|
348
|
-
body = @pdf.send :translate_paths, @body, @env
|
349
|
-
body.should == "<a href='http://example.com/'><img src='http://example.com/logo.jpg' ></a>"
|
350
|
-
end
|
351
|
-
|
352
|
-
it "should return the body even if there are no valid substitutions found" do
|
353
|
-
@body = "NO MATCH"
|
354
|
-
body = @pdf.send :translate_paths, @body, @env
|
355
|
-
expect(body).to eq("NO MATCH")
|
509
|
+
expect(root_url).to eq('http://example.com/')
|
510
|
+
expect(protocol).to eq('http')
|
511
|
+
end
|
356
512
|
end
|
357
|
-
end
|
358
513
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
514
|
+
context 'when root_url is configured' do
|
515
|
+
before do
|
516
|
+
PDFKit.configuration.root_url = 'http://example.net/'
|
517
|
+
end
|
518
|
+
after do
|
519
|
+
PDFKit.configuration.root_url = nil
|
365
520
|
end
|
366
|
-
end
|
367
521
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
expect(body).to eq("<html><head><link href='http://example.net/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src=\"http://example.net/test.png\" /></body></html>")
|
372
|
-
end
|
522
|
+
it "takes the root_url from the configuration, and infers the protocol from the environment" do
|
523
|
+
root_url = @pdf.send(:root_url, @env)
|
524
|
+
protocol = @pdf.send(:protocol, @env)
|
373
525
|
|
374
|
-
|
375
|
-
|
376
|
-
config.root_url = nil
|
526
|
+
expect(root_url).to eq('http://example.net/')
|
527
|
+
expect(protocol).to eq('http')
|
377
528
|
end
|
378
529
|
end
|
379
530
|
end
|
380
|
-
|
381
|
-
it "should not get stuck rendering each request as pdf" do
|
382
|
-
mock_app
|
383
|
-
# false by default. No requests.
|
384
|
-
expect(@app.send(:rendering_pdf?)).to eq(false)
|
385
|
-
|
386
|
-
# Remain false on a normal request
|
387
|
-
get 'http://www.example.org/public/file'
|
388
|
-
expect(@app.send(:rendering_pdf?)).to eq(false)
|
389
|
-
|
390
|
-
# Return true on a pdf request.
|
391
|
-
get 'http://www.example.org/public/file.pdf'
|
392
|
-
expect(@app.send(:rendering_pdf?)).to eq(true)
|
393
|
-
|
394
|
-
# Restore to false on any non-pdf request.
|
395
|
-
get 'http://www.example.org/public/file'
|
396
|
-
expect(@app.send(:rendering_pdf?)).to eq(false)
|
397
|
-
end
|
398
531
|
end
|
data/spec/os_spec.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'spec_helper'
|
5
|
+
require 'rbconfig'
|
6
|
+
|
7
|
+
describe 'OS' do
|
8
|
+
subject { PDFKit::OS }
|
9
|
+
|
10
|
+
describe 'host_is_windows?' do
|
11
|
+
it 'is callable' do
|
12
|
+
expect(subject).to respond_to(:host_is_windows?)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_is_windows(bool, host_os)
|
16
|
+
allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return(host_os)
|
17
|
+
|
18
|
+
expect(subject.host_is_windows?).to be bool
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'returns true if the host_os is set to "mswin"' do
|
22
|
+
test_is_windows(true, 'mswin')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'returns true if the host_os is set to "msys"' do
|
26
|
+
test_is_windows(true, 'msys')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'returns false if the host_os is set to "linux-gnu"' do
|
30
|
+
test_is_windows(false, 'linux-gnu')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'returns false if the host_os is set to "darwin14.1.0"' do
|
34
|
+
test_is_windows(false, 'darwin14.1.0')
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'shell_escape_for_os' do
|
39
|
+
it 'is callable' do
|
40
|
+
expect(subject).to respond_to(:shell_escape_for_os)
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'calls shelljoin on linux' do
|
44
|
+
args = double(:shelljoin)
|
45
|
+
allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('linux-gnu')
|
46
|
+
|
47
|
+
expect(args).to receive(:shelljoin)
|
48
|
+
PDFKit::OS.shell_escape_for_os(args)
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'calls shelljoin on darwin14.1.10' do
|
52
|
+
args = double(:shelljoin)
|
53
|
+
allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('darwin14.1.10-gnu')
|
54
|
+
|
55
|
+
expect(args).to receive(:shelljoin)
|
56
|
+
PDFKit::OS.shell_escape_for_os(args)
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'escapes special characters on Windows' do
|
60
|
+
args = ['foo|bar', 'biz(baz)', 'foo<baz>bar', 'hello^world&goodbye']
|
61
|
+
allow(RbConfig::CONFIG).to receive(:[]).with('host_os').and_return('mswin')
|
62
|
+
|
63
|
+
escaped_args = PDFKit::OS.shell_escape_for_os(args)
|
64
|
+
expect(escaped_args).to eq('foo^|bar biz^(baz^) foo^<baz^>bar hello^^world^&goodbye')
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|