hssc_pdfkit 0.5.4
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.
- data/.document +5 -0
- data/.gitignore +23 -0
- data/.rspec +1 -0
- data/.travis.yml +4 -0
- data/CHANGELOG.md +36 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +40 -0
- data/LICENSE +20 -0
- data/POST_INSTALL +14 -0
- data/README.md +146 -0
- data/Rakefile +24 -0
- data/lib/pdfkit/configuration.rb +43 -0
- data/lib/pdfkit/middleware.rb +94 -0
- data/lib/pdfkit/pdfkit.rb +143 -0
- data/lib/pdfkit/source.rb +23 -0
- data/lib/pdfkit/version.rb +3 -0
- data/lib/pdfkit.rb +4 -0
- data/pdfkit.gemspec +30 -0
- data/spec/fixtures/example.css +1 -0
- data/spec/fixtures/example.html +5 -0
- data/spec/middleware_spec.rb +314 -0
- data/spec/pdfkit_spec.rb +255 -0
- data/spec/source_spec.rb +78 -0
- data/spec/spec_helper.rb +15 -0
- metadata +189 -0
@@ -0,0 +1,314 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
def app; Rack::Lint.new(@app); end
|
4
|
+
|
5
|
+
def mock_app(options = {}, conditions = {})
|
6
|
+
main_app = lambda { |env|
|
7
|
+
@env = env
|
8
|
+
headers = {'Content-Type' => "text/html"}
|
9
|
+
[200, headers, @body || ['Hello world!']]
|
10
|
+
}
|
11
|
+
|
12
|
+
builder = Rack::Builder.new
|
13
|
+
builder.use PDFKit::Middleware, options, conditions
|
14
|
+
builder.run main_app
|
15
|
+
@app = builder.to_app
|
16
|
+
end
|
17
|
+
|
18
|
+
describe PDFKit::Middleware do
|
19
|
+
|
20
|
+
describe "#call" do
|
21
|
+
describe "conditions" do
|
22
|
+
describe ":only" do
|
23
|
+
|
24
|
+
describe "regex" do
|
25
|
+
describe "one" do
|
26
|
+
before { mock_app({}, :only => %r[^/public]) }
|
27
|
+
|
28
|
+
context "matching" do
|
29
|
+
specify do
|
30
|
+
get 'http://www.example.org/public/test.pdf'
|
31
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
32
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "not matching" do
|
37
|
+
specify do
|
38
|
+
get 'http://www.example.org/secret/test.pdf'
|
39
|
+
last_response.headers["Content-Type"].should == "text/html"
|
40
|
+
last_response.body.should == "Hello world!"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end # one regex
|
44
|
+
|
45
|
+
describe "multiple" do
|
46
|
+
before { mock_app({}, :only => [%r[^/invoice], %r[^/public]]) }
|
47
|
+
|
48
|
+
context "matching" do
|
49
|
+
specify do
|
50
|
+
get 'http://www.example.org/public/test.pdf'
|
51
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
52
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "not matching" do
|
57
|
+
specify do
|
58
|
+
get 'http://www.example.org/secret/test.pdf'
|
59
|
+
last_response.headers["Content-Type"].should == "text/html"
|
60
|
+
last_response.body.should == "Hello world!"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end # multiple regex
|
64
|
+
end # regex
|
65
|
+
|
66
|
+
describe "string" do
|
67
|
+
describe "one" do
|
68
|
+
before { mock_app({}, :only => '/public') }
|
69
|
+
|
70
|
+
context "matching" do
|
71
|
+
specify do
|
72
|
+
get 'http://www.example.org/public/test.pdf'
|
73
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
74
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
context "not matching" do
|
79
|
+
specify do
|
80
|
+
get 'http://www.example.org/secret/test.pdf'
|
81
|
+
last_response.headers["Content-Type"].should == "text/html"
|
82
|
+
last_response.body.should == "Hello world!"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end # one string
|
86
|
+
|
87
|
+
describe "multiple" do
|
88
|
+
before { mock_app({}, :only => ['/invoice', '/public']) }
|
89
|
+
|
90
|
+
context "matching" do
|
91
|
+
specify do
|
92
|
+
get 'http://www.example.org/public/test.pdf'
|
93
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
94
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "not matching" do
|
99
|
+
specify do
|
100
|
+
get 'http://www.example.org/secret/test.pdf'
|
101
|
+
last_response.headers["Content-Type"].should == "text/html"
|
102
|
+
last_response.body.should == "Hello world!"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end # multiple string
|
106
|
+
end # string
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
describe ":except" do
|
111
|
+
|
112
|
+
describe "regex" do
|
113
|
+
describe "one" do
|
114
|
+
before { mock_app({}, :except => %r[^/secret]) }
|
115
|
+
|
116
|
+
context "matching" do
|
117
|
+
specify do
|
118
|
+
get 'http://www.example.org/public/test.pdf'
|
119
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
120
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context "not matching" do
|
125
|
+
specify do
|
126
|
+
get 'http://www.example.org/secret/test.pdf'
|
127
|
+
last_response.headers["Content-Type"].should == "text/html"
|
128
|
+
last_response.body.should == "Hello world!"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end # one regex
|
132
|
+
|
133
|
+
describe "multiple" do
|
134
|
+
before { mock_app({}, :except => [%r[^/prawn], %r[^/secret]]) }
|
135
|
+
|
136
|
+
context "matching" do
|
137
|
+
specify do
|
138
|
+
get 'http://www.example.org/public/test.pdf'
|
139
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
140
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "not matching" do
|
145
|
+
specify do
|
146
|
+
get 'http://www.example.org/secret/test.pdf'
|
147
|
+
last_response.headers["Content-Type"].should == "text/html"
|
148
|
+
last_response.body.should == "Hello world!"
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end # multiple regex
|
152
|
+
end # regex
|
153
|
+
|
154
|
+
describe "string" do
|
155
|
+
describe "one" do
|
156
|
+
before { mock_app({}, :except => '/secret') }
|
157
|
+
|
158
|
+
context "matching" do
|
159
|
+
specify do
|
160
|
+
get 'http://www.example.org/public/test.pdf'
|
161
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
162
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
context "not matching" do
|
167
|
+
specify do
|
168
|
+
get 'http://www.example.org/secret/test.pdf'
|
169
|
+
last_response.headers["Content-Type"].should == "text/html"
|
170
|
+
last_response.body.should == "Hello world!"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end # one string
|
174
|
+
|
175
|
+
describe "multiple" do
|
176
|
+
before { mock_app({}, :except => ['/prawn', '/secret']) }
|
177
|
+
|
178
|
+
context "matching" do
|
179
|
+
specify do
|
180
|
+
get 'http://www.example.org/public/test.pdf'
|
181
|
+
last_response.headers["Content-Type"].should == "application/pdf"
|
182
|
+
last_response.body.bytesize.should == PDFKit.new("Hello world!").to_pdf.bytesize
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
context "not matching" do
|
187
|
+
specify do
|
188
|
+
get 'http://www.example.org/secret/test.pdf'
|
189
|
+
last_response.headers["Content-Type"].should == "text/html"
|
190
|
+
last_response.body.should == "Hello world!"
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end # multiple string
|
194
|
+
end # string
|
195
|
+
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
describe "remove .pdf from PATH_INFO and REQUEST_URI" do
|
200
|
+
before { mock_app }
|
201
|
+
|
202
|
+
context "matching" do
|
203
|
+
|
204
|
+
specify do
|
205
|
+
get 'http://www.example.org/public/file.pdf'
|
206
|
+
@env["PATH_INFO"].should == "/public/file"
|
207
|
+
@env["REQUEST_URI"].should == "/public/file"
|
208
|
+
@env["SCRIPT_NAME"].should be_empty
|
209
|
+
end
|
210
|
+
specify do
|
211
|
+
get 'http://www.example.org/public/file.txt'
|
212
|
+
@env["PATH_INFO"].should == "/public/file.txt"
|
213
|
+
@env["REQUEST_URI"].should be_nil
|
214
|
+
@env["SCRIPT_NAME"].should be_empty
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context "subdomain matching" do
|
219
|
+
before do
|
220
|
+
main_app = lambda { |env|
|
221
|
+
@env = env
|
222
|
+
@env['SCRIPT_NAME'] = '/example.org'
|
223
|
+
headers = {'Content-Type' => "text/html"}
|
224
|
+
[200, headers, @body || ['Hello world!']]
|
225
|
+
}
|
226
|
+
|
227
|
+
builder = Rack::Builder.new
|
228
|
+
builder.use PDFKit::Middleware
|
229
|
+
builder.run main_app
|
230
|
+
@app = builder.to_app
|
231
|
+
end
|
232
|
+
specify do
|
233
|
+
get 'http://example.org/sub/public/file.pdf'
|
234
|
+
@env["PATH_INFO"].should == "/sub/public/file"
|
235
|
+
@env["REQUEST_URI"].should == "/sub/public/file"
|
236
|
+
@env["SCRIPT_NAME"].should == "/example.org"
|
237
|
+
end
|
238
|
+
specify do
|
239
|
+
get 'http://example.org/sub/public/file.txt'
|
240
|
+
@env["PATH_INFO"].should == "/sub/public/file.txt"
|
241
|
+
@env["REQUEST_URI"].should be_nil
|
242
|
+
@env["SCRIPT_NAME"].should == "/example.org"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
describe "#translate_paths" do
|
250
|
+
before do
|
251
|
+
@pdf = PDFKit::Middleware.new({})
|
252
|
+
@env = { 'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com' }
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should correctly parse relative url with single quotes" do
|
256
|
+
@body = %{<html><head><link href='/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src="/test.png" /></body></html>}
|
257
|
+
body = @pdf.send :translate_paths, @body, @env
|
258
|
+
body.should == "<html><head><link href='http://example.com/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src=\"http://example.com/test.png\" /></body></html>"
|
259
|
+
end
|
260
|
+
|
261
|
+
it "should correctly parse relative url with double quotes" do
|
262
|
+
@body = %{<link href="/stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />}
|
263
|
+
body = @pdf.send :translate_paths, @body, @env
|
264
|
+
body.should == "<link href=\"http://example.com/stylesheets/application.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should return the body even if there are no valid substitutions found" do
|
268
|
+
@body = "NO MATCH"
|
269
|
+
body = @pdf.send :translate_paths, @body, @env
|
270
|
+
body.should == "NO MATCH"
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
describe "#translate_paths with root_url configuration" do
|
275
|
+
before do
|
276
|
+
@pdf = PDFKit::Middleware.new({})
|
277
|
+
@env = { 'REQUEST_URI' => 'http://example.com/document.pdf', 'rack.url_scheme' => 'http', 'HTTP_HOST' => 'example.com' }
|
278
|
+
PDFKit.configure do |config|
|
279
|
+
config.root_url = "http://example.net/"
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should add the root_url" do
|
284
|
+
@body = %{<html><head><link href='/stylesheets/application.css' media='screen' rel='stylesheet' type='text/css' /></head><body><img alt='test' src="/test.png" /></body></html>}
|
285
|
+
body = @pdf.send :translate_paths, @body, @env
|
286
|
+
body.should == "<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>"
|
287
|
+
end
|
288
|
+
|
289
|
+
after do
|
290
|
+
PDFKit.configure do |config|
|
291
|
+
config.root_url = nil
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should not get stuck rendering each request as pdf" do
|
297
|
+
mock_app
|
298
|
+
# false by default. No requests.
|
299
|
+
@app.send(:rendering_pdf?).should be_false
|
300
|
+
|
301
|
+
# Remain false on a normal request
|
302
|
+
get 'http://www.example.org/public/file'
|
303
|
+
@app.send(:rendering_pdf?).should be_false
|
304
|
+
|
305
|
+
# Return true on a pdf request.
|
306
|
+
get 'http://www.example.org/public/file.pdf'
|
307
|
+
@app.send(:rendering_pdf?).should be_true
|
308
|
+
|
309
|
+
# Restore to false on any non-pdf request.
|
310
|
+
get 'http://www.example.org/public/file'
|
311
|
+
@app.send(:rendering_pdf?).should be_false
|
312
|
+
end
|
313
|
+
|
314
|
+
end
|
data/spec/pdfkit_spec.rb
ADDED
@@ -0,0 +1,255 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe PDFKit do
|
5
|
+
|
6
|
+
context "initialization" do
|
7
|
+
it "should accept HTML as the source" do
|
8
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
9
|
+
pdfkit.source.should be_html
|
10
|
+
pdfkit.source.to_s.should == '<h1>Oh Hai</h1>'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should accept a URL as the source" do
|
14
|
+
pdfkit = PDFKit.new('http://google.com')
|
15
|
+
pdfkit.source.should be_url
|
16
|
+
pdfkit.source.to_s.should == 'http://google.com'
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should accept a File as the source" do
|
20
|
+
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
21
|
+
pdfkit = PDFKit.new(File.new(file_path))
|
22
|
+
pdfkit.source.should be_file
|
23
|
+
pdfkit.source.to_s.should == file_path
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should parse the options into a cmd line friedly format" do
|
27
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
28
|
+
pdfkit.options.should have_key('--page-size')
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should parse complex options into a cmd line friedly format" do
|
32
|
+
pdfkit = PDFKit.new('html', :replace => {'value' => 'something else'} )
|
33
|
+
pdfkit.options.should have_key('--replace')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should provide default options" do
|
37
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
38
|
+
['--margin-top', '--margin-right', '--margin-bottom', '--margin-left'].each do |option|
|
39
|
+
pdfkit.options.should have_key(option)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should default to 'UTF-8' encoding" do
|
44
|
+
pdfkit = PDFKit.new('Captación')
|
45
|
+
pdfkit.options['--encoding'].should == 'UTF-8'
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should not have any stylesheedt by default" do
|
49
|
+
pdfkit = PDFKit.new('<h1>Oh Hai</h1>')
|
50
|
+
pdfkit.stylesheets.should be_empty
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "command" do
|
55
|
+
it "should contstruct the correct command" do
|
56
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter', :toc_l1_font_size => 12, :replace => {'foo' => 'bar'})
|
57
|
+
command = pdfkit.command
|
58
|
+
command.should include "wkhtmltopdf"
|
59
|
+
command.should include "--page-size Letter"
|
60
|
+
command.should include "--toc-l1-font-size 12"
|
61
|
+
command.should include "--replace foo bar"
|
62
|
+
end
|
63
|
+
|
64
|
+
it "will not include default options it is told to omit" do
|
65
|
+
PDFKit.configure do |config|
|
66
|
+
config.default_options[:disable_smart_shrinking] = true
|
67
|
+
end
|
68
|
+
|
69
|
+
pdfkit = PDFKit.new('html')
|
70
|
+
pdfkit.command.should include('--disable-smart-shrinking')
|
71
|
+
pdfkit = PDFKit.new('html', :disable_smart_shrinking => false)
|
72
|
+
pdfkit.command.should_not include('--disable-smart-shrinking')
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should encapsulate string arguments in quotes" do
|
76
|
+
pdfkit = PDFKit.new('html', :header_center => "foo [page]")
|
77
|
+
pdfkit.command.should include "--header-center foo\\ \\[page\\]"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should sanitize string arguments" do
|
81
|
+
pdfkit = PDFKit.new('html', :header_center => "$(ls)")
|
82
|
+
pdfkit.command.should include "--header-center \\$\\(ls\\)"
|
83
|
+
end
|
84
|
+
|
85
|
+
it "read the source from stdin if it is html" do
|
86
|
+
pdfkit = PDFKit.new('html')
|
87
|
+
pdfkit.command.should match /- -$/
|
88
|
+
end
|
89
|
+
|
90
|
+
it "specify the URL to the source if it is a url" do
|
91
|
+
pdfkit = PDFKit.new('http://google.com')
|
92
|
+
pdfkit.command.should match /http:\/\/google.com -$/
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should specify the path to the source if it is a file" do
|
96
|
+
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
97
|
+
pdfkit = PDFKit.new(File.new(file_path))
|
98
|
+
pdfkit.command.should match /#{file_path} -$/
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should specify the path for the ouput if a apth is given" do
|
102
|
+
file_path = "/path/to/output.pdf"
|
103
|
+
pdfkit = PDFKit.new("html")
|
104
|
+
pdfkit.command(file_path).should match /#{file_path}$/
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should detect special pdfkit meta tags" do
|
108
|
+
body = %{
|
109
|
+
<html>
|
110
|
+
<head>
|
111
|
+
<meta name="pdfkit-page_size" content="Legal"/>
|
112
|
+
<meta name="pdfkit-orientation" content="Landscape"/>
|
113
|
+
</head>
|
114
|
+
</html>
|
115
|
+
}
|
116
|
+
pdfkit = PDFKit.new(body)
|
117
|
+
command = pdfkit.command
|
118
|
+
command.should include "--page-size Legal"
|
119
|
+
command.should include "--orientation Landscape"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should detect special pdfkit meta tags despite bad markup" do
|
123
|
+
body = %{
|
124
|
+
<html>
|
125
|
+
<head>
|
126
|
+
<meta name="pdfkit-page_size" content="Legal"/>
|
127
|
+
<meta name="pdfkit-orientation" content="Landscape"/>
|
128
|
+
</head>
|
129
|
+
<br>
|
130
|
+
</html>
|
131
|
+
}
|
132
|
+
pdfkit = PDFKit.new(body)
|
133
|
+
command = pdfkit.command
|
134
|
+
command.should include "--page-size Legal"
|
135
|
+
command.should include "--orientation Landscape"
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should skip non-pdfkit meta tags" do
|
139
|
+
body = %{
|
140
|
+
<html>
|
141
|
+
<head>
|
142
|
+
<meta name="test-page_size" content="Legal"/>
|
143
|
+
<meta name="pdfkit-orientation" content="Landscape"/>
|
144
|
+
</head>
|
145
|
+
<br>
|
146
|
+
</html>
|
147
|
+
}
|
148
|
+
pdfkit = PDFKit.new(body)
|
149
|
+
command = pdfkit.command
|
150
|
+
command.should_not include "--page-size Legal"
|
151
|
+
command.should include "--orientation Landscape"
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
context "#to_pdf" do
|
157
|
+
it "should generate a PDF of the HTML" do
|
158
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
159
|
+
pdf = pdfkit.to_pdf
|
160
|
+
pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should generate a PDF with a numerical parameter" do
|
164
|
+
pdfkit = PDFKit.new('html', :header_spacing => 1)
|
165
|
+
pdf = pdfkit.to_pdf
|
166
|
+
pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should generate a PDF with a symbol parameter" do
|
170
|
+
pdfkit = PDFKit.new('html', :page_size => :Letter)
|
171
|
+
pdf = pdfkit.to_pdf
|
172
|
+
pdf[0...4].should == "%PDF" # PDF Signature at beginning of file
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should have the stylesheet added to the head if it has one" do
|
176
|
+
pdfkit = PDFKit.new("<html><head></head><body>Hai!</body></html>")
|
177
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
178
|
+
pdfkit.stylesheets << css
|
179
|
+
pdfkit.to_pdf
|
180
|
+
pdfkit.source.to_s.should include("<style>#{File.read(css)}</style>")
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should prepend style tags if the HTML doesn't have a head tag" do
|
184
|
+
pdfkit = PDFKit.new("<html><body>Hai!</body></html>")
|
185
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
186
|
+
pdfkit.stylesheets << css
|
187
|
+
pdfkit.to_pdf
|
188
|
+
pdfkit.source.to_s.should include("<style>#{File.read(css)}</style><html>")
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should throw an error if the source is not html and stylesheets have been added" do
|
192
|
+
pdfkit = PDFKit.new('http://google.com')
|
193
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
194
|
+
pdfkit.stylesheets << css
|
195
|
+
lambda { pdfkit.to_pdf }.should raise_error(PDFKit::ImproperSourceError)
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should be able to deal with ActiveSupport::SafeBuffer" do
|
199
|
+
pdfkit = PDFKit.new(ActiveSupport::SafeBuffer.new "<html><head></head><body>Hai!</body></html>")
|
200
|
+
css = File.join(SPEC_ROOT,'fixtures','example.css')
|
201
|
+
pdfkit.stylesheets << css
|
202
|
+
pdfkit.to_pdf
|
203
|
+
pdfkit.source.to_s.should include("<style>#{File.read(css)}</style></head>")
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should throw an error if it is unable to connect" do
|
207
|
+
pdfkit = PDFKit.new("http://google.com/this-should-not-be-found/404.html")
|
208
|
+
lambda { pdfkit.to_pdf }.should raise_error
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "#to_file" do
|
213
|
+
before do
|
214
|
+
@file_path = File.join(SPEC_ROOT,'fixtures','test.pdf')
|
215
|
+
File.delete(@file_path) if File.exist?(@file_path)
|
216
|
+
end
|
217
|
+
|
218
|
+
after do
|
219
|
+
File.delete(@file_path)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should create a file with the PDF as content" do
|
223
|
+
pdfkit = PDFKit.new('html', :page_size => 'Letter')
|
224
|
+
file = pdfkit.to_file(@file_path)
|
225
|
+
file.should be_instance_of(File)
|
226
|
+
File.read(file.path)[0...4].should == "%PDF" # PDF Signature at beginning of file
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should not truncate data (in Ruby 1.8.6)" do
|
230
|
+
file_path = File.join(SPEC_ROOT,'fixtures','example.html')
|
231
|
+
pdfkit = PDFKit.new(File.new(file_path))
|
232
|
+
pdf_data = pdfkit.to_pdf
|
233
|
+
file = pdfkit.to_file(@file_path)
|
234
|
+
file_data = open(@file_path, 'rb') {|io| io.read }
|
235
|
+
pdf_data.size.should == file_data.size
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
context "security" do
|
240
|
+
before do
|
241
|
+
@test_path = File.join(SPEC_ROOT,'fixtures','security-oops')
|
242
|
+
File.delete(@test_path) if File.exist?(@test_path)
|
243
|
+
end
|
244
|
+
|
245
|
+
after do
|
246
|
+
File.delete(@test_path) if File.exist?(@test_path)
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should not allow shell injection in options" do
|
250
|
+
pdfkit = PDFKit.new('html', :header_center => "a title\"; touch #{@test_path} #")
|
251
|
+
pdfkit.to_pdf
|
252
|
+
File.exist?(@test_path).should be_false
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
data/spec/source_spec.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PDFKit::Source do
|
4
|
+
|
5
|
+
describe "#url?" do
|
6
|
+
it "should return true if passed a url like string" do
|
7
|
+
source = PDFKit::Source.new('http://google.com')
|
8
|
+
source.should be_url
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should return false if passed a file" do
|
12
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
13
|
+
source.should_not be_url
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should return false if passed HTML" do
|
17
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
18
|
+
source.should_not be_url
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return false if passed HTML with embedded urls at the beginning of a line" do
|
22
|
+
source = PDFKit::Source.new("<blink>Oh Hai!</blink>\nhttp://www.google.com")
|
23
|
+
source.should_not be_url
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "#file?" do
|
28
|
+
it "should return true if passed a file" do
|
29
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
30
|
+
source.should be_file
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should return false if passed a url like string" do
|
34
|
+
source = PDFKit::Source.new('http://google.com')
|
35
|
+
source.should_not be_file
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return false if passed HTML" do
|
39
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
40
|
+
source.should_not be_file
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "#html?" do
|
45
|
+
it "should return true if passed HTML" do
|
46
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
47
|
+
source.should be_html
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should return false if passed a file" do
|
51
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
52
|
+
source.should_not be_html
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should return false if passed a url like string" do
|
56
|
+
source = PDFKit::Source.new('http://google.com')
|
57
|
+
source.should_not be_html
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "#to_s" do
|
62
|
+
it "should return the HTML if passed HTML" do
|
63
|
+
source = PDFKit::Source.new('<blink>Oh Hai!</blink>')
|
64
|
+
source.to_s.should == '<blink>Oh Hai!</blink>'
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should return a path if passed a file" do
|
68
|
+
source = PDFKit::Source.new(File.new(__FILE__))
|
69
|
+
source.to_s.should == __FILE__
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should return the url if passed a url like string" do
|
73
|
+
source = PDFKit::Source.new('http://google.com')
|
74
|
+
source.to_s.should == 'http://google.com'
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
SPEC_ROOT = File.dirname(__FILE__)
|
2
|
+
$LOAD_PATH.unshift(SPEC_ROOT)
|
3
|
+
$LOAD_PATH.unshift(File.join(SPEC_ROOT, '..', 'lib'))
|
4
|
+
require 'pdfkit'
|
5
|
+
require 'rspec'
|
6
|
+
require 'rspec/autorun'
|
7
|
+
require 'mocha'
|
8
|
+
require 'rack'
|
9
|
+
require 'rack/test'
|
10
|
+
require 'active_support'
|
11
|
+
require 'custom_wkhtmltopdf_path' if File.exists?(File.join(SPEC_ROOT, 'custom_wkhtmltopdf_path.rb'))
|
12
|
+
|
13
|
+
RSpec.configure do |config|
|
14
|
+
include Rack::Test::Methods
|
15
|
+
end
|