gin 0.0.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ require 'test/test_helper'
2
+ require 'gin/config'
3
+
4
+ class ConfigTest < Test::Unit::TestCase
5
+
6
+ def config_dir
7
+ File.expand_path("../mock_config", __FILE__)
8
+ end
9
+
10
+
11
+ def test_config_dev
12
+ config = Gin::Config.new "development", config_dir
13
+
14
+ assert_equal "localhost", config.memcache['host']
15
+ assert_equal 1, config.memcache['connections']
16
+
17
+ assert_equal "dev.backend.example.com", config.backend['host']
18
+
19
+ assert_raises(NoMethodError){ config.not_a_config }
20
+ end
21
+
22
+
23
+ def test_config_unknown_env
24
+ config = Gin::Config.new "foo", config_dir
25
+
26
+ assert_equal "example.com", config.memcache['host']
27
+ assert_equal 5, config.memcache['connections']
28
+
29
+ assert_equal "backend.example.com", config.backend['host']
30
+
31
+ assert_raises(NoMethodError){ config.not_a_config }
32
+ end
33
+ end
@@ -0,0 +1,808 @@
1
+ require "test/test_helper"
2
+
3
+ unless defined? EventMachine
4
+ class EventMachine; end
5
+ end
6
+
7
+ class AppController < Gin::Controller
8
+ FILTERS_RUN = []
9
+
10
+ before_filter :f1 do
11
+ FILTERS_RUN << :f1
12
+ end
13
+
14
+ after_filter :f2 do
15
+ FILTERS_RUN << :f2
16
+ end
17
+
18
+ error Gin::BadRequest do
19
+ body "Bad Request"
20
+ end
21
+ end
22
+
23
+ class TestController < Gin::Controller
24
+ def show id
25
+ "SHOW #{id}!"
26
+ end
27
+ end
28
+
29
+ class BarController < AppController
30
+ before_filter :stop, :only => :delete do
31
+ FILTERS_RUN << :stop
32
+ halt 404, "Not Found"
33
+ end
34
+
35
+ error 404 do
36
+ content_type "text/plain"
37
+ body "This is not the page you are looking for."
38
+ end
39
+
40
+ def show id
41
+ "SHOW #{id}!"
42
+ end
43
+
44
+ def delete id, email=nil, name=nil
45
+ "DELETE!"
46
+ end
47
+
48
+ def index
49
+ raise "OH NOES"
50
+ end
51
+
52
+ def caught_error
53
+ raise Gin::BadRequest, "Something is wrong"
54
+ end
55
+ end
56
+
57
+
58
+ class ControllerTest < Test::Unit::TestCase
59
+ class MockApp < Gin::App
60
+ mount BarController do
61
+ get :show, "/:id"
62
+ get :delete, :rm_bar
63
+ get :index, "/"
64
+ get :caught_error
65
+ end
66
+ end
67
+
68
+
69
+ def setup
70
+ MockApp.instance_variable_set("@environment", nil)
71
+ MockApp.instance_variable_set("@asset_host", nil)
72
+ @app = MockApp.new
73
+ @ctrl = BarController.new(@app, rack_env)
74
+ end
75
+
76
+
77
+ def teardown
78
+ BarController::FILTERS_RUN.clear
79
+ end
80
+
81
+
82
+ def rack_env
83
+ @rack_env ||= {
84
+ 'HTTP_HOST' => 'example.com',
85
+ 'rack.input' => '',
86
+ 'gin.path_query_hash' => {'id' => 123},
87
+ }
88
+ end
89
+
90
+
91
+ def test_etag
92
+ @ctrl.etag("my-etag")
93
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
94
+
95
+ @ctrl.etag("my-etag", kind: :strong)
96
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
97
+
98
+ @ctrl.etag("my-etag", :strong)
99
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
100
+ end
101
+
102
+
103
+ def test_etag_weak
104
+ @ctrl.etag("my-etag", kind: :weak)
105
+ assert_equal 'W/"my-etag"', @ctrl.response['ETag']
106
+
107
+ @ctrl.etag("my-etag", :weak)
108
+ assert_equal 'W/"my-etag"', @ctrl.response['ETag']
109
+ end
110
+
111
+
112
+ def test_etag_if_match
113
+ rack_env['HTTP_IF_MATCH'] = '"other-etag"'
114
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
115
+ assert_equal 412, resp
116
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
117
+
118
+ rack_env['HTTP_IF_MATCH'] = '*'
119
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
120
+ assert_equal nil, resp
121
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
122
+
123
+ rack_env['HTTP_IF_MATCH'] = '*'
124
+ resp = catch(:halt){ @ctrl.etag "my-etag", new_resource: true }
125
+ assert_equal 412, resp
126
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
127
+
128
+ rack_env['REQUEST_METHOD'] = 'POST'
129
+ rack_env['HTTP_IF_MATCH'] = '*'
130
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
131
+ assert_equal 412, resp
132
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
133
+ end
134
+
135
+
136
+ def test_etag_if_none_match
137
+ rack_env['REQUEST_METHOD'] = 'GET'
138
+
139
+ rack_env['HTTP_IF_NONE_MATCH'] = '"other-etag"'
140
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
141
+ assert_equal nil, resp
142
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
143
+
144
+ rack_env['HTTP_IF_NONE_MATCH'] = '"other-etag", "my-etag"'
145
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
146
+ assert_equal 304, resp
147
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
148
+
149
+ rack_env['HTTP_IF_NONE_MATCH'] = '*'
150
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
151
+ assert_equal 304, resp
152
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
153
+
154
+ rack_env['REQUEST_METHOD'] = 'POST'
155
+ rack_env['HTTP_IF_NONE_MATCH'] = '*'
156
+ resp = catch(:halt){ @ctrl.etag "my-etag", new_resource: false }
157
+ assert_equal 412, resp
158
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
159
+ end
160
+
161
+
162
+ def test_etag_non_error_status
163
+ [200, 201, 202, 304].each do |code|
164
+ @ctrl.status code
165
+ rack_env['HTTP_IF_MATCH'] = '"other-etag"'
166
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
167
+ assert_equal 412, resp
168
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
169
+ end
170
+ end
171
+
172
+
173
+ def test_etag_error_status
174
+ [301, 302, 303, 400, 404, 500, 502, 503].each do |code|
175
+ @ctrl.status code
176
+ rack_env['HTTP_IF_MATCH'] = '"other-etag"'
177
+ resp = catch(:halt){ @ctrl.etag "my-etag" }
178
+ assert_equal nil, resp
179
+ assert_equal "my-etag".inspect, @ctrl.response['ETag']
180
+ end
181
+ end
182
+
183
+
184
+ def test_cache_control
185
+ @ctrl.cache_control :public, :must_revalidate, max_age: 60
186
+ assert_equal "public, must-revalidate, max-age=60",
187
+ @ctrl.response['Cache-Control']
188
+
189
+ @ctrl.cache_control public:true, must_revalidate:false, max_age:'foo'
190
+ assert_equal "public, max-age=0", @ctrl.response['Cache-Control']
191
+ end
192
+
193
+
194
+ def test_expires_int
195
+ time = Time.now
196
+ @ctrl.expires 60, :public, :must_revalidate
197
+
198
+ assert_equal "public, must-revalidate, max-age=60",
199
+ @ctrl.response['Cache-Control']
200
+
201
+ assert_equal (time + 60).httpdate, @ctrl.response['Expires']
202
+ end
203
+
204
+
205
+ def test_expires_time
206
+ time = Time.now + 60
207
+ @ctrl.expires time, :public, must_revalidate:false, max_age:20
208
+
209
+ assert_equal "public, max-age=20",
210
+ @ctrl.response['Cache-Control']
211
+
212
+ assert_equal time.httpdate, @ctrl.response['Expires']
213
+ end
214
+
215
+
216
+ def test_expires_str
217
+ time = Time.now + 60
218
+ @ctrl.expires time.strftime("%Y/%m/%d %H:%M:%S"),
219
+ :public, must_revalidate:false, max_age:20
220
+
221
+ assert_equal "public, max-age=20",
222
+ @ctrl.response['Cache-Control']
223
+
224
+ assert_equal time.httpdate, @ctrl.response['Expires']
225
+ end
226
+
227
+
228
+ def test_expire_cache_control
229
+ @ctrl.expire_cache_control
230
+ assert_equal 'no-cache', @ctrl.response['Pragma']
231
+ assert_equal 'no-cache, no-store, must-revalidate, max-age=0',
232
+ @ctrl.response['Cache-Control']
233
+ assert_equal Time.new("1990","01","01").httpdate,
234
+ @ctrl.response['Expires']
235
+ end
236
+
237
+
238
+ def test_set_cookie
239
+ cookie = {:value => "user@example.com", :expires => Time.now + 360}
240
+ @ctrl.cookies['test'] = cookie
241
+ assert_equal cookie, @ctrl.env["rack.request.cookie_hash"]["test"]
242
+ assert_equal "user@example.com", @ctrl.cookies['test'][:value]
243
+ end
244
+
245
+
246
+ def test_set_session
247
+ @ctrl.session['test'] = 'user@example.com'
248
+ assert_equal({"test"=>"user@example.com"}, @ctrl.env['rack.session'])
249
+ end
250
+
251
+
252
+ def test_call_action
253
+ resp = @ctrl.call_action(:show)
254
+ assert_equal [:f1, :f2], BarController::FILTERS_RUN
255
+ assert_equal [200, {"Content-Type"=>"text/html;charset=UTF-8", "Content-Length"=>"9"},
256
+ ["SHOW 123!"]], resp
257
+ end
258
+
259
+
260
+ def test_call_action_error
261
+ @ctrl.call_action(:index)
262
+ assert_equal [:f1, :f2], BarController::FILTERS_RUN
263
+ end
264
+
265
+
266
+ def test_call_action_caught_error
267
+ resp = @ctrl.call_action(:caught_error)
268
+ assert_equal [:f1, :f2], BarController::FILTERS_RUN
269
+ assert_equal [400, {"Content-Type"=>"text/html;charset=UTF-8", "Content-Length"=>"11"},
270
+ ["Bad Request"]], resp
271
+ end
272
+
273
+
274
+ def test_call_action_halt
275
+ resp = @ctrl.call_action(:delete)
276
+ assert_equal [:f1, :stop, :f2], BarController::FILTERS_RUN
277
+ assert_equal [404, {"Content-Type"=>"text/plain;charset=UTF-8", "Content-Length"=>"41"},
278
+ ["This is not the page you are looking for."]], resp
279
+ end
280
+
281
+
282
+ def test_dispatch
283
+ @ctrl.send(:dispatch, :show)
284
+ assert_equal [:f1, :f2], BarController::FILTERS_RUN
285
+ assert_equal 200, @ctrl.response.status
286
+ assert_equal ["SHOW 123!"], @ctrl.response.body
287
+ end
288
+
289
+
290
+ def test_dispatch_error
291
+ @ctrl.content_type :json
292
+ @ctrl.send(:dispatch, :index)
293
+ assert_equal [:f1, :f2], BarController::FILTERS_RUN
294
+ assert_equal 500, @ctrl.response.status
295
+ assert RuntimeError === @ctrl.env['gin.errors'].first
296
+ assert_equal String, @ctrl.response.body[0].class
297
+ assert_equal "text/html;charset=UTF-8", @ctrl.response['Content-Type']
298
+ assert @ctrl.response.body[0].include?('<h1>RuntimeError</h1>')
299
+ assert @ctrl.response.body[0].include?('<pre>')
300
+ end
301
+
302
+
303
+ def test_dispatch_error_nondev
304
+ MockApp.environment "prod"
305
+ @ctrl.send(:dispatch, :index)
306
+
307
+ assert_equal 500, @ctrl.response.status
308
+ assert RuntimeError === @ctrl.env['gin.errors'].first
309
+
310
+ assert_equal File.read(File.join(Gin::PUBLIC_DIR, "500.html")),
311
+ @ctrl.body.read
312
+ end
313
+
314
+
315
+ def test_dispatch_bad_request_nondev
316
+ MockApp.environment "prod"
317
+ @ctrl = TestController.new @app, rack_env
318
+ @ctrl.params.delete('id')
319
+ @ctrl.send(:dispatch, :show)
320
+
321
+ assert_equal 400, @ctrl.response.status
322
+ assert Gin::BadRequest === @ctrl.env['gin.errors'].first
323
+ assert_equal File.read(File.join(Gin::PUBLIC_DIR, "400.html")),
324
+ @ctrl.body.read
325
+ end
326
+
327
+
328
+ def test_dispatch_not_found_nondev
329
+ MockApp.environment "prod"
330
+ @ctrl = TestController.new @app, rack_env
331
+ @ctrl.params.delete('id')
332
+ @ctrl.send(:dispatch, :not_found)
333
+
334
+ assert_equal 404, @ctrl.response.status
335
+ assert Gin::NotFound === @ctrl.env['gin.errors'].first
336
+ assert_equal File.read(File.join(Gin::PUBLIC_DIR, "404.html")),
337
+ @ctrl.body.read
338
+ end
339
+
340
+
341
+ def test_dispatch_filter_halt
342
+ @ctrl.send(:dispatch, :delete)
343
+ assert_equal [:f1, :stop, :f2], BarController::FILTERS_RUN
344
+ assert_equal 404, @ctrl.response.status
345
+ assert_equal ["Not Found"], @ctrl.response.body
346
+ end
347
+
348
+
349
+ def test_invoke
350
+ @ctrl.send(:invoke){ "test body" }
351
+ assert_equal ["test body"], @ctrl.body
352
+
353
+ @ctrl.send(:invoke){ [401, "test body"] }
354
+ assert_equal 401, @ctrl.status
355
+ assert_equal ["test body"], @ctrl.body
356
+
357
+ @ctrl.send(:invoke){ [302, {'Location' => 'http://foo.com'}, "test body"] }
358
+ assert_equal 302, @ctrl.status
359
+ assert_equal 'http://foo.com', @ctrl.response['Location']
360
+ assert_equal ["test body"], @ctrl.body
361
+
362
+ @ctrl.send(:invoke){ 301 }
363
+ assert_equal 301, @ctrl.status
364
+ end
365
+
366
+
367
+ def test_action_arguments
368
+ assert_raises(Gin::NotFound){ @ctrl.send("action_arguments", "nonaction") }
369
+ assert_equal [], @ctrl.send("action_arguments", "index")
370
+
371
+ assert_equal [123], @ctrl.send("action_arguments", "show")
372
+ assert_equal [123], @ctrl.send("action_arguments", "delete")
373
+
374
+ @ctrl.params.update 'name' => 'bob'
375
+ assert_equal [123,nil,'bob'], @ctrl.send("action_arguments", "delete")
376
+
377
+ @ctrl.params.delete('id')
378
+ assert_raises(Gin::BadRequest){
379
+ @ctrl.send("action_arguments", "show")
380
+ }
381
+ end
382
+
383
+
384
+ if RUBY_VERSION =~ /^2.0/
385
+ eval <<-EVAL
386
+ class SpecialCtrl < Gin::Controller
387
+ def find(q, title_only:false, count: 10); end
388
+ end
389
+ EVAL
390
+
391
+ def test_action_arguments_key_parameters
392
+ @ctrl = SpecialCtrl.new nil, rack_env.merge('QUERY_STRING'=>'q=pizza&count=20')
393
+ assert_equal ["pizza", {count: 20}], @ctrl.send("action_arguments", "find")
394
+ end
395
+ end
396
+
397
+
398
+ def test_asset_url
399
+ old_public_dir = MockApp.public_dir
400
+ MockApp.public_dir File.dirname(__FILE__)
401
+
402
+ file_id = MockApp.md5 __FILE__
403
+ expected = "/test_controller.rb?#{file_id}"
404
+
405
+ assert_equal 8, file_id.length
406
+ assert_equal expected, @ctrl.asset_url(File.basename(__FILE__))
407
+
408
+ ensure
409
+ MockApp.public_dir old_public_dir
410
+ end
411
+
412
+
413
+ def test_asset_url_unknown
414
+ assert_equal "/foo.jpg", @ctrl.asset_url("foo.jpg")
415
+ end
416
+
417
+
418
+ def test_asset_url_w_host
419
+ MockApp.asset_host "http://example.com"
420
+ assert_equal "http://example.com/foo.jpg", @ctrl.asset_url("foo.jpg")
421
+
422
+ MockApp.asset_host do |file|
423
+ file =~ /\.js$/ ? "http://js.example.com" : "http://img.example.com"
424
+ end
425
+ assert_equal "http://js.example.com/foo.js", @ctrl.asset_url("foo.js")
426
+ assert_equal "http://img.example.com/foo.jpg", @ctrl.asset_url("foo.jpg")
427
+ end
428
+
429
+
430
+ def test_redirect_non_get
431
+ rack_env['REQUEST_METHOD'] = 'POST'
432
+ rack_env['HTTP_VERSION'] = 'HTTP/1.0'
433
+ catch(:halt){ @ctrl.redirect "/foo" }
434
+ assert_equal 302, @ctrl.status
435
+ assert_equal "http://example.com/foo", @ctrl.response['Location']
436
+
437
+ rack_env['HTTP_VERSION'] = 'HTTP/1.1'
438
+ catch(:halt){ @ctrl.redirect "/foo" }
439
+ assert_equal 303, @ctrl.status
440
+ assert_equal "http://example.com/foo", @ctrl.response['Location']
441
+ end
442
+
443
+
444
+ def test_redirect
445
+ catch(:halt){ @ctrl.redirect "/foo" }
446
+ assert_equal 302, @ctrl.status
447
+ assert_equal "http://example.com/foo", @ctrl.response['Location']
448
+
449
+ resp = catch(:halt){ @ctrl.redirect "https://google.com/foo", 301, "Move Along" }
450
+ assert_equal 302, @ctrl.status
451
+ assert_equal "https://google.com/foo", @ctrl.response['Location']
452
+ assert_equal [301, "Move Along"], resp
453
+
454
+ resp = catch(:halt){ @ctrl.redirect "https://google.com/foo", 301, {'X-LOC' => "test"}, "Move Along" }
455
+ assert_equal 302, @ctrl.status
456
+ assert_equal "https://google.com/foo", @ctrl.response['Location']
457
+ assert_equal [301, {'X-LOC' => "test"}, "Move Along"], resp
458
+ end
459
+
460
+
461
+ def test_url_to
462
+ assert_equal "http://example.com/bar/123",
463
+ @ctrl.url_to(BarController, :show, :id => 123)
464
+ assert_equal "http://example.com/bar/123", @ctrl.url_to(:show, :id => 123)
465
+ assert_equal "http://example.com/bar/delete?id=123",
466
+ @ctrl.url_to(:rm_bar, :id => 123)
467
+ assert_equal "https://foo.com/path?id=123",
468
+ @ctrl.url_to("https://foo.com/path", :id => 123)
469
+ assert_equal "http://example.com/bar/123",
470
+ @ctrl.to(BarController, :show, :id => 123)
471
+ end
472
+
473
+
474
+ def test_path_to
475
+ assert_equal "/bar/123", @ctrl.path_to(BarController, :show, id: 123)
476
+ assert_equal "/bar/123", @ctrl.path_to(:show, id: 123)
477
+ assert_equal "/bar/delete?id=123", @ctrl.path_to(:rm_bar, id: 123)
478
+ assert_equal "/bar/delete", @ctrl.path_to(:rm_bar)
479
+ assert_equal "/test?id=123", @ctrl.path_to("/test", id: 123)
480
+ assert_equal "/test", @ctrl.path_to("/test")
481
+ end
482
+
483
+
484
+ def test_session
485
+ assert_equal(@ctrl.request.session, @ctrl.session)
486
+ end
487
+
488
+
489
+ def test_params
490
+ assert_equal({'id' => 123}, @ctrl.params)
491
+ assert_equal(@ctrl.request.params, @ctrl.params)
492
+ end
493
+
494
+
495
+ def test_logger
496
+ assert_equal @app.logger, @ctrl.logger
497
+ end
498
+
499
+
500
+ def test_stream
501
+ @ctrl.stream{|out| out << "BODY"}
502
+ assert Gin::Stream === @ctrl.body
503
+ assert_equal Gin::Stream, @ctrl.body.instance_variable_get("@scheduler")
504
+
505
+ @ctrl.env.merge! "async.callback" => lambda{}
506
+
507
+ @ctrl.stream{|out| out << "BODY"}
508
+ assert Gin::Stream === @ctrl.body
509
+ assert_equal EventMachine, @ctrl.body.instance_variable_get("@scheduler")
510
+ end
511
+
512
+
513
+ def test_headers
514
+ @ctrl.headers "Content-Length" => 123
515
+ assert_equal @ctrl.response.headers, @ctrl.headers
516
+ assert_equal({"Content-Length"=>123}, @ctrl.headers)
517
+ end
518
+
519
+
520
+ def test_error_num_and_str
521
+ resp = catch :halt do
522
+ @ctrl.error 404, "Not Found"
523
+ "BAD RESP"
524
+ end
525
+
526
+ assert_equal 404, resp
527
+ assert_equal ["Not Found"], @ctrl.body
528
+ end
529
+
530
+
531
+ def test_error_num
532
+ resp = catch :halt do
533
+ @ctrl.error 404
534
+ "BAD RESP"
535
+ end
536
+
537
+ assert_equal 404, resp
538
+ assert_equal [], @ctrl.body
539
+ end
540
+
541
+
542
+ def test_error_str
543
+ resp = catch :halt do
544
+ @ctrl.error "OH NOES"
545
+ "BAD RESP"
546
+ end
547
+
548
+ assert_equal 500, resp
549
+ assert_equal ["OH NOES"], @ctrl.body
550
+ end
551
+
552
+
553
+ def test_halt_single
554
+ resp = catch :halt do
555
+ @ctrl.halt 400
556
+ "BAD RESP"
557
+ end
558
+
559
+ assert_equal 400, resp
560
+ end
561
+
562
+
563
+ def test_halt_ary
564
+ resp = catch :halt do
565
+ @ctrl.halt 201, "Accepted"
566
+ "BAD RESP"
567
+ end
568
+
569
+ assert_equal [201, "Accepted"], resp
570
+ end
571
+
572
+
573
+ def test_last_modified
574
+ time = Time.now
575
+ @ctrl.last_modified time
576
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
577
+
578
+ date = DateTime.parse time.to_s
579
+ @ctrl.last_modified date
580
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
581
+
582
+ date = Date.parse time.to_s
583
+ expected = Time.new(time.year, time.month, time.day)
584
+ @ctrl.last_modified date
585
+ assert_equal expected.httpdate, @ctrl.response['Last-Modified']
586
+ end
587
+
588
+
589
+ def test_last_modified_str
590
+ time = Time.now
591
+ @ctrl.last_modified time.to_s
592
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
593
+ end
594
+
595
+
596
+ def test_last_modified_int
597
+ time = Time.now
598
+ @ctrl.last_modified time.to_i
599
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
600
+ end
601
+
602
+
603
+ def test_last_modified_false
604
+ @ctrl.last_modified false
605
+ assert_nil @ctrl.response['Last-Modified']
606
+ end
607
+
608
+
609
+ def test_last_modified_if_modified_since
610
+ rack_env['HTTP_IF_MODIFIED_SINCE'] = Time.parse("10 Feb 3012").httpdate
611
+ time = Time.now
612
+ @ctrl.status 200
613
+ res = catch(:halt){ @ctrl.last_modified time }
614
+
615
+ assert_equal 304, res
616
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
617
+
618
+ rack_env['HTTP_IF_MODIFIED_SINCE'] = Time.parse("10 Feb 2012").httpdate
619
+ time = Time.now
620
+ @ctrl.status 200
621
+ @ctrl.last_modified time
622
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
623
+ end
624
+
625
+
626
+ def test_last_modified_if_modified_since_non_200
627
+ rack_env['HTTP_IF_MODIFIED_SINCE'] = Time.parse("10 Feb 3012").httpdate
628
+ time = Time.now
629
+ @ctrl.status 404
630
+ @ctrl.last_modified time
631
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
632
+ end
633
+
634
+
635
+ def test_last_modified_if_unmodified_since
636
+ [200, 299, 412].each do |code|
637
+ rack_env['HTTP_IF_UNMODIFIED_SINCE'] = Time.parse("10 Feb 2012").httpdate
638
+ time = Time.now
639
+ @ctrl.status code
640
+ res = catch(:halt){ @ctrl.last_modified time }
641
+
642
+ assert_equal 412, res
643
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
644
+
645
+ rack_env['HTTP_IF_MODIFIED_SINCE'] = Time.parse("10 Feb 3012").httpdate
646
+ time = Time.now
647
+ @ctrl.status code
648
+ @ctrl.last_modified time
649
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
650
+ end
651
+ end
652
+
653
+
654
+ def test_last_modified_if_unmodified_since_404
655
+ rack_env['HTTP_IF_UNMODIFIED_SINCE'] = Time.parse("10 Feb 2012").httpdate
656
+ time = Time.now
657
+ @ctrl.status 404
658
+ @ctrl.last_modified time
659
+
660
+ assert_equal 404, @ctrl.status
661
+ assert_equal time.httpdate, @ctrl.response['Last-Modified']
662
+ end
663
+
664
+
665
+ def test_send_file
666
+ res = catch(:halt){ @ctrl.send_file "./Manifest.txt" }
667
+ assert_equal 200, res[0]
668
+ assert File === res[1]
669
+
670
+ @ctrl.status 404
671
+ @ctrl.send(:invoke){ @ctrl.send_file "./Manifest.txt" }
672
+ assert_equal 200, @ctrl.status
673
+ assert_equal "text/plain;charset=UTF-8", @ctrl.headers["Content-Type"]
674
+ assert_equal File.size("./Manifest.txt").to_s, @ctrl.headers["Content-Length"]
675
+ assert(Time.parse(@ctrl.headers["Last-Modified"]) >
676
+ Time.parse("Fri, 22 Feb 2012 18:51:31 GMT"))
677
+ assert File === @ctrl.body
678
+
679
+ read_body = ""
680
+ @ctrl.body.each{|data| read_body << data}
681
+ assert_equal File.read("./Manifest.txt"), read_body
682
+ end
683
+
684
+
685
+ def test_send_file_not_found
686
+ res = catch(:halt){ @ctrl.send_file "./no-such-file" }
687
+ assert_equal 404, res
688
+ end
689
+
690
+
691
+ def test_send_file_last_modified
692
+ mod_date = Time.now
693
+ catch(:halt){ @ctrl.send_file "./Manifest.txt", last_modified: mod_date }
694
+ assert_equal mod_date.httpdate, @ctrl.headers["Last-Modified"]
695
+ assert_nil @ctrl.headers['Content-Disposition']
696
+ end
697
+
698
+
699
+ def test_send_file_attachment
700
+ res = catch(:halt){ @ctrl.send_file "./Manifest.txt", :disposition => 'attachment' }
701
+ expected = "attachment; filename=\"Manifest.txt\""
702
+ assert_equal expected, @ctrl.headers['Content-Disposition']
703
+
704
+ res = catch(:halt){
705
+ @ctrl.send_file "./Manifest.txt", :disposition => 'attachment', :filename => "foo.txt"
706
+ }
707
+ expected = "attachment; filename=\"foo.txt\""
708
+ assert_equal expected, @ctrl.headers['Content-Disposition']
709
+ end
710
+
711
+
712
+ def test_mime_type
713
+ assert_equal "text/html", @ctrl.mime_type(:html)
714
+ assert_equal @ctrl.app.mime_type(:html), @ctrl.mime_type(:html)
715
+ end
716
+
717
+
718
+ def test_content_type
719
+ assert_nil @ctrl.content_type
720
+ assert_nil @ctrl.response['Content-Type']
721
+
722
+ @ctrl.content_type 'text/json'
723
+ assert_equal "text/json;charset=UTF-8", @ctrl.content_type
724
+ assert_equal "text/json;charset=UTF-8", @ctrl.response['Content-Type']
725
+
726
+ assert_equal "application/json;charset=UTF-8", @ctrl.content_type(".json")
727
+ end
728
+
729
+
730
+ def test_content_type_params
731
+ assert_equal "application/json;charset=ASCII-8BIT",
732
+ @ctrl.content_type(".json", charset: "ASCII-8BIT")
733
+
734
+ assert_equal "application/json;foo=bar, charset=UTF-8",
735
+ @ctrl.content_type(".json", foo: "bar")
736
+ end
737
+
738
+
739
+ def test_content_type_unknown
740
+ assert_raises RuntimeError do
741
+ @ctrl.content_type 'fhwbghd'
742
+ end
743
+
744
+ assert_equal "text/html;charset=UTF-8",
745
+ @ctrl.content_type('fhwbghd', default: 'text/html')
746
+ end
747
+
748
+
749
+ def test_body
750
+ assert_equal [], @ctrl.body
751
+ assert_equal [], @ctrl.response.body
752
+
753
+ @ctrl.body("<HTML></HTML>")
754
+ assert_equal ["<HTML></HTML>"], @ctrl.body
755
+ assert_equal ["<HTML></HTML>"], @ctrl.response.body
756
+ end
757
+
758
+
759
+ def test_status
760
+ assert_equal 200, @ctrl.status
761
+ assert_equal 200, @ctrl.response.status
762
+
763
+ @ctrl.status(404)
764
+ assert_equal 404, @ctrl.status
765
+ assert_equal 404, @ctrl.response.status
766
+ end
767
+
768
+
769
+ def test_init
770
+ assert Gin::Request === @ctrl.request
771
+ assert Gin::Response === @ctrl.response
772
+ assert_nil @ctrl.response['Content-Type']
773
+ assert_equal @app, @ctrl.app
774
+ assert_equal rack_env, @ctrl.env
775
+ end
776
+
777
+
778
+ def test_supports_features
779
+ assert Gin::Controller.ancestors.include?(Gin::Filterable)
780
+ assert Gin::Controller.ancestors.include?(Gin::Errorable)
781
+ end
782
+
783
+
784
+ def test_class_controller_name
785
+ assert_equal "app", AppController.controller_name
786
+ assert_equal "bar", BarController.controller_name
787
+
788
+ assert_equal "app", AppController.new(nil,rack_env).controller_name
789
+ end
790
+
791
+
792
+ def test_class_content_type
793
+ assert_equal "text/html", AppController.content_type
794
+ assert_equal "text/html", BarController.content_type
795
+
796
+ AppController.content_type "application/json"
797
+ assert_equal "application/json", AppController.content_type
798
+ assert_equal "application/json", BarController.content_type
799
+
800
+ BarController.content_type "text/plain"
801
+ assert_equal "application/json", AppController.content_type
802
+ assert_equal "text/plain", BarController.content_type
803
+
804
+ ensure
805
+ AppController.instance_variable_set("@content_type",nil)
806
+ BarController.instance_variable_set("@content_type",nil)
807
+ end
808
+ end