roda 2.2.0 → 2.3.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 +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
|