haveapi 0.28.1 → 0.28.3
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 +46 -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
|
|
@@ -268,6 +268,10 @@ module HaveAPI
|
|
|
268
268
|
datetime :created_at
|
|
269
269
|
end
|
|
270
270
|
|
|
271
|
+
params(:public) do
|
|
272
|
+
string :name
|
|
273
|
+
end
|
|
274
|
+
|
|
271
275
|
define_action(:Index, superclass: HaveAPI::Actions::Default::Index) do
|
|
272
276
|
extend DocFilter
|
|
273
277
|
|
|
@@ -292,7 +296,41 @@ module HaveAPI
|
|
|
292
296
|
authorize { allow }
|
|
293
297
|
|
|
294
298
|
def exec
|
|
295
|
-
project = HaveAPI::ClientTestAPI::Store.find_project(
|
|
299
|
+
project = HaveAPI::ClientTestAPI::Store.find_project(path_params['project_id'])
|
|
300
|
+
error!('project not found', {}, http_status: 404) unless project
|
|
301
|
+
project
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
define_action(:PublicList, superclass: HaveAPI::Actions::Default::Index) do
|
|
306
|
+
extend DocFilter
|
|
307
|
+
|
|
308
|
+
route 'public/list'
|
|
309
|
+
aliases []
|
|
310
|
+
resolve { |obj| obj[:id] }
|
|
311
|
+
output(:object_list) { use :public }
|
|
312
|
+
authorize { allow }
|
|
313
|
+
|
|
314
|
+
def exec
|
|
315
|
+
HaveAPI::ClientTestAPI::Store.list_projects
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
def count
|
|
319
|
+
HaveAPI::ClientTestAPI::Store.count_projects
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
define_action(:PublicShow, superclass: HaveAPI::Actions::Default::Show) do
|
|
324
|
+
extend DocFilter
|
|
325
|
+
|
|
326
|
+
route 'public/{project_id}/show'
|
|
327
|
+
aliases []
|
|
328
|
+
resolve { |obj| obj[:id] }
|
|
329
|
+
output(:object) { use :public }
|
|
330
|
+
authorize { allow }
|
|
331
|
+
|
|
332
|
+
def exec
|
|
333
|
+
project = HaveAPI::ClientTestAPI::Store.find_project(path_params['project_id'])
|
|
296
334
|
error!('project not found', {}, http_status: 404) unless project
|
|
297
335
|
project
|
|
298
336
|
end
|
|
@@ -333,11 +371,11 @@ module HaveAPI
|
|
|
333
371
|
authorize { allow }
|
|
334
372
|
|
|
335
373
|
def exec
|
|
336
|
-
HaveAPI::ClientTestAPI::Store.list_tasks(
|
|
374
|
+
HaveAPI::ClientTestAPI::Store.list_tasks(path_params['project_id'])
|
|
337
375
|
end
|
|
338
376
|
|
|
339
377
|
def count
|
|
340
|
-
HaveAPI::ClientTestAPI::Store.list_tasks(
|
|
378
|
+
HaveAPI::ClientTestAPI::Store.list_tasks(path_params['project_id']).size
|
|
341
379
|
end
|
|
342
380
|
end
|
|
343
381
|
|
|
@@ -349,7 +387,7 @@ module HaveAPI
|
|
|
349
387
|
authorize { allow }
|
|
350
388
|
|
|
351
389
|
def exec
|
|
352
|
-
task = HaveAPI::ClientTestAPI::Store.find_task(
|
|
390
|
+
task = HaveAPI::ClientTestAPI::Store.find_task(path_params['project_id'], path_params['task_id'])
|
|
353
391
|
error!('task not found', {}, http_status: 404) unless task
|
|
354
392
|
task
|
|
355
393
|
end
|
|
@@ -368,7 +406,7 @@ module HaveAPI
|
|
|
368
406
|
|
|
369
407
|
def exec
|
|
370
408
|
HaveAPI::ClientTestAPI::Store.create_task(
|
|
371
|
-
|
|
409
|
+
path_params['project_id'],
|
|
372
410
|
input[:label],
|
|
373
411
|
input[:done]
|
|
374
412
|
)
|
|
@@ -387,8 +425,8 @@ module HaveAPI
|
|
|
387
425
|
|
|
388
426
|
def exec
|
|
389
427
|
task = HaveAPI::ClientTestAPI::Store.update_task(
|
|
390
|
-
|
|
391
|
-
|
|
428
|
+
path_params['project_id'],
|
|
429
|
+
path_params['task_id'],
|
|
392
430
|
input[:done]
|
|
393
431
|
)
|
|
394
432
|
error!('task not found', {}, http_status: 404) unless task
|
|
@@ -406,7 +444,7 @@ module HaveAPI
|
|
|
406
444
|
authorize { allow }
|
|
407
445
|
|
|
408
446
|
def exec
|
|
409
|
-
task = HaveAPI::ClientTestAPI::Store.find_task(
|
|
447
|
+
task = HaveAPI::ClientTestAPI::Store.find_task(path_params['project_id'], path_params['task_id'])
|
|
410
448
|
error!('task not found', {}, http_status: 404) unless task
|
|
411
449
|
|
|
412
450
|
@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.3
|
|
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.3
|
|
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.3
|
|
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
|