restfulness 0.3.2 → 0.3.3
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/.gitignore +1 -0
- data/.travis.yml +6 -5
- data/README.md +98 -80
- data/lib/restfulness.rb +3 -0
- data/lib/restfulness/dispatchers/rack.rb +1 -0
- data/lib/restfulness/headers/accept.rb +66 -0
- data/lib/restfulness/headers/media_type.rb +127 -0
- data/lib/restfulness/request.rb +43 -15
- data/lib/restfulness/version.rb +1 -1
- data/restfulness.gemspec +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/application_spec.rb +14 -14
- data/spec/unit/dispatcher_spec.rb +1 -1
- data/spec/unit/dispatchers/rack_spec.rb +21 -20
- data/spec/unit/exceptions_spec.rb +5 -5
- data/spec/unit/headers/accept_spec.rb +70 -0
- data/spec/unit/headers/media_type_spec.rb +262 -0
- data/spec/unit/http_authentication/basic_spec.rb +7 -7
- data/spec/unit/path_spec.rb +19 -19
- data/spec/unit/request_spec.rb +96 -44
- data/spec/unit/requests/authorization_header_spec.rb +8 -8
- data/spec/unit/requests/authorization_spec.rb +3 -3
- data/spec/unit/resource_spec.rb +28 -28
- data/spec/unit/resources/authentication_spec.rb +2 -2
- data/spec/unit/resources/events_spec.rb +1 -1
- data/spec/unit/response_spec.rb +53 -53
- data/spec/unit/route_spec.rb +24 -24
- data/spec/unit/router_spec.rb +29 -29
- data/spec/unit/sanitizer_spec.rb +9 -9
- metadata +13 -7
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Restfulness::Headers::Accept do
|
4
|
+
|
5
|
+
let :klass do
|
6
|
+
Restfulness::Headers::Accept
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "initialization" do
|
10
|
+
|
11
|
+
it "should work without string" do
|
12
|
+
obj = klass.new
|
13
|
+
expect(obj.media_types).to be_empty
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should parse a basic string" do
|
17
|
+
obj = klass.new("application/json")
|
18
|
+
expect(obj.media_types.first.to_s).to eql("application/json")
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "parsing" do
|
24
|
+
|
25
|
+
it "should parse array of media types" do
|
26
|
+
obj = klass.new("application/json, text/*")
|
27
|
+
expect(obj.media_types.length).to eql(2)
|
28
|
+
expect(obj.media_types.first.to_s).to eql("application/json")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should parse and re-order media types" do
|
32
|
+
obj = klass.new("text/plain, application/json; version=1, text/*")
|
33
|
+
expect(obj.media_types.length).to eql(3)
|
34
|
+
expect(obj.media_types.first.to_s).to eql("application/json;version=1")
|
35
|
+
expect(obj.media_types.last.to_s).to eql("text/*")
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "#version" do
|
41
|
+
it "should attempt to provide version" do
|
42
|
+
obj = klass.new("text/plain, application/json; version=1, text/*")
|
43
|
+
expect(obj.version).to eql("1")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#json?" do
|
48
|
+
it "should confirm if content includes json" do
|
49
|
+
obj = klass.new("text/plain, application/json; version=1, text/*")
|
50
|
+
expect(obj.json?).to be true
|
51
|
+
end
|
52
|
+
it "should confirm if json not accepted" do
|
53
|
+
obj = klass.new("text/plain, text/*")
|
54
|
+
expect(obj.json?).to be false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
describe "#xml?" do
|
60
|
+
it "should confirm if content includes xml" do
|
61
|
+
obj = klass.new("text/plain, application/xml; version=1, text/*")
|
62
|
+
expect(obj.xml?).to be true
|
63
|
+
end
|
64
|
+
it "should confirm if json not accepted" do
|
65
|
+
obj = klass.new("text/plain, application/json, text/*")
|
66
|
+
expect(obj.xml?).to be false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,262 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Restfulness::Headers::MediaType do
|
4
|
+
|
5
|
+
let :klass do
|
6
|
+
Restfulness::Headers::MediaType
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "initialization" do
|
10
|
+
|
11
|
+
it "should be able to except no parameter and set defaults" do
|
12
|
+
obj = klass.new
|
13
|
+
expect(obj.type).to eql("*")
|
14
|
+
expect(obj.subtype).to eql("*")
|
15
|
+
expect(obj.parameters).to eql({})
|
16
|
+
expect(obj.vendor).to eql("")
|
17
|
+
expect(obj.suffix).to eql("")
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should handle string and parse" do
|
21
|
+
obj = klass.new("application/json")
|
22
|
+
expect(obj.type).to eql("application")
|
23
|
+
expect(obj.subtype).to eql("json")
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "parsing" do
|
29
|
+
|
30
|
+
it "should handle params" do
|
31
|
+
obj = klass.new("applcation/json;version=2")
|
32
|
+
expect(obj.subtype).to eql('json')
|
33
|
+
expect(obj.parameters[:version]).to eql("2")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should handle params with white space" do
|
37
|
+
obj = klass.new("applcation/json; version=3")
|
38
|
+
expect(obj.subtype).to eql('json')
|
39
|
+
expect(obj.parameters[:version]).to eql("3")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should handle multiple params" do
|
43
|
+
obj = klass.new("applcation/json;version=2;test=yes")
|
44
|
+
expect(obj.subtype).to eql('json')
|
45
|
+
expect(obj.parameters[:version]).to eql("2")
|
46
|
+
expect(obj.parameters[:test]).to eql("yes")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should handle suffix" do
|
50
|
+
obj = klass.new("applcation/xhtml+xml")
|
51
|
+
expect(obj.subtype).to eql('xhtml')
|
52
|
+
expect(obj.suffix).to eql('xml')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should handle vendor" do
|
56
|
+
obj = klass.new("applcation/vnd.example.user; version=3")
|
57
|
+
expect(obj.subtype).to eql('user')
|
58
|
+
expect(obj.vendor).to eql('example')
|
59
|
+
expect(obj.suffix).to eql('')
|
60
|
+
expect(obj.parameters[:version]).to eql("3")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should handle vendor with suffix" do
|
64
|
+
obj = klass.new("applcation/vnd.example.user+json; version=3")
|
65
|
+
expect(obj.subtype).to eql('user')
|
66
|
+
expect(obj.vendor).to eql('example')
|
67
|
+
expect(obj.suffix).to eql('json')
|
68
|
+
expect(obj.parameters[:version]).to eql("3")
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should handle vendor with domain" do
|
72
|
+
obj = klass.new("applcation/vnd.example.com.user; version=3")
|
73
|
+
expect(obj.subtype).to eql('user')
|
74
|
+
expect(obj.vendor).to eql('example.com')
|
75
|
+
expect(obj.suffix).to eql('')
|
76
|
+
expect(obj.parameters[:version]).to eql("3")
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "conversion to string" do
|
82
|
+
|
83
|
+
it "should handle empty type" do
|
84
|
+
obj = klass.new
|
85
|
+
expect(obj.to_s).to eql("*/*")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should handle basic type" do
|
89
|
+
obj = klass.new
|
90
|
+
obj.type = "application"
|
91
|
+
obj.subtype = "json"
|
92
|
+
expect(obj.to_s).to eql('application/json')
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should handle parameter" do
|
96
|
+
obj = klass.new
|
97
|
+
obj.type = "application"
|
98
|
+
obj.subtype = "json"
|
99
|
+
obj.parameters[:version] = 1
|
100
|
+
expect(obj.to_s).to eql('application/json;version=1')
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should handle multiple parameters" do
|
104
|
+
obj = klass.new
|
105
|
+
obj.type = "application"
|
106
|
+
obj.subtype = "json"
|
107
|
+
obj.parameters[:version] = 1
|
108
|
+
obj.parameters[:charset] = "UTF-8"
|
109
|
+
expect(obj.to_s).to eql('application/json;version=1;charset=UTF-8')
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should handle suffix" do
|
113
|
+
obj = klass.new
|
114
|
+
obj.type = "application"
|
115
|
+
obj.subtype = "xhtml"
|
116
|
+
obj.suffix = "xml"
|
117
|
+
expect(obj.to_s).to eql('application/xhtml+xml')
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should handle vendor" do
|
121
|
+
obj = klass.new
|
122
|
+
obj.type = "application"
|
123
|
+
obj.vendor = "example.com"
|
124
|
+
obj.subtype = "user"
|
125
|
+
expect(obj.to_s).to eql('application/vnd.example.com.user')
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should handle vendor with suffix" do
|
129
|
+
obj = klass.new
|
130
|
+
obj.type = "application"
|
131
|
+
obj.vendor = "example.com"
|
132
|
+
obj.subtype = "user"
|
133
|
+
obj.suffix = "json"
|
134
|
+
expect(obj.to_s).to eql('application/vnd.example.com.user+json')
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should handle vendor with suffix and params" do
|
138
|
+
obj = klass.new
|
139
|
+
obj.type = "application"
|
140
|
+
obj.vendor = "example.com"
|
141
|
+
obj.subtype = "user"
|
142
|
+
obj.suffix = "json"
|
143
|
+
obj.parameters[:version] = "1"
|
144
|
+
expect(obj.to_s).to eql('application/vnd.example.com.user+json;version=1')
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "comparisons" do
|
150
|
+
|
151
|
+
describe "with a string" do
|
152
|
+
|
153
|
+
it "should compare matching strings" do
|
154
|
+
obj = klass.new("application/json")
|
155
|
+
expect(obj == "application/json").to be true
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should fail on non-matching strings" do
|
159
|
+
obj = klass.new("application/xhtml+xml")
|
160
|
+
expect(obj == "application/xml").to be false
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should ignore whitespace" do
|
164
|
+
obj = klass.new("application/json;version=1")
|
165
|
+
expect(obj == "application/json; version=1").to be true
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "with an object" do
|
171
|
+
|
172
|
+
it "should compare matching objs" do
|
173
|
+
obj = klass.new("application/json")
|
174
|
+
obj2 = klass.new("application/json")
|
175
|
+
expect(obj == obj2).to be true
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should compare non-matching objs" do
|
179
|
+
obj = klass.new("application/json")
|
180
|
+
obj2 = klass.new("application/xml")
|
181
|
+
expect(obj == obj2).to be false
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should compare complex objects" do
|
185
|
+
obj = klass.new("application/vnd.example.com.user+json;version=1")
|
186
|
+
obj2 = klass.new("application/vnd.example.com.user+json;version=1")
|
187
|
+
expect(obj == obj2).to be true
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
describe "with rubbish" do
|
193
|
+
it "should raise an exception" do
|
194
|
+
obj = klass.new("application/json")
|
195
|
+
expect {
|
196
|
+
obj == 1
|
197
|
+
}.to raise_error(/Invalid type comparison/)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "parameter wrappers" do
|
203
|
+
|
204
|
+
it "should provide charset" do
|
205
|
+
obj = klass.new("application/json; charset=UTF-8")
|
206
|
+
expect(obj.charset).to eql("UTF-8")
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should provide version" do
|
210
|
+
obj = klass.new("application/json; version=2")
|
211
|
+
expect(obj.version).to eql("2")
|
212
|
+
end
|
213
|
+
|
214
|
+
end
|
215
|
+
|
216
|
+
describe "type tests" do
|
217
|
+
|
218
|
+
it "should should match basic json type" do
|
219
|
+
obj = klass.new("application/json; version=2")
|
220
|
+
expect(obj.json?).to be true
|
221
|
+
end
|
222
|
+
|
223
|
+
it "should should match vendored json type" do
|
224
|
+
obj = klass.new("application/vnd.example.com.user+json; version=2")
|
225
|
+
expect(obj.json?).to be true
|
226
|
+
end
|
227
|
+
|
228
|
+
it "should should match basic xml type" do
|
229
|
+
obj = klass.new("application/xml")
|
230
|
+
expect(obj.json?).to be false
|
231
|
+
expect(obj.xml?).to be true
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should should match vendored json type" do
|
235
|
+
obj = klass.new("application/vnd.example.com.user+xml; version=2")
|
236
|
+
expect(obj.json?).to be false
|
237
|
+
expect(obj.xml?).to be true
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should match text type" do
|
241
|
+
obj = klass.new("text/plain")
|
242
|
+
expect(obj.text?).to be true
|
243
|
+
end
|
244
|
+
|
245
|
+
it "should not match non-text type" do
|
246
|
+
obj = klass.new("application/json")
|
247
|
+
expect(obj.text?).to be false
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should match form type" do
|
251
|
+
obj = klass.new("application/x-www-form-urlencoded")
|
252
|
+
expect(obj.form?).to be true
|
253
|
+
end
|
254
|
+
|
255
|
+
it "should not match non-text type" do
|
256
|
+
obj = klass.new("application/json")
|
257
|
+
expect(obj.form?).to be false
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
@@ -15,25 +15,25 @@ describe Restfulness::HttpAuthentication::Basic do
|
|
15
15
|
describe "#initialize" do
|
16
16
|
it "should set the header" do
|
17
17
|
obj = klass.new(header)
|
18
|
-
obj.header.
|
18
|
+
expect(obj.header).to eql(header)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
describe "#valid?" do
|
23
23
|
it "should detect valid schema and credentials" do
|
24
24
|
obj = klass.new(header)
|
25
|
-
obj.valid
|
25
|
+
expect(obj.valid?).to be true
|
26
26
|
end
|
27
27
|
|
28
28
|
it "should reject different schema" do
|
29
29
|
obj = klass.new(header_klass.new("Fooo Bar"))
|
30
|
-
obj.valid
|
30
|
+
expect(obj.valid?).to be false
|
31
31
|
end
|
32
32
|
|
33
33
|
it "should reject if the basic request credentials are of invalid length" do
|
34
34
|
creds = ::Base64.strict_encode64("username")
|
35
35
|
obj = klass.new(header_klass.new("Fooo #{creds}"))
|
36
|
-
obj.valid
|
36
|
+
expect(obj.valid?).to be false
|
37
37
|
end
|
38
38
|
end
|
39
39
|
|
@@ -41,9 +41,9 @@ describe Restfulness::HttpAuthentication::Basic do
|
|
41
41
|
|
42
42
|
it "should decode and prepare the params" do
|
43
43
|
obj = klass.new(header)
|
44
|
-
obj.credentials.length.
|
45
|
-
obj.username.
|
46
|
-
obj.password.
|
44
|
+
expect(obj.credentials.length).to eql(2)
|
45
|
+
expect(obj.username).to eql('Aladdin')
|
46
|
+
expect(obj.password).to eql('open sesame')
|
47
47
|
end
|
48
48
|
|
49
49
|
end
|
data/spec/unit/path_spec.rb
CHANGED
@@ -25,25 +25,25 @@ describe Restfulness::Path do
|
|
25
25
|
|
26
26
|
it "should assign route" do
|
27
27
|
obj = klass.new(simple_route, '/project')
|
28
|
-
obj.route.
|
28
|
+
expect(obj.route).to eql(simple_route)
|
29
29
|
end
|
30
30
|
|
31
31
|
context "simple paths" do
|
32
32
|
it "should prepare basic path" do
|
33
33
|
obj = klass.new(simple_route, '/project')
|
34
|
-
obj.components.
|
35
|
-
obj.params[:id].
|
34
|
+
expect(obj.components).to eql(['project'])
|
35
|
+
expect(obj.params[:id]).to be_nil
|
36
36
|
end
|
37
37
|
|
38
38
|
it "should prepare irregular path components" do
|
39
39
|
obj = klass.new(simple_route, '/project/')
|
40
|
-
obj.components.
|
40
|
+
expect(obj.components).to eql(['project'])
|
41
41
|
end
|
42
42
|
|
43
43
|
it "should include id" do
|
44
44
|
obj = klass.new(simple_route, '/project/12345')
|
45
|
-
obj.components.
|
46
|
-
obj.params[:id].
|
45
|
+
expect(obj.components).to eql(['project', '12345'])
|
46
|
+
expect(obj.params[:id]).to eql('12345')
|
47
47
|
end
|
48
48
|
end
|
49
49
|
|
@@ -51,15 +51,15 @@ describe Restfulness::Path do
|
|
51
51
|
context "complex paths" do
|
52
52
|
it "should prepare path" do
|
53
53
|
obj = klass.new(complex_route, '/project/12345/status')
|
54
|
-
obj.components.
|
55
|
-
obj.params[:project_id].
|
54
|
+
expect(obj.components).to eql(['project', '12345', 'status'])
|
55
|
+
expect(obj.params[:project_id]).to eql('12345')
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should handle end id" do
|
59
59
|
obj = klass.new(complex_route, '/project/12345/status/23456')
|
60
|
-
obj.components.
|
61
|
-
obj.params[:project_id].
|
62
|
-
obj.params[:id].
|
60
|
+
expect(obj.components).to eql(['project', '12345', 'status', '23456'])
|
61
|
+
expect(obj.params[:project_id]).to eql('12345')
|
62
|
+
expect(obj.params[:id]).to eql('23456')
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -67,7 +67,7 @@ describe Restfulness::Path do
|
|
67
67
|
describe "#to_s" do
|
68
68
|
it "should provide simple string" do
|
69
69
|
obj = klass.new(complex_route, '/project/12345/status/23456')
|
70
|
-
obj.to_s.
|
70
|
+
expect(obj.to_s).to eql('/project/12345/status/23456')
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -76,15 +76,15 @@ describe Restfulness::Path do
|
|
76
76
|
obj = klass.new(complex_route, '/project/12345/status/23456')
|
77
77
|
end
|
78
78
|
it "should grant access to components by index" do
|
79
|
-
obj[0].
|
80
|
-
obj[1].
|
81
|
-
obj[2].
|
82
|
-
obj[3].
|
83
|
-
obj[4].
|
79
|
+
expect(obj[0]).to eql('project')
|
80
|
+
expect(obj[1]).to eql('12345')
|
81
|
+
expect(obj[2]).to eql('status')
|
82
|
+
expect(obj[3]).to eql('23456')
|
83
|
+
expect(obj[4]).to be_nil
|
84
84
|
end
|
85
85
|
it "should grant access to path parameters by symbol" do
|
86
|
-
obj[:project_id].
|
87
|
-
obj[:id].
|
86
|
+
expect(obj[:project_id]).to eql('12345')
|
87
|
+
expect(obj[:id]).to eql('23456')
|
88
88
|
end
|
89
89
|
end
|
90
90
|
|