haveapi 0.28.1 → 0.28.2
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 +1 -1
- data/lib/haveapi/action.rb +64 -50
- data/lib/haveapi/authentication/token/provider.rb +12 -0
- data/lib/haveapi/authorization.rb +21 -0
- data/lib/haveapi/context.rb +17 -2
- data/lib/haveapi/example.rb +1 -0
- data/lib/haveapi/extensions/exception_mailer.rb +6 -2
- data/lib/haveapi/metadata.rb +1 -1
- data/lib/haveapi/model_adapters/active_record.rb +9 -4
- data/lib/haveapi/parameters/resource.rb +5 -4
- data/lib/haveapi/parameters/typed.rb +34 -2
- data/lib/haveapi/params.rb +16 -14
- data/lib/haveapi/resources/action_state.rb +3 -3
- data/lib/haveapi/server.rb +43 -8
- data/lib/haveapi/spec/api_builder.rb +10 -0
- data/lib/haveapi/spec/mock_action.rb +10 -9
- data/lib/haveapi/spec/spec_methods.rb +4 -0
- data/lib/haveapi/version.rb +1 -1
- data/spec/action/runtime_spec.rb +271 -16
- data/spec/action/validation_http_status_spec.rb +76 -0
- data/spec/action_state_spec.rb +28 -5
- data/spec/documentation/auth_filtering_spec.rb +14 -2
- data/spec/model_adapters/active_record_spec.rb +167 -12
- data/spec/parameters/typed_spec.rb +54 -0
- data/spec/server/integration_spec.rb +1 -1
- data/test_support/client_test_api.rb +8 -8
- metadata +4 -3
|
@@ -47,10 +47,24 @@ module ARAdapterSpec
|
|
|
47
47
|
class StringAccount < ActiveRecord::Base
|
|
48
48
|
self.primary_key = 'uuid'
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
class Dataset < ActiveRecord::Base
|
|
52
|
+
has_many :snapshots, class_name: 'ARAdapterSpec::Snapshot'
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
class Snapshot < ActiveRecord::Base
|
|
56
|
+
belongs_to :dataset, class_name: 'ARAdapterSpec::Dataset'
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
class SnapshotLink < ActiveRecord::Base
|
|
60
|
+
belongs_to :snapshot, class_name: 'ARAdapterSpec::Snapshot'
|
|
61
|
+
end
|
|
50
62
|
end
|
|
51
63
|
|
|
52
64
|
describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
53
65
|
api do
|
|
66
|
+
snapshot_resource = nil
|
|
67
|
+
|
|
54
68
|
env_resource = define_resource(:Environment) do
|
|
55
69
|
version 1
|
|
56
70
|
auth false
|
|
@@ -79,7 +93,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
79
93
|
end
|
|
80
94
|
|
|
81
95
|
def exec
|
|
82
|
-
self.class.model.find(
|
|
96
|
+
self.class.model.find(path_params['environment_id'])
|
|
83
97
|
end
|
|
84
98
|
end
|
|
85
99
|
end
|
|
@@ -113,12 +127,12 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
113
127
|
end
|
|
114
128
|
|
|
115
129
|
def prepare
|
|
116
|
-
group = self.class.model.find(
|
|
130
|
+
group = self.class.model.find(path_params['group_id'])
|
|
117
131
|
error!('access denied') if group.note == 'PRIVATE_GROUP_NOTE'
|
|
118
132
|
end
|
|
119
133
|
|
|
120
134
|
def exec
|
|
121
|
-
self.class.model.find(
|
|
135
|
+
self.class.model.find(path_params['group_id'])
|
|
122
136
|
end
|
|
123
137
|
end
|
|
124
138
|
end
|
|
@@ -158,7 +172,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
158
172
|
end
|
|
159
173
|
|
|
160
174
|
def exec
|
|
161
|
-
self.class.model.find(
|
|
175
|
+
self.class.model.find(path_params['filtered_group_id'])
|
|
162
176
|
end
|
|
163
177
|
end
|
|
164
178
|
end
|
|
@@ -178,7 +192,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
178
192
|
end
|
|
179
193
|
|
|
180
194
|
def exec
|
|
181
|
-
with_includes(self.class.model.where(id:
|
|
195
|
+
with_includes(self.class.model.where(id: path_params['filtered_member_id'])).take!
|
|
182
196
|
end
|
|
183
197
|
end
|
|
184
198
|
end
|
|
@@ -225,7 +239,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
225
239
|
end
|
|
226
240
|
|
|
227
241
|
def exec
|
|
228
|
-
id =
|
|
242
|
+
id = path_params['user_id'].to_i
|
|
229
243
|
with_includes(self.class.model.where(id: id)).take!
|
|
230
244
|
end
|
|
231
245
|
end
|
|
@@ -244,7 +258,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
244
258
|
end
|
|
245
259
|
|
|
246
260
|
def exec
|
|
247
|
-
self.class.model.find(
|
|
261
|
+
self.class.model.find(path_params['user_id'])
|
|
248
262
|
end
|
|
249
263
|
end
|
|
250
264
|
|
|
@@ -312,7 +326,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
312
326
|
end
|
|
313
327
|
|
|
314
328
|
def exec
|
|
315
|
-
self.class.model.find(
|
|
329
|
+
self.class.model.find(path_params['hidden_account_id'])
|
|
316
330
|
end
|
|
317
331
|
end
|
|
318
332
|
end
|
|
@@ -332,7 +346,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
332
346
|
end
|
|
333
347
|
|
|
334
348
|
def exec
|
|
335
|
-
self.class.model.find(
|
|
349
|
+
self.class.model.find(path_params['invoice_id'])
|
|
336
350
|
end
|
|
337
351
|
end
|
|
338
352
|
|
|
@@ -352,6 +366,95 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
352
366
|
end
|
|
353
367
|
end
|
|
354
368
|
end
|
|
369
|
+
|
|
370
|
+
define_resource(:Dataset) do
|
|
371
|
+
version 1
|
|
372
|
+
auth false
|
|
373
|
+
route 'datasets/{dataset_id}'
|
|
374
|
+
model ARAdapterSpec::Dataset
|
|
375
|
+
|
|
376
|
+
snapshot_resource = define_resource(:Snapshot) do
|
|
377
|
+
auth false
|
|
378
|
+
model ARAdapterSpec::Snapshot
|
|
379
|
+
|
|
380
|
+
define_action(:Index, superclass: HaveAPI::Actions::Default::Index) do
|
|
381
|
+
authorize { allow }
|
|
382
|
+
|
|
383
|
+
output(:object_list) do
|
|
384
|
+
integer :id
|
|
385
|
+
string :label
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
def exec
|
|
389
|
+
self.class.model.where(dataset_id: path_params['dataset_id']).order(id: :asc).to_a
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
define_action(:Show, superclass: HaveAPI::Actions::Default::Show) do
|
|
394
|
+
resolve ->(snapshot) { [snapshot.dataset_id, snapshot.id] }
|
|
395
|
+
authorize do |_u, params|
|
|
396
|
+
snapshot = ARAdapterSpec::Snapshot.find_by(id: params['snapshot_id'])
|
|
397
|
+
|
|
398
|
+
if snapshot && snapshot.dataset_id == params['dataset_id'].to_i
|
|
399
|
+
allow
|
|
400
|
+
else
|
|
401
|
+
deny
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
output(:object) do
|
|
406
|
+
integer :id
|
|
407
|
+
string :label
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
def prepare
|
|
411
|
+
snapshot = self.class.model.find(path_params['snapshot_id'])
|
|
412
|
+
error!('wrong dataset') if snapshot.dataset_id != path_params['dataset_id'].to_i
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def exec
|
|
416
|
+
self.class.model.find(path_params['snapshot_id'])
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
define_resource(:SnapshotLink) do
|
|
423
|
+
version 1
|
|
424
|
+
auth false
|
|
425
|
+
model ARAdapterSpec::SnapshotLink
|
|
426
|
+
|
|
427
|
+
define_action(:Show, superclass: HaveAPI::Actions::Default::Show) do
|
|
428
|
+
authorize { allow }
|
|
429
|
+
|
|
430
|
+
output(:object) do
|
|
431
|
+
integer :id
|
|
432
|
+
string :label
|
|
433
|
+
resource snapshot_resource
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def exec
|
|
437
|
+
id = path_params['snapshot_link_id']
|
|
438
|
+
with_includes(self.class.model.where(id:)).take!
|
|
439
|
+
end
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
define_action(:Update, superclass: HaveAPI::Actions::Default::Update) do
|
|
443
|
+
authorize { allow }
|
|
444
|
+
|
|
445
|
+
input(:hash) do
|
|
446
|
+
resource snapshot_resource
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
output(:hash) do
|
|
450
|
+
bool :assigned
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
def exec
|
|
454
|
+
{ assigned: input[:snapshot].is_a?(ARAdapterSpec::Snapshot) }
|
|
455
|
+
end
|
|
456
|
+
end
|
|
457
|
+
end
|
|
355
458
|
end
|
|
356
459
|
|
|
357
460
|
default_version 1
|
|
@@ -396,6 +499,20 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
396
499
|
t.string :uuid, primary_key: true
|
|
397
500
|
t.string :label, null: false
|
|
398
501
|
end
|
|
502
|
+
|
|
503
|
+
create_table :datasets do |t|
|
|
504
|
+
t.string :label, null: false
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
create_table :snapshots do |t|
|
|
508
|
+
t.integer :dataset_id, null: false
|
|
509
|
+
t.string :label, null: false
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
create_table :snapshot_links do |t|
|
|
513
|
+
t.integer :snapshot_id, null: false
|
|
514
|
+
t.string :label, null: false
|
|
515
|
+
end
|
|
399
516
|
end
|
|
400
517
|
end
|
|
401
518
|
|
|
@@ -406,6 +523,9 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
406
523
|
ARAdapterSpec::Invoice.delete_all
|
|
407
524
|
ARAdapterSpec::HiddenAccount.delete_all
|
|
408
525
|
ARAdapterSpec::StringAccount.delete_all
|
|
526
|
+
ARAdapterSpec::SnapshotLink.delete_all
|
|
527
|
+
ARAdapterSpec::Snapshot.delete_all
|
|
528
|
+
ARAdapterSpec::Dataset.delete_all
|
|
409
529
|
end
|
|
410
530
|
|
|
411
531
|
let(:dummy_action) do
|
|
@@ -435,6 +555,14 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
435
555
|
ARAdapterSpec::User.create!(defaults.merge(attrs))
|
|
436
556
|
end
|
|
437
557
|
|
|
558
|
+
def create_snapshot_link
|
|
559
|
+
dataset = ARAdapterSpec::Dataset.create!(label: 'dataset')
|
|
560
|
+
snapshot = ARAdapterSpec::Snapshot.create!(dataset:, label: 'snapshot')
|
|
561
|
+
link = ARAdapterSpec::SnapshotLink.create!(snapshot:, label: 'link')
|
|
562
|
+
|
|
563
|
+
[dataset, snapshot, link]
|
|
564
|
+
end
|
|
565
|
+
|
|
438
566
|
def action_class(resource, action)
|
|
439
567
|
klass, = find_action(1, resource, action)
|
|
440
568
|
klass
|
|
@@ -533,7 +661,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
533
661
|
expect(group_data[:environment]).not_to have_key(:note)
|
|
534
662
|
end
|
|
535
663
|
|
|
536
|
-
it 'passes
|
|
664
|
+
it 'passes path params to associated show prepare when included' do
|
|
537
665
|
group = ARAdapterSpec::Group.create!(label: 'grp', note: 'GROUP_NOTE')
|
|
538
666
|
user = create_user(name: 'user', group: group)
|
|
539
667
|
|
|
@@ -580,6 +708,33 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
580
708
|
expect(env_data[:note]).to eq('ENV_NOTE')
|
|
581
709
|
end
|
|
582
710
|
|
|
711
|
+
it 'uses full nested paths for associated show prepare' do
|
|
712
|
+
_dataset, snapshot, link = create_snapshot_link
|
|
713
|
+
|
|
714
|
+
get "/v1/snapshot_links/#{link.id}", { _meta: { includes: 'snapshot' } }, input: ''
|
|
715
|
+
|
|
716
|
+
expect(last_response.status).to eq(200)
|
|
717
|
+
expect(api_response).to be_ok
|
|
718
|
+
|
|
719
|
+
snapshot_data = api_response[:snapshot_link][:snapshot]
|
|
720
|
+
expect(snapshot_data[:_meta][:resolved]).to be(true)
|
|
721
|
+
expect(snapshot_data).to include(id: snapshot.id, label: 'snapshot')
|
|
722
|
+
end
|
|
723
|
+
|
|
724
|
+
it 'uses full nested paths when authorizing resource input records' do
|
|
725
|
+
_dataset, snapshot, link = create_snapshot_link
|
|
726
|
+
|
|
727
|
+
put "/v1/snapshot_links/#{link.id}", {
|
|
728
|
+
snapshot_link: {
|
|
729
|
+
snapshot: snapshot.id
|
|
730
|
+
}
|
|
731
|
+
}.to_json, 'CONTENT_TYPE' => 'application/json'
|
|
732
|
+
|
|
733
|
+
expect(last_response.status).to eq(200)
|
|
734
|
+
expect(api_response).to be_ok
|
|
735
|
+
expect(api_response[:snapshot_link]).to eq(assigned: true)
|
|
736
|
+
end
|
|
737
|
+
|
|
583
738
|
it 'drops invalid nested include paths from requests' do
|
|
584
739
|
group = ARAdapterSpec::Group.create!(label: 'grp', note: 'GRP_NOTE')
|
|
585
740
|
user = create_user(name: 'user', group: group)
|
|
@@ -698,7 +853,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
698
853
|
}
|
|
699
854
|
}.to_json, 'CONTENT_TYPE' => 'application/json'
|
|
700
855
|
|
|
701
|
-
expect(last_response.status).to eq(
|
|
856
|
+
expect(last_response.status).to eq(200)
|
|
702
857
|
expect(api_response).not_to be_ok
|
|
703
858
|
expect(api_response.errors[:hidden_account]).to include('resource not found')
|
|
704
859
|
end
|
|
@@ -799,7 +954,7 @@ describe HaveAPI::ModelAdapters::ActiveRecord do
|
|
|
799
954
|
it 'rejects excessive pagination limits' do
|
|
800
955
|
get '/v1/users', { user: { limit: HaveAPI::Actions::Paginable::MAX_LIMIT + 1 } }, input: ''
|
|
801
956
|
|
|
802
|
-
expect(last_response.status).to eq(
|
|
957
|
+
expect(last_response.status).to eq(200)
|
|
803
958
|
expect(api_response).not_to be_ok
|
|
804
959
|
expect(api_response.errors[:limit].first).to include(
|
|
805
960
|
"range <0, #{HaveAPI::Actions::Paginable::MAX_LIMIT}>"
|
|
@@ -193,6 +193,60 @@ describe 'Parameters::Typed' do
|
|
|
193
193
|
expect(p.clean('value')).to be_nil
|
|
194
194
|
end
|
|
195
195
|
|
|
196
|
+
it 'deep stringifies custom parameter keys by default' do
|
|
197
|
+
p = p_arg(type: Custom)
|
|
198
|
+
raw = {
|
|
199
|
+
rawId: 'credential-id',
|
|
200
|
+
response: {
|
|
201
|
+
clientDataJSON: 'client-data'
|
|
202
|
+
},
|
|
203
|
+
transports: [
|
|
204
|
+
{ type: :usb }
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
expect(p.clean(raw)).to eq({
|
|
209
|
+
'rawId' => 'credential-id',
|
|
210
|
+
'response' => {
|
|
211
|
+
'clientDataJSON' => 'client-data'
|
|
212
|
+
},
|
|
213
|
+
'transports' => [
|
|
214
|
+
{ 'type' => :usb }
|
|
215
|
+
]
|
|
216
|
+
})
|
|
217
|
+
expect(raw).to have_key(:rawId)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
it 'deep symbolizes custom parameter keys when requested' do
|
|
221
|
+
p = p_arg(type: Custom, symbolize_keys: true)
|
|
222
|
+
|
|
223
|
+
expect(p.clean({
|
|
224
|
+
'rawId' => 'credential-id',
|
|
225
|
+
'response' => {
|
|
226
|
+
'clientDataJSON' => 'client-data'
|
|
227
|
+
},
|
|
228
|
+
'transports' => [
|
|
229
|
+
{ 'type' => 'usb' }
|
|
230
|
+
]
|
|
231
|
+
})).to eq({
|
|
232
|
+
rawId: 'credential-id',
|
|
233
|
+
response: {
|
|
234
|
+
clientDataJSON: 'client-data'
|
|
235
|
+
},
|
|
236
|
+
transports: [
|
|
237
|
+
{ type: 'usb' }
|
|
238
|
+
]
|
|
239
|
+
})
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'passes normalized custom keys to custom cleaners' do
|
|
243
|
+
p = p_arg(type: Custom, clean: proc { |v| v.fetch('rawId') })
|
|
244
|
+
expect(p.clean({ rawId: 'credential-id' })).to eq('credential-id')
|
|
245
|
+
|
|
246
|
+
p = p_arg(type: Custom, symbolize_keys: true, clean: proc { |v| v.fetch(:rawId) })
|
|
247
|
+
expect(p.clean({ 'rawId' => 'credential-id' })).to eq('credential-id')
|
|
248
|
+
end
|
|
249
|
+
|
|
196
250
|
it 'rejects invalid string encoding during coercion' do
|
|
197
251
|
invalid = "\xff".b.force_encoding(Encoding::UTF_8)
|
|
198
252
|
|
|
@@ -106,7 +106,7 @@ describe HaveAPI::Server do
|
|
|
106
106
|
'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
expect(last_response.status).to eq(
|
|
109
|
+
expect(last_response.status).to eq(200)
|
|
110
110
|
expect(api_response).not_to be_ok
|
|
111
111
|
expect(ServerIntegrationSpec::State.writes).to be_empty
|
|
112
112
|
end
|
|
@@ -292,7 +292,7 @@ module HaveAPI
|
|
|
292
292
|
authorize { allow }
|
|
293
293
|
|
|
294
294
|
def exec
|
|
295
|
-
project = HaveAPI::ClientTestAPI::Store.find_project(
|
|
295
|
+
project = HaveAPI::ClientTestAPI::Store.find_project(path_params['project_id'])
|
|
296
296
|
error!('project not found', {}, http_status: 404) unless project
|
|
297
297
|
project
|
|
298
298
|
end
|
|
@@ -333,11 +333,11 @@ module HaveAPI
|
|
|
333
333
|
authorize { allow }
|
|
334
334
|
|
|
335
335
|
def exec
|
|
336
|
-
HaveAPI::ClientTestAPI::Store.list_tasks(
|
|
336
|
+
HaveAPI::ClientTestAPI::Store.list_tasks(path_params['project_id'])
|
|
337
337
|
end
|
|
338
338
|
|
|
339
339
|
def count
|
|
340
|
-
HaveAPI::ClientTestAPI::Store.list_tasks(
|
|
340
|
+
HaveAPI::ClientTestAPI::Store.list_tasks(path_params['project_id']).size
|
|
341
341
|
end
|
|
342
342
|
end
|
|
343
343
|
|
|
@@ -349,7 +349,7 @@ module HaveAPI
|
|
|
349
349
|
authorize { allow }
|
|
350
350
|
|
|
351
351
|
def exec
|
|
352
|
-
task = HaveAPI::ClientTestAPI::Store.find_task(
|
|
352
|
+
task = HaveAPI::ClientTestAPI::Store.find_task(path_params['project_id'], path_params['task_id'])
|
|
353
353
|
error!('task not found', {}, http_status: 404) unless task
|
|
354
354
|
task
|
|
355
355
|
end
|
|
@@ -368,7 +368,7 @@ module HaveAPI
|
|
|
368
368
|
|
|
369
369
|
def exec
|
|
370
370
|
HaveAPI::ClientTestAPI::Store.create_task(
|
|
371
|
-
|
|
371
|
+
path_params['project_id'],
|
|
372
372
|
input[:label],
|
|
373
373
|
input[:done]
|
|
374
374
|
)
|
|
@@ -387,8 +387,8 @@ module HaveAPI
|
|
|
387
387
|
|
|
388
388
|
def exec
|
|
389
389
|
task = HaveAPI::ClientTestAPI::Store.update_task(
|
|
390
|
-
|
|
391
|
-
|
|
390
|
+
path_params['project_id'],
|
|
391
|
+
path_params['task_id'],
|
|
392
392
|
input[:done]
|
|
393
393
|
)
|
|
394
394
|
error!('task not found', {}, http_status: 404) unless task
|
|
@@ -406,7 +406,7 @@ module HaveAPI
|
|
|
406
406
|
authorize { allow }
|
|
407
407
|
|
|
408
408
|
def exec
|
|
409
|
-
task = HaveAPI::ClientTestAPI::Store.find_task(
|
|
409
|
+
task = HaveAPI::ClientTestAPI::Store.find_task(path_params['project_id'], path_params['task_id'])
|
|
410
410
|
error!('task not found', {}, http_status: 404) unless task
|
|
411
411
|
|
|
412
412
|
@state_id = HaveAPI::ClientTestAPI::ActionStateBackend.create_state(
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: haveapi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.28.
|
|
4
|
+
version: 0.28.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jakub Skokan
|
|
@@ -29,14 +29,14 @@ dependencies:
|
|
|
29
29
|
requirements:
|
|
30
30
|
- - "~>"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.28.
|
|
32
|
+
version: 0.28.2
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - "~>"
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.28.
|
|
39
|
+
version: 0.28.2
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: json
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -297,6 +297,7 @@ files:
|
|
|
297
297
|
- spec/action/authorize_spec.rb
|
|
298
298
|
- spec/action/dsl_spec.rb
|
|
299
299
|
- spec/action/runtime_spec.rb
|
|
300
|
+
- spec/action/validation_http_status_spec.rb
|
|
300
301
|
- spec/action_state_spec.rb
|
|
301
302
|
- spec/authentication/basic_spec.rb
|
|
302
303
|
- spec/authentication/oauth2_spec.rb
|