haveapi 0.18.2 → 0.19.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/haveapi.gemspec +2 -1
- data/lib/haveapi/action.rb +72 -31
- data/lib/haveapi/authentication/base.rb +1 -1
- data/lib/haveapi/authentication/basic/provider.rb +2 -2
- data/lib/haveapi/authentication/chain.rb +4 -4
- data/lib/haveapi/authentication/oauth2/config.rb +52 -14
- data/lib/haveapi/authentication/oauth2/provider.rb +98 -17
- data/lib/haveapi/authentication/oauth2/revoke_endpoint.rb +36 -0
- data/lib/haveapi/authentication/token/config.rb +1 -0
- data/lib/haveapi/authorization.rb +19 -12
- data/lib/haveapi/client_examples/js_client.rb +11 -1
- data/lib/haveapi/client_examples/php_client.rb +43 -1
- data/lib/haveapi/context.rb +21 -2
- data/lib/haveapi/example.rb +9 -9
- data/lib/haveapi/hooks.rb +23 -23
- data/lib/haveapi/metadata.rb +1 -1
- data/lib/haveapi/model_adapter.rb +14 -14
- data/lib/haveapi/model_adapters/active_record.rb +20 -20
- data/lib/haveapi/output_formatter.rb +4 -4
- data/lib/haveapi/output_formatters/base.rb +1 -1
- data/lib/haveapi/parameters/resource.rb +22 -22
- data/lib/haveapi/parameters/typed.rb +7 -7
- data/lib/haveapi/params.rb +24 -22
- data/lib/haveapi/resource.rb +9 -3
- data/lib/haveapi/resources/action_state.rb +16 -16
- data/lib/haveapi/route.rb +3 -2
- data/lib/haveapi/server.rb +113 -98
- data/lib/haveapi/spec/mock_action.rb +7 -7
- data/lib/haveapi/spec/spec_methods.rb +8 -8
- data/lib/haveapi/tasks/yard.rb +2 -2
- data/lib/haveapi/validator.rb +13 -13
- data/lib/haveapi/validator_chain.rb +6 -6
- data/lib/haveapi/validators/acceptance.rb +2 -2
- data/lib/haveapi/validators/confirmation.rb +4 -4
- data/lib/haveapi/validators/exclusion.rb +4 -4
- data/lib/haveapi/validators/format.rb +4 -4
- data/lib/haveapi/validators/inclusion.rb +3 -3
- data/lib/haveapi/validators/length.rb +1 -1
- data/lib/haveapi/validators/numericality.rb +3 -3
- data/lib/haveapi/validators/presence.rb +2 -2
- data/lib/haveapi/version.rb +1 -1
- data/lib/haveapi/views/version_page/auth_body.erb +6 -4
- data/lib/haveapi/views/version_page/resource_body.erb +2 -0
- data/lib/haveapi.rb +1 -0
- data/spec/authorization_spec.rb +28 -28
- data/spec/envelope_spec.rb +4 -4
- data/spec/parameters/typed_spec.rb +3 -3
- data/spec/params_spec.rb +2 -2
- data/spec/validators/acceptance_spec.rb +2 -2
- data/spec/validators/confirmation_spec.rb +4 -4
- data/spec/validators/exclusion_spec.rb +2 -2
- data/spec/validators/format_spec.rb +5 -5
- data/spec/validators/inclusion_spec.rb +8 -8
- data/spec/validators/presence_spec.rb +1 -1
- metadata +19 -4
@@ -26,12 +26,12 @@ module HaveAPI::Resources
|
|
26
26
|
module Mixin
|
27
27
|
def state_to_hash(state)
|
28
28
|
hash = {
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
29
|
+
id: state.id,
|
30
|
+
label: state.label,
|
31
|
+
status: state.status,
|
32
|
+
created_at: state.created_at,
|
33
|
+
updated_at: state.updated_at,
|
34
|
+
can_cancel: state.can_cancel?,
|
35
35
|
}
|
36
36
|
|
37
37
|
if state.finished?
|
@@ -68,10 +68,10 @@ module HaveAPI::Resources
|
|
68
68
|
def exec
|
69
69
|
ret = []
|
70
70
|
actions = @context.server.action_state.list_pending(
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
current_user,
|
72
|
+
input[:offset],
|
73
|
+
input[:limit],
|
74
|
+
input[:order].to_sym
|
75
75
|
)
|
76
76
|
|
77
77
|
actions.each do |state|
|
@@ -110,8 +110,8 @@ module HaveAPI::Resources
|
|
110
110
|
|
111
111
|
loop do
|
112
112
|
state = @context.server.action_state.new(
|
113
|
-
|
114
|
-
|
113
|
+
current_user,
|
114
|
+
id: params[:action_state_id]
|
115
115
|
)
|
116
116
|
|
117
117
|
error('action state not found') unless state.valid?
|
@@ -147,8 +147,8 @@ module HaveAPI::Resources
|
|
147
147
|
|
148
148
|
def exec
|
149
149
|
state = @context.server.action_state.new(
|
150
|
-
|
151
|
-
|
150
|
+
current_user,
|
151
|
+
id: params[:action_state_id]
|
152
152
|
)
|
153
153
|
|
154
154
|
return state_to_hash(state) if state.valid?
|
@@ -168,8 +168,8 @@ module HaveAPI::Resources
|
|
168
168
|
|
169
169
|
def exec
|
170
170
|
state = @context.server.action_state.new(
|
171
|
-
|
172
|
-
|
171
|
+
current_user,
|
172
|
+
id: params[:action_state_id]
|
173
173
|
)
|
174
174
|
|
175
175
|
error('action state not found') unless state.valid?
|
data/lib/haveapi/route.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
module HaveAPI
|
2
2
|
class Route
|
3
|
-
attr_reader :path, :sinatra_path, :action
|
3
|
+
attr_reader :path, :sinatra_path, :action, :resource_path
|
4
4
|
|
5
|
-
def initialize(path, action)
|
5
|
+
def initialize(path, action, resource_path)
|
6
6
|
@path = path
|
7
7
|
@sinatra_path = path.gsub(/:([a-zA-Z\-_]+)/, '{\1}')
|
8
8
|
@action = action
|
9
|
+
@resource_path = resource_path
|
9
10
|
end
|
10
11
|
|
11
12
|
def http_method
|
data/lib/haveapi/server.rb
CHANGED
@@ -17,21 +17,33 @@ module HaveAPI
|
|
17
17
|
has_hook :post_authenticated,
|
18
18
|
desc: 'Called after the user was authenticated',
|
19
19
|
args: {
|
20
|
-
|
20
|
+
current_user: 'object returned by the authentication backend',
|
21
21
|
}
|
22
22
|
|
23
23
|
has_hook :description_exception,
|
24
24
|
desc: 'Called when an exception occurs when building self-description',
|
25
25
|
args: {
|
26
|
-
|
27
|
-
|
26
|
+
context: 'HaveAPI::Context',
|
27
|
+
exception: 'exception instance',
|
28
28
|
},
|
29
29
|
ret: {
|
30
|
-
|
31
|
-
|
30
|
+
http_status: 'HTTP status code to send to client',
|
31
|
+
message: 'error message sent to the client',
|
32
32
|
}
|
33
33
|
|
34
34
|
module ServerHelpers
|
35
|
+
def setup_formatter
|
36
|
+
return if @formatter
|
37
|
+
@formatter = OutputFormatter.new
|
38
|
+
|
39
|
+
unless @formatter.supports?(request.accept)
|
40
|
+
@halted = true
|
41
|
+
halt 406, "Not Acceptable\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
content_type @formatter.content_type, charset: 'utf-8'
|
45
|
+
end
|
46
|
+
|
35
47
|
def authenticate!(v)
|
36
48
|
require_auth! unless authenticated?(v)
|
37
49
|
end
|
@@ -47,11 +59,11 @@ module HaveAPI
|
|
47
59
|
def access_control
|
48
60
|
if request.env['HTTP_ORIGIN'] && request.env['HTTP_ACCESS_CONTROL_REQUEST_METHOD']
|
49
61
|
halt 200, {
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
62
|
+
'Access-Control-Allow-Origin' => '*',
|
63
|
+
'Access-Control-Allow-Methods' => 'GET,POST,OPTIONS,PATCH,PUT,DELETE',
|
64
|
+
'Access-Control-Allow-Credentials' => 'false',
|
65
|
+
'Access-Control-Allow-Headers' => settings.api_server.allowed_headers,
|
66
|
+
'Access-Control-Max-Age' => (60*60).to_s
|
55
67
|
}, ''
|
56
68
|
end
|
57
69
|
end
|
@@ -66,12 +78,16 @@ module HaveAPI
|
|
66
78
|
end
|
67
79
|
|
68
80
|
def require_auth!
|
69
|
-
report_error(
|
70
|
-
|
81
|
+
report_error(
|
82
|
+
401,
|
83
|
+
{'WWW-Authenticate' => 'Basic realm="Restricted Area"'},
|
84
|
+
'Action requires user to authenticate'
|
85
|
+
)
|
71
86
|
end
|
72
87
|
|
73
88
|
def report_error(code, headers, msg)
|
74
89
|
@halted = true
|
90
|
+
|
75
91
|
content_type @formatter.content_type, charset: 'utf-8'
|
76
92
|
halt code, headers, @formatter.format(false, nil, msg, version: false)
|
77
93
|
end
|
@@ -151,13 +167,12 @@ module HaveAPI
|
|
151
167
|
@extensions = []
|
152
168
|
end
|
153
169
|
|
154
|
-
# Include specific version
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
# set_default_version otherwise.
|
170
|
+
# Include specific version `v` of API.
|
171
|
+
#
|
172
|
+
# `default` is set only when including concrete version. Use {set_default_version}
|
173
|
+
# otherwise.
|
174
|
+
#
|
175
|
+
# @param v [:all, Array<String>, String]
|
161
176
|
def use_version(v, default: false)
|
162
177
|
@versions ||= []
|
163
178
|
|
@@ -178,7 +193,7 @@ module HaveAPI
|
|
178
193
|
end
|
179
194
|
|
180
195
|
# Load routes for all resource from included API versions.
|
181
|
-
# All routes are mounted under prefix
|
196
|
+
# All routes are mounted under prefix `path`.
|
182
197
|
# If no default version is set, the last included version is used.
|
183
198
|
def mount(prefix='/')
|
184
199
|
@root = prefix
|
@@ -198,19 +213,11 @@ module HaveAPI
|
|
198
213
|
set :show_exceptions, false
|
199
214
|
end
|
200
215
|
|
216
|
+
helpers Sinatra::Cookies
|
201
217
|
helpers ServerHelpers
|
202
218
|
helpers DocHelpers
|
203
219
|
|
204
220
|
before do
|
205
|
-
@formatter = OutputFormatter.new
|
206
|
-
|
207
|
-
unless @formatter.supports?(request.accept)
|
208
|
-
@halted = true
|
209
|
-
halt 406, "Not Acceptable\n"
|
210
|
-
end
|
211
|
-
|
212
|
-
content_type @formatter.content_type, charset: 'utf-8'
|
213
|
-
|
214
221
|
if request.env['HTTP_ORIGIN']
|
215
222
|
headers 'Access-Control-Allow-Origin' => '*',
|
216
223
|
'Access-Control-Allow-Credentials' => 'false'
|
@@ -218,6 +225,7 @@ module HaveAPI
|
|
218
225
|
end
|
219
226
|
|
220
227
|
not_found do
|
228
|
+
setup_formatter
|
221
229
|
report_error(404, {}, 'Action not found') unless @halted
|
222
230
|
end
|
223
231
|
|
@@ -236,9 +244,9 @@ module HaveAPI
|
|
236
244
|
authenticated?(settings.api_server.default_version)
|
237
245
|
|
238
246
|
@api = settings.api_server.describe(Context.new(
|
239
|
-
|
240
|
-
|
241
|
-
|
247
|
+
settings.api_server,
|
248
|
+
user: current_user,
|
249
|
+
params: params
|
242
250
|
))
|
243
251
|
|
244
252
|
content_type 'text/html'
|
@@ -246,30 +254,31 @@ module HaveAPI
|
|
246
254
|
end
|
247
255
|
|
248
256
|
@sinatra.options @root do
|
257
|
+
setup_formatter
|
249
258
|
access_control
|
250
259
|
authenticated?(settings.api_server.default_version)
|
251
260
|
ret = nil
|
252
261
|
|
253
262
|
case params[:describe]
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
263
|
+
when 'versions'
|
264
|
+
ret = {
|
265
|
+
versions: settings.api_server.versions,
|
266
|
+
default: settings.api_server.default_version
|
267
|
+
}
|
268
|
+
|
269
|
+
when 'default'
|
270
|
+
ret = settings.api_server.describe_version(Context.new(
|
271
|
+
settings.api_server,
|
272
|
+
version: settings.api_server.default_version,
|
273
|
+
user: current_user, params: params
|
274
|
+
))
|
266
275
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
276
|
+
else
|
277
|
+
ret = settings.api_server.describe(Context.new(
|
278
|
+
settings.api_server,
|
279
|
+
user: current_user,
|
280
|
+
params: params
|
281
|
+
))
|
273
282
|
end
|
274
283
|
|
275
284
|
@formatter.format(true, ret)
|
@@ -348,10 +357,10 @@ module HaveAPI
|
|
348
357
|
|
349
358
|
@v = v
|
350
359
|
@help = settings.api_server.describe_version(Context.new(
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
360
|
+
settings.api_server,
|
361
|
+
version: v,
|
362
|
+
user: current_user,
|
363
|
+
params: params
|
355
364
|
))
|
356
365
|
|
357
366
|
content_type 'text/html'
|
@@ -362,14 +371,15 @@ module HaveAPI
|
|
362
371
|
end
|
363
372
|
|
364
373
|
@sinatra.options prefix do
|
374
|
+
setup_formatter
|
365
375
|
access_control
|
366
376
|
authenticated?(v)
|
367
377
|
|
368
378
|
@formatter.format(true, settings.api_server.describe_version(Context.new(
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
379
|
+
settings.api_server,
|
380
|
+
version: v,
|
381
|
+
user: current_user,
|
382
|
+
params: params
|
373
383
|
)))
|
374
384
|
end
|
375
385
|
|
@@ -380,10 +390,10 @@ module HaveAPI
|
|
380
390
|
|
381
391
|
if action_state
|
382
392
|
mount_resource(
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
393
|
+
prefix,
|
394
|
+
v,
|
395
|
+
HaveAPI::Resources::ActionState,
|
396
|
+
@routes[v][:resources]
|
387
397
|
)
|
388
398
|
end
|
389
399
|
|
@@ -406,8 +416,8 @@ module HaveAPI
|
|
406
416
|
resource.routes(prefix).each do |route|
|
407
417
|
if route.is_a?(Hash)
|
408
418
|
hash[resource][:resources][route.keys.first] = mount_nested_resource(
|
409
|
-
|
410
|
-
|
419
|
+
v,
|
420
|
+
route.values.first
|
411
421
|
)
|
412
422
|
|
413
423
|
else
|
@@ -435,6 +445,8 @@ module HaveAPI
|
|
435
445
|
|
436
446
|
def mount_action(v, route)
|
437
447
|
@sinatra.method(route.http_method).call(route.sinatra_path) do
|
448
|
+
setup_formatter
|
449
|
+
|
438
450
|
if route.action.auth
|
439
451
|
authenticate!(v)
|
440
452
|
else
|
@@ -457,14 +469,15 @@ module HaveAPI
|
|
457
469
|
end
|
458
470
|
|
459
471
|
action = route.action.new(request, v, params, body, Context.new(
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
472
|
+
settings.api_server,
|
473
|
+
version: v,
|
474
|
+
request: self,
|
475
|
+
action: route.action,
|
476
|
+
path: route.path,
|
477
|
+
params: params,
|
478
|
+
user: current_user,
|
479
|
+
endpoint: true,
|
480
|
+
resource_path: route.resource_path,
|
468
481
|
))
|
469
482
|
|
470
483
|
unless action.authorized?(current_user)
|
@@ -475,18 +488,19 @@ module HaveAPI
|
|
475
488
|
@halted = true
|
476
489
|
|
477
490
|
[
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
491
|
+
http_status || 200,
|
492
|
+
@formatter.format(
|
493
|
+
status,
|
494
|
+
status ? reply : nil,
|
495
|
+
!status ? reply : nil,
|
496
|
+
errors,
|
497
|
+
version: false
|
498
|
+
),
|
486
499
|
]
|
487
500
|
end
|
488
501
|
|
489
502
|
@sinatra.options route.sinatra_path do |*args|
|
503
|
+
setup_formatter
|
490
504
|
access_control
|
491
505
|
route_method = route.http_method.to_s.upcase
|
492
506
|
|
@@ -499,15 +513,16 @@ module HaveAPI
|
|
499
513
|
end
|
500
514
|
|
501
515
|
ctx = Context.new(
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
516
|
+
settings.api_server,
|
517
|
+
version: v,
|
518
|
+
request: self,
|
519
|
+
action: route.action,
|
520
|
+
path: route.path,
|
521
|
+
args: args,
|
522
|
+
params: params,
|
523
|
+
user: current_user,
|
524
|
+
endpoint: true,
|
525
|
+
resource_path: route.resource_path,
|
511
526
|
)
|
512
527
|
|
513
528
|
begin
|
@@ -520,9 +535,9 @@ module HaveAPI
|
|
520
535
|
rescue => e
|
521
536
|
tmp = settings.api_server.call_hooks_for(:description_exception, args: [ctx, e])
|
522
537
|
report_error(
|
523
|
-
|
524
|
-
|
525
|
-
|
538
|
+
tmp[:http_status] || 500,
|
539
|
+
{},
|
540
|
+
tmp[:message] || 'Server error occured'
|
526
541
|
)
|
527
542
|
end
|
528
543
|
|
@@ -534,8 +549,8 @@ module HaveAPI
|
|
534
549
|
context.version = @default_version
|
535
550
|
|
536
551
|
ret = {
|
537
|
-
|
538
|
-
|
552
|
+
default_version: @default_version,
|
553
|
+
versions: {default: describe_version(context)},
|
539
554
|
}
|
540
555
|
|
541
556
|
@versions.each do |v|
|
@@ -548,10 +563,10 @@ module HaveAPI
|
|
548
563
|
|
549
564
|
def describe_version(context)
|
550
565
|
ret = {
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
566
|
+
authentication: @auth_chain.describe(context),
|
567
|
+
resources: {},
|
568
|
+
meta: Metadata.describe,
|
569
|
+
help: version_prefix(context.version)
|
555
570
|
}
|
556
571
|
|
557
572
|
#puts JSON.pretty_generate(@routes)
|
@@ -10,13 +10,13 @@ module HaveAPI::Spec
|
|
10
10
|
|
11
11
|
def call(input, user: nil, &block)
|
12
12
|
action = @action.new(nil, @v, input, nil, HaveAPI::Context.new(
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
@server,
|
14
|
+
version: @v,
|
15
|
+
action: @action,
|
16
|
+
path: @path,
|
17
|
+
params: input,
|
18
|
+
user: user,
|
19
|
+
endpoint: true
|
20
20
|
))
|
21
21
|
|
22
22
|
unless action.authorized?(user)
|
@@ -35,23 +35,23 @@ module HaveAPI::Spec
|
|
35
35
|
app
|
36
36
|
|
37
37
|
action, path = find_action(
|
38
|
-
|
39
|
-
|
38
|
+
(params && params[:version]) || @api.default_version,
|
39
|
+
r_name, a_name
|
40
40
|
)
|
41
41
|
|
42
42
|
method(action.http_method).call(
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
path,
|
44
|
+
params && params.to_json,
|
45
|
+
{'Content-Type' => 'application/json'}
|
46
46
|
)
|
47
47
|
|
48
48
|
else
|
49
49
|
http_method, path, params = args
|
50
50
|
|
51
51
|
method(http_method).call(
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
path,
|
53
|
+
params && params.to_json,
|
54
|
+
{'Content-Type' => 'application/json'}
|
55
55
|
)
|
56
56
|
end
|
57
57
|
end
|
data/lib/haveapi/tasks/yard.rb
CHANGED
data/lib/haveapi/validator.rb
CHANGED
@@ -8,15 +8,15 @@ module HaveAPI
|
|
8
8
|
# when default configuration is sufficient. Custom settings can be set using
|
9
9
|
# the full form.
|
10
10
|
#
|
11
|
-
# The short form means the validator is configured as
|
12
|
-
# The full form is
|
11
|
+
# The short form means the validator is configured as `<option> => <single value>`.
|
12
|
+
# The full form is `<option> => { hash with configuration options }`.
|
13
13
|
#
|
14
14
|
# It is up to each validator what exactly the short form means and what options
|
15
15
|
# can be set. Specify only those options that you wish to override. The only
|
16
|
-
# common option is
|
16
|
+
# common option is `message` - the error message sent to the client if the provided
|
17
17
|
# value did not pass the validator.
|
18
18
|
#
|
19
|
-
# The
|
19
|
+
# The `message` can contain `%{value}`, which is replaced by the actual value
|
20
20
|
# that did not pass the validator.
|
21
21
|
class Validator
|
22
22
|
class << self
|
@@ -35,13 +35,13 @@ module HaveAPI
|
|
35
35
|
@takes = opts
|
36
36
|
end
|
37
37
|
|
38
|
-
# True if this validator uses any of options in hash
|
38
|
+
# True if this validator uses any of options in hash `opts`.
|
39
39
|
def use?(opts)
|
40
40
|
!(opts.keys & @takes).empty?
|
41
41
|
end
|
42
42
|
|
43
|
-
# Use the validator on given set of options in hash
|
44
|
-
# options are removed from
|
43
|
+
# Use the validator on given set of options in hash `opts`. Used
|
44
|
+
# options are removed from `opts`.
|
45
45
|
def use(opts)
|
46
46
|
keys = opts.keys & @takes
|
47
47
|
|
@@ -84,7 +84,7 @@ module HaveAPI
|
|
84
84
|
end
|
85
85
|
|
86
86
|
# Calls method valid?, but before calling it sets instance variable
|
87
|
-
#
|
87
|
+
# `@params`. It contains of hash of all other parameters. The validator
|
88
88
|
# may use this information as it will.
|
89
89
|
def validate(v, params)
|
90
90
|
@params = params
|
@@ -96,12 +96,12 @@ module HaveAPI
|
|
96
96
|
protected
|
97
97
|
# This method has three modes of function.
|
98
98
|
#
|
99
|
-
# 1. If
|
99
|
+
# 1. If `v` is nil, it returns `@opts`. It is used if `@opts` is not a hash
|
100
100
|
# but a single value - abbreviation if we're ok with default settings
|
101
101
|
# for given validator.
|
102
|
-
# 2. If
|
103
|
-
# 3. If
|
104
|
-
# returned. Otherwise the
|
102
|
+
# 2. If `v` is not nil and `@opts` is not a hash, it returns `default`
|
103
|
+
# 3. If `v` is not nil and `@opts` is a hash and `@opts[v]` is not nil, it is
|
104
|
+
# returned. Otherwise the `default` is returned.
|
105
105
|
def take(v = nil, default = nil)
|
106
106
|
if v.nil?
|
107
107
|
@opts
|
@@ -120,7 +120,7 @@ module HaveAPI
|
|
120
120
|
@useful = false
|
121
121
|
end
|
122
122
|
|
123
|
-
# Returns true if
|
123
|
+
# Returns true if `@opts` is not a hash.
|
124
124
|
def simple?
|
125
125
|
!@opts.is_a?(::Hash)
|
126
126
|
end
|
@@ -13,11 +13,11 @@ module HaveAPI
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
# Adds validator that takes option
|
16
|
+
# Adds validator that takes option `name` with configuration in `opt`.
|
17
17
|
# If such validator already exists, it is reconfigured with newly provided
|
18
|
-
#
|
18
|
+
# `opt`.
|
19
19
|
#
|
20
|
-
# If
|
20
|
+
# If `opt` is `nil`, the validator is removed.
|
21
21
|
def add_or_replace(name, opt)
|
22
22
|
args = { name => opt }
|
23
23
|
|
@@ -61,8 +61,8 @@ module HaveAPI
|
|
61
61
|
ret
|
62
62
|
end
|
63
63
|
|
64
|
-
# Validate
|
65
|
-
# either
|
64
|
+
# Validate `value` using all configured validators. It returns
|
65
|
+
# either `true` if the value passed all validators or an array
|
66
66
|
# of errors.
|
67
67
|
def validate(value, params)
|
68
68
|
ret = []
|
@@ -70,7 +70,7 @@ module HaveAPI
|
|
70
70
|
@validators.each do |validator|
|
71
71
|
next if validator.validate(value, params)
|
72
72
|
ret << validator.message % {
|
73
|
-
|
73
|
+
value: value
|
74
74
|
}
|
75
75
|
end
|
76
76
|
|
@@ -13,7 +13,7 @@ module HaveAPI
|
|
13
13
|
# message: 'the error message'
|
14
14
|
# }
|
15
15
|
#
|
16
|
-
#
|
16
|
+
# `equal` defaults to `true`.
|
17
17
|
class Validators::Confirmation < Validator
|
18
18
|
name :confirm
|
19
19
|
takes :confirm
|
@@ -30,9 +30,9 @@ module HaveAPI
|
|
30
30
|
|
31
31
|
def describe
|
32
32
|
{
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
equal: @equal ? true : false,
|
34
|
+
parameter: @param,
|
35
|
+
message: @message,
|
36
36
|
}
|
37
37
|
end
|
38
38
|
|