roda 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +34 -0
- data/Rakefile +22 -46
- data/doc/release_notes/2.3.0.txt +109 -0
- data/lib/roda/plugins/assets.rb +2 -1
- data/lib/roda/plugins/caching.rb +1 -1
- data/lib/roda/plugins/chunked.rb +1 -1
- data/lib/roda/plugins/error_email.rb +1 -1
- data/lib/roda/plugins/head.rb +6 -0
- data/lib/roda/plugins/heartbeat.rb +40 -0
- data/lib/roda/plugins/json.rb +23 -3
- data/lib/roda/plugins/json_parser.rb +72 -0
- data/lib/roda/plugins/mailer.rb +22 -5
- data/lib/roda/plugins/named_templates.rb +2 -2
- data/lib/roda/plugins/path_rewriter.rb +82 -0
- data/lib/roda/plugins/precompile_templates.rb +87 -0
- data/lib/roda/plugins/render.rb +111 -43
- data/lib/roda/plugins/render_each.rb +1 -1
- data/lib/roda/plugins/shared_vars.rb +1 -1
- data/lib/roda/plugins/view_options.rb +28 -3
- data/lib/roda/version.rb +1 -1
- data/spec/composition_spec.rb +3 -3
- data/spec/env_spec.rb +1 -1
- data/spec/freeze_spec.rb +6 -6
- data/spec/integration_spec.rb +16 -15
- data/spec/matchers_spec.rb +110 -110
- data/spec/opts_spec.rb +8 -8
- data/spec/plugin/_erubis_escaping_spec.rb +34 -3
- data/spec/plugin/all_verbs_spec.rb +8 -8
- data/spec/plugin/assets_spec.rb +164 -150
- data/spec/plugin/backtracking_array_spec.rb +18 -18
- data/spec/plugin/caching_spec.rb +70 -70
- data/spec/plugin/chunked_spec.rb +38 -38
- data/spec/plugin/class_level_routing_spec.rb +78 -78
- data/spec/plugin/content_for_spec.rb +2 -2
- data/spec/plugin/cookies_spec.rb +4 -4
- data/spec/plugin/csrf_spec.rb +8 -8
- data/spec/plugin/default_headers_spec.rb +6 -6
- data/spec/plugin/delay_build_spec.rb +7 -6
- data/spec/plugin/delegate_spec.rb +2 -2
- data/spec/plugin/delete_empty_headers_spec.rb +2 -2
- data/spec/plugin/drop_body_spec.rb +6 -6
- data/spec/plugin/empty_root_spec.rb +3 -3
- data/spec/plugin/environments_spec.rb +7 -7
- data/spec/plugin/error_email_spec.rb +23 -23
- data/spec/plugin/error_handler_spec.rb +14 -14
- data/spec/plugin/flash_spec.rb +30 -29
- data/spec/plugin/h_spec.rb +1 -1
- data/spec/plugin/halt_spec.rb +16 -16
- data/spec/plugin/hash_matcher_spec.rb +5 -5
- data/spec/plugin/head_spec.rb +10 -10
- data/spec/plugin/header_matchers_spec.rb +13 -13
- data/spec/plugin/heartbeat_spec.rb +74 -0
- data/spec/plugin/hooks_spec.rb +20 -20
- data/spec/plugin/indifferent_params_spec.rb +1 -1
- data/spec/plugin/json_parser_spec.rb +72 -0
- data/spec/plugin/json_spec.rb +22 -9
- data/spec/plugin/mailer_spec.rb +72 -58
- data/spec/plugin/match_affix_spec.rb +2 -2
- data/spec/plugin/middleware_spec.rb +7 -7
- data/spec/plugin/module_include_spec.rb +4 -4
- data/spec/plugin/multi_route_spec.rb +66 -66
- data/spec/plugin/multi_run_spec.rb +21 -21
- data/spec/plugin/named_templates_spec.rb +6 -6
- data/spec/plugin/not_allowed_spec.rb +17 -17
- data/spec/plugin/not_found_spec.rb +14 -14
- data/spec/plugin/padrino_render_spec.rb +2 -2
- data/spec/plugin/param_matchers_spec.rb +6 -6
- data/spec/plugin/partials_spec.rb +3 -3
- data/spec/plugin/pass_spec.rb +7 -7
- data/spec/plugin/path_matchers_spec.rb +6 -6
- data/spec/plugin/path_rewriter_spec.rb +37 -0
- data/spec/plugin/path_spec.rb +41 -40
- data/spec/plugin/per_thread_caching_spec.rb +6 -6
- data/spec/plugin/precompile_templates_spec.rb +74 -0
- data/spec/plugin/render_each_spec.rb +4 -4
- data/spec/plugin/render_spec.rb +179 -76
- data/spec/plugin/shared_vars_spec.rb +4 -4
- data/spec/plugin/sinatra_helpers_spec.rb +121 -121
- data/spec/plugin/slash_path_empty_spec.rb +10 -10
- data/spec/plugin/static_spec.rb +4 -4
- data/spec/plugin/streaming_spec.rb +11 -11
- data/spec/plugin/symbol_matchers_spec.rb +24 -24
- data/spec/plugin/symbol_views_spec.rb +3 -3
- data/spec/plugin/view_options_spec.rb +10 -10
- data/spec/plugin_spec.rb +2 -2
- data/spec/redirect_spec.rb +10 -10
- data/spec/request_spec.rb +8 -8
- data/spec/response_spec.rb +23 -23
- data/spec/session_spec.rb +4 -4
- data/spec/spec_helper.rb +5 -19
- data/spec/version_spec.rb +4 -4
- data/spec/views/iv.erb +1 -0
- metadata +16 -5
data/spec/plugin/hooks_spec.rb
CHANGED
@@ -29,19 +29,19 @@ describe "hooks plugin" do
|
|
29
29
|
|
30
30
|
it "adds before and after hooks for running code before and after requests" do
|
31
31
|
s, h, b = req
|
32
|
-
s.
|
33
|
-
h['foo'].
|
34
|
-
b.join.
|
35
|
-
@a.
|
32
|
+
s.must_equal 201
|
33
|
+
h['foo'].must_equal 'baz'
|
34
|
+
b.join.must_equal 'bar'
|
35
|
+
@a.must_equal [[200, 'baz', ['bar']]]
|
36
36
|
end
|
37
37
|
|
38
38
|
it "multiple plugin calls do not override existing hooks" do
|
39
39
|
app.plugin :hooks
|
40
40
|
s, h, b = req
|
41
|
-
s.
|
42
|
-
h['foo'].
|
43
|
-
b.join.
|
44
|
-
@a.
|
41
|
+
s.must_equal 201
|
42
|
+
h['foo'].must_equal 'baz'
|
43
|
+
b.join.must_equal 'bar'
|
44
|
+
@a.must_equal [[200, 'baz', ['bar']]]
|
45
45
|
end
|
46
46
|
|
47
47
|
it "after hooks are still called if an exception is raised" do
|
@@ -55,9 +55,9 @@ describe "hooks plugin" do
|
|
55
55
|
a << $!
|
56
56
|
end
|
57
57
|
|
58
|
-
proc{req}.
|
59
|
-
a.pop.
|
60
|
-
a.pop.
|
58
|
+
proc{req}.must_raise(Roda::RodaError)
|
59
|
+
a.pop.must_be_kind_of(Roda::RodaError)
|
60
|
+
a.pop.must_equal nil
|
61
61
|
end
|
62
62
|
|
63
63
|
it "handles multiple before and after blocks correctly" do
|
@@ -72,11 +72,11 @@ describe "hooks plugin" do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
s, h, b = req
|
75
|
-
s.
|
76
|
-
h['foo'].
|
77
|
-
h['bar'].
|
78
|
-
b.join.
|
79
|
-
a.
|
75
|
+
s.must_equal 402
|
76
|
+
h['foo'].must_equal 'baz'
|
77
|
+
h['bar'].must_equal 'foo'
|
78
|
+
b.join.must_equal 'bar'
|
79
|
+
a.must_equal [[200, 'baz', ['bar']], 'foo']
|
80
80
|
end
|
81
81
|
|
82
82
|
it "copies before and after blocks when subclassing" do
|
@@ -87,9 +87,9 @@ describe "hooks plugin" do
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
s, h, b = req
|
90
|
-
s.
|
91
|
-
h['foo'].
|
92
|
-
b.join.
|
93
|
-
@a.
|
90
|
+
s.must_equal 201
|
91
|
+
h['foo'].must_equal 'bar'
|
92
|
+
b.join.must_equal 'foo'
|
93
|
+
@a.must_equal [[200, 'bar', ['foo']]]
|
94
94
|
end
|
95
95
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "json_parser plugin" do
|
4
|
+
before do
|
5
|
+
app(:json_parser) do |r|
|
6
|
+
r.params['a']['b'].to_s
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "parses incoming json if content type specifies json" do
|
11
|
+
body('rack.input'=>StringIO.new('{"a":{"b":1}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't affect parsing of non-json content type" do
|
15
|
+
body('rack.input'=>StringIO.new('a[b]=1'), 'REQUEST_METHOD'=>'POST').must_equal '1'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "returns 400 for invalid json" do
|
19
|
+
req('rack.input'=>StringIO.new('{"a":{"b":1}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal [400, {}, []]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "json_parser plugin" do
|
24
|
+
it "handles empty request bodies" do
|
25
|
+
app(:json_parser) do |r|
|
26
|
+
r.params.length.to_s
|
27
|
+
end
|
28
|
+
body('rack.input'=>StringIO.new(''), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '0'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "supports :error_handler option" do
|
32
|
+
app(:bare) do
|
33
|
+
plugin(:json_parser, :error_handler=>proc{|r| r.halt [401, {}, ['bad']]})
|
34
|
+
route do |r|
|
35
|
+
r.params['a']['b'].to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
req('rack.input'=>StringIO.new('{"a":{"b":1}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal [401, {}, ['bad']]
|
39
|
+
end
|
40
|
+
|
41
|
+
it "works with bare POST" do
|
42
|
+
app(:bare) do
|
43
|
+
plugin(:json_parser, :error_handler=>proc{|r| r.halt [401, {}, ['bad']]})
|
44
|
+
route do |r|
|
45
|
+
(r.POST['a']['b'] + r.POST['a']['c']).to_s
|
46
|
+
end
|
47
|
+
end
|
48
|
+
body('rack.input'=>StringIO.new('{"a":{"b":1,"c":2}}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '3'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "supports :parser option" do
|
52
|
+
app(:bare) do
|
53
|
+
plugin(:json_parser, :parser=>method(:eval))
|
54
|
+
route do |r|
|
55
|
+
r.params['a']['b'].to_s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
body('rack.input'=>StringIO.new("{'a'=>{'b'=>1}}"), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '1'
|
59
|
+
end
|
60
|
+
|
61
|
+
it "supports :include_request option" do
|
62
|
+
app(:bare) do
|
63
|
+
plugin(:json_parser,
|
64
|
+
:include_request => true,
|
65
|
+
:parser => lambda{|s,r| {'a'=>s, 'b'=>r.path_info}})
|
66
|
+
route do |r|
|
67
|
+
"#{r.params['a']}:#{r.params['b']}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
body('rack.input'=>StringIO.new('{}'), 'CONTENT_TYPE'=>'text/json', 'REQUEST_METHOD'=>'POST').must_equal '{}:/'
|
71
|
+
end
|
72
|
+
end
|
data/spec/plugin/json_spec.rb
CHANGED
@@ -28,22 +28,35 @@ describe "json plugin" do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "should use a json content type for a json response" do
|
31
|
-
header('Content-Type', "/array").
|
32
|
-
header('Content-Type', "/hash").
|
33
|
-
header('Content-Type', "/c").
|
34
|
-
header('Content-Type').
|
31
|
+
header('Content-Type', "/array").must_equal 'application/json'
|
32
|
+
header('Content-Type', "/hash").must_equal 'application/json'
|
33
|
+
header('Content-Type', "/c").must_equal 'application/json'
|
34
|
+
header('Content-Type').must_equal 'text/html'
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should convert objects to json" do
|
38
|
-
body('/array').gsub(/\s/, '').
|
39
|
-
body('/hash').gsub(/\s/, '').
|
40
|
-
body('/c').
|
41
|
-
body.
|
38
|
+
body('/array').gsub(/\s/, '').must_equal '[1,2,3]'
|
39
|
+
body('/hash').gsub(/\s/, '').must_equal '{"a":"b"}'
|
40
|
+
body('/c').must_equal '[1]'
|
41
|
+
body.must_equal ''
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should work when subclassing" do
|
45
45
|
@app = Class.new(app)
|
46
46
|
app.route{[1]}
|
47
|
-
body.
|
47
|
+
body.must_equal '[1]'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should accept custom serializers" do
|
51
|
+
app.plugin :json, :serializer => proc{|o| o.inspect}
|
52
|
+
body("/hash").must_equal '{"a"=>"b"}'
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should give serializer the request if :include_request is set" do
|
56
|
+
app.plugin :json,
|
57
|
+
:include_request => true,
|
58
|
+
:serializer => lambda{|o,r| "#{o['a']}:#{r.path_info}"}
|
59
|
+
|
60
|
+
body("/hash").must_equal 'b:/hash'
|
48
61
|
end
|
49
62
|
end
|
data/spec/plugin/mailer_spec.rb
CHANGED
@@ -36,28 +36,28 @@ describe "mailer plugin" do
|
|
36
36
|
end
|
37
37
|
|
38
38
|
m = app.mail('/foo')
|
39
|
-
deliveries.
|
40
|
-
m.from.
|
41
|
-
m.to.
|
42
|
-
m.cc.
|
43
|
-
m.bcc.
|
44
|
-
m.subject.
|
45
|
-
m.body.
|
46
|
-
m.header['X-Foo'].to_s.
|
39
|
+
deliveries.must_equal []
|
40
|
+
m.from.must_equal ['f@example.com']
|
41
|
+
m.to.must_equal ['t@example.com']
|
42
|
+
m.cc.must_equal ['c@example.com']
|
43
|
+
m.bcc.must_equal ['b@example.com']
|
44
|
+
m.subject.must_equal 's'
|
45
|
+
m.body.must_be :==, 'b'
|
46
|
+
m.header['X-Foo'].to_s.must_equal 'Bar'
|
47
47
|
|
48
48
|
m.deliver!
|
49
|
-
deliveries.
|
49
|
+
deliveries.must_equal [m]
|
50
50
|
|
51
51
|
deliveries.clear
|
52
52
|
m = app.sendmail('/foo')
|
53
|
-
deliveries.
|
54
|
-
m.from.
|
55
|
-
m.to.
|
56
|
-
m.cc.
|
57
|
-
m.bcc.
|
58
|
-
m.subject.
|
59
|
-
m.body.
|
60
|
-
m.header['X-Foo'].to_s.
|
53
|
+
deliveries.must_equal [m]
|
54
|
+
m.from.must_equal ['f@example.com']
|
55
|
+
m.to.must_equal ['t@example.com']
|
56
|
+
m.cc.must_equal ['c@example.com']
|
57
|
+
m.bcc.must_equal ['b@example.com']
|
58
|
+
m.subject.must_equal 's'
|
59
|
+
m.body.must_be :==, 'b'
|
60
|
+
m.header['X-Foo'].to_s.must_equal 'Bar'
|
61
61
|
end
|
62
62
|
|
63
63
|
it "supports arguments to mail/sendmail methods, yielding them to the route blocks" do
|
@@ -71,8 +71,22 @@ describe "mailer plugin" do
|
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
-
app.mail('/foo', 1, 2).body.
|
75
|
-
app.sendmail('/bar', 1, 2).body.
|
74
|
+
app.mail('/foo', 1, 2).body.must_be :==, 'foo[1, 2]'
|
75
|
+
app.sendmail('/bar', 1, 2).body.must_be :==, '["bar", 1, 2]'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "supports no_mail! method for skipping mailing" do
|
79
|
+
app(:mailer) do |r|
|
80
|
+
instance_exec(&setup_email)
|
81
|
+
r.mail "foo" do |*args|
|
82
|
+
no_mail!
|
83
|
+
raise
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
app.mail('/foo', 1, 2).must_equal nil
|
88
|
+
app.sendmail('/foo', 1, 2).must_equal nil
|
89
|
+
deliveries.must_equal []
|
76
90
|
end
|
77
91
|
|
78
92
|
it "supports attachments" do
|
@@ -84,11 +98,11 @@ describe "mailer plugin" do
|
|
84
98
|
end
|
85
99
|
|
86
100
|
m = app.mail('foo')
|
87
|
-
m.attachments.length.
|
88
|
-
m.attachments.first.content_type.
|
89
|
-
m.content_type.
|
90
|
-
m.parts.length.
|
91
|
-
m.parts.first.body.
|
101
|
+
m.attachments.length.must_equal 1
|
102
|
+
m.attachments.first.content_type.must_match(/mailer_spec\.rb/)
|
103
|
+
m.content_type.must_match(/\Amultipart\/mixed/)
|
104
|
+
m.parts.length.must_equal 1
|
105
|
+
m.parts.first.body.must_be :==, File.read(__FILE__)
|
92
106
|
end
|
93
107
|
|
94
108
|
it "supports attachments with blocks" do
|
@@ -102,11 +116,11 @@ describe "mailer plugin" do
|
|
102
116
|
end
|
103
117
|
|
104
118
|
m = app.mail('foo')
|
105
|
-
m.attachments.length.
|
106
|
-
m.attachments.first.content_type.
|
107
|
-
m.content_type.
|
108
|
-
m.parts.length.
|
109
|
-
m.parts.first.body.
|
119
|
+
m.attachments.length.must_equal 1
|
120
|
+
m.attachments.first.content_type.must_equal 'text/foo'
|
121
|
+
m.content_type.must_match(/\Amultipart\/mixed/)
|
122
|
+
m.parts.length.must_equal 1
|
123
|
+
m.parts.first.body.must_be :==, File.read(__FILE__)
|
110
124
|
end
|
111
125
|
|
112
126
|
it "supports plain-text attachments with an email body" do
|
@@ -119,14 +133,14 @@ describe "mailer plugin" do
|
|
119
133
|
end
|
120
134
|
|
121
135
|
m = app.mail('foo')
|
122
|
-
m.parts.length.
|
123
|
-
m.parts.first.content_type.
|
124
|
-
m.parts.first.body.
|
125
|
-
m.parts.last.content_type.
|
126
|
-
m.parts.last.body.
|
127
|
-
m.attachments.length.
|
128
|
-
m.attachments.first.content_type.
|
129
|
-
m.content_type.
|
136
|
+
m.parts.length.must_equal 2
|
137
|
+
m.parts.first.content_type.must_match(/text\/plain/)
|
138
|
+
m.parts.first.body.must_be :==, 'c'
|
139
|
+
m.parts.last.content_type.must_match(/text\/plain/)
|
140
|
+
m.parts.last.body.must_be :==, 'b'
|
141
|
+
m.attachments.length.must_equal 1
|
142
|
+
m.attachments.first.content_type.must_match(/a\.txt/)
|
143
|
+
m.content_type.must_match(/\Amultipart\/mixed/)
|
130
144
|
end
|
131
145
|
|
132
146
|
it "supports regular web requests in same application" do
|
@@ -140,8 +154,8 @@ describe "mailer plugin" do
|
|
140
154
|
end
|
141
155
|
end
|
142
156
|
|
143
|
-
body("/foo/baz", 'rack.input'=>StringIO.new).
|
144
|
-
app.mail('/bar').body.
|
157
|
+
body("/foo/baz", 'rack.input'=>StringIO.new).must_equal 'foobaz'
|
158
|
+
app.mail('/bar').body.must_be :==, 'b'
|
145
159
|
end
|
146
160
|
|
147
161
|
it "supports multipart email using text_part/html_pat" do
|
@@ -154,9 +168,9 @@ describe "mailer plugin" do
|
|
154
168
|
end
|
155
169
|
|
156
170
|
m = app.mail('/foo')
|
157
|
-
m.text_part.body.
|
158
|
-
m.html_part.body.
|
159
|
-
m.content_type.
|
171
|
+
m.text_part.body.must_be :==, 't'
|
172
|
+
m.html_part.body.must_be :==, 'h'
|
173
|
+
m.content_type.must_match(/\Amultipart\/alternative/)
|
160
174
|
end
|
161
175
|
|
162
176
|
it "supports setting arbitrary email headers for multipart emails" do
|
@@ -169,21 +183,21 @@ describe "mailer plugin" do
|
|
169
183
|
end
|
170
184
|
|
171
185
|
m = app.mail('/foo')
|
172
|
-
m.text_part.body.
|
173
|
-
m.text_part.header['X-Text'].to_s.
|
174
|
-
m.html_part.body.
|
175
|
-
m.html_part.header['X-HTML'].to_s.
|
176
|
-
m.content_type.
|
186
|
+
m.text_part.body.must_be :==, 't'
|
187
|
+
m.text_part.header['X-Text'].to_s.must_equal 'T'
|
188
|
+
m.html_part.body.must_be :==, 'h'
|
189
|
+
m.html_part.header['X-HTML'].to_s.must_equal 'H'
|
190
|
+
m.content_type.must_match(/\Amultipart\/alternative/)
|
177
191
|
end
|
178
192
|
|
179
193
|
it "raises error if mail object is not returned" do
|
180
194
|
app(:mailer){}
|
181
|
-
proc{app.mail('/')}.
|
195
|
+
proc{app.mail('/')}.must_raise(Roda::RodaPlugins::Mailer::Error)
|
182
196
|
end
|
183
197
|
|
184
198
|
it "does not raise an error when using an explicitly empty body" do
|
185
199
|
app(:mailer){""}
|
186
|
-
|
200
|
+
app.mail('/')
|
187
201
|
end
|
188
202
|
|
189
203
|
it "supports setting the default content-type for emails when loading the plugin" do
|
@@ -191,7 +205,7 @@ describe "mailer plugin" do
|
|
191
205
|
plugin :mailer, :content_type=>'text/html'
|
192
206
|
route{""}
|
193
207
|
end
|
194
|
-
app.mail('/').content_type.
|
208
|
+
app.mail('/').content_type.must_match(/\Atext\/html/)
|
195
209
|
end
|
196
210
|
|
197
211
|
it "supports loading the plugin multiple times" do
|
@@ -200,7 +214,7 @@ describe "mailer plugin" do
|
|
200
214
|
plugin :mailer
|
201
215
|
route{""}
|
202
216
|
end
|
203
|
-
app.mail('/').content_type.
|
217
|
+
app.mail('/').content_type.must_match(/\Atext\/html/)
|
204
218
|
end
|
205
219
|
|
206
220
|
it "supports manually overridding the default content-type for emails" do
|
@@ -211,7 +225,7 @@ describe "mailer plugin" do
|
|
211
225
|
""
|
212
226
|
end
|
213
227
|
end
|
214
|
-
app.mail('/').content_type.
|
228
|
+
app.mail('/').content_type.must_match(/\Atext\/foo/)
|
215
229
|
end
|
216
230
|
|
217
231
|
it "supports setting the default content type when attachments are used" do
|
@@ -223,12 +237,12 @@ describe "mailer plugin" do
|
|
223
237
|
end
|
224
238
|
end
|
225
239
|
m = app.mail('/')
|
226
|
-
m.content_type.
|
227
|
-
m.parts.length.
|
228
|
-
m.parts.first.content_type.
|
229
|
-
m.parts.first.body.
|
230
|
-
m.parts.last.content_type.
|
231
|
-
m.parts.last.body.
|
240
|
+
m.content_type.must_match(/\Amultipart\/mixed/)
|
241
|
+
m.parts.length.must_equal 2
|
242
|
+
m.parts.first.content_type.must_match(/\Atext\/html/)
|
243
|
+
m.parts.first.body.must_be :==, "a"
|
244
|
+
m.parts.last.content_type.must_match(/\Atext\/css/)
|
245
|
+
m.parts.last.body.must_be :==, File.read('spec/assets/css/raw.css')
|
232
246
|
end
|
233
247
|
end
|
234
248
|
end
|
@@ -42,18 +42,18 @@ describe "middleware plugin" do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
body('/a').
|
46
|
-
body('/b').
|
47
|
-
body('/a', 'REQUEST_METHOD'=>'POST').
|
48
|
-
body('/b', 'REQUEST_METHOD'=>'POST').
|
49
|
-
body('/a', 'REQUEST_METHOD'=>'PATCH').
|
50
|
-
body('/b', 'REQUEST_METHOD'=>'PATCH').
|
45
|
+
body('/a').must_equal 'a3'
|
46
|
+
body('/b').must_equal 'b3'
|
47
|
+
body('/a', 'REQUEST_METHOD'=>'POST').must_equal 'a2'
|
48
|
+
body('/b', 'REQUEST_METHOD'=>'POST').must_equal 'b2'
|
49
|
+
body('/a', 'REQUEST_METHOD'=>'PATCH').must_equal 'a2'
|
50
|
+
body('/b', 'REQUEST_METHOD'=>'PATCH').must_equal 'b1'
|
51
51
|
end
|
52
52
|
|
53
53
|
it "makes it still possible to use the Roda app normally" do
|
54
54
|
app(:middleware) do
|
55
55
|
"a"
|
56
56
|
end
|
57
|
-
body.
|
57
|
+
body.must_equal 'a'
|
58
58
|
end
|
59
59
|
end
|