praxis 0.22.pre.2 → 2.0.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +323 -324
- data/lib/praxis/action_definition.rb +7 -9
- data/lib/praxis/api_definition.rb +27 -44
- data/lib/praxis/api_general_info.rb +2 -3
- data/lib/praxis/application.rb +14 -141
- data/lib/praxis/bootloader.rb +1 -2
- data/lib/praxis/bootloader_stages/environment.rb +13 -0
- data/lib/praxis/controller.rb +0 -2
- data/lib/praxis/dispatcher.rb +4 -6
- data/lib/praxis/docs/generator.rb +8 -18
- data/lib/praxis/docs/link_builder.rb +1 -1
- data/lib/praxis/error_handler.rb +5 -5
- data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +1 -1
- data/lib/praxis/extensions/attribute_filtering/sequel_filter_query_builder.rb +125 -0
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +16 -18
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +5 -5
- data/lib/praxis/extensions/field_selection.rb +1 -12
- data/lib/praxis/extensions/rendering.rb +1 -1
- data/lib/praxis/file_group.rb +1 -1
- data/lib/praxis/handlers/xml.rb +1 -1
- data/lib/praxis/mapper/active_model_compat.rb +63 -0
- data/lib/praxis/mapper/resource.rb +242 -0
- data/lib/praxis/mapper/selector_generator.rb +126 -0
- data/lib/praxis/mapper/sequel_compat.rb +37 -0
- data/lib/praxis/middleware_app.rb +13 -15
- data/lib/praxis/multipart/part.rb +3 -5
- data/lib/praxis/plugins/mapper_plugin.rb +50 -0
- data/lib/praxis/request.rb +14 -7
- data/lib/praxis/request_stages/response.rb +2 -3
- data/lib/praxis/resource_definition.rb +10 -14
- data/lib/praxis/response.rb +6 -5
- data/lib/praxis/response_definition.rb +5 -7
- data/lib/praxis/response_template.rb +3 -4
- data/lib/praxis/responses/http.rb +36 -0
- data/lib/praxis/responses/internal_server_error.rb +12 -3
- data/lib/praxis/responses/multipart_ok.rb +11 -4
- data/lib/praxis/responses/validation_error.rb +10 -1
- data/lib/praxis/router.rb +3 -3
- data/lib/praxis/tasks/api_docs.rb +2 -10
- data/lib/praxis/tasks/routes.rb +0 -1
- data/lib/praxis/version.rb +1 -1
- data/lib/praxis.rb +13 -9
- data/praxis.gemspec +2 -3
- data/spec/functional_spec.rb +0 -1
- data/spec/praxis/action_definition_spec.rb +15 -26
- data/spec/praxis/api_definition_spec.rb +8 -13
- data/spec/praxis/api_general_info_spec.rb +8 -3
- data/spec/praxis/application_spec.rb +7 -13
- data/spec/praxis/handlers/xml_spec.rb +2 -2
- data/spec/praxis/mapper/resource_spec.rb +169 -0
- data/spec/praxis/mapper/selector_generator_spec.rb +301 -0
- data/spec/praxis/middleware_app_spec.rb +15 -9
- data/spec/praxis/request_spec.rb +7 -17
- data/spec/praxis/request_stages/validate_spec.rb +1 -1
- data/spec/praxis/resource_definition_spec.rb +10 -12
- data/spec/praxis/response_definition_spec.rb +5 -22
- data/spec/praxis/response_spec.rb +5 -12
- data/spec/praxis/responses/internal_server_error_spec.rb +5 -2
- data/spec/praxis/router_spec.rb +4 -8
- data/spec/spec_app/app/models/person.rb +3 -3
- data/spec/spec_app/config/environment.rb +3 -21
- data/spec/spec_app/config.ru +6 -1
- data/spec/spec_helper.rb +2 -17
- data/spec/support/spec_resources.rb +131 -0
- metadata +19 -31
- data/lib/praxis/extensions/attribute_filtering/query_builder.rb +0 -39
- data/lib/praxis/extensions/attribute_filtering.rb +0 -28
- data/lib/praxis/extensions/mapper_selectors.rb +0 -16
- data/lib/praxis/media_type_collection.rb +0 -127
- data/lib/praxis/plugins/praxis_mapper_plugin.rb +0 -246
- data/spec/praxis/media_type_collection_spec.rb +0 -157
- data/spec/praxis/plugins/praxis_mapper_plugin_spec.rb +0 -142
@@ -0,0 +1,301 @@
|
|
1
|
+
# require 'spec_helper'
|
2
|
+
|
3
|
+
# describe Praxis::Mapper::SelectorGenerator do
|
4
|
+
# let(:properties) { {} }
|
5
|
+
# let(:resource) { BlogResource }
|
6
|
+
# subject(:generator) {Praxis::Mapper::SelectorGenerator.new }
|
7
|
+
|
8
|
+
# before do
|
9
|
+
# generator.add(resource,properties)
|
10
|
+
# end
|
11
|
+
|
12
|
+
# let(:expected_selectors) { {} }
|
13
|
+
|
14
|
+
# context 'for a simple field' do
|
15
|
+
# let(:properties) { {id: true} }
|
16
|
+
# let(:expected_selectors) do
|
17
|
+
# {
|
18
|
+
# BlogModel => {
|
19
|
+
# select: Set.new([:id]),
|
20
|
+
# track: Set.new()
|
21
|
+
# }
|
22
|
+
# }
|
23
|
+
# end
|
24
|
+
|
25
|
+
# it 'generates the correct set of selectors' do
|
26
|
+
# generator.selectors.should eq expected_selectors
|
27
|
+
# end
|
28
|
+
# end
|
29
|
+
|
30
|
+
# context 'for a simple property' do
|
31
|
+
# let(:properties) { {display_name: true} }
|
32
|
+
# let(:expected_selectors) do
|
33
|
+
# {
|
34
|
+
# BlogModel => {
|
35
|
+
# select: Set.new([:name]),
|
36
|
+
# track: Set.new()
|
37
|
+
# }
|
38
|
+
# }
|
39
|
+
# end
|
40
|
+
# it 'generates the correct set of selectors' do
|
41
|
+
# generator.selectors.should eq expected_selectors
|
42
|
+
# end
|
43
|
+
# end
|
44
|
+
|
45
|
+
# context 'for an association' do
|
46
|
+
# let(:properties) { {owner: true} }
|
47
|
+
# let(:expected_selectors) do
|
48
|
+
# {
|
49
|
+
# BlogModel => {
|
50
|
+
# select: Set.new([:owner_id]),
|
51
|
+
# track: Set.new([:owner])
|
52
|
+
# }
|
53
|
+
# }
|
54
|
+
# end
|
55
|
+
# it 'generates the correct set of selectors' do
|
56
|
+
# generator.selectors.should eq expected_selectors
|
57
|
+
# end
|
58
|
+
|
59
|
+
# context 'that is many_to_many' do
|
60
|
+
# let(:properties) { {commented_posts: true} }
|
61
|
+
# let(:resource) { UserResource }
|
62
|
+
# let(:expected_selectors) do
|
63
|
+
# {
|
64
|
+
# CommentModel => {
|
65
|
+
# select: Set.new([:author_id, :post_id]),
|
66
|
+
# track: Set.new([:post])
|
67
|
+
# },
|
68
|
+
# UserModel => {
|
69
|
+
# select: Set.new([]),
|
70
|
+
# track: Set.new([:comments])
|
71
|
+
# }
|
72
|
+
# }
|
73
|
+
# end
|
74
|
+
# it 'generates the correct set of selectors' do
|
75
|
+
# generator.selectors.should eq expected_selectors
|
76
|
+
# end
|
77
|
+
# end
|
78
|
+
|
79
|
+
# context 'that is many_to_many without a :through option' do
|
80
|
+
# let(:properties) { {other_commented_posts: { id: true} } }
|
81
|
+
# let(:resource) { UserResource }
|
82
|
+
# let(:expected_selectors) do
|
83
|
+
# {
|
84
|
+
# PostModel => {
|
85
|
+
# select: Set.new([:id]),
|
86
|
+
# track: Set.new([])
|
87
|
+
# },
|
88
|
+
# UserModel => {
|
89
|
+
# select: Set.new([]),
|
90
|
+
# track: Set.new([:other_commented_posts])
|
91
|
+
# }
|
92
|
+
# }
|
93
|
+
# end
|
94
|
+
# it 'generates the correct set of selectors' do
|
95
|
+
# generator.selectors.should eq expected_selectors
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
|
99
|
+
|
100
|
+
# context 'that uses a composite key' do
|
101
|
+
# let(:properties) { {composite_model: {id: true, type: true} } }
|
102
|
+
# let(:resource) { OtherResource }
|
103
|
+
# let(:expected_selectors) do
|
104
|
+
# {
|
105
|
+
# OtherModel => {
|
106
|
+
# select: Set.new([:composite_id,:composite_type]),
|
107
|
+
# track: Set.new([:composite_model])
|
108
|
+
# },
|
109
|
+
# CompositeIdModel => {
|
110
|
+
# select: Set.new([:id,:type]),
|
111
|
+
# track: Set.new
|
112
|
+
# }
|
113
|
+
# }
|
114
|
+
# end
|
115
|
+
# it 'generates the correct set of selectors' do
|
116
|
+
# generator.selectors.should eq expected_selectors
|
117
|
+
# end
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
|
121
|
+
# context 'for a property that specifies a field from an association' do
|
122
|
+
# let(:properties) { {owner_email: true} }
|
123
|
+
# let(:expected_selectors) do
|
124
|
+
# {
|
125
|
+
# BlogModel => {
|
126
|
+
# select: Set.new([:owner_id]),
|
127
|
+
# track: Set.new([:owner])
|
128
|
+
# },
|
129
|
+
# UserModel => {
|
130
|
+
# select: Set.new([:email]),
|
131
|
+
# track: Set.new()
|
132
|
+
# }
|
133
|
+
# }
|
134
|
+
# end
|
135
|
+
|
136
|
+
# it 'generates the correct set of selectors' do
|
137
|
+
# generator.selectors.should eq expected_selectors
|
138
|
+
# end
|
139
|
+
# end
|
140
|
+
|
141
|
+
# context 'for a simple property that requires all fields' do
|
142
|
+
# let(:properties) { {everything: true} }
|
143
|
+
# let(:expected_selectors) do
|
144
|
+
# {
|
145
|
+
# BlogModel => {
|
146
|
+
# select: true,
|
147
|
+
# track: Set.new()
|
148
|
+
# }
|
149
|
+
# }
|
150
|
+
# end
|
151
|
+
# it 'generates the correct set of selectors' do
|
152
|
+
# generator.selectors.should eq expected_selectors
|
153
|
+
# end
|
154
|
+
# end
|
155
|
+
|
156
|
+
# context 'for property that uses an associated property' do
|
157
|
+
# let(:properties) { {owner_full_name: true} }
|
158
|
+
# let(:expected_selectors) do
|
159
|
+
# {
|
160
|
+
# BlogModel => {
|
161
|
+
# select: Set.new([:owner_id]),
|
162
|
+
# track: Set.new([:owner])
|
163
|
+
# },
|
164
|
+
# UserModel => {
|
165
|
+
# select: Set.new([:first_name, :last_name]),
|
166
|
+
# track: Set.new()
|
167
|
+
# }
|
168
|
+
# }
|
169
|
+
# end
|
170
|
+
# it 'generates the correct set of selectors' do
|
171
|
+
# generator.selectors.should eq expected_selectors
|
172
|
+
# end
|
173
|
+
# end
|
174
|
+
|
175
|
+
|
176
|
+
# context 'for a property that requires all fields from an association' do
|
177
|
+
# let(:properties) { {everything_from_owner: true} }
|
178
|
+
# let(:expected_selectors) do
|
179
|
+
# {
|
180
|
+
# BlogModel => {
|
181
|
+
# select: Set.new([:owner_id]),
|
182
|
+
# track: Set.new([:owner])
|
183
|
+
# },
|
184
|
+
# UserModel => {
|
185
|
+
# select: true,
|
186
|
+
# track: Set.new()
|
187
|
+
# }
|
188
|
+
# }
|
189
|
+
# end
|
190
|
+
# it 'generates the correct set of selectors' do
|
191
|
+
# generator.selectors.should eq expected_selectors
|
192
|
+
# end
|
193
|
+
# end
|
194
|
+
|
195
|
+
# context 'using a property that specifies a :through option' do
|
196
|
+
# let(:properties) { {recent_posts: {author: {full_name: true}}} }
|
197
|
+
# let(:resource) { UserResource }
|
198
|
+
# let(:expected_selectors) do
|
199
|
+
# {
|
200
|
+
# PostModel => {
|
201
|
+
# select: Set.new([:author_id, :created_at]),
|
202
|
+
# track: Set.new([:author])
|
203
|
+
# },
|
204
|
+
# UserModel => {
|
205
|
+
# select: Set.new([:first_name, :last_name]),
|
206
|
+
# track: Set.new([:posts])
|
207
|
+
# }
|
208
|
+
# }
|
209
|
+
# end
|
210
|
+
# it 'generates the correct set of selectors' do
|
211
|
+
# generator.selectors.should eq expected_selectors
|
212
|
+
# end
|
213
|
+
# end
|
214
|
+
|
215
|
+
# context 'with a property with a circular definition (ie, includes its own field)' do
|
216
|
+
# let(:resource) { PostResource }
|
217
|
+
|
218
|
+
# let(:properties) { {id: true, slug: true} }
|
219
|
+
# let(:expected_selectors) do
|
220
|
+
# {
|
221
|
+
# PostModel => {
|
222
|
+
# select: Set.new([:id, :slug, :title]),
|
223
|
+
# track: Set.new
|
224
|
+
# }
|
225
|
+
# }
|
226
|
+
# end
|
227
|
+
# it 'generates the correct set of selectors' do
|
228
|
+
# generator.selectors.should eq expected_selectors
|
229
|
+
# end
|
230
|
+
# end
|
231
|
+
|
232
|
+
# context 'with a property without the :through option' do
|
233
|
+
# let(:resource) { UserResource }
|
234
|
+
# let(:properties) { {blogs_summary: {size: true}} }
|
235
|
+
# let(:expected_selectors) do
|
236
|
+
# {
|
237
|
+
# BlogModel => {
|
238
|
+
# select: Set.new([:owner_id]),
|
239
|
+
# track: Set.new()
|
240
|
+
# },
|
241
|
+
# UserModel => {
|
242
|
+
# select: Set.new([:id]),
|
243
|
+
# track: Set.new([:blogs])
|
244
|
+
# }
|
245
|
+
# }
|
246
|
+
# end
|
247
|
+
# it 'ignores any subsequent fields when generating selectors' do
|
248
|
+
# generator.selectors.should eq expected_selectors
|
249
|
+
# end
|
250
|
+
# end
|
251
|
+
|
252
|
+
# context 'for a property with no dependencies' do
|
253
|
+
# let(:properties) { {id: true, kind: true} }
|
254
|
+
# let(:expected_selectors) do
|
255
|
+
# {
|
256
|
+
# BlogModel => {
|
257
|
+
# select: Set.new([:id]),
|
258
|
+
# track: Set.new()
|
259
|
+
# }
|
260
|
+
# }
|
261
|
+
# end
|
262
|
+
# it 'generates the correct set of selectors' do
|
263
|
+
# generator.selectors.should eq expected_selectors
|
264
|
+
# end
|
265
|
+
# end
|
266
|
+
|
267
|
+
# context 'with large set of properties' do
|
268
|
+
|
269
|
+
# let(:properties) do
|
270
|
+
# {
|
271
|
+
# display_name: true,
|
272
|
+
# owner: {
|
273
|
+
# id: true,
|
274
|
+
# full_name: true,
|
275
|
+
# blogs_summary: {href: true, size: true},
|
276
|
+
# main_blog: {id: true},
|
277
|
+
# },
|
278
|
+
# administrator: {id: true, full_name: true}
|
279
|
+
# }
|
280
|
+
# end
|
281
|
+
|
282
|
+
# let(:expected_selectors) do
|
283
|
+
# {
|
284
|
+
# BlogModel=> {
|
285
|
+
# select: Set.new([:id, :name, :owner_id, :administrator_id]),
|
286
|
+
# track: Set.new([:owner, :administrator])
|
287
|
+
# },
|
288
|
+
# UserModel=> {
|
289
|
+
# select: Set.new([:id, :first_name, :last_name, :main_blog_id]),
|
290
|
+
# track: Set.new([:blogs, :main_blog])
|
291
|
+
# }
|
292
|
+
# }
|
293
|
+
# end
|
294
|
+
|
295
|
+
# it 'generates the correct set of selectors' do
|
296
|
+
# generator.selectors.should eq(expected_selectors)
|
297
|
+
# end
|
298
|
+
|
299
|
+
# end
|
300
|
+
|
301
|
+
# end
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Praxis::MiddlewareApp do
|
4
4
|
|
5
|
-
let(:init_args){ { root: 'here'
|
5
|
+
let(:init_args){ { root: 'here'} }
|
6
6
|
let(:middleware) { Praxis::MiddlewareApp.for( init_args ) }
|
7
7
|
let(:instance){ middleware.new(target)}
|
8
8
|
|
@@ -29,22 +29,28 @@ describe Praxis::MiddlewareApp do
|
|
29
29
|
end
|
30
30
|
|
31
31
|
context '.call' do
|
32
|
-
let(:the_instance) { double("The instance", setup: nil) }
|
33
32
|
let(:env){ {} }
|
34
33
|
let(:praxis_response){ [200,{}] }
|
35
34
|
subject(:response){ instance.call(env) }
|
36
35
|
before do
|
37
36
|
# always invokes the praxis app
|
38
|
-
expect( Praxis::Application ).to receive(:
|
39
|
-
expect( the_instance ).to receive(:call).with( env ).once.and_return(praxis_response)
|
40
|
-
allow( the_instance ).to receive(:setup).and_return(the_instance)
|
37
|
+
expect( Praxis::Application.instance ).to receive(:call).with( env ).once.and_return(praxis_response)
|
41
38
|
end
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
context 'when it has not been setup yet' do
|
41
|
+
it 'initializes the application singleton with the passed parameters' do
|
42
|
+
expect( Praxis::Application.instance ).to receive(:setup).with( init_args ).once
|
43
|
+
subject
|
44
|
+
end
|
45
|
+
end
|
46
|
+
context 'when it has already been setup' do
|
47
|
+
it 'does NOT call instance setup' do
|
48
|
+
middleware.setup
|
49
|
+
expect( Praxis::Application.instance ).to_not receive(:setup)
|
50
|
+
subject
|
51
|
+
end
|
46
52
|
end
|
47
|
-
|
53
|
+
|
48
54
|
context 'properly handled (non-404 and 405) responses from praxis' do
|
49
55
|
it 'are returned straight through' do
|
50
56
|
expect( response ).to be(praxis_response)
|
data/spec/praxis/request_spec.rb
CHANGED
@@ -12,17 +12,7 @@ describe Praxis::Request do
|
|
12
12
|
env['HTTP_AUTHORIZATION'] = 'Secret'
|
13
13
|
env
|
14
14
|
end
|
15
|
-
|
16
|
-
app = Praxis::Application.new(skip_registration: true)
|
17
|
-
app.versioning_scheme = [:header, :params]
|
18
|
-
app.handler 'json' , Praxis::Handlers::JSON
|
19
|
-
app.handler 'x-www-form-urlencoded', Praxis::Handlers::WWWForm
|
20
|
-
app.api_definition.info do # applies to all API infos
|
21
|
-
base_path "/api"
|
22
|
-
end
|
23
|
-
app
|
24
|
-
end
|
25
|
-
|
15
|
+
|
26
16
|
let(:action) { Instances.definition.actions[:show] }
|
27
17
|
|
28
18
|
let(:context) do
|
@@ -34,7 +24,7 @@ describe Praxis::Request do
|
|
34
24
|
end
|
35
25
|
|
36
26
|
subject(:request) do
|
37
|
-
request = Praxis::Request.new(env
|
27
|
+
request = Praxis::Request.new(env)
|
38
28
|
request.action = action
|
39
29
|
request
|
40
30
|
end
|
@@ -47,10 +37,10 @@ describe Praxis::Request do
|
|
47
37
|
context 'path versioning' do
|
48
38
|
before do
|
49
39
|
allow(
|
50
|
-
|
40
|
+
Praxis::Application.instance
|
51
41
|
).to receive(:versioning_scheme).and_return(:path)
|
52
42
|
allow(
|
53
|
-
|
43
|
+
Praxis::ApiDefinition.instance.info
|
54
44
|
).to receive(:base_path).and_return('/api/v:api_version')
|
55
45
|
|
56
46
|
end
|
@@ -74,7 +64,7 @@ describe Praxis::Request do
|
|
74
64
|
let(:versioning_scheme){ Praxis::Request::VERSION_USING_DEFAULTS }
|
75
65
|
before do
|
76
66
|
allow(
|
77
|
-
|
67
|
+
Praxis::Application.instance
|
78
68
|
).to receive(:versioning_scheme).and_return(versioning_scheme)
|
79
69
|
end
|
80
70
|
|
@@ -94,7 +84,7 @@ describe Praxis::Request do
|
|
94
84
|
|
95
85
|
before do
|
96
86
|
allow(
|
97
|
-
|
87
|
+
Praxis::ApiDefinition.instance.info
|
98
88
|
).to receive(:base_path).and_return('/v:api_version')
|
99
89
|
end
|
100
90
|
it { should eq('5.0') }
|
@@ -219,7 +209,7 @@ describe Praxis::Request do
|
|
219
209
|
let(:parsed_result){ double("parsed") }
|
220
210
|
|
221
211
|
before do
|
222
|
-
|
212
|
+
Praxis::Application.instance.handler 'xml', Praxis::Handlers::XML
|
223
213
|
end
|
224
214
|
|
225
215
|
after do
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Praxis::RequestStages::Validate do
|
4
|
-
let(:dispatcher) { Praxis::Dispatcher.new
|
4
|
+
let(:dispatcher) { Praxis::Dispatcher.new }
|
5
5
|
|
6
6
|
# Instances controller is defined in the 'app' folder and is already in scope. Using this
|
7
7
|
# controller for the specs instead of creating a simple controller.
|
@@ -101,13 +101,12 @@ describe Praxis::ResourceDefinition do
|
|
101
101
|
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
api_def.info do
|
104
|
+
|
105
|
+
let(:non_singleton_api) do
|
106
|
+
api_def=Praxis::ApiDefinition.__send__(:new)
|
107
|
+
api_def.instance_eval do |api|
|
108
|
+
|
109
|
+
api.info do
|
111
110
|
base_path '/api/:base_param'
|
112
111
|
base_params do
|
113
112
|
attribute :base_param, String
|
@@ -117,23 +116,22 @@ describe Praxis::ResourceDefinition do
|
|
117
116
|
end
|
118
117
|
end
|
119
118
|
|
120
|
-
|
119
|
+
api.info '1.0' do
|
121
120
|
base_params do
|
122
121
|
attribute :app_name, String
|
123
122
|
end
|
124
123
|
end
|
125
|
-
|
124
|
+
api.info '2.0' do
|
126
125
|
base_params do
|
127
126
|
attribute :v2_param, String
|
128
127
|
end
|
129
128
|
end
|
130
|
-
|
131
129
|
end
|
132
|
-
|
130
|
+
api_def
|
133
131
|
end
|
134
132
|
|
135
133
|
before do
|
136
|
-
allow(Praxis::
|
134
|
+
allow(Praxis::ApiDefinition).to receive(:instance).and_return(non_singleton_api)
|
137
135
|
end
|
138
136
|
|
139
137
|
it 'are applied to actions' do
|
@@ -1,24 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Praxis::ResponseDefinition do
|
4
|
-
|
5
|
-
app = Praxis::Application.new(skip_registration: true)
|
6
|
-
app.versioning_scheme = [:header, :params]
|
7
|
-
app.handler 'json' , Praxis::Handlers::JSON
|
8
|
-
app.handler 'x-www-form-urlencoded', Praxis::Handlers::WWWForm
|
9
|
-
app.handler 'xml', Praxis::Handlers::XML
|
10
|
-
app.api_definition.instance_eval do |api_def|
|
11
|
-
api_def.info do
|
12
|
-
base_path "/api"
|
13
|
-
produces 'json','xml'
|
14
|
-
end
|
15
|
-
end
|
16
|
-
app
|
17
|
-
end
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
subject(:response_definition) { Praxis::ResponseDefinition.new(name, praxis_app, &block) }
|
4
|
+
subject(:response_definition) { Praxis::ResponseDefinition.new(name, &block) }
|
22
5
|
let(:name) { 'response_name' }
|
23
6
|
|
24
7
|
let(:block) do
|
@@ -499,7 +482,7 @@ describe Praxis::ResponseDefinition do
|
|
499
482
|
context 'with invalid definitions' do
|
500
483
|
it 'raises an error if status code is not part of the definition' do
|
501
484
|
expect do
|
502
|
-
Praxis::ResponseDefinition.new('response name'
|
485
|
+
Praxis::ResponseDefinition.new('response name') do
|
503
486
|
description "testing"
|
504
487
|
end
|
505
488
|
end.to raise_error(Praxis::Exceptions::InvalidConfiguration)
|
@@ -513,7 +496,7 @@ describe Praxis::ResponseDefinition do
|
|
513
496
|
let(:parts) { nil }
|
514
497
|
|
515
498
|
let(:response) do
|
516
|
-
Praxis::ResponseDefinition.new(:custom
|
499
|
+
Praxis::ResponseDefinition.new(:custom) do
|
517
500
|
status 300
|
518
501
|
end
|
519
502
|
end
|
@@ -541,8 +524,8 @@ describe Praxis::ResponseDefinition do
|
|
541
524
|
its(['xml', :content_type]) { should eq('application/vnd.acme.instance+xml') }
|
542
525
|
|
543
526
|
it 'properly encodes the example bodies' do
|
544
|
-
json =
|
545
|
-
xml =
|
527
|
+
json = Praxis::Application.instance.handlers['json'].parse(examples['json'][:body])
|
528
|
+
xml = Praxis::Application.instance.handlers['xml'].parse(examples['xml'][:body])
|
546
529
|
expect(json).to eq xml
|
547
530
|
end
|
548
531
|
|
@@ -49,14 +49,7 @@ describe Praxis::Response do
|
|
49
49
|
end
|
50
50
|
|
51
51
|
subject(:response) { Praxis::Responses::Ok.new(status: response_status, headers: response_headers) }
|
52
|
-
|
53
|
-
double("PraxisApp", handlers: handlers, config: praxis_config)
|
54
|
-
end
|
55
|
-
let(:handlers) do
|
56
|
-
{'json' => Praxis::Handlers::JSON.new }
|
57
|
-
end
|
58
|
-
let(:praxis_config){ double(praxis: double("...") ) }
|
59
|
-
|
52
|
+
|
60
53
|
describe '#validate' do
|
61
54
|
before do
|
62
55
|
allow(action).to receive(:responses).and_return({response_spec.name => response_spec })
|
@@ -93,7 +86,7 @@ describe Praxis::Response do
|
|
93
86
|
before { response.body = response_body_entity }
|
94
87
|
|
95
88
|
it 'leaves well enough alone' do
|
96
|
-
response.encode!
|
89
|
+
response.encode!
|
97
90
|
expect(response.body).to eq(response_body_entity)
|
98
91
|
end
|
99
92
|
end
|
@@ -102,7 +95,7 @@ describe Praxis::Response do
|
|
102
95
|
before { response.body = response_body_structured_data }
|
103
96
|
|
104
97
|
it 'encodes using a suitable handler' do
|
105
|
-
response.encode!
|
98
|
+
response.encode!
|
106
99
|
expect(JSON.load(response.body)).to eq(response_body_structured_data)
|
107
100
|
end
|
108
101
|
end
|
@@ -115,7 +108,7 @@ describe Praxis::Response do
|
|
115
108
|
'Location' => '/api/resources/123' }
|
116
109
|
}
|
117
110
|
it 'still defaults to the default handler' do
|
118
|
-
response.encode!
|
111
|
+
response.encode!
|
119
112
|
expect(JSON.load(response.body)).to eq(response_body_structured_data)
|
120
113
|
end
|
121
114
|
end
|
@@ -165,7 +158,7 @@ describe Praxis::Response do
|
|
165
158
|
response.status = 500
|
166
159
|
end
|
167
160
|
|
168
|
-
let!(:finished_response) { response.finish
|
161
|
+
let!(:finished_response) { response.finish }
|
169
162
|
|
170
163
|
it 'returns status, headers, body' do
|
171
164
|
expect(finished_response).to eq([response.status, response.headers, response.body])
|
@@ -17,12 +17,15 @@ describe Praxis::Responses::InternalServerError do
|
|
17
17
|
|
18
18
|
|
19
19
|
context '.format!' do
|
20
|
-
let(:app){ double("PraxisApp", config: double(praxis: config)) }
|
21
20
|
let(:error) { double('error', message: 'error message', backtrace: [1, 2], cause: cause) }
|
22
21
|
|
23
22
|
let(:show_exceptions) { true }
|
24
23
|
let(:config) { double("config", show_exceptions: show_exceptions) }
|
25
24
|
|
25
|
+
before do
|
26
|
+
allow(Praxis::Application.instance.config).to receive(:praxis).and_return(config)
|
27
|
+
end
|
28
|
+
|
26
29
|
context 'with show_exceptions false' do
|
27
30
|
end
|
28
31
|
|
@@ -50,7 +53,7 @@ describe Praxis::Responses::InternalServerError do
|
|
50
53
|
subject(:response) { Praxis::Responses::InternalServerError.new(error: error) }
|
51
54
|
before do
|
52
55
|
expect(response.body).to be_nil
|
53
|
-
response.format!
|
56
|
+
response.format!
|
54
57
|
end
|
55
58
|
|
56
59
|
end
|
data/spec/praxis/router_spec.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Praxis::Router do
|
4
|
-
let(:application) do
|
5
|
-
app = Praxis::Application.new(skip_registration: true)
|
6
|
-
app.versioning_scheme = [:header, :params]
|
7
|
-
app
|
8
|
-
end
|
9
4
|
describe Praxis::Router::VersionMatcher do
|
10
5
|
let(:resource_definition){ double("resource_definition", version_options: { using: [:header, :params] }) }
|
11
6
|
let(:action){ double("action", resource_definition: resource_definition ) }
|
@@ -22,7 +17,7 @@ describe Praxis::Router do
|
|
22
17
|
|
23
18
|
context '.call' do
|
24
19
|
let(:env){ {"HTTP_X_API_VERSION" => request_version } }
|
25
|
-
let(:request) {Praxis::Request.new(env
|
20
|
+
let(:request) {Praxis::Request.new(env)}
|
26
21
|
|
27
22
|
context 'with matching versions' do
|
28
23
|
let(:request_version) { "1.0" }
|
@@ -72,6 +67,7 @@ describe Praxis::Router do
|
|
72
67
|
end
|
73
68
|
end
|
74
69
|
|
70
|
+
let(:application) { instance_double('Praxis::Application')}
|
75
71
|
subject(:router) {Praxis::Router.new(application)}
|
76
72
|
|
77
73
|
context "attributes" do
|
@@ -108,7 +104,7 @@ describe Praxis::Router do
|
|
108
104
|
let(:request_verb) { 'POST' }
|
109
105
|
let(:request_path_info) { '/' }
|
110
106
|
let(:request_version){ nil }
|
111
|
-
let(:request) {Praxis::Request.new(env
|
107
|
+
let(:request) {Praxis::Request.new(env)}
|
112
108
|
let(:router_response){ 1 }
|
113
109
|
let(:router_response_for_post){ "POST result" }
|
114
110
|
let(:router_response_for_wildcard){ "* result" }
|
@@ -189,7 +185,7 @@ describe Praxis::Router do
|
|
189
185
|
end
|
190
186
|
|
191
187
|
context 'with X-Cascade disabled' do
|
192
|
-
let(:config) {
|
188
|
+
let(:config) { Praxis::Application.instance.config.praxis }
|
193
189
|
before do
|
194
190
|
expect(config).to receive(:x_cascade).and_return(false)
|
195
191
|
end
|
@@ -1,3 +1,3 @@
|
|
1
|
-
class PersonModel
|
2
|
-
|
3
|
-
end
|
1
|
+
# class PersonModel #< Praxis::Mapper::Model
|
2
|
+
# # table_name 'people'
|
3
|
+
# end
|