strelka 0.0.1pre4 → 0.0.1.pre129
Sign up to get free protection for your applications and to get access to all the features.
- data/History.rdoc +1 -1
- data/IDEAS.rdoc +62 -0
- data/Manifest.txt +38 -7
- data/README.rdoc +124 -5
- data/Rakefile +22 -6
- data/bin/leash +102 -157
- data/contrib/hoetemplate/.autotest.erb +23 -0
- data/contrib/hoetemplate/History.rdoc.erb +4 -0
- data/contrib/hoetemplate/Manifest.txt.erb +8 -0
- data/contrib/hoetemplate/README.rdoc.erb +17 -0
- data/contrib/hoetemplate/Rakefile.erb +24 -0
- data/contrib/hoetemplate/data/file_name/apps/file_name_app +36 -0
- data/contrib/hoetemplate/data/file_name/templates/layout.tmpl.erb +13 -0
- data/contrib/hoetemplate/data/file_name/templates/top.tmpl.erb +8 -0
- data/contrib/hoetemplate/lib/file_name.rb.erb +18 -0
- data/contrib/hoetemplate/spec/file_name_spec.rb.erb +21 -0
- data/data/strelka/apps/hello-world +30 -0
- data/lib/strelka/app/defaultrouter.rb +49 -30
- data/lib/strelka/app/errors.rb +121 -0
- data/lib/strelka/app/exclusiverouter.rb +40 -0
- data/lib/strelka/app/filters.rb +18 -7
- data/lib/strelka/app/negotiation.rb +122 -0
- data/lib/strelka/app/parameters.rb +171 -14
- data/lib/strelka/app/paramvalidator.rb +751 -0
- data/lib/strelka/app/plugins.rb +66 -46
- data/lib/strelka/app/restresources.rb +499 -0
- data/lib/strelka/app/router.rb +73 -0
- data/lib/strelka/app/routing.rb +140 -18
- data/lib/strelka/app/templating.rb +12 -3
- data/lib/strelka/app.rb +174 -24
- data/lib/strelka/constants.rb +0 -20
- data/lib/strelka/exceptions.rb +29 -0
- data/lib/strelka/httprequest/acceptparams.rb +377 -0
- data/lib/strelka/httprequest/negotiation.rb +257 -0
- data/lib/strelka/httprequest.rb +155 -7
- data/lib/strelka/httpresponse/negotiation.rb +579 -0
- data/lib/strelka/httpresponse.rb +140 -0
- data/lib/strelka/logging.rb +4 -1
- data/lib/strelka/mixins.rb +53 -0
- data/lib/strelka.rb +22 -1
- data/spec/data/error.tmpl +1 -0
- data/spec/lib/constants.rb +0 -1
- data/spec/lib/helpers.rb +21 -0
- data/spec/strelka/app/defaultrouter_spec.rb +41 -35
- data/spec/strelka/app/errors_spec.rb +212 -0
- data/spec/strelka/app/exclusiverouter_spec.rb +220 -0
- data/spec/strelka/app/filters_spec.rb +196 -0
- data/spec/strelka/app/negotiation_spec.rb +73 -0
- data/spec/strelka/app/parameters_spec.rb +149 -0
- data/spec/strelka/app/paramvalidator_spec.rb +1059 -0
- data/spec/strelka/app/plugins_spec.rb +26 -19
- data/spec/strelka/app/restresources_spec.rb +393 -0
- data/spec/strelka/app/router_spec.rb +63 -0
- data/spec/strelka/app/routing_spec.rb +183 -9
- data/spec/strelka/app/templating_spec.rb +1 -2
- data/spec/strelka/app_spec.rb +265 -32
- data/spec/strelka/exceptions_spec.rb +53 -0
- data/spec/strelka/httprequest/acceptparams_spec.rb +282 -0
- data/spec/strelka/httprequest/negotiation_spec.rb +246 -0
- data/spec/strelka/httprequest_spec.rb +204 -14
- data/spec/strelka/httpresponse/negotiation_spec.rb +464 -0
- data/spec/strelka/httpresponse_spec.rb +114 -0
- data/spec/strelka/mixins_spec.rb +99 -0
- data.tar.gz.sig +1 -0
- metadata +175 -79
- metadata.gz.sig +2 -0
- data/IDEAS.textile +0 -174
- data/data/strelka/apps/strelka-admin +0 -65
- data/data/strelka/apps/strelka-setup +0 -26
- data/data/strelka/bootstrap-config.rb +0 -34
- data/data/strelka/templates/admin/console.tmpl +0 -21
- data/data/strelka/templates/layout.tmpl +0 -30
- data/lib/strelka/process.rb +0 -19
@@ -0,0 +1,282 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
10
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
|
+
}
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
|
15
|
+
require 'spec/lib/helpers'
|
16
|
+
|
17
|
+
require 'strelka'
|
18
|
+
require 'strelka/httprequest/acceptparams'
|
19
|
+
|
20
|
+
|
21
|
+
#####################################################################
|
22
|
+
### C O N T E X T S
|
23
|
+
#####################################################################
|
24
|
+
|
25
|
+
describe Strelka::HTTPRequest, "accept params" do
|
26
|
+
before( :all ) do
|
27
|
+
setup_logging( :fatal )
|
28
|
+
end
|
29
|
+
|
30
|
+
after( :all ) do
|
31
|
+
reset_logging()
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
describe Strelka::HTTPRequest::MediaType do
|
36
|
+
|
37
|
+
VALID_HEADERS = {
|
38
|
+
'*/*' =>
|
39
|
+
{:type => nil, :subtype => nil, :qval => 1.0},
|
40
|
+
'*/*; q=0.1' =>
|
41
|
+
{:type => nil, :subtype => nil, :qval => 0.1},
|
42
|
+
'*/*;q=0.1' =>
|
43
|
+
{:type => nil, :subtype => nil, :qval => 0.1},
|
44
|
+
'image/*' =>
|
45
|
+
{:type => 'image', :subtype => nil, :qval => 1.0},
|
46
|
+
'image/*; q=0.18' =>
|
47
|
+
{:type => 'image', :subtype => nil, :qval => 0.18},
|
48
|
+
'image/*;q=0.4' =>
|
49
|
+
{:type => 'image', :subtype => nil, :qval => 0.4},
|
50
|
+
'image/*;q=0.9; porn=0; anseladams=1' =>
|
51
|
+
{:type => 'image', :subtype => nil, :qval => 0.9,
|
52
|
+
:extensions => %w[anseladams=1 porn=0]},
|
53
|
+
'image/png' =>
|
54
|
+
{:type => 'image', :subtype => 'png', :qval => 1.0},
|
55
|
+
'IMAGE/pNg' =>
|
56
|
+
{:type => 'image', :subtype => 'png', :qval => 1.0},
|
57
|
+
'application/x-porno' =>
|
58
|
+
{:type => 'application', :subtype => 'x-porno', :qval => 1.0},
|
59
|
+
'image/png; q=0.2' =>
|
60
|
+
{:type => 'image', :subtype => 'png', :qval => 0.2},
|
61
|
+
'image/x-giraffes;q=0.2' =>
|
62
|
+
{:type => 'image', :subtype => 'x-giraffes', :qval => 0.2},
|
63
|
+
'example/pork; headcheese=0;withfennel=1' =>
|
64
|
+
{:type => 'example', :subtype => 'pork', :qval => 1.0,
|
65
|
+
:extensions => %w[headcheese=0 withfennel=1]},
|
66
|
+
'model/vnd.moml+xml' =>
|
67
|
+
{:type => 'model', :subtype => 'vnd.moml+xml', :qval => 1.0},
|
68
|
+
'model/parasolid.transmit.binary; q=0.2' =>
|
69
|
+
{:type => 'model', :subtype => 'parasolid.transmit.binary',
|
70
|
+
:qval => 0.2},
|
71
|
+
'image/png; q=0.2; compression=1' =>
|
72
|
+
{:type => 'image', :subtype => 'png', :qval => 0.2,
|
73
|
+
:extensions => %w[compression=1]},
|
74
|
+
}
|
75
|
+
|
76
|
+
|
77
|
+
it "parses valid Accept header values" do
|
78
|
+
VALID_HEADERS.each do |hdr, expectations|
|
79
|
+
rval = Strelka::HTTPRequest::MediaType.parse( hdr )
|
80
|
+
|
81
|
+
rval.should be_an_instance_of( Strelka::HTTPRequest::MediaType )
|
82
|
+
rval.type.should == expectations[:type]
|
83
|
+
rval.subtype.should == expectations[:subtype]
|
84
|
+
rval.qvalue.should == expectations[:qval]
|
85
|
+
|
86
|
+
if expectations[:extensions]
|
87
|
+
expectations[:extensions].each do |ext|
|
88
|
+
rval.extensions.should include( ext )
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
it "is lenient (but warns) about invalid qvalues" do
|
96
|
+
rval = Strelka::HTTPRequest::MediaType.parse( '*/*; q=18' )
|
97
|
+
rval.should be_an_instance_of( Strelka::HTTPRequest::MediaType )
|
98
|
+
rval.qvalue.should == 1.0
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
it "rejects invalid Accept header values" do
|
103
|
+
lambda {
|
104
|
+
Strelka::HTTPRequest::MediaType.parse( 'porksausage' )
|
105
|
+
}.should raise_error()
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
it "can represent itself in a human-readable object format" do
|
110
|
+
header = "text/html; q=0.9; level=2"
|
111
|
+
acceptparam = Strelka::HTTPRequest::MediaType.parse( header )
|
112
|
+
acceptparam.inspect.should =~ %r{MediaType.*text/html.*q=0.9}
|
113
|
+
end
|
114
|
+
|
115
|
+
|
116
|
+
it "can represent itself as an Accept header" do
|
117
|
+
header = "text/html;q=0.9;level=2"
|
118
|
+
acceptparam = Strelka::HTTPRequest::MediaType.parse( header )
|
119
|
+
acceptparam.to_s.should == header
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
it "can compare and sort on specificity" do
|
124
|
+
header = "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9," +
|
125
|
+
"text/html;q=0.9;level=1,text/plain;q=0.8,image/png,*/*;q=0.5"
|
126
|
+
params = header.
|
127
|
+
split( /\s*,\s*/ ).
|
128
|
+
collect {|par| Strelka::HTTPRequest::MediaType.parse( par ) }.
|
129
|
+
sort
|
130
|
+
|
131
|
+
params[0].to_s.should == 'application/xhtml+xml;q=1.0'
|
132
|
+
params[1].to_s.should == 'application/xml;q=1.0'
|
133
|
+
params[2].to_s.should == 'image/png;q=1.0'
|
134
|
+
params[3].to_s.should == 'text/xml;q=1.0'
|
135
|
+
params[4].to_s.should == 'text/html;q=0.9'
|
136
|
+
params[5].to_s.should == 'text/html;q=0.9;level=1'
|
137
|
+
params[6].to_s.should == 'text/plain;q=0.8'
|
138
|
+
params[7].to_s.should == '*/*;q=0.5'
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
it "can be compared against strings" do
|
143
|
+
specific_param = Strelka::HTTPRequest::MediaType.parse( 'text/html' )
|
144
|
+
subtype_wildcard_param = Strelka::HTTPRequest::MediaType.parse( 'image/*' )
|
145
|
+
|
146
|
+
( specific_param =~ 'text/html' ).should be_true()
|
147
|
+
( specific_param =~ 'image/png' ).should be_false()
|
148
|
+
|
149
|
+
( subtype_wildcard_param =~ 'image/png' ).should be_true()
|
150
|
+
( subtype_wildcard_param =~ 'image/jpeg' ).should be_true()
|
151
|
+
( subtype_wildcard_param =~ 'text/plain' ).should be_false()
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
|
156
|
+
describe Strelka::HTTPRequest::Language do
|
157
|
+
|
158
|
+
it "can parse a simple language code" do
|
159
|
+
hdr = 'en'
|
160
|
+
param = Strelka::HTTPRequest::Language.parse( hdr )
|
161
|
+
|
162
|
+
param.should be_an_instance_of( Strelka::HTTPRequest::Language )
|
163
|
+
param.primary_tag.should == 'en'
|
164
|
+
param.subtag.should be_nil()
|
165
|
+
param.qvalue.should == 1.0
|
166
|
+
param.extensions.should be_empty()
|
167
|
+
end
|
168
|
+
|
169
|
+
it "can parse a language range with a dialect" do
|
170
|
+
hdr = 'en-gb'
|
171
|
+
param = Strelka::HTTPRequest::Language.parse( hdr )
|
172
|
+
|
173
|
+
param.should be_an_instance_of( Strelka::HTTPRequest::Language )
|
174
|
+
param.primary_tag.should == 'en'
|
175
|
+
param.subtag.should == 'gb'
|
176
|
+
param.qvalue.should == 1.0
|
177
|
+
param.extensions.should be_empty()
|
178
|
+
end
|
179
|
+
|
180
|
+
it "can parse a language tag with a q-value" do
|
181
|
+
hdr = 'en-US; q=0.8'
|
182
|
+
param = Strelka::HTTPRequest::Language.parse( hdr )
|
183
|
+
|
184
|
+
param.should be_an_instance_of( Strelka::HTTPRequest::Language )
|
185
|
+
param.primary_tag.should == 'en'
|
186
|
+
param.subtag.should == 'us'
|
187
|
+
param.qvalue.should == 0.8
|
188
|
+
param.extensions.should be_empty()
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
describe Strelka::HTTPRequest::Charset do
|
195
|
+
|
196
|
+
it "can parse a simple charset" do
|
197
|
+
hdr = 'iso-8859-1'
|
198
|
+
param = Strelka::HTTPRequest::Charset.parse( hdr )
|
199
|
+
|
200
|
+
param.should be_an_instance_of( Strelka::HTTPRequest::Charset )
|
201
|
+
param.name.should == 'iso-8859-1'
|
202
|
+
param.subtype.should be_nil()
|
203
|
+
param.qvalue.should == 1.0
|
204
|
+
param.extensions.should be_empty()
|
205
|
+
end
|
206
|
+
|
207
|
+
it "can parse a charset with a q-value" do
|
208
|
+
hdr = 'iso-8859-15; q=0.5'
|
209
|
+
param = Strelka::HTTPRequest::Charset.parse( hdr )
|
210
|
+
|
211
|
+
param.should be_an_instance_of( Strelka::HTTPRequest::Charset )
|
212
|
+
param.name.should == 'iso-8859-15'
|
213
|
+
param.subtype.should be_nil()
|
214
|
+
param.qvalue.should == 0.5
|
215
|
+
param.extensions.should be_empty()
|
216
|
+
end
|
217
|
+
|
218
|
+
it "can return the Ruby Encoding object associated with its character set" do
|
219
|
+
param = Strelka::HTTPRequest::Charset.parse( 'koi8-r' )
|
220
|
+
param.name.should == 'koi8-r'
|
221
|
+
param.encoding_object.should == Encoding::KOI8_R
|
222
|
+
end
|
223
|
+
|
224
|
+
it "can be compared against strings" do
|
225
|
+
specific_param = Strelka::HTTPRequest::Charset.parse( 'us-ascii' )
|
226
|
+
|
227
|
+
( specific_param =~ 'us-ascii' ).should be_true()
|
228
|
+
( specific_param =~ 'ansi_x3.4-1968' ).should be_true()
|
229
|
+
( specific_param =~ 'utf-8' ).should be_false()
|
230
|
+
end
|
231
|
+
|
232
|
+
it "can be compared against Encoding objects" do
|
233
|
+
specific_param = Strelka::HTTPRequest::Charset.parse( 'utf-8' )
|
234
|
+
|
235
|
+
( specific_param =~ Encoding::UTF_8 ).should be_true()
|
236
|
+
( specific_param =~ Encoding::CP65001 ).should be_true()
|
237
|
+
( specific_param =~ Encoding::MacThai ).should be_false()
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
describe Strelka::HTTPRequest::Encoding do
|
243
|
+
|
244
|
+
it "can parse a simple encoding" do
|
245
|
+
hdr = 'identity'
|
246
|
+
param = Strelka::HTTPRequest::Encoding.parse( hdr )
|
247
|
+
|
248
|
+
param.should be_an_instance_of( Strelka::HTTPRequest::Encoding )
|
249
|
+
param.content_coding.should == 'identity'
|
250
|
+
param.subtype.should be_nil()
|
251
|
+
param.qvalue.should == 1.0
|
252
|
+
param.extensions.should be_empty()
|
253
|
+
end
|
254
|
+
|
255
|
+
it "can parse an encoding with a q-value" do
|
256
|
+
hdr = 'gzip; q=0.55'
|
257
|
+
param = Strelka::HTTPRequest::Encoding.parse( hdr )
|
258
|
+
|
259
|
+
param.should be_an_instance_of( Strelka::HTTPRequest::Encoding )
|
260
|
+
param.content_coding.should == 'gzip'
|
261
|
+
param.subtype.should be_nil()
|
262
|
+
param.qvalue.should == 0.55
|
263
|
+
param.extensions.should be_empty()
|
264
|
+
end
|
265
|
+
|
266
|
+
it "can be compared against strings" do
|
267
|
+
specific_param = Strelka::HTTPRequest::MediaType.parse( 'text/html' )
|
268
|
+
subtype_wildcard_param = Strelka::HTTPRequest::MediaType.parse( 'image/*' )
|
269
|
+
|
270
|
+
( specific_param =~ 'text/html' ).should be_true()
|
271
|
+
( specific_param =~ 'image/png' ).should be_false()
|
272
|
+
|
273
|
+
( subtype_wildcard_param =~ 'image/png' ).should be_true()
|
274
|
+
( subtype_wildcard_param =~ 'image/jpeg' ).should be_true()
|
275
|
+
( subtype_wildcard_param =~ 'text/plain' ).should be_false()
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
# vim: set nosta noet ts=4 sw=4:
|
@@ -0,0 +1,246 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
BEGIN {
|
4
|
+
require 'pathname'
|
5
|
+
basedir = Pathname.new( __FILE__ ).dirname.parent.parent.parent
|
6
|
+
|
7
|
+
libdir = basedir + "lib"
|
8
|
+
|
9
|
+
$LOAD_PATH.unshift( basedir ) unless $LOAD_PATH.include?( basedir )
|
10
|
+
$LOAD_PATH.unshift( libdir ) unless $LOAD_PATH.include?( libdir )
|
11
|
+
}
|
12
|
+
|
13
|
+
require 'rspec'
|
14
|
+
|
15
|
+
require 'spec/lib/helpers'
|
16
|
+
|
17
|
+
require 'strelka'
|
18
|
+
require 'strelka/httprequest/negotiation'
|
19
|
+
require 'strelka/httpresponse/negotiation'
|
20
|
+
|
21
|
+
|
22
|
+
#####################################################################
|
23
|
+
### C O N T E X T S
|
24
|
+
#####################################################################
|
25
|
+
|
26
|
+
describe Strelka::HTTPRequest::Negotiation do
|
27
|
+
|
28
|
+
before( :all ) do
|
29
|
+
setup_logging( :fatal )
|
30
|
+
@request_factory = Mongrel2::RequestFactory.new( route: '/service/user' )
|
31
|
+
end
|
32
|
+
|
33
|
+
after( :all ) do
|
34
|
+
reset_logging()
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
before( :each ) do
|
39
|
+
@req = @request_factory.get( '/service/user/estark' )
|
40
|
+
@req.extend( described_class )
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
describe "mediatype negotiation" do
|
45
|
+
|
46
|
+
it "know what content-types are accepted by the client" do
|
47
|
+
@req.headers.accept = 'application/x-yaml, application/json; q=0.2, text/xml; q=0.75'
|
48
|
+
|
49
|
+
@req.accepted_types.should have(3).members
|
50
|
+
@req.accepted_types[0].mediatype.should == 'application/x-yaml'
|
51
|
+
@req.accepted_types[0].qvalue.should == 1.0
|
52
|
+
@req.accepted_types[1].mediatype.should == 'application/json'
|
53
|
+
@req.accepted_types[1].qvalue.should == 0.2
|
54
|
+
@req.accepted_types[2].mediatype.should == 'text/xml'
|
55
|
+
@req.accepted_types[2].qvalue.should == 0.75
|
56
|
+
end
|
57
|
+
|
58
|
+
it "knows what mimetypes are acceptable responses" do
|
59
|
+
@req.headers.accept = 'text/html, text/plain; q=0.5, image/*;q=0.1'
|
60
|
+
|
61
|
+
@req.accepts?( 'text/html' ).should be_true()
|
62
|
+
@req.accepts?( 'text/plain' ).should be_true()
|
63
|
+
@req.accepts?( 'text/ascii' ).should be_false()
|
64
|
+
@req.accepts?( 'image/png' ).should be_true()
|
65
|
+
@req.accepts?( 'application/x-yaml' ).should be_false()
|
66
|
+
end
|
67
|
+
|
68
|
+
it "knows what mimetypes are explicitly acceptable responses" do
|
69
|
+
@req.headers.accept = 'text/html, text/plain; q=0.5, image/*;q=0.1, */*'
|
70
|
+
|
71
|
+
@req.explicitly_accepts?( 'text/html' ).should be_true()
|
72
|
+
@req.explicitly_accepts?( 'text/plain' ).should be_true()
|
73
|
+
@req.explicitly_accepts?( 'text/ascii' ).should be_false()
|
74
|
+
@req.explicitly_accepts?( 'image/png' ).should be_false()
|
75
|
+
@req.explicitly_accepts?( 'application/x-yaml' ).should be_false()
|
76
|
+
end
|
77
|
+
|
78
|
+
it "accepts anything if the client doesn't provide an Accept header" do
|
79
|
+
@req.headers.delete( :accept )
|
80
|
+
|
81
|
+
@req.accepts?( 'text/html' ).should be_true()
|
82
|
+
@req.accepts?( 'text/plain' ).should be_true()
|
83
|
+
@req.accepts?( 'text/ascii' ).should be_true()
|
84
|
+
@req.accepts?( 'image/png' ).should be_true()
|
85
|
+
@req.accepts?( 'application/x-yaml' ).should be_true()
|
86
|
+
end
|
87
|
+
|
88
|
+
it "doesn't explicitly accept anything if the client doesn't provide an Accept header" do
|
89
|
+
@req.headers.delete( :accept )
|
90
|
+
|
91
|
+
@req.explicitly_accepts?( 'text/html' ).should be_false()
|
92
|
+
@req.explicitly_accepts?( 'text/plain' ).should be_false()
|
93
|
+
@req.explicitly_accepts?( 'text/ascii' ).should be_false()
|
94
|
+
@req.explicitly_accepts?( 'image/png' ).should be_false()
|
95
|
+
@req.explicitly_accepts?( 'application/x-yaml' ).should be_false()
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
describe "character-set negotiation" do
|
102
|
+
|
103
|
+
it "knows what character sets are accepted by the client" do
|
104
|
+
@req.headers.accept_charset = 'iso-8859-5, utf-8;q=0.8'
|
105
|
+
|
106
|
+
@req.accepted_charsets.should have(2).members
|
107
|
+
@req.accepted_charsets[0].name.should == 'iso-8859-5'
|
108
|
+
@req.accepted_charsets[0].qvalue.should == 1.0
|
109
|
+
@req.accepted_charsets[1].name.should == 'utf-8'
|
110
|
+
@req.accepted_charsets[1].qvalue.should == 0.8
|
111
|
+
end
|
112
|
+
|
113
|
+
it "knows what charsets are acceptable responses" do
|
114
|
+
@req.headers.accept_charset = 'iso-8859-5, utf-8;q=0.8'
|
115
|
+
|
116
|
+
@req.accepts_charset?( 'iso8859-5' ).should be_true()
|
117
|
+
@req.accepts_charset?( 'iso-8859-5' ).should be_true()
|
118
|
+
@req.accepts_charset?( 'utf-8' ).should be_true()
|
119
|
+
@req.accepts_charset?( Encoding::CP65001 ).should be_true()
|
120
|
+
@req.accepts_charset?( 'mac' ).should be_false()
|
121
|
+
@req.accepts_charset?( Encoding::SJIS ).should be_false()
|
122
|
+
end
|
123
|
+
|
124
|
+
it "accepts any charset if the client doesn't provide an Accept-Charset header" do
|
125
|
+
@req.headers.delete( :accept_charset )
|
126
|
+
|
127
|
+
@req.accepts_charset?( 'iso8859-5' ).should be_true()
|
128
|
+
@req.accepts_charset?( 'iso-8859-5' ).should be_true()
|
129
|
+
@req.accepts_charset?( 'utf-8' ).should be_true()
|
130
|
+
@req.accepts_charset?( Encoding::CP65001 ).should be_true()
|
131
|
+
@req.accepts_charset?( 'mac' ).should be_true()
|
132
|
+
@req.accepts_charset?( Encoding::SJIS ).should be_true()
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
describe "content encoding negotiation" do
|
139
|
+
|
140
|
+
it "knows what encodings are accepted by the client" do
|
141
|
+
@req.headers.accept_encoding = 'gzip;q=1.0, identity; q=0.5, *;q=0'
|
142
|
+
|
143
|
+
@req.accepted_encodings.should have(3).members
|
144
|
+
@req.accepted_encodings[0].content_coding.should == 'gzip'
|
145
|
+
@req.accepted_encodings[0].qvalue.should == 1.0
|
146
|
+
@req.accepted_encodings[1].content_coding.should == 'identity'
|
147
|
+
@req.accepted_encodings[1].qvalue.should == 0.5
|
148
|
+
@req.accepted_encodings[2].content_coding.should be_nil()
|
149
|
+
@req.accepted_encodings[2].qvalue.should == 0.0
|
150
|
+
end
|
151
|
+
|
152
|
+
it "knows what encodings are acceptable" do
|
153
|
+
@req.headers.accept_encoding = 'gzip;q=1.0, identity; q=0.5, *;q=0'
|
154
|
+
|
155
|
+
@req.accepts_encoding?( 'gzip' ).should be_true()
|
156
|
+
@req.accepts_encoding?( 'identity' ).should be_true()
|
157
|
+
@req.accepts_encoding?( 'compress' ).should be_false()
|
158
|
+
end
|
159
|
+
|
160
|
+
it "knows that the identity encoding is acceptable if it isn't disabled" do
|
161
|
+
@req.headers.accept_encoding = 'gzip;q=1.0, compress; q=0.5'
|
162
|
+
|
163
|
+
@req.accepts_encoding?( 'gzip' ).should be_true()
|
164
|
+
@req.accepts_encoding?( 'identity' ).should be_true()
|
165
|
+
@req.accepts_encoding?( 'compress' ).should be_true()
|
166
|
+
@req.accepts_encoding?( 'clowns' ).should be_false()
|
167
|
+
end
|
168
|
+
|
169
|
+
it "accepts only the 'identity' encoding if the Accept-Encoding field is empty" do
|
170
|
+
@req.headers.accept_encoding = ''
|
171
|
+
|
172
|
+
@req.accepts_encoding?( 'identity' ).should be_true()
|
173
|
+
@req.accepts_encoding?( 'gzip' ).should be_false()
|
174
|
+
@req.accepts_encoding?( 'compress' ).should be_false()
|
175
|
+
end
|
176
|
+
|
177
|
+
it "doesn't accept the 'identity' encoding if the Accept-Encoding field explicitly disables it" do
|
178
|
+
@req.headers.accept_encoding = 'gzip;q=0.5, identity;q=0'
|
179
|
+
|
180
|
+
@req.accepts_encoding?( 'identity' ).should be_false()
|
181
|
+
@req.accepts_encoding?( 'gzip' ).should be_true()
|
182
|
+
@req.accepts_encoding?( 'compress' ).should be_false()
|
183
|
+
end
|
184
|
+
|
185
|
+
it "doesn't accept the 'identity' encoding if the Accept-Encoding field has a wildcard " +
|
186
|
+
"with q-value of 0 and doesn't explicitly include 'identity'" do
|
187
|
+
@req.headers.accept_encoding = 'gzip;q=0.5, *;q=0'
|
188
|
+
|
189
|
+
@req.accepts_encoding?( 'identity' ).should be_false()
|
190
|
+
@req.accepts_encoding?( 'gzip' ).should be_true()
|
191
|
+
@req.accepts_encoding?( 'compress' ).should be_false()
|
192
|
+
end
|
193
|
+
|
194
|
+
it "accepts every encoding if the request doesn't have an Accept-Encoding header" do
|
195
|
+
@req.headers.delete( :accept_encoding )
|
196
|
+
|
197
|
+
@req.accepts_encoding?( 'identity' ).should be_true()
|
198
|
+
@req.accepts_encoding?( 'gzip' ).should be_true()
|
199
|
+
@req.accepts_encoding?( 'compress' ).should be_true()
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
describe "natural language negotiation" do
|
206
|
+
|
207
|
+
it "knows what languages are accepted by the client" do
|
208
|
+
@req.headers.accept_language = 'da, en-gb;q=0.8, en;q=0.7'
|
209
|
+
|
210
|
+
@req.accepted_languages.should have(3).members
|
211
|
+
@req.accepted_languages[0].primary_tag.should == 'da'
|
212
|
+
@req.accepted_languages[0].subtag.should == nil
|
213
|
+
@req.accepted_languages[0].qvalue.should == 1.0
|
214
|
+
@req.accepted_languages[1].primary_tag.should == 'en'
|
215
|
+
@req.accepted_languages[1].subtag.should == 'gb'
|
216
|
+
@req.accepted_languages[1].qvalue.should == 0.8
|
217
|
+
@req.accepted_languages[2].primary_tag.should == 'en'
|
218
|
+
@req.accepted_languages[2].subtag.should == nil
|
219
|
+
@req.accepted_languages[2].qvalue.should == 0.7
|
220
|
+
end
|
221
|
+
|
222
|
+
it "knows what languages may be used in acceptable responses" do
|
223
|
+
@req.headers.accept_language = 'da, en-gb;q=0.8, en;q=0.7'
|
224
|
+
|
225
|
+
@req.accepts_language?( 'da' ).should be_true()
|
226
|
+
@req.accepts_language?( 'en' ).should be_true()
|
227
|
+
@req.accepts_language?( 'en-gb' ).should be_true()
|
228
|
+
@req.accepts_language?( 'en-cockney' ).should be_true()
|
229
|
+
@req.accepts_language?( 'de' ).should be_false()
|
230
|
+
@req.accepts_language?( 'tlh' ).should be_false()
|
231
|
+
end
|
232
|
+
|
233
|
+
it "accepts any language if the client doesn't provide an Accept-Language header" do
|
234
|
+
@req.headers.delete( :accept_language )
|
235
|
+
|
236
|
+
@req.accepts_language?( 'da' ).should be_true()
|
237
|
+
@req.accepts_language?( 'en' ).should be_true()
|
238
|
+
@req.accepts_language?( 'en-gb' ).should be_true()
|
239
|
+
@req.accepts_language?( 'en-cockney' ).should be_true()
|
240
|
+
@req.accepts_language?( 'de' ).should be_true()
|
241
|
+
@req.accepts_language?( 'tlh' ).should be_true()
|
242
|
+
end
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|