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.
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>