praxis 0.22.pre.2 → 2.0.pre.1
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/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
|