moonrope 1.4.1 → 2.0.0
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/Gemfile +9 -0
- data/Gemfile.lock +47 -0
- data/MIT-LICENCE +20 -0
- data/README.md +24 -0
- data/bin/moonrope +28 -0
- data/docs/authentication.md +114 -0
- data/docs/controllers.md +106 -0
- data/docs/exceptions.md +27 -0
- data/docs/introduction.md +29 -0
- data/docs/structures.md +214 -0
- data/example/authentication.rb +50 -0
- data/example/controllers/meta_controller.rb +14 -0
- data/example/controllers/users_controller.rb +92 -0
- data/example/structures/pet_structure.rb +12 -0
- data/example/structures/user_structure.rb +35 -0
- data/html/assets/lock.svg +3 -0
- data/html/assets/reset.css +101 -0
- data/html/assets/style.css +348 -0
- data/html/assets/tool.svg +4 -0
- data/html/assets/try.js +151 -0
- data/html/authenticators/default.html +191 -0
- data/html/controllers/meta/version.html +144 -0
- data/html/controllers/meta.html +73 -0
- data/html/controllers/users/create.html +341 -0
- data/html/controllers/users/list.html +348 -0
- data/html/controllers/users/show.html +261 -0
- data/html/controllers/users/update.html +387 -0
- data/html/controllers/users.html +93 -0
- data/html/index.html +166 -0
- data/html/moonrope.txt +0 -0
- data/html/structures/pet.html +176 -0
- data/html/structures/user.html +338 -0
- data/lib/moonrope/action.rb +165 -37
- data/lib/moonrope/authenticator.rb +39 -0
- data/lib/moonrope/base.rb +24 -6
- data/lib/moonrope/controller.rb +4 -2
- data/lib/moonrope/doc_context.rb +94 -0
- data/lib/moonrope/doc_server.rb +123 -0
- data/lib/moonrope/dsl/action_dsl.rb +159 -9
- data/lib/moonrope/dsl/authenticator_dsl.rb +31 -0
- data/lib/moonrope/dsl/base_dsl.rb +21 -18
- data/lib/moonrope/dsl/controller_dsl.rb +60 -9
- data/lib/moonrope/dsl/filterable_dsl.rb +27 -0
- data/lib/moonrope/dsl/structure_dsl.rb +27 -2
- data/lib/moonrope/errors.rb +3 -0
- data/lib/moonrope/eval_environment.rb +82 -3
- data/lib/moonrope/eval_helpers/filter_helper.rb +82 -0
- data/lib/moonrope/eval_helpers.rb +28 -5
- data/lib/moonrope/guard.rb +35 -0
- data/lib/moonrope/html_generator.rb +65 -0
- data/lib/moonrope/param_set.rb +11 -1
- data/lib/moonrope/rack_middleware.rb +1 -1
- data/lib/moonrope/railtie.rb +31 -14
- data/lib/moonrope/request.rb +25 -14
- data/lib/moonrope/structure.rb +74 -11
- data/lib/moonrope/structure_attribute.rb +15 -0
- data/lib/moonrope/version.rb +1 -1
- data/lib/moonrope.rb +5 -4
- data/moonrope.gemspec +21 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/specs/action_spec.rb +455 -0
- data/spec/specs/base_spec.rb +29 -0
- data/spec/specs/controller_spec.rb +31 -0
- data/spec/specs/param_set_spec.rb +31 -0
- data/templates/basic/_action_form.erb +77 -0
- data/templates/basic/_errors_table.erb +32 -0
- data/templates/basic/_structure_attributes_list.erb +55 -0
- data/templates/basic/action.erb +168 -0
- data/templates/basic/assets/lock.svg +3 -0
- data/templates/basic/assets/reset.css +101 -0
- data/templates/basic/assets/style.css +348 -0
- data/templates/basic/assets/tool.svg +4 -0
- data/templates/basic/assets/try.js +151 -0
- data/templates/basic/authenticator.erb +51 -0
- data/templates/basic/controller.erb +20 -0
- data/templates/basic/index.erb +114 -0
- data/templates/basic/layout.erb +46 -0
- data/templates/basic/structure.erb +23 -0
- data/test/test_helper.rb +81 -0
- data/test/tests/action_access_test.rb +63 -0
- data/test/tests/actions_test.rb +524 -0
- data/test/tests/authenticators_test.rb +87 -0
- data/test/tests/base_test.rb +35 -0
- data/test/tests/controllers_test.rb +49 -0
- data/test/tests/eval_environment_test.rb +136 -0
- data/test/tests/evel_helpers_test.rb +60 -0
- data/test/tests/examples_test.rb +11 -0
- data/test/tests/helpers_test.rb +97 -0
- data/test/tests/param_set_test.rb +44 -0
- data/test/tests/rack_middleware_test.rb +109 -0
- data/test/tests/request_test.rb +232 -0
- data/test/tests/structures_param_extensions_test.rb +159 -0
- data/test/tests/structures_test.rb +335 -0
- metadata +82 -48
@@ -0,0 +1,455 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'moonrope/base'
|
3
|
+
require 'moonrope/controller'
|
4
|
+
require 'moonrope/action'
|
5
|
+
require 'moonrope/param_set'
|
6
|
+
require 'moonrope/eval_environment'
|
7
|
+
|
8
|
+
describe Moonrope::Action do
|
9
|
+
subject(:base) { Moonrope::Base.new }
|
10
|
+
subject(:controller) { Moonrope::Controller.new(base, :users) }
|
11
|
+
subject(:action) { Moonrope::Action.new(controller, :list) }
|
12
|
+
subject(:request) { FakeRequest.new }
|
13
|
+
subject(:env) { Moonrope::EvalEnvironment.new(base, request, action) }
|
14
|
+
|
15
|
+
context "an action" do
|
16
|
+
it "should be able to have a name" do
|
17
|
+
expect(action.name).to eq :list
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should be able to have a description" do
|
21
|
+
action.dsl.description "Some description"
|
22
|
+
expect(action.description).to eq("Some description")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a hash of params" do
|
26
|
+
action.dsl.param :username
|
27
|
+
action.dsl.param :password
|
28
|
+
expect(action.params).to be_a(Hash)
|
29
|
+
expect(action.params.size).to eq(2)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should have a return value" do
|
33
|
+
action.dsl.returns :hash
|
34
|
+
expect(action.returns).to be_a(Hash)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have errors" do
|
38
|
+
action.dsl.error 'SomeError', "With Description"
|
39
|
+
expect(action.errors).to be_a(Hash)
|
40
|
+
expect(action.errors.size).to eq 1
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be able to use shared actions from the controller" do
|
44
|
+
controller.dsl.shared_action :crud do
|
45
|
+
param :username
|
46
|
+
end
|
47
|
+
action.dsl.use :crud
|
48
|
+
expect(action.params.size).to eq 1
|
49
|
+
end
|
50
|
+
|
51
|
+
it "shuold raise an error if tries to use a share that doesn't exist" do
|
52
|
+
expect { action.dsl.use :crud }.to raise_error(Moonrope::Errors::InvalidSharedAction)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should be able to use shared actions from the base" do
|
56
|
+
base.dsl.shared_action :some_base_thing do
|
57
|
+
param :username
|
58
|
+
end
|
59
|
+
action.dsl.use :some_base_thing
|
60
|
+
expect(action.params.size).to eq 1
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should have a action blocks" do
|
64
|
+
action.dsl.action { true }
|
65
|
+
expect(action.actions).to be_a(Array)
|
66
|
+
expect(action.actions.first).to be_a(Proc)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
context "#default_params" do
|
71
|
+
it "should return the default params for the action" do
|
72
|
+
action.dsl.param :param_with_default, :default => 100
|
73
|
+
action.dsl.param :param_with_no_default
|
74
|
+
expect(action.default_params).to be_a Hash
|
75
|
+
expect(action.default_params.size).to eq 1
|
76
|
+
expect(action.default_params['param_with_default']).to eq 100
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "#validate_parameters" do
|
81
|
+
it "should return an error if a required parameter is missing" do
|
82
|
+
action = Moonrope::Action.new(controller, :list) do
|
83
|
+
param :param, :required => true
|
84
|
+
end
|
85
|
+
param_set = Moonrope::ParamSet.new
|
86
|
+
expect { action.validate_parameters(param_set) }.to raise_error(Moonrope::Errors::ParameterError)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should return an error if a parameter doesn't match its regex" do
|
90
|
+
action = Moonrope::Action.new(controller, :list) do
|
91
|
+
param :param, :regex => /\Ahello\z/
|
92
|
+
end
|
93
|
+
param_set = Moonrope::ParamSet.new('param' => 'nope')
|
94
|
+
expect { action.validate_parameters(param_set) }.to raise_error(Moonrope::Errors::ParameterError)
|
95
|
+
param_set = Moonrope::ParamSet.new('param' => 'hello')
|
96
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should return an error if a parameter isn't included in an options list" do
|
100
|
+
action = Moonrope::Action.new(controller, :list) do
|
101
|
+
param :param, :options => ['apple', 'orange']
|
102
|
+
end
|
103
|
+
param_set = Moonrope::ParamSet.new('param' => 'banana')
|
104
|
+
expect { action.validate_parameters(param_set) }.to raise_error(Moonrope::Errors::ParameterError)
|
105
|
+
param_set = Moonrope::ParamSet.new('param' => 'apple')
|
106
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should return an error if the type is invalid" do
|
110
|
+
action = Moonrope::Action.new(controller, :list) do
|
111
|
+
param :param, :type => String
|
112
|
+
end
|
113
|
+
param_set = Moonrope::ParamSet.new('param' => 123)
|
114
|
+
expect { action.validate_parameters(param_set) }.to raise_error(Moonrope::Errors::ParameterError)
|
115
|
+
param_set = Moonrope::ParamSet.new('param' => 'apple')
|
116
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should return an error if the type is a boolean and it is invalid" do
|
120
|
+
action = Moonrope::Action.new(controller, :list) do
|
121
|
+
param :param, :type => :boolean
|
122
|
+
end
|
123
|
+
param_set = Moonrope::ParamSet.new('param' => 123)
|
124
|
+
expect { action.validate_parameters(param_set) }.to raise_error(Moonrope::Errors::ParameterError)
|
125
|
+
param_set = Moonrope::ParamSet.new('param' => 'true')
|
126
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
127
|
+
param_set = Moonrope::ParamSet.new('param' => 1)
|
128
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
129
|
+
param_set = Moonrope::ParamSet.new('param' => false)
|
130
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should not return an error if the type is a symbol" do
|
134
|
+
action = Moonrope::Action.new(controller, :list) do
|
135
|
+
param :param, :type => :something
|
136
|
+
end
|
137
|
+
param_set = Moonrope::ParamSet.new('param' => 'anything')
|
138
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
139
|
+
param_set = Moonrope::ParamSet.new('param' => 1234.3)
|
140
|
+
expect { action.validate_parameters(param_set) }.to_not raise_error
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
context "#access_rule_to_use" do
|
145
|
+
it "should return the action's access rule if defined on action" do
|
146
|
+
action.dsl.access_rule :rule
|
147
|
+
expect(action.access_rule_to_use).to eq(:rule)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should return the controller's access rule if none on action" do
|
151
|
+
controller.access_rule = :crule
|
152
|
+
expect(action.access_rule_to_use).to eq(:crule)
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should return the default access rule if none on action or controller" do
|
156
|
+
expect(action.access_rule_to_use).to eq(:default)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
context "#authenticator_to_use" do
|
161
|
+
it "should return the action's authentication if defined on action" do
|
162
|
+
base.dsl.authenticator :something
|
163
|
+
action.dsl.authenticator :something
|
164
|
+
expect(action.authenticator_to_use).to be_a(Moonrope::Authenticator)
|
165
|
+
expect(action.authenticator_to_use.name).to eq(:something)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should return the controller's authenticator if none on action" do
|
169
|
+
base.dsl.authenticator :csomething
|
170
|
+
controller.dsl.authenticator :csomething
|
171
|
+
expect(action.authenticator_to_use).to be_a(Moonrope::Authenticator)
|
172
|
+
expect(action.authenticator_to_use.name).to eq(:csomething)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should return no authenticator if none on action or controller and none are defined" do
|
176
|
+
expect(action.authenticator_to_use).to eq :none
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should return default authenticator if none on action or controller and there is a default" do
|
180
|
+
base.dsl.authenticator :default
|
181
|
+
expect(action.authenticator_to_use).to be_a(Moonrope::Authenticator)
|
182
|
+
expect(action.authenticator_to_use.name).to eq(:default)
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should return not_found if the chosen authenticator isn't valid" do
|
186
|
+
action.dsl.authenticator :something
|
187
|
+
expect(action.authenticator_to_use).to eq :not_found
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
context "#convert_errors_to_action_result" do
|
192
|
+
it "should return the block result if no errors" do
|
193
|
+
result = action.convert_errors_to_action_result { 1234 }
|
194
|
+
expect(result).to eq(1234)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should return an ActionResult if a request error is encountered" do
|
198
|
+
result = action.convert_errors_to_action_result do
|
199
|
+
raise Moonrope::Errors::ParameterError, "Invalid param"
|
200
|
+
end
|
201
|
+
expect(result).to be_a(Moonrope::ActionResult)
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should return an ActionResult if a registered external error is encountered" do
|
205
|
+
class SomeError < StandardError
|
206
|
+
end
|
207
|
+
base.register_external_error SomeError do |exception, result|
|
208
|
+
result.status = 'some-error'
|
209
|
+
result.data = {:hello => "world"}
|
210
|
+
end
|
211
|
+
result = action.convert_errors_to_action_result do
|
212
|
+
raise SomeError
|
213
|
+
end
|
214
|
+
expect(result).to be_a(Moonrope::ActionResult)
|
215
|
+
expect(result.status).to eq('some-error')
|
216
|
+
expect(result.data).to be_a(Hash)
|
217
|
+
expect(result.data[:hello]).to eq 'world'
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should raise as normal for any non recognized error" do
|
221
|
+
expect { action.convert_errors_to_action_result{ raise StandardError }}.to raise_error(StandardError)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
context "#check_access" do
|
226
|
+
it "should return true if no authenticator is available" do
|
227
|
+
expect(action.check_access(env)).to be true
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should return an error if the given access rule is not defined on the authenticator" do
|
231
|
+
base.dsl.authenticator :default
|
232
|
+
action.dsl.access_rule :invalid_rule
|
233
|
+
expect { action.check_access(env) }.to raise_error(Moonrope::Errors::MissingAccessRule)
|
234
|
+
end
|
235
|
+
|
236
|
+
it "should return true if the authenticator has no default rule and the default has been requested" do
|
237
|
+
base.dsl.authenticator :default
|
238
|
+
expect(action.access_rule_to_use).to eq :default
|
239
|
+
expect(action.check_access(env)).to be true
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should return the value of the authenticators access block" do
|
243
|
+
rule_has_executed = false
|
244
|
+
base.dsl.authenticator :default do
|
245
|
+
rule :default, "NotPermitted" do
|
246
|
+
rule_has_executed = true
|
247
|
+
false
|
248
|
+
end
|
249
|
+
end
|
250
|
+
expect(action.check_access(env)).to eq false
|
251
|
+
expect(rule_has_executed).to be true
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context "#execute" do
|
256
|
+
|
257
|
+
it "should validate parameters are valid" do
|
258
|
+
allow(action).to receive(:validate_parameters).and_return true
|
259
|
+
action.dsl.action { true }
|
260
|
+
action.execute(env)
|
261
|
+
expect(action).to have_received(:validate_parameters).once
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should execute before actions from the controller" do
|
265
|
+
before_action_run = false
|
266
|
+
controller.dsl.before { before_action_run = true }
|
267
|
+
action.dsl.action { true }
|
268
|
+
action.execute(env)
|
269
|
+
expect(before_action_run).to be true
|
270
|
+
end
|
271
|
+
|
272
|
+
it "should return an ActionResult instance" do
|
273
|
+
action.dsl.action { true }
|
274
|
+
result = action.execute(env)
|
275
|
+
expect(result).to be_a Moonrope::ActionResult
|
276
|
+
end
|
277
|
+
|
278
|
+
it "should have a status" do
|
279
|
+
action.dsl.action { true }
|
280
|
+
expect(action.execute(env).status).to eq 'success'
|
281
|
+
end
|
282
|
+
|
283
|
+
it "should return a time" do
|
284
|
+
action.dsl.action { true }
|
285
|
+
expect(action.execute(env).time).to be_a(Float)
|
286
|
+
end
|
287
|
+
|
288
|
+
it "should return the result" do
|
289
|
+
action.dsl.action { 1234 }
|
290
|
+
expect(action.execute(env).data).to eq 1234
|
291
|
+
end
|
292
|
+
|
293
|
+
it "should include flags from the eval environment" do
|
294
|
+
action.dsl.action do
|
295
|
+
set_flag 'hello', 'world'
|
296
|
+
end
|
297
|
+
result = action.execute(env)
|
298
|
+
expect(result.flags).to be_a(Hash)
|
299
|
+
expect(result.flags['hello']).to eq 'world'
|
300
|
+
end
|
301
|
+
|
302
|
+
it "should include headers from the eval environment" do
|
303
|
+
action.dsl.action do
|
304
|
+
set_header 'X-Something', 'Monkey'
|
305
|
+
end
|
306
|
+
result = action.execute(env)
|
307
|
+
expect(result.headers).to be_a(Hash)
|
308
|
+
expect(result.headers['X-Something']).to eq 'Monkey'
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
context "#can_change_full?" do
|
313
|
+
it "should return true if the action is fully paramable" do
|
314
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => true}
|
315
|
+
expect(action.can_change_full?).to be true
|
316
|
+
end
|
317
|
+
|
318
|
+
it "should return true if the action paramable allow full changes" do
|
319
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:full => true}}
|
320
|
+
expect(action.can_change_full?).to be true
|
321
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:full => false}}
|
322
|
+
expect(action.can_change_full?).to be true
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should return false otherwise" do
|
326
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {}
|
327
|
+
expect(action.can_change_full?).to be false
|
328
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:full => true}
|
329
|
+
expect(action.can_change_full?).to be false
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
context "#includes_full_attributes?" do
|
334
|
+
it "should return true if the action is paramable" do
|
335
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:full => true}}
|
336
|
+
expect(action.includes_full_attributes?).to be true
|
337
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:full => false}}
|
338
|
+
expect(action.includes_full_attributes?).to be false
|
339
|
+
end
|
340
|
+
|
341
|
+
it "should return true if it always returns full attributes" do
|
342
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:full => true}
|
343
|
+
expect(action.includes_full_attributes?).to be true
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should be false if paramable is enabled" do
|
347
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => true}
|
348
|
+
expect(action.includes_full_attributes?).to be false
|
349
|
+
end
|
350
|
+
|
351
|
+
it "should return false otherwise" do
|
352
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:full => false}
|
353
|
+
expect(action.includes_full_attributes?).to be false
|
354
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {}
|
355
|
+
expect(action.includes_full_attributes?).to be false
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
context "#can_change_expansions?" do
|
360
|
+
it "should return true if the action is fully paramable" do
|
361
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => true}
|
362
|
+
expect(action.can_change_expansions?).to be true
|
363
|
+
end
|
364
|
+
it "should return true if the action paramable allow expansion changes" do
|
365
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:expansions => true}}
|
366
|
+
expect(action.can_change_expansions?).to be true
|
367
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:expansions => false}}
|
368
|
+
expect(action.can_change_expansions?).to be true
|
369
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:expansions => []}}
|
370
|
+
expect(action.can_change_expansions?).to be true
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should return false otherwise" do
|
374
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {}
|
375
|
+
expect(action.can_change_expansions?).to be false
|
376
|
+
end
|
377
|
+
end
|
378
|
+
|
379
|
+
context "#includes_expansion?" do
|
380
|
+
it "should return false if the action's paramable expansions are true" do
|
381
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => true}
|
382
|
+
expect(action.includes_expansion?(:user)).to be false
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should return true if the action always returns all expansions" do
|
386
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:expansions => true}
|
387
|
+
expect(action.includes_expansion?(:user)).to be true
|
388
|
+
end
|
389
|
+
|
390
|
+
it "should return true if the action's paramable expansions is an array and it includes the expansion" do
|
391
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:expansions => [:user]}}
|
392
|
+
expect(action.includes_expansion?(:user)).to be true
|
393
|
+
expect(action.includes_expansion?(:another)).to be false
|
394
|
+
end
|
395
|
+
|
396
|
+
it "should return true if the action expansions is an array and it includes the expansion" do
|
397
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:expansions => [:user]}
|
398
|
+
expect(action.includes_expansion?(:user)).to be true
|
399
|
+
expect(action.includes_expansion?(:another)).to be false
|
400
|
+
end
|
401
|
+
|
402
|
+
it "should return false otherwise" do
|
403
|
+
action.dsl.returns :hash, :structure => :user
|
404
|
+
expect(action.includes_expansion?(:user)).to be false
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
context "#available_expansions" do
|
409
|
+
it "should include all the structure's expansions if no array if expansions is provided" do
|
410
|
+
base.dsl.structure :user do
|
411
|
+
expansion :owner
|
412
|
+
expansion :admin
|
413
|
+
end
|
414
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => true}
|
415
|
+
expect(action.available_expansions).to eq([:owner, :admin])
|
416
|
+
end
|
417
|
+
|
418
|
+
it "should include only listed expansions if an array is set" do
|
419
|
+
action.dsl.returns :hash, :structure => :user, :structure_opts => {:paramable => {:expansions => [:owner]}}
|
420
|
+
expect(action.available_expansions).to eq([:owner])
|
421
|
+
end
|
422
|
+
|
423
|
+
it "should be empty if there's no structure" do
|
424
|
+
action.dsl.returns :hash
|
425
|
+
expect(action.available_expansions).to eq([])
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
context "dsl#filterable" do
|
430
|
+
before do
|
431
|
+
action.dsl.filterable do
|
432
|
+
attribute :name
|
433
|
+
attribute :user_id, :operators => [:eq, :not_eq, :in, :not_in] do |operator, value, scope|
|
434
|
+
scope.where(:user => User.find_by_id(value) || error('InvalidUser'))
|
435
|
+
end
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
it "should have an hash of fields" do
|
440
|
+
expect(action.filters).to be_a(Hash)
|
441
|
+
expect(action.filters[:name]).to be_a(Hash)
|
442
|
+
expect(action.filters[:user_id]).to be_a(Hash)
|
443
|
+
expect(action.filters[:user_id][:block]).to be_a(Proc)
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should add a 'filters' param" do
|
447
|
+
expect(action.params[:filters]).to be_a Hash
|
448
|
+
end
|
449
|
+
|
450
|
+
it "should add an error for filter errors" do
|
451
|
+
expect(action.errors['FilterError']).to be_a Hash
|
452
|
+
end
|
453
|
+
|
454
|
+
end
|
455
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'moonrope/base'
|
3
|
+
|
4
|
+
describe Moonrope::Base do
|
5
|
+
subject(:base) { Moonrope::Base.new }
|
6
|
+
|
7
|
+
context "the base" do
|
8
|
+
it "should be able to define & return a controller" do
|
9
|
+
base.dsl.controller :users
|
10
|
+
expect(base.controller(:users)).to be_a(Moonrope::Controller)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be able to define & return a structure" do
|
14
|
+
base.dsl.structure :user
|
15
|
+
expect(base.structure(:user)).to be_a(Moonrope::Structure)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be able to define & return an authenticator" do
|
19
|
+
base.dsl.authenticator :admin
|
20
|
+
expect(base.authenticators[:admin]).to be_a(Moonrope::Authenticator)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to define & return an authenticator" do
|
24
|
+
base.dsl.shared_action(:find_something) { 1234 }
|
25
|
+
expect(base.shared_actions[:find_something]).to be_a(Proc)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'moonrope/controller'
|
3
|
+
require 'moonrope/base'
|
4
|
+
|
5
|
+
describe Moonrope::Controller do
|
6
|
+
context "a controller" do
|
7
|
+
it "should be able to define & return an action" do
|
8
|
+
controller = Moonrope::Controller.new(Moonrope::Base.new, :users) do
|
9
|
+
action :list
|
10
|
+
end
|
11
|
+
expect(controller.action(:list)).to be_a(Moonrope::Action)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should be able to define & return a before filter" do
|
15
|
+
controller = Moonrope::Controller.new(Moonrope::Base.new, :users) do
|
16
|
+
before {}
|
17
|
+
end
|
18
|
+
expect(controller.befores.size).to eq(1)
|
19
|
+
expect(controller.befores.first).to be_a(Moonrope::BeforeAction)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should be able to define & return a shared action" do
|
23
|
+
controller = Moonrope::Controller.new(Moonrope::Base.new, :users) do
|
24
|
+
shared_action :example do
|
25
|
+
end
|
26
|
+
end
|
27
|
+
expect(controller.shared_actions.size).to eq(1)
|
28
|
+
expect(controller.shared_actions[:example]).to be_a(Proc)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'moonrope/param_set'
|
3
|
+
|
4
|
+
describe Moonrope::ParamSet do
|
5
|
+
|
6
|
+
context "a param set" do
|
7
|
+
subject(:param_set) { Moonrope::ParamSet.new('example' => 'Hello') }
|
8
|
+
|
9
|
+
it "should return values in hash format" do
|
10
|
+
expect(param_set[:example]).to eq('Hello')
|
11
|
+
expect(param_set['example']).to eq('Hello')
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return values in dot format" do
|
15
|
+
expect(param_set.example).to eq('Hello')
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be able to say if a param exists or not" do
|
19
|
+
expect(param_set.has?(:example)).to be true
|
20
|
+
expect(param_set.has?('example')).to be true
|
21
|
+
expect(param_set.has?(:unknown)).to be false
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should return a default if one exists and there's no other value" do
|
25
|
+
param_set._defaults = {'fruit' =>'Apple'}
|
26
|
+
expect(param_set.has?(:fruit)).to be true
|
27
|
+
expect(param_set.fruit).to eq 'Apple'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<p class='tryFormActivate'><a class='tryFormActivate__button' href='#'>Try this request in your browser</a></p>
|
2
|
+
<form class='tryForm'>
|
3
|
+
<input type='hidden' name='controller' value='<%= controller.name %>'>
|
4
|
+
<input type='hidden' name='action' value='<%= action.name %>'>
|
5
|
+
<div class='tryForm__header'>
|
6
|
+
<input type='text' id='host' name='host' value='<%= host %>'>
|
7
|
+
/api/
|
8
|
+
<input type='text' id='version' name='version' value='v1' class='v'>
|
9
|
+
/<%= controller.name %>/<%= action.name %>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<% if action.authenticator_to_use.is_a?(Moonrope::Authenticator) %>
|
13
|
+
<p class='tryForm__heading'>Headers</p>
|
14
|
+
<table class='tryForm__table'>
|
15
|
+
<% for name, options in action.authenticator_to_use.headers %>
|
16
|
+
<tr>
|
17
|
+
<td width="50%"><code><%= name %></code></td>
|
18
|
+
<td width="50%"><input type='text' class='tryForm__tableField headerField' name='<%= name %>'></td>
|
19
|
+
</tr>
|
20
|
+
<% end %>
|
21
|
+
</table>
|
22
|
+
<% end %>
|
23
|
+
|
24
|
+
<% unless action.params.empty? %>
|
25
|
+
<p class='tryForm__heading'>Parameters</p>
|
26
|
+
<table class='tryForm__table'>
|
27
|
+
<% for name, param in action.params %>
|
28
|
+
<tr>
|
29
|
+
<td width="30%"><code><%= name %></code></td>
|
30
|
+
<td width="20%"><%= friendly_type param[:type] %></td>
|
31
|
+
<td width="50%"><input type='text' class='tryForm__tableField paramField' name='<%= name %>' placeholder='<%= param[:default] %>' data-type='<%= param[:type] %>'></td>
|
32
|
+
</tr>
|
33
|
+
<% end %>
|
34
|
+
</table>
|
35
|
+
<% end %>
|
36
|
+
|
37
|
+
<% if action.can_change_full? || action.can_change_expansions? %>
|
38
|
+
<p class='tryForm__heading'>Structures</p>
|
39
|
+
<table class='tryForm__table'>
|
40
|
+
<% if action.can_change_full? %>
|
41
|
+
<tr>
|
42
|
+
<td width="50%">Include extended attributes?</td>
|
43
|
+
<td width="50%">
|
44
|
+
<div class='tryForm__checkbox'>
|
45
|
+
<input type='checkbox' class='tryForm__fullAttrs' name='full' id="full_attrs" <% if action.includes_full_attributes? %>checked='checked'<%end%>>
|
46
|
+
<label for="full_attrs">Yes - include extended attributes</label>
|
47
|
+
</div>
|
48
|
+
</td>
|
49
|
+
</tr>
|
50
|
+
<% end %>
|
51
|
+
<% if action.can_change_expansions? %>
|
52
|
+
<tr>
|
53
|
+
<td width="50%">Include expansions?</td>
|
54
|
+
<td width="50%">
|
55
|
+
<% for expansion in action.available_expansions %>
|
56
|
+
<div class='tryForm__checkbox'>
|
57
|
+
<input type='checkbox' class='tryForm__expansions' name='<%= expansion%>' id="expan_<%= expansion %>" <% if action.includes_expansion?(expansion) %>checked='checked'<%end%>>
|
58
|
+
<label for="expan_<%= expansion %>"><%= expansion %></label>
|
59
|
+
</div>
|
60
|
+
<% end %>
|
61
|
+
</td>
|
62
|
+
</tr>
|
63
|
+
<% end %>
|
64
|
+
|
65
|
+
</table>
|
66
|
+
|
67
|
+
<% end %>
|
68
|
+
|
69
|
+
<p class='tryForm__button'>
|
70
|
+
<button class='tryForm__buttonLink' type='submit'>Make this request</button>
|
71
|
+
<button class='tryForm__buttonLink tryFormCancel' type='button'>Cancel</button>
|
72
|
+
</p>
|
73
|
+
|
74
|
+
<pre class='tryForm__output'>The request output will be shown here...</pre>
|
75
|
+
</form>
|
76
|
+
|
77
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<table class='table errorsTable'>
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th width="60%">Error</th>
|
5
|
+
<th width="40%">Attributes</th>
|
6
|
+
</tr>
|
7
|
+
</thead>
|
8
|
+
<% for name, error in errors %>
|
9
|
+
<tr>
|
10
|
+
<td>
|
11
|
+
<p>
|
12
|
+
<span class='paramTable__name'><%= name %></span>
|
13
|
+
<% if error[:description] %>
|
14
|
+
<p class='paramTable__description'><%= error[:description] %></p>
|
15
|
+
<% end %>
|
16
|
+
</p>
|
17
|
+
</td>
|
18
|
+
<td>
|
19
|
+
<% if error[:attributes].is_a?(Hash) %>
|
20
|
+
<ul class='errorAttributeList'>
|
21
|
+
<% for name, description in error[:attributes] %>
|
22
|
+
<li>
|
23
|
+
<p class='errorAttributeList__name'><%= name %></p>
|
24
|
+
<p class='errorAttributeList__desc'><%= description %></p>
|
25
|
+
</li>
|
26
|
+
<% end %>
|
27
|
+
</ul>
|
28
|
+
<% end %>
|
29
|
+
</td>
|
30
|
+
</tr>
|
31
|
+
<% end %>
|
32
|
+
</table>
|