my_pdfkit 0.1.0.0
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/.document +5 -0
- data/.github/workflows/release-drafter.yml +19 -0
- data/.github/workflows/stale.yml +19 -0
- data/.github/workflows/test.yml +71 -0
- data/.gitignore +25 -0
- data/.rspec +1 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +46 -0
- data/CHANGELOG.md +154 -0
- data/Gemfile +12 -0
- data/LICENSE +20 -0
- data/POST_INSTALL +14 -0
- data/README.md +190 -0
- data/Rakefile +24 -0
- data/lib/my_pdfkit/configuration.rb +89 -0
- data/lib/my_pdfkit/html_preprocessor.rb +25 -0
- data/lib/my_pdfkit/middleware.rb +117 -0
- data/lib/my_pdfkit/os.rb +21 -0
- data/lib/my_pdfkit/pdfkit.rb +153 -0
- data/lib/my_pdfkit/source.rb +52 -0
- data/lib/my_pdfkit/version.rb +5 -0
- data/lib/my_pdfkit/wkhtmltopdf.rb +82 -0
- data/lib/my_pdfkit.rb +10 -0
- data/my_pdfkit.gemspec +33 -0
- data/spec/configuration_spec.rb +171 -0
- data/spec/fixtures/example.css +1 -0
- data/spec/fixtures/example.html +5 -0
- data/spec/fixtures/example_with_hex_symbol.css +3 -0
- data/spec/html_preprocessor_spec.rb +71 -0
- data/spec/middleware_spec.rb +531 -0
- data/spec/os_spec.rb +67 -0
- data/spec/pdfkit_spec.rb +608 -0
- data/spec/source_spec.rb +125 -0
- data/spec/spec_helper.rb +33 -0
- metadata +175 -0
@@ -0,0 +1,531 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
def app; Rack::Lint.new(@app); end
|
6
|
+
|
7
|
+
def mock_app(options = {}, conditions = {}, custom_headers = {})
|
8
|
+
main_app = lambda { |env|
|
9
|
+
@env = env
|
10
|
+
full_headers = headers.merge custom_headers
|
11
|
+
[200, full_headers, @body || ['Hello world!']]
|
12
|
+
}
|
13
|
+
|
14
|
+
builder = Rack::Builder.new
|
15
|
+
builder.use MyPDFKit::Middleware, options, conditions
|
16
|
+
builder.run main_app
|
17
|
+
@app = builder.to_app
|
18
|
+
end
|
19
|
+
|
20
|
+
describe MyPDFKit::Middleware do
|
21
|
+
let(:headers) do
|
22
|
+
{'content-type' => "text/html"}
|
23
|
+
end
|
24
|
+
|
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
|
+
|
55
|
+
describe "caching" do
|
56
|
+
let(:headers) do
|
57
|
+
{
|
58
|
+
'content-type' => "text/html",
|
59
|
+
'etag' => 'foo',
|
60
|
+
'cache-control' => 'max-age=2592000, public'
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
context "by default" do
|
65
|
+
before { mock_app }
|
66
|
+
|
67
|
+
it "deletes etag" do
|
68
|
+
get 'http://www.example.org/public/test.pdf'
|
69
|
+
expect(last_response.headers["etag"]).to be_nil
|
70
|
+
end
|
71
|
+
it "deletes cache-control" do
|
72
|
+
get 'http://www.example.org/public/test.pdf'
|
73
|
+
expect(last_response.headers["cache-control"]).to be_nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when on" do
|
78
|
+
before { mock_app({}, :caching => true) }
|
79
|
+
|
80
|
+
it "preserves etag" do
|
81
|
+
get 'http://www.example.org/public/test.pdf'
|
82
|
+
expect(last_response.headers["etag"]).not_to be_nil
|
83
|
+
end
|
84
|
+
|
85
|
+
it "preserves cache-control" do
|
86
|
+
get 'http://www.example.org/public/test.pdf'
|
87
|
+
expect(last_response.headers["cache-control"]).not_to be_nil
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "conditions" do
|
93
|
+
describe ":only" do
|
94
|
+
|
95
|
+
describe "regex" do
|
96
|
+
describe "one" do
|
97
|
+
before { mock_app({}, :only => %r[^/public]) }
|
98
|
+
|
99
|
+
context "matching" do
|
100
|
+
specify do
|
101
|
+
get 'http://www.example.org/public/test.pdf'
|
102
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
103
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
context "not matching" do
|
108
|
+
specify do
|
109
|
+
get 'http://www.example.org/secret/test.pdf'
|
110
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
111
|
+
expect(last_response.body).to eq("Hello world!")
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end # one regex
|
115
|
+
|
116
|
+
describe "multiple" do
|
117
|
+
before { mock_app({}, :only => [%r[^/invoice], %r[^/public]]) }
|
118
|
+
|
119
|
+
context "matching" do
|
120
|
+
specify do
|
121
|
+
get 'http://www.example.org/public/test.pdf'
|
122
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
123
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
context "not matching" do
|
128
|
+
specify do
|
129
|
+
get 'http://www.example.org/secret/test.pdf'
|
130
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
131
|
+
expect(last_response.body).to eq("Hello world!")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end # multiple regex
|
135
|
+
end # regex
|
136
|
+
|
137
|
+
describe "string" do
|
138
|
+
describe "one" do
|
139
|
+
before { mock_app({}, :only => '/public') }
|
140
|
+
|
141
|
+
context "matching" do
|
142
|
+
specify do
|
143
|
+
get 'http://www.example.org/public/test.pdf'
|
144
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
145
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
context "not matching" do
|
150
|
+
specify do
|
151
|
+
get 'http://www.example.org/secret/test.pdf'
|
152
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
153
|
+
expect(last_response.body).to eq("Hello world!")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end # one string
|
157
|
+
|
158
|
+
describe "multiple" do
|
159
|
+
before { mock_app({}, :only => ['/invoice', '/public']) }
|
160
|
+
|
161
|
+
context "matching" do
|
162
|
+
specify do
|
163
|
+
get 'http://www.example.org/public/test.pdf'
|
164
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
165
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "not matching" do
|
170
|
+
specify do
|
171
|
+
get 'http://www.example.org/secret/test.pdf'
|
172
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
173
|
+
expect(last_response.body).to eq("Hello world!")
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end # multiple string
|
177
|
+
end # string
|
178
|
+
|
179
|
+
end
|
180
|
+
|
181
|
+
describe ":except" do
|
182
|
+
|
183
|
+
describe "regex" do
|
184
|
+
describe "one" do
|
185
|
+
before { mock_app({}, :except => %r[^/secret]) }
|
186
|
+
|
187
|
+
context "matching" do
|
188
|
+
specify do
|
189
|
+
get 'http://www.example.org/public/test.pdf'
|
190
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
191
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context "not matching" do
|
196
|
+
specify do
|
197
|
+
get 'http://www.example.org/secret/test.pdf'
|
198
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
199
|
+
expect(last_response.body).to eq("Hello world!")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end # one regex
|
203
|
+
|
204
|
+
describe "multiple" do
|
205
|
+
before { mock_app({}, :except => [%r[^/prawn], %r[^/secret]]) }
|
206
|
+
|
207
|
+
context "matching" do
|
208
|
+
specify do
|
209
|
+
get 'http://www.example.org/public/test.pdf'
|
210
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
211
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
context "not matching" do
|
216
|
+
specify do
|
217
|
+
get 'http://www.example.org/secret/test.pdf'
|
218
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
219
|
+
expect(last_response.body).to eq("Hello world!")
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end # multiple regex
|
223
|
+
end # regex
|
224
|
+
|
225
|
+
describe "string" do
|
226
|
+
describe "one" do
|
227
|
+
before { mock_app({}, :except => '/secret') }
|
228
|
+
|
229
|
+
context "matching" do
|
230
|
+
specify do
|
231
|
+
get 'http://www.example.org/public/test.pdf'
|
232
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
233
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "not matching" do
|
238
|
+
specify do
|
239
|
+
get 'http://www.example.org/secret/test.pdf'
|
240
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
241
|
+
expect(last_response.body).to eq("Hello world!")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end # one string
|
245
|
+
|
246
|
+
describe "multiple" do
|
247
|
+
before { mock_app({}, :except => ['/prawn', '/secret']) }
|
248
|
+
|
249
|
+
context "matching" do
|
250
|
+
specify do
|
251
|
+
get 'http://www.example.org/public/test.pdf'
|
252
|
+
expect(last_response.headers["content-type"]).to eq("application/pdf")
|
253
|
+
expect(last_response.body.bytesize).to eq(MyPDFKit.new("Hello world!").to_pdf.bytesize)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
context "not matching" do
|
258
|
+
specify do
|
259
|
+
get 'http://www.example.org/secret/test.pdf'
|
260
|
+
expect(last_response.headers["content-type"]).to eq("text/html")
|
261
|
+
expect(last_response.body).to eq("Hello world!")
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end # multiple string
|
265
|
+
end # string
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
describe "saving generated pdf to disk" do
|
270
|
+
before do
|
271
|
+
#make sure tests don't find an old test_save.pdf
|
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
|
275
|
+
|
276
|
+
context "when header MyPDFKit-save-pdf is present" do
|
277
|
+
it "saves the .pdf to disk" do
|
278
|
+
headers = { 'MyPDFKit-save-pdf' => 'spec/test_save.pdf' }
|
279
|
+
mock_app({}, {only: '/public'}, headers)
|
280
|
+
get 'http://www.example.org/public/test_save.pdf'
|
281
|
+
expect(File.exist?('spec/test_save.pdf')).to eq(true)
|
282
|
+
end
|
283
|
+
|
284
|
+
it "does not raise when target directory does not exist" do
|
285
|
+
headers = { 'MyPDFKit-save-pdf' => '/this/dir/does/not/exist/spec/test_save.pdf' }
|
286
|
+
mock_app({}, {only: '/public'}, headers)
|
287
|
+
expect {
|
288
|
+
get 'http://www.example.com/public/test_save.pdf'
|
289
|
+
}.not_to raise_error
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
context "when header MyPDFKit-save-pdf is not present" do
|
294
|
+
it "does not saved the .pdf to disk" do
|
295
|
+
mock_app({}, {only: '/public'}, {} )
|
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 MyPDFKit-javascript-delay is present' do
|
304
|
+
it 'passes header value through to MyPDFKit initialiser' do
|
305
|
+
expect(MyPDFKit).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 = { 'MyPDFKit-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(MyPDFKit).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 = { 'MyPDFKit-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(MyPDFKit).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 = { 'MyPDFKit-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 MyPDFKit-javascript-delay is not present' do
|
336
|
+
it 'passes through default option' do
|
337
|
+
expect(MyPDFKit).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(MyPDFKit).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)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
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 }
|
450
|
+
|
451
|
+
context "matching" do
|
452
|
+
|
453
|
+
specify do
|
454
|
+
get 'http://www.example.org/public/file.pdf'
|
455
|
+
expect(@env["PATH_INFO"]).to eq("/public/file")
|
456
|
+
expect(@env["REQUEST_URI"]).to eq("/public/file")
|
457
|
+
expect(@env["SCRIPT_NAME"]).to be_empty
|
458
|
+
end
|
459
|
+
specify do
|
460
|
+
get 'http://www.example.org/public/file.txt'
|
461
|
+
expect(@env["PATH_INFO"]).to eq("/public/file.txt")
|
462
|
+
expect(@env["REQUEST_URI"]).to be_nil
|
463
|
+
expect(@env["SCRIPT_NAME"]).to be_empty
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
context "subdomain matching" do
|
468
|
+
before do
|
469
|
+
main_app = lambda { |env|
|
470
|
+
@env = env
|
471
|
+
@env['SCRIPT_NAME'] = '/example.org'
|
472
|
+
headers = {'content-type' => "text/html"}
|
473
|
+
[200, headers, @body || ['Hello world!']]
|
474
|
+
}
|
475
|
+
|
476
|
+
builder = Rack::Builder.new
|
477
|
+
builder.use MyPDFKit::Middleware
|
478
|
+
builder.run main_app
|
479
|
+
@app = builder.to_app
|
480
|
+
end
|
481
|
+
specify do
|
482
|
+
get 'http://example.org/sub/public/file.pdf'
|
483
|
+
expect(@env["PATH_INFO"]).to eq("/sub/public/file")
|
484
|
+
expect(@env["REQUEST_URI"]).to eq("/sub/public/file")
|
485
|
+
expect(@env["SCRIPT_NAME"]).to eq("/example.org")
|
486
|
+
end
|
487
|
+
specify do
|
488
|
+
get 'http://example.org/sub/public/file.txt'
|
489
|
+
expect(@env["PATH_INFO"]).to eq("/sub/public/file.txt")
|
490
|
+
expect(@env["REQUEST_URI"]).to be_nil
|
491
|
+
expect(@env["SCRIPT_NAME"]).to eq("/example.org")
|
492
|
+
end
|
493
|
+
end
|
494
|
+
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
498
|
+
describe "#root_url and #protocol" do
|
499
|
+
before do
|
500
|
+
@pdf = MyPDFKit::Middleware.new({})
|
501
|
+
@env = { 'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com' }
|
502
|
+
end
|
503
|
+
|
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)
|
508
|
+
|
509
|
+
expect(root_url).to eq('http://example.com/')
|
510
|
+
expect(protocol).to eq('http')
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
context 'when root_url is configured' do
|
515
|
+
before do
|
516
|
+
MyPDFKit.configuration.root_url = 'http://example.net/'
|
517
|
+
end
|
518
|
+
after do
|
519
|
+
MyPDFKit.configuration.root_url = nil
|
520
|
+
end
|
521
|
+
|
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)
|
525
|
+
|
526
|
+
expect(root_url).to eq('http://example.net/')
|
527
|
+
expect(protocol).to eq('http')
|
528
|
+
end
|
529
|
+
end
|
530
|
+
end
|
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 { MyPDFKit::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
|
+
MyPDFKit::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
|
+
MyPDFKit::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 = MyPDFKit::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
|