hssc_pdfkit 0.5.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|