rack-contrib 1.2.0 → 1.2.0.39.g17d21b4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +98 -0
  3. data/lib/rack/contrib.rb +3 -1
  4. data/lib/rack/contrib/enforce_valid_encoding.rb +23 -0
  5. data/lib/rack/contrib/jsonp.rb +5 -1
  6. data/lib/rack/contrib/locale.rb +1 -1
  7. data/lib/rack/contrib/mailexceptions.rb +41 -10
  8. data/lib/rack/contrib/post_body_content_type_parser.rb +1 -1
  9. data/lib/rack/contrib/relative_redirect.rb +1 -1
  10. data/lib/rack/contrib/try_static.rb +1 -1
  11. metadata +166 -113
  12. data/README.rdoc +0 -98
  13. data/Rakefile +0 -89
  14. data/rack-contrib.gemspec +0 -112
  15. data/test/404.html +0 -1
  16. data/test/Maintenance.html +0 -1
  17. data/test/documents/existing.html +0 -1
  18. data/test/documents/index.htm +0 -1
  19. data/test/documents/index.html +0 -1
  20. data/test/documents/test +0 -1
  21. data/test/mail_settings.rb +0 -20
  22. data/test/spec_rack_accept_format.rb +0 -72
  23. data/test/spec_rack_access.rb +0 -154
  24. data/test/spec_rack_backstage.rb +0 -26
  25. data/test/spec_rack_callbacks.rb +0 -65
  26. data/test/spec_rack_common_cookies.rb +0 -107
  27. data/test/spec_rack_config.rb +0 -22
  28. data/test/spec_rack_contrib.rb +0 -8
  29. data/test/spec_rack_cookies.rb +0 -56
  30. data/test/spec_rack_csshttprequest.rb +0 -66
  31. data/test/spec_rack_deflect.rb +0 -107
  32. data/test/spec_rack_evil.rb +0 -19
  33. data/test/spec_rack_expectation_cascade.rb +0 -72
  34. data/test/spec_rack_garbagecollector.rb +0 -13
  35. data/test/spec_rack_host_meta.rb +0 -50
  36. data/test/spec_rack_jsonp.rb +0 -188
  37. data/test/spec_rack_lighttpd_script_name_fix.rb +0 -16
  38. data/test/spec_rack_mailexceptions.rb +0 -169
  39. data/test/spec_rack_nested_params.rb +0 -46
  40. data/test/spec_rack_not_found.rb +0 -17
  41. data/test/spec_rack_post_body_content_type_parser.rb +0 -40
  42. data/test/spec_rack_proctitle.rb +0 -26
  43. data/test/spec_rack_profiler.rb +0 -42
  44. data/test/spec_rack_relative_redirect.rb +0 -78
  45. data/test/spec_rack_response_cache.rb +0 -137
  46. data/test/spec_rack_response_headers.rb +0 -35
  47. data/test/spec_rack_runtime.rb +0 -35
  48. data/test/spec_rack_sendfile.rb +0 -86
  49. data/test/spec_rack_simple_endpoint.rb +0 -95
  50. data/test/spec_rack_static_cache.rb +0 -104
  51. data/test/spec_rack_try_static.rb +0 -56
  52. data/test/statics/test +0 -1
@@ -1,19 +0,0 @@
1
- require 'test/spec'
2
- require 'rack/mock'
3
- require 'rack/contrib/evil'
4
- require 'erb'
5
-
6
- context "Rack::Evil" do
7
- app = lambda do |env|
8
- template = ERB.new("<%= throw :response, [404, {'Content-Type' => 'text/html'}, 'Never know where it comes from'] %>")
9
- [200, {'Content-Type' => 'text/plain'}, template.result(binding)]
10
- end
11
-
12
- specify "should enable the app to return the response from anywhere" do
13
- status, headers, body = Rack::Evil.new(app).call({})
14
-
15
- status.should.equal 404
16
- headers['Content-Type'].should.equal 'text/html'
17
- body.should.equal 'Never know where it comes from'
18
- end
19
- end
@@ -1,72 +0,0 @@
1
- require 'test/spec'
2
- require 'rack/mock'
3
- require 'rack/contrib/expectation_cascade'
4
-
5
- context "Rack::ExpectationCascade" do
6
- specify "with no apps returns a 404 if no expectation header was set" do
7
- app = Rack::ExpectationCascade.new
8
- env = {}
9
- response = app.call(env)
10
- response[0].should.equal 404
11
- env.should.equal({})
12
- end
13
-
14
- specify "with no apps returns a 417 if expectation header was set" do
15
- app = Rack::ExpectationCascade.new
16
- env = {"Expect" => "100-continue"}
17
- response = app.call(env)
18
- response[0].should.equal 417
19
- env.should.equal({"Expect" => "100-continue"})
20
- end
21
-
22
- specify "returns first successful response" do
23
- app = Rack::ExpectationCascade.new do |cascade|
24
- cascade << lambda { |env| [417, {"Content-Type" => "text/plain"}, []] }
25
- cascade << lambda { |env| [200, {"Content-Type" => "text/plain"}, ["OK"]] }
26
- end
27
- response = app.call({})
28
- response[0].should.equal 200
29
- response[2][0].should.equal "OK"
30
- end
31
-
32
- specify "expectation is set if it has not been already" do
33
- app = Rack::ExpectationCascade.new do |cascade|
34
- cascade << lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Expect: #{env["Expect"]}"]] }
35
- end
36
- response = app.call({})
37
- response[0].should.equal 200
38
- response[2][0].should.equal "Expect: 100-continue"
39
- end
40
-
41
- specify "returns a 404 if no apps where matched and no expectation header was set" do
42
- app = Rack::ExpectationCascade.new do |cascade|
43
- cascade << lambda { |env| [417, {"Content-Type" => "text/plain"}, []] }
44
- end
45
- response = app.call({})
46
- response[0].should.equal 404
47
- response[2][0].should.equal nil
48
- end
49
-
50
- specify "returns a 417 if no apps where matched and a expectation header was set" do
51
- app = Rack::ExpectationCascade.new do |cascade|
52
- cascade << lambda { |env| [417, {"Content-Type" => "text/plain"}, []] }
53
- end
54
- response = app.call({"Expect" => "100-continue"})
55
- response[0].should.equal 417
56
- response[2][0].should.equal nil
57
- end
58
-
59
- specify "nests expectation cascades" do
60
- app = Rack::ExpectationCascade.new do |c1|
61
- c1 << Rack::ExpectationCascade.new do |c2|
62
- c2 << lambda { |env| [417, {"Content-Type" => "text/plain"}, []] }
63
- end
64
- c1 << Rack::ExpectationCascade.new do |c2|
65
- c2 << lambda { |env| [200, {"Content-Type" => "text/plain"}, ["OK"]] }
66
- end
67
- end
68
- response = app.call({})
69
- response[0].should.equal 200
70
- response[2][0].should.equal "OK"
71
- end
72
- end
@@ -1,13 +0,0 @@
1
- require 'test/spec'
2
- require 'rack/mock'
3
- require 'rack/contrib/garbagecollector'
4
-
5
- context 'Rack::GarbageCollector' do
6
-
7
- specify 'starts the garbage collector after each request' do
8
- app = lambda { |env|
9
- [200, {'Content-Type'=>'text/plain'}, ['Hello World']] }
10
- Rack::GarbageCollector.new(app).call({})
11
- end
12
-
13
- end
@@ -1,50 +0,0 @@
1
- require 'test/spec'
2
- require 'rack/mock'
3
- require 'rack/contrib/host_meta'
4
- require 'rack/contrib/not_found'
5
-
6
- context "Rack::HostMeta" do
7
-
8
- setup do
9
- app = Rack::Builder.new do
10
- use Rack::Lint
11
- use Rack::ContentLength
12
- use Rack::HostMeta do
13
- link :uri => '/robots.txt', :rel => 'robots'
14
- link :uri => '/w3c/p3p.xml', :rel => 'privacy', :type => 'application/p3p.xml'
15
- link :pattern => '{uri};json_schema', :rel => 'describedby', :type => 'application/x-schema+json'
16
- end
17
- run Rack::NotFound.new('test/404.html')
18
- end
19
- @response = Rack::MockRequest.new(app).get('/host-meta')
20
- end
21
-
22
- specify "should respond to /host-meta" do
23
- @response.status.should.equal 200
24
- end
25
-
26
- specify "should respond with the correct media type" do
27
- @response['Content-Type'].should.equal 'application/host-meta'
28
- end
29
-
30
- specify "should include a Link entry for each Link item in the config block" do
31
- @response.body.should.match(/Link:\s*<\/robots.txt>;.*\n/)
32
- @response.body.should.match(/Link:\s*<\/w3c\/p3p.xml>;.*/)
33
- end
34
-
35
- specify "should include a Link-Pattern entry for each Link-Pattern item in the config" do
36
- @response.body.should.match(/Link-Pattern:\s*<\{uri\};json_schema>;.*/)
37
- end
38
-
39
- specify "should include a rel attribute for each Link or Link-Pattern entry where specified" do
40
- @response.body.should.match(/rel="robots"/)
41
- @response.body.should.match(/rel="privacy"/)
42
- @response.body.should.match(/rel="describedby"/)
43
- end
44
-
45
- specify "should include a type attribute for each Link or Link-Pattern entry where specified" do
46
- @response.body.should.match(/Link:\s*<\/w3c\/p3p.xml>;.*type.*application\/p3p.xml/)
47
- @response.body.should.match(/Link-Pattern:\s*<\{uri\};json_schema>;.*type.*application\/x-schema\+json/)
48
- end
49
-
50
- end
@@ -1,188 +0,0 @@
1
- require 'test/spec'
2
- require 'rack/mock'
3
- require 'rack/contrib/jsonp'
4
-
5
- context "Rack::JSONP" do
6
-
7
- context "when a callback parameter is provided" do
8
- specify "should wrap the response body in the Javascript callback if JSON" do
9
- test_body = '{"bar":"foo"}'
10
- callback = 'foo'
11
- app = lambda { |env| [200, {'Content-Type' => 'application/json'}, [test_body]] }
12
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
13
- body = Rack::JSONP.new(app).call(request).last
14
- body.should.equal ["#{callback}(#{test_body})"]
15
- end
16
-
17
- specify "should not wrap the response body in a callback if body is not JSON" do
18
- test_body = '{"bar":"foo"}'
19
- callback = 'foo'
20
- app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, [test_body]] }
21
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
22
- body = Rack::JSONP.new(app).call(request).last
23
- body.should.equal ['{"bar":"foo"}']
24
- end
25
-
26
- specify "should update content length if it was set" do
27
- test_body = '{"bar":"foo"}'
28
- callback = 'foo'
29
- app = lambda { |env| [200, {'Content-Type' => 'application/json', 'Content-Length' => test_body.length}, [test_body]] }
30
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
31
-
32
- headers = Rack::JSONP.new(app).call(request)[1]
33
- expected_length = test_body.length + callback.length + "()".length
34
- headers['Content-Length'].should.equal(expected_length.to_s)
35
- end
36
-
37
- specify "should not touch content length if not set" do
38
- test_body = '{"bar":"foo"}'
39
- callback = 'foo'
40
- app = lambda { |env| [200, {'Content-Type' => 'application/json'}, [test_body]] }
41
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
42
- headers = Rack::JSONP.new(app).call(request)[1]
43
- headers['Content-Length'].should.equal nil
44
- end
45
-
46
- specify "should modify the content type to application/javascript" do
47
- test_body = '{"bar":"foo"}'
48
- callback = 'foo'
49
- app = lambda { |env| [200, {'Content-Type' => 'application/json'}, [test_body]] }
50
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
51
- headers = Rack::JSONP.new(app).call(request)[1]
52
- headers['Content-Type'].should.equal('application/javascript')
53
- end
54
-
55
- specify "should not allow literal U+2028 or U+2029" do
56
- test_body = unless "\u2028" == 'u2028'
57
- "{\"bar\":\"\u2028 and \u2029\"}"
58
- else
59
- "{\"bar\":\"\342\200\250 and \342\200\251\"}"
60
- end
61
- callback = 'foo'
62
- app = lambda { |env| [200, {'Content-Type' => 'application/json'}, [test_body]] }
63
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
64
- body = Rack::JSONP.new(app).call(request).last
65
- unless "\u2028" == 'u2028'
66
- body.join.should.not.match(/\u2028|\u2029/)
67
- else
68
- body.join.should.not.match(/\342\200\250|\342\200\251/)
69
- end
70
- end
71
-
72
- context "but is empty" do
73
- specify "should " do
74
- test_body = '{"bar":"foo"}'
75
- callback = ''
76
- app = lambda { |env| [200, {'Content-Type' => 'application/json'}, [test_body]] }
77
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
78
- body = Rack::JSONP.new(app).call(request).last
79
- body.should.equal ['{"bar":"foo"}']
80
- end
81
- end
82
-
83
- context 'but is invalid' do
84
- context 'with content-type application/json' do
85
- specify 'should return "Bad Request"' do
86
- test_body = '{"bar":"foo"}'
87
- callback = '*'
88
- content_type = 'application/json'
89
- app = lambda { |env| [200, {'Content-Type' => content_type}, [test_body]] }
90
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
91
- body = Rack::JSONP.new(app).call(request).last
92
- body.should.equal ['Bad Request']
93
- end
94
-
95
- specify 'should return set the response code to 400' do
96
- test_body = '{"bar":"foo"}'
97
- callback = '*'
98
- content_type = 'application/json'
99
- app = lambda { |env| [200, {'Content-Type' => content_type}, [test_body]] }
100
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
101
- response_code = Rack::JSONP.new(app).call(request).first
102
- response_code.should.equal 400
103
- end
104
- end
105
-
106
- context 'with content-type text/plain' do
107
- specify 'should return "Good Request"' do
108
- test_body = 'Good Request'
109
- callback = '*'
110
- content_type = 'text/plain'
111
- app = lambda { |env| [200, {'Content-Type' => content_type}, [test_body]] }
112
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
113
- body = Rack::JSONP.new(app).call(request).last
114
- body.should.equal ['Good Request']
115
- end
116
-
117
- specify 'should not change the response code from 200' do
118
- test_body = '{"bar":"foo"}'
119
- callback = '*'
120
- content_type = 'text/plain'
121
- app = lambda { |env| [200, {'Content-Type' => content_type}, [test_body]] }
122
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
123
- response_code = Rack::JSONP.new(app).call(request).first
124
- response_code.should.equal 200
125
- end
126
- end
127
- end
128
-
129
- context "with XSS vulnerability attempts" do
130
- def request(callback, body = '{"bar":"foo"}')
131
- app = lambda { |env| [200, {'Content-Type' => 'application/json'}, [body]] }
132
- request = Rack::MockRequest.env_for("/", :params => "foo=bar&callback=#{callback}")
133
- Rack::JSONP.new(app).call(request)
134
- end
135
-
136
- def assert_bad_request(response)
137
- response.should.not.equal nil
138
- status, headers, body = response
139
- status.should.equal 400
140
- body.should.equal ["Bad Request"]
141
- end
142
-
143
- specify "should return bad request for callback with invalid characters" do
144
- assert_bad_request(request("foo<bar>baz()$"))
145
- end
146
-
147
- specify "should return bad request for callbacks with <script> tags" do
148
- assert_bad_request(request("foo<script>alert(1)</script>"))
149
- end
150
-
151
- specify "should return bad requests for callbacks with multiple statements" do
152
- assert_bad_request(request("foo%3balert(1)//")) # would render: "foo;alert(1)//"
153
- end
154
-
155
- specify "should not return a bad request for callbacks with dots in the callback" do
156
- status, headers, body = request(callback = "foo.bar.baz", test_body = '{"foo":"bar"}')
157
- status.should.equal 200
158
- body.should.equal ["#{callback}(#{test_body})"]
159
- end
160
- end
161
-
162
- end
163
-
164
- specify "should not change anything if no callback param is provided" do
165
- test_body = ['{"bar":"foo"}']
166
- app = lambda { |env| [200, {'Content-Type' => 'application/json'}, test_body] }
167
- request = Rack::MockRequest.env_for("/", :params => "foo=bar")
168
- body = Rack::JSONP.new(app).call(request).last
169
- body.should.equal test_body
170
- end
171
-
172
- specify "should not change anything if it's not a json response" do
173
- test_body = '<html><body>404 Not Found</body></html>'
174
- app = lambda { |env| [404, {'Content-Type' => 'text/html'}, [test_body]] }
175
- request = Rack::MockRequest.env_for("/", :params => "callback=foo", 'HTTP_ACCEPT' => 'application/json')
176
- body = Rack::JSONP.new(app).call(request).last
177
- body.should.equal [test_body]
178
- end
179
-
180
- specify "should not change anything if there is no Content-Type header" do
181
- test_body = '<html><body>404 Not Found</body></html>'
182
- app = lambda { |env| [404, {}, [test_body]] }
183
- request = Rack::MockRequest.env_for("/", :params => "callback=foo", 'HTTP_ACCEPT' => 'application/json')
184
- body = Rack::JSONP.new(app).call(request).last
185
- body.should.equal [test_body]
186
- end
187
-
188
- end
@@ -1,16 +0,0 @@
1
- require 'test/spec'
2
- require 'rack/mock'
3
- require 'rack/contrib/lighttpd_script_name_fix'
4
-
5
- context "Rack::LighttpdScriptNameFix" do
6
- specify "corrects SCRIPT_NAME and PATH_INFO set by lighttpd " do
7
- env = {
8
- "PATH_INFO" => "/foo/bar/baz",
9
- "SCRIPT_NAME" => "/hello"
10
- }
11
- app = lambda { |_| [200, {'Content-Type' => 'text/plain'}, ["Hello, World!"]] }
12
- response = Rack::LighttpdScriptNameFix.new(app).call(env)
13
- env['SCRIPT_NAME'].should.be.empty
14
- env['PATH_INFO'].should.equal '/hello/foo/bar/baz'
15
- end
16
- end
@@ -1,169 +0,0 @@
1
- require 'test/spec'
2
- require 'rack/mock'
3
-
4
- begin
5
- require './lib/rack/contrib/mailexceptions'
6
- require './test/mail_settings.rb'
7
-
8
- class TestError < RuntimeError
9
- end
10
-
11
- def test_exception
12
- raise TestError, 'Suffering Succotash!'
13
- rescue => boom
14
- return boom
15
- end
16
-
17
- context 'Rack::MailExceptions' do
18
-
19
- setup do
20
- @app = lambda { |env| raise TestError, 'Why, I say' }
21
- @env = Rack::MockRequest.env_for("/foo",
22
- 'FOO' => 'BAR',
23
- :method => 'GET',
24
- :input => 'THE BODY'
25
- )
26
- @smtp_settings = {
27
- :server => 'example.com',
28
- :domain => 'example.com',
29
- :port => 500,
30
- :authentication => :login,
31
- :user_name => 'joe',
32
- :password => 'secret'
33
- }
34
- end
35
-
36
- specify 'yields a configuration object to the block when created' do
37
- called = false
38
- mailer =
39
- Rack::MailExceptions.new(@app) do |mail|
40
- called = true
41
- mail.to 'foo@example.org'
42
- mail.from 'bar@example.org'
43
- mail.subject '[ERROR] %s'
44
- mail.smtp @smtp_settings
45
- end
46
- called.should.be == true
47
- end
48
-
49
- specify 'generates a TMail object with configured settings' do
50
- mailer =
51
- Rack::MailExceptions.new(@app) do |mail|
52
- mail.to 'foo@example.org'
53
- mail.from 'bar@example.org'
54
- mail.subject '[ERROR] %s'
55
- mail.smtp @smtp_settings
56
- end
57
-
58
- mail = mailer.send(:generate_mail, test_exception, @env)
59
- mail.to.should.equal ['foo@example.org']
60
- mail.from.should.equal ['bar@example.org']
61
- mail.subject.should.equal '[ERROR] Suffering Succotash!'
62
- mail.body.should.not.be.nil
63
- mail.body.should.be =~ /FOO:\s+"BAR"/
64
- mail.body.should.be =~ /^\s*THE BODY\s*$/
65
- end
66
-
67
- specify 'catches exceptions raised from app, sends mail, and re-raises' do
68
- mailer =
69
- Rack::MailExceptions.new(@app) do |mail|
70
- mail.to 'foo@example.org'
71
- mail.from 'bar@example.org'
72
- mail.subject '[ERROR] %s'
73
- mail.smtp @smtp_settings
74
- end
75
- lambda { mailer.call(@env) }.should.raise(TestError)
76
- @env['mail.sent'].should.be == true
77
- end
78
-
79
- if TEST_SMTP && ! TEST_SMTP.empty?
80
- specify 'sends mail' do
81
- mailer =
82
- Rack::MailExceptions.new(@app) do |mail|
83
- mail.config.merge! TEST_SMTP
84
- end
85
- lambda { mailer.call(@env) }.should.raise(TestError)
86
- @env['mail.sent'].should.be == true
87
- end
88
- else
89
- STDERR.puts 'WARN: Skipping SMTP tests (edit test/mail_settings.rb to enable)'
90
- end
91
-
92
- context 'for tls enabled smtp' do
93
- setup do
94
- @smtp_settings.merge!(TEST_SMTP_TLS)
95
- @mailer =
96
- Rack::MailExceptions.new(@app) do |mail|
97
- mail.to TEST_SMTP_TLS.values_at(:user_name, :domain).join('@')
98
- mail.from 'bar@example.org'
99
- mail.subject '[ERROR] %s'
100
- mail.smtp @smtp_settings.merge( :enable_starttls_auto => true)
101
- end
102
- end
103
-
104
- describe 'with :enable_starttls_auto set to :auto' do
105
- specify 'sends mail' do
106
- @mailer.smtp.merge(:enable_starttls_auto => :auto)
107
- lambda { @mailer.call(@env) }.should.raise(TestError)
108
- @env['mail.sent'].should.be true
109
- end
110
- end
111
-
112
- describe 'with :enable_starttls_auto set to true' do
113
- specify 'sends mail' do
114
- @mailer.smtp.merge(:enable_starttls_auto => true)
115
- lambda { @mailer.call(@env) }.should.raise(TestError)
116
- @env['mail.sent'].should.be true
117
- end
118
- end
119
- end if defined?(TEST_SMTP_TLS)
120
-
121
- describe 'for tls enabled fake smtp' do
122
- class FakeSMTP
123
- def initialize(*args); @@_tls = nil; end
124
- def start(*args); end
125
- def enable_starttls_auto; @@_tls = :auto; end
126
- def enable_starttls; @@_tls = true; end
127
- def send_message(*args); end
128
- def self.tls; @@_tls; end
129
- end
130
-
131
- setup do
132
- Rack::MailExceptions.class_eval { def service; FakeSMTP; end}
133
- @mailer =
134
- Rack::MailExceptions.new(@app) do |mail|
135
- mail.to 'foo@example.org'
136
- mail.from 'bar@example.org'
137
- mail.subject '[ERROR] %s'
138
- mail.smtp @smtp_settings.merge( :server => 'server.com')
139
- end
140
- end
141
-
142
- context 'with :enable_starttls_auto unset' do
143
- specify 'sends mail' do
144
- @mailer.smtp[:enable_starttls_auto] = nil
145
- lambda { @mailer.call(@env) }.should.raise(TestError)
146
- FakeSMTP.tls.should.be nil
147
- end
148
- end
149
-
150
- context 'with :enable_starttls_auto set to true' do
151
- specify 'sends mail' do
152
- @mailer.smtp[:enable_starttls_auto] = true
153
- lambda { @mailer.call(@env) }.should.raise(TestError)
154
- FakeSMTP.tls.should == true
155
- end
156
- end
157
-
158
- context 'with :enable_starttls_auto set to :auto' do
159
- specify 'sends mail' do
160
- @mailer.smtp[:enable_starttls_auto] = :auto
161
- lambda { @mailer.call(@env) }.should.raise(TestError)
162
- FakeSMTP.tls.should == :auto
163
- end
164
- end
165
- end
166
- end
167
- rescue LoadError => boom
168
- STDERR.puts "WARN: Skipping Rack::MailExceptions tests (mail not installed)"
169
- end