moonrope 1.4.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +47 -0
  4. data/MIT-LICENCE +20 -0
  5. data/README.md +24 -0
  6. data/bin/moonrope +28 -0
  7. data/docs/authentication.md +114 -0
  8. data/docs/controllers.md +106 -0
  9. data/docs/exceptions.md +27 -0
  10. data/docs/introduction.md +29 -0
  11. data/docs/structures.md +214 -0
  12. data/example/authentication.rb +50 -0
  13. data/example/controllers/meta_controller.rb +14 -0
  14. data/example/controllers/users_controller.rb +92 -0
  15. data/example/structures/pet_structure.rb +12 -0
  16. data/example/structures/user_structure.rb +35 -0
  17. data/html/assets/lock.svg +3 -0
  18. data/html/assets/reset.css +101 -0
  19. data/html/assets/style.css +348 -0
  20. data/html/assets/tool.svg +4 -0
  21. data/html/assets/try.js +151 -0
  22. data/html/authenticators/default.html +191 -0
  23. data/html/controllers/meta/version.html +144 -0
  24. data/html/controllers/meta.html +73 -0
  25. data/html/controllers/users/create.html +341 -0
  26. data/html/controllers/users/list.html +348 -0
  27. data/html/controllers/users/show.html +261 -0
  28. data/html/controllers/users/update.html +387 -0
  29. data/html/controllers/users.html +93 -0
  30. data/html/index.html +166 -0
  31. data/html/moonrope.txt +0 -0
  32. data/html/structures/pet.html +176 -0
  33. data/html/structures/user.html +338 -0
  34. data/lib/moonrope/action.rb +165 -37
  35. data/lib/moonrope/authenticator.rb +39 -0
  36. data/lib/moonrope/base.rb +24 -6
  37. data/lib/moonrope/controller.rb +4 -2
  38. data/lib/moonrope/doc_context.rb +94 -0
  39. data/lib/moonrope/doc_server.rb +123 -0
  40. data/lib/moonrope/dsl/action_dsl.rb +159 -9
  41. data/lib/moonrope/dsl/authenticator_dsl.rb +31 -0
  42. data/lib/moonrope/dsl/base_dsl.rb +21 -18
  43. data/lib/moonrope/dsl/controller_dsl.rb +60 -9
  44. data/lib/moonrope/dsl/filterable_dsl.rb +27 -0
  45. data/lib/moonrope/dsl/structure_dsl.rb +27 -2
  46. data/lib/moonrope/errors.rb +3 -0
  47. data/lib/moonrope/eval_environment.rb +82 -3
  48. data/lib/moonrope/eval_helpers/filter_helper.rb +82 -0
  49. data/lib/moonrope/eval_helpers.rb +28 -5
  50. data/lib/moonrope/guard.rb +35 -0
  51. data/lib/moonrope/html_generator.rb +65 -0
  52. data/lib/moonrope/param_set.rb +11 -1
  53. data/lib/moonrope/rack_middleware.rb +1 -1
  54. data/lib/moonrope/railtie.rb +31 -14
  55. data/lib/moonrope/request.rb +25 -14
  56. data/lib/moonrope/structure.rb +74 -11
  57. data/lib/moonrope/structure_attribute.rb +15 -0
  58. data/lib/moonrope/version.rb +1 -1
  59. data/lib/moonrope.rb +5 -4
  60. data/moonrope.gemspec +21 -0
  61. data/spec/spec_helper.rb +32 -0
  62. data/spec/specs/action_spec.rb +455 -0
  63. data/spec/specs/base_spec.rb +29 -0
  64. data/spec/specs/controller_spec.rb +31 -0
  65. data/spec/specs/param_set_spec.rb +31 -0
  66. data/templates/basic/_action_form.erb +77 -0
  67. data/templates/basic/_errors_table.erb +32 -0
  68. data/templates/basic/_structure_attributes_list.erb +55 -0
  69. data/templates/basic/action.erb +168 -0
  70. data/templates/basic/assets/lock.svg +3 -0
  71. data/templates/basic/assets/reset.css +101 -0
  72. data/templates/basic/assets/style.css +348 -0
  73. data/templates/basic/assets/tool.svg +4 -0
  74. data/templates/basic/assets/try.js +151 -0
  75. data/templates/basic/authenticator.erb +51 -0
  76. data/templates/basic/controller.erb +20 -0
  77. data/templates/basic/index.erb +114 -0
  78. data/templates/basic/layout.erb +46 -0
  79. data/templates/basic/structure.erb +23 -0
  80. data/test/test_helper.rb +81 -0
  81. data/test/tests/action_access_test.rb +63 -0
  82. data/test/tests/actions_test.rb +524 -0
  83. data/test/tests/authenticators_test.rb +87 -0
  84. data/test/tests/base_test.rb +35 -0
  85. data/test/tests/controllers_test.rb +49 -0
  86. data/test/tests/eval_environment_test.rb +136 -0
  87. data/test/tests/evel_helpers_test.rb +60 -0
  88. data/test/tests/examples_test.rb +11 -0
  89. data/test/tests/helpers_test.rb +97 -0
  90. data/test/tests/param_set_test.rb +44 -0
  91. data/test/tests/rack_middleware_test.rb +109 -0
  92. data/test/tests/request_test.rb +232 -0
  93. data/test/tests/structures_param_extensions_test.rb +159 -0
  94. data/test/tests/structures_test.rb +335 -0
  95. 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>