File tree Expand file tree Collapse file tree 6 files changed +80
-11
lines changed
Expand file tree Collapse file tree 6 files changed +80
-11
lines changed Original file line number Diff line number Diff line change @@ -10,7 +10,7 @@ group :development do
1010end
1111
1212group :test do
13- gem 'rspec' , '>= 2.0.0.beta.19 '
13+ gem 'rspec' , '>= 2.0.0.beta.20 '
1414 gem 'rack-test'
1515 gem 'cucumber' , '>= 0.8.5'
1616end
Original file line number Diff line number Diff line change 2525 rack-test (0.5.4 )
2626 rack (>= 1.0 )
2727 rake (0.8.7 )
28- rspec (2.0.0.beta.19 )
29- rspec-core (= 2.0.0.beta.19 )
30- rspec-expectations (= 2.0.0.beta.19 )
31- rspec-mocks (= 2.0.0.beta.19 )
32- rspec-core (2.0.0.beta.19 )
33- rspec-expectations (2.0.0.beta.19 )
28+ rspec (2.0.0.beta.20 )
29+ rspec-core (= 2.0.0.beta.20 )
30+ rspec-expectations (= 2.0.0.beta.20 )
31+ rspec-mocks (= 2.0.0.beta.20 )
32+ rspec-core (2.0.0.beta.20 )
33+ rspec-expectations (2.0.0.beta.20 )
3434 diff-lcs (>= 1.1.2 )
35- rspec-mocks (2.0.0.beta.19 )
35+ rspec-mocks (2.0.0.beta.20 )
3636 rubyforge (2.0.4 )
3737 json_pure (>= 1.1.7 )
3838 term-ansicolor (1.0.5 )
@@ -50,4 +50,4 @@ DEPENDENCIES
5050 rack-mount
5151 rack-test
5252 rake
53- rspec (>= 2.0.0.beta.19 )
53+ rspec (>= 2.0.0.beta.20 )
Original file line number Diff line number Diff line change @@ -22,9 +22,17 @@ def content_types
2222 CONTENT_TYPES . merge ( options [ :content_types ] )
2323 end
2424
25+ def mime_types
26+ CONTENT_TYPES . invert
27+ end
28+
29+ def headers
30+ env . dup . inject ( { } ) { |h , ( k , v ) | h [ k . downcase ] = v ; h }
31+ end
32+
2533 def before
2634 fmt = format_from_extension || format_from_header || options [ :default_format ]
27-
35+
2836 if content_types . key? ( fmt )
2937 env [ 'api.format' ] = fmt
3038 else
@@ -44,7 +52,24 @@ def format_from_extension
4452 end
4553
4654 def format_from_header
47- # TODO: Implement Accept header parsing.
55+ mime_array . each do |t |
56+ if mime_types . key? ( t )
57+ return mime_types [ t ]
58+ end
59+ end
60+ nil
61+ end
62+
63+ def mime_array
64+ accept = headers [ 'accept' ]
65+ if accept
66+ accept . gsub ( /\b / , '' ) .
67+ scan ( /(\w +\/ [\w +]+)(?:;[^,]*q=([0-9.]+)[^,]*)?/i ) .
68+ sort_by { |a | -a [ 1 ] . to_f } .
69+ map { |a | a [ 0 ] }
70+ else
71+ [ ]
72+ end
4873 end
4974
5075 def after
Original file line number Diff line number Diff line change @@ -13,6 +13,10 @@ def before
1313 pieces = env [ 'PATH_INFO' ] . split ( '/' )
1414 potential_version = pieces [ 1 ]
1515 if potential_version =~ options [ :pattern ]
16+ if options [ :versions ] && !options [ :versions ] . include? ( potential_version )
17+ throw :error , :status => 404 , :message => "The specified version of the API does not exist."
18+ end
19+
1620 truncated_path = "/#{ pieces [ 2 ..-1 ] . join ( '/' ) } "
1721 env [ 'api.version' ] = potential_version
1822 env [ 'PATH_INFO' ] = truncated_path
Original file line number Diff line number Diff line change 3232 err . should == { :status => 406 , :message => "The requested format is not supported." }
3333 end
3434 end
35+
36+ context 'Accept header detection' do
37+ it 'should detect from the Accept header' do
38+ subject . call ( { 'PATH_INFO' => '/info' , 'Accept' => 'application/xml' } )
39+ subject . env [ 'api.format' ] . should == :xml
40+ end
41+
42+ it 'should look for case-indifferent headers' do
43+ subject . call ( { 'PATH_INFO' => '/info' , 'accept' => 'application/xml' } )
44+ subject . env [ 'api.format' ] . should == :xml
45+ end
46+
47+ it 'should use quality rankings to determine formats' do
48+ subject . call ( { 'PATH_INFO' => '/info' , 'Accept' => 'application/json; q=0.3,application/xml; q=1.0' } )
49+ subject . env [ 'api.format' ] . should == :xml
50+ subject . call ( { 'PATH_INFO' => '/info' , 'Accept' => 'application/json; q=1.0,application/xml; q=0.3' } )
51+ subject . env [ 'api.format' ] . should == :json
52+ end
53+
54+ it 'should handle quality rankings mixed with nothing' do
55+ subject . call ( { 'PATH_INFO' => '/info' , 'Accept' => 'application/json,application/xml; q=1.0' } )
56+ subject . env [ 'api.format' ] . should == :xml
57+ end
58+
59+ it 'should properly parse headers with other attributes' do
60+ subject . call ( { 'PATH_INFO' => '/info' , 'Accept' => 'application/json; abc=2.3; q=1.0,application/xml; q=0.7' } )
61+ subject . env [ 'api.format' ] . should == :json
62+ end
63+ end
3564end
Original file line number Diff line number Diff line change 2626 subject . call ( 'PATH_INFO' => '/awesome/radical' ) . last . should be_nil
2727 end
2828 end
29+
30+ context 'with specified versions' do
31+ before { @options = { :versions => [ 'v1' , 'v2' ] } }
32+ it 'should throw an error if a non-allowed version is specified' do
33+ catch ( :error ) { subject . call ( 'PATH_INFO' => '/v3/awesome' ) } [ :status ] . should == 404
34+ end
35+
36+ it 'should allow versions that have been specified' do
37+ subject . call ( 'PATH_INFO' => '/v1/asoasd' ) . last . should == 'v1'
38+ end
39+ end
2940end
You can’t perform that action at this time.
0 commit comments