dor-workflow-service 2.10.2 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +3 -3
- data/lib/dor/services/workflow_service.rb +84 -19
- data/lib/dor/workflow_version.rb +1 -1
- data/spec/workflow_service_spec.rb +219 -62
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8f863086a378b50a1d61a7a2defaa0c33731683b53c7082108438725a7d7ec1
|
4
|
+
data.tar.gz: b398505b2babc4b039678f3b17e06ccd120df459ec8ef38784994690fc0dbf19
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3e0bbcea11e6b9ba2070ff50a47145f9cdc6a8e9b2d9b59d8da5961bcf7683c80767ad39928f426358ec7e627b402c1e89846c329988fda417ada8267223c21d
|
7
|
+
data.tar.gz: 9b9006a691d3e89917442e9040bb1c3907c1789c472da4e399b9e5214fd46737455b28822fa2958e53f6c0c791b4947ec9549e04cce2b018ddd9a90ea149e1fa
|
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config`
|
3
|
-
# on 2019-03
|
3
|
+
# on 2019-04-03 11:51:29 -0500 using RuboCop version 0.63.1.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -23,7 +23,7 @@ Metrics/AbcSize:
|
|
23
23
|
# Offense count: 1
|
24
24
|
# Configuration parameters: CountComments.
|
25
25
|
Metrics/ClassLength:
|
26
|
-
Max:
|
26
|
+
Max: 305
|
27
27
|
|
28
28
|
# Offense count: 3
|
29
29
|
# Configuration parameters: CountComments, ExcludedMethods.
|
@@ -42,7 +42,7 @@ Naming/FileName:
|
|
42
42
|
Exclude:
|
43
43
|
- 'lib/dor-workflow-service.rb'
|
44
44
|
|
45
|
-
# Offense count:
|
45
|
+
# Offense count: 8
|
46
46
|
Style/ClassVars:
|
47
47
|
Exclude:
|
48
48
|
- 'lib/dor/services/workflow_service.rb'
|
@@ -94,8 +94,8 @@ module Dor
|
|
94
94
|
# @param [String] workflow The name of the workflow
|
95
95
|
# @param [String] process The name of the process step
|
96
96
|
# @return [String] status for repo-workflow-process-druid
|
97
|
-
def
|
98
|
-
workflow_md =
|
97
|
+
def workflow_status(repo, druid, workflow, process)
|
98
|
+
workflow_md = workflow_xml(repo, druid, workflow)
|
99
99
|
doc = Nokogiri::XML(workflow_md)
|
100
100
|
raise Dor::WorkflowException, "Unable to parse response:\n#{workflow_md}" if doc.root.nil?
|
101
101
|
|
@@ -104,16 +104,38 @@ module Dor
|
|
104
104
|
process&.attr('status')
|
105
105
|
end
|
106
106
|
|
107
|
+
def get_workflow_status(repo, druid, workflow, process)
|
108
|
+
Deprecation.warn(self, 'use workflow_status instead. This will be removed in dor-workflow-service version 3')
|
109
|
+
workflow_status(repo, druid, workflow, process)
|
110
|
+
end
|
111
|
+
|
107
112
|
#
|
108
113
|
# Retrieves the raw XML for the given workflow
|
109
114
|
# @param [String] repo The repository the object resides in. Currently recoginzes "dor" and "sdr".
|
110
115
|
# @param [String] druid The id of the object
|
111
116
|
# @param [String] workflow The name of the workflow
|
112
117
|
# @return [String] XML of the workflow
|
113
|
-
def
|
118
|
+
def workflow_xml(repo, druid, workflow)
|
119
|
+
unless workflow
|
120
|
+
Deprecation.warn(self, 'calling workflow_xml without a workflow is deprecated and will be removed in version 3. Use all_workflows_xml instead.')
|
121
|
+
return all_workflows_xml(druid)
|
122
|
+
end
|
114
123
|
workflow_resource_method "#{repo}/objects/#{druid}/workflows/#{workflow}"
|
115
124
|
end
|
116
125
|
|
126
|
+
def get_workflow_xml(repo, druid, workflow)
|
127
|
+
Deprecation.warn(self, 'use workflow_xml instead. This will be removed in dor-workflow-service version 3')
|
128
|
+
workflow_xml(repo, druid, workflow)
|
129
|
+
end
|
130
|
+
|
131
|
+
#
|
132
|
+
# Retrieves the raw XML for all the workflows for the the given object
|
133
|
+
# @param [String] druid The id of the object
|
134
|
+
# @return [String] XML of the workflow
|
135
|
+
def all_workflows_xml(druid)
|
136
|
+
workflow_resource_method "objects/#{druid}/workflows"
|
137
|
+
end
|
138
|
+
|
117
139
|
# Get workflow names into an array for given PID
|
118
140
|
# This method only works when this gem is used in a project that is configured to connect to DOR
|
119
141
|
#
|
@@ -121,13 +143,18 @@ module Dor
|
|
121
143
|
# @param [String] repo repository for the object
|
122
144
|
# @return [Array<String>] list of worklows
|
123
145
|
# @example
|
124
|
-
# Dor::WorkflowService.
|
146
|
+
# Dor::WorkflowService.workflows('druid:sr100hp0609')
|
125
147
|
# => ["accessionWF", "assemblyWF", "disseminationWF"]
|
126
|
-
def
|
127
|
-
xml_doc = Nokogiri::XML(
|
148
|
+
def workflows(pid, repo = 'dor')
|
149
|
+
xml_doc = Nokogiri::XML(workflow_xml(repo, pid, ''))
|
128
150
|
xml_doc.xpath('//workflow').collect { |workflow| workflow['id'] }
|
129
151
|
end
|
130
152
|
|
153
|
+
def get_workflows(pid, repo = 'dor')
|
154
|
+
Deprecation.warn(self, 'use workflows instead. This will be removed in dor-workflow-service version 3')
|
155
|
+
workflows(pid, repo)
|
156
|
+
end
|
157
|
+
|
131
158
|
# Get active workflow names into an array for given PID
|
132
159
|
# This method only works when this gem is used in a project that is configured to connect to DOR
|
133
160
|
#
|
@@ -135,14 +162,16 @@ module Dor
|
|
135
162
|
# @param [String] pid id of object
|
136
163
|
# @return [Array<String>] list of active worklows. Returns an empty Array if none are found
|
137
164
|
# @example
|
138
|
-
# Dor::WorkflowService.
|
165
|
+
# Dor::WorkflowService.active_workflows('dor', 'druid:sr100hp0609')
|
139
166
|
# => ["accessionWF", "assemblyWF", "disseminationWF"]
|
140
|
-
def
|
167
|
+
def active_workflows(repo, pid)
|
141
168
|
Deprecation.warn(self, 'get_active_workflows will be removed without replacement because the workflow server no longer archives processes')
|
142
169
|
doc = Nokogiri::XML(get_workflow_xml(repo, pid, ''))
|
143
170
|
doc.xpath(%(//workflow[not(process/@archived)]/@id )).map(&:value)
|
144
171
|
end
|
145
172
|
|
173
|
+
alias get_active_workflows active_workflows
|
174
|
+
|
146
175
|
# @param [String] repo repository of the object
|
147
176
|
# @param [String] pid id of object
|
148
177
|
# @param [String] workflow_name The name of the workflow
|
@@ -197,7 +226,7 @@ module Dor
|
|
197
226
|
# <milestone date="2010-04-29T10:12:51-0700">inprocess</milestone>
|
198
227
|
# <milestone date="2010-06-15T16:08:58-0700">released</milestone>
|
199
228
|
# </lifecycle>
|
200
|
-
def
|
229
|
+
def lifecycle(repo, druid, milestone)
|
201
230
|
doc = query_lifecycle(repo, druid)
|
202
231
|
milestone = doc.at_xpath("//lifecycle/milestone[text() = '#{milestone}']")
|
203
232
|
return Time.parse(milestone['date']) if milestone
|
@@ -205,6 +234,11 @@ module Dor
|
|
205
234
|
nil
|
206
235
|
end
|
207
236
|
|
237
|
+
def get_lifecycle(repo, druid, milestone)
|
238
|
+
Deprecation.warn(self, 'use lifecycle instead. This will be removed in dor-workflow-service version 3')
|
239
|
+
lifecycle(repo, druid, milestone)
|
240
|
+
end
|
241
|
+
|
208
242
|
# Returns the Date for a requested milestone ONLY FROM THE ACTIVE workflow table
|
209
243
|
# @param [String] repo repository name
|
210
244
|
# @param [String] druid object id
|
@@ -216,7 +250,7 @@ module Dor
|
|
216
250
|
# <milestone date="2010-04-29T10:12:51-0700">inprocess</milestone>
|
217
251
|
# <milestone date="2010-06-15T16:08:58-0700">released</milestone>
|
218
252
|
# </lifecycle>
|
219
|
-
def
|
253
|
+
def active_lifecycle(repo, druid, milestone)
|
220
254
|
doc = query_lifecycle(repo, druid, true)
|
221
255
|
milestone = doc.at_xpath("//lifecycle/milestone[text() = '#{milestone}']")
|
222
256
|
return Time.parse(milestone['date']) if milestone
|
@@ -224,14 +258,24 @@ module Dor
|
|
224
258
|
nil
|
225
259
|
end
|
226
260
|
|
261
|
+
def get_active_lifecycle(repo, druid, milestone)
|
262
|
+
Deprecation.warn(self, 'use active_lifecycle instead. This will be removed in dor-workflow-service version 3')
|
263
|
+
active_lifecycle(repo, druid, milestone)
|
264
|
+
end
|
265
|
+
|
227
266
|
# @return [Hash]
|
228
|
-
def
|
267
|
+
def milestones(repo, druid)
|
229
268
|
doc = query_lifecycle(repo, druid)
|
230
269
|
doc.xpath('//lifecycle/milestone').collect do |node|
|
231
270
|
{ milestone: node.text, at: Time.parse(node['date']), version: node['version'] }
|
232
271
|
end
|
233
272
|
end
|
234
273
|
|
274
|
+
def get_milestones(repo, druid)
|
275
|
+
Deprecation.warn(self, 'use milestones instead. This will be removed in dor-workflow-service version 3')
|
276
|
+
milestones(repo, druid)
|
277
|
+
end
|
278
|
+
|
235
279
|
# Converts repo-workflow-step into repo:workflow:step
|
236
280
|
# @param [String] default_repository
|
237
281
|
# @param [String] default_workflow
|
@@ -260,7 +304,7 @@ module Dor
|
|
260
304
|
# @return [Array<String>] Array of druids
|
261
305
|
#
|
262
306
|
# @example
|
263
|
-
#
|
307
|
+
# objects_for_workstep(...)
|
264
308
|
# => [
|
265
309
|
# "druid:py156ps0477",
|
266
310
|
# "druid:tt628cb6479",
|
@@ -268,19 +312,19 @@ module Dor
|
|
268
312
|
# ]
|
269
313
|
#
|
270
314
|
# @example
|
271
|
-
#
|
315
|
+
# objects_for_workstep(..., "lane1")
|
272
316
|
# => {
|
273
317
|
# "druid:py156ps0477",
|
274
318
|
# "druid:tt628cb6479",
|
275
319
|
# }
|
276
320
|
#
|
277
321
|
# @example
|
278
|
-
#
|
322
|
+
# objects_for_workstep(..., "lane1", limit: 1)
|
279
323
|
# => {
|
280
324
|
# "druid:py156ps0477",
|
281
325
|
# }
|
282
326
|
#
|
283
|
-
def
|
327
|
+
def objects_for_workstep(completed, waiting, lane_id = 'default', options = {})
|
284
328
|
waiting_param = qualify_step(options[:default_repository], options[:default_workflow], waiting)
|
285
329
|
uri_string = "workflow_queue?waiting=#{waiting_param}"
|
286
330
|
if completed
|
@@ -308,6 +352,11 @@ module Dor
|
|
308
352
|
result.map { |n| n[:id] }
|
309
353
|
end
|
310
354
|
|
355
|
+
def get_objects_for_workstep(completed, waiting, lane_id = 'default', options = {})
|
356
|
+
Deprecation.warn(self, 'use objects_for_workstep instead. This will be removed in dor-workflow-service version 3')
|
357
|
+
objects_for_workstep(completed, waiting, lane_id, options)
|
358
|
+
end
|
359
|
+
|
311
360
|
# Get a list of druids that have errored out in a particular workflow and step
|
312
361
|
#
|
313
362
|
# @param [String] workflow name
|
@@ -316,10 +365,10 @@ module Dor
|
|
316
365
|
#
|
317
366
|
# @return [Hash] hash of results, with key has a druid, and value as the error message
|
318
367
|
# @example
|
319
|
-
# Dor::WorkflowService.
|
368
|
+
# Dor::WorkflowService.errored_objects_for_workstep('accessionWF','content-metadata')
|
320
369
|
# => {"druid:qd556jq0580"=>"druid:qd556jq0580 - Item error; caused by
|
321
370
|
# #<Rubydora::FedoraInvalidRequest: Error modifying datastream contentMetadata for druid:qd556jq0580. See logger for details>"}
|
322
|
-
def
|
371
|
+
def errored_objects_for_workstep(workflow, step, repository = 'dor')
|
323
372
|
resp = workflow_resource_method "workflow_queue?repository=#{repository}&workflow=#{workflow}&error=#{step}"
|
324
373
|
result = {}
|
325
374
|
Nokogiri::XML(resp).xpath('//object').collect do |node|
|
@@ -328,6 +377,11 @@ module Dor
|
|
328
377
|
result
|
329
378
|
end
|
330
379
|
|
380
|
+
def get_errored_objects_for_workstep(workflow, step, repository = 'dor')
|
381
|
+
Deprecation.warn(self, 'use errored_objects_for_workstep instead. This will be removed in dor-workflow-service version 3')
|
382
|
+
errored_objects_for_workstep(workflow, step, repository)
|
383
|
+
end
|
384
|
+
|
331
385
|
# Returns the number of objects that have a status of 'error' in a particular workflow and step
|
332
386
|
#
|
333
387
|
# @param [String] workflow name
|
@@ -356,6 +410,7 @@ module Dor
|
|
356
410
|
# @param [String] repository -- optional, default=dor
|
357
411
|
# @return [Integer] Number of objects with this repository:workflow that have been archived
|
358
412
|
def count_archived_for_workflow(workflow, repository = 'dor')
|
413
|
+
Deprecation.warn(self, 'count_archived_for_workflow will be removed without replacement because the workflow server no longer archives processes')
|
359
414
|
resp = workflow_resource_method "workflow_archive?repository=#{repository}&workflow=#{workflow}&count-only=true"
|
360
415
|
extract_object_count(resp)
|
361
416
|
end
|
@@ -369,11 +424,16 @@ module Dor
|
|
369
424
|
# @option opts [Integer] :limit sets the maximum number of workflow steps that can be returned. Defaults to no limit
|
370
425
|
# @return [Array[Hash]] each Hash represents a workflow step. It will have the following keys:
|
371
426
|
# :workflow, :step, :druid, :lane_id
|
372
|
-
def
|
427
|
+
def stale_queued_workflows(repository, opts = {})
|
373
428
|
uri_string = build_queued_uri(repository, opts)
|
374
429
|
parse_queued_workflows_response workflow_resource_method(uri_string)
|
375
430
|
end
|
376
431
|
|
432
|
+
def get_stale_queued_workflows(repository, opts = {})
|
433
|
+
Deprecation.warn(self, 'use stale_queued_workflows instead. This will be removed in dor-workflow-service version 3')
|
434
|
+
stale_queued_workflows(repository, opts)
|
435
|
+
end
|
436
|
+
|
377
437
|
# Returns a count of workflow steps that have a status of 'queued' that have a last-updated timestamp older than the number of hours passed in
|
378
438
|
# @param [String] repository name of the repository you want to query, like 'dor' or 'sdr'
|
379
439
|
# @param [Hash] opts optional values for query
|
@@ -444,13 +504,18 @@ module Dor
|
|
444
504
|
# @param [String] workflow name
|
445
505
|
# @param [String] process name
|
446
506
|
# @return [Array<String>] all of the distinct laneIds. Array will be empty if no lane ids were found
|
447
|
-
def
|
507
|
+
def lane_ids(repo, workflow, process)
|
448
508
|
uri = "workflow_queue/lane_ids?step=#{repo}:#{workflow}:#{process}"
|
449
509
|
doc = Nokogiri::XML(workflow_resource_method(uri))
|
450
510
|
nodes = doc.xpath('/lanes/lane')
|
451
511
|
nodes.map { |n| n['id'] }
|
452
512
|
end
|
453
513
|
|
514
|
+
def get_lane_ids(repo, workflow, process)
|
515
|
+
Deprecation.warn(self, 'use lane_ids instead. This will be removed in dor-workflow-service version 3')
|
516
|
+
lane_ids(repo, workflow, process)
|
517
|
+
end
|
518
|
+
|
454
519
|
### MIMICKING ATTRIBUTE READER
|
455
520
|
# @return [Faraday::Connection] the REST client resource created during configure()
|
456
521
|
def workflow_resource
|
data/lib/dor/workflow_version.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
|
-
describe Dor::WorkflowService do
|
5
|
+
RSpec.describe Dor::WorkflowService do
|
6
6
|
let(:wf_xml) do
|
7
7
|
<<-EOXML
|
8
8
|
<workflow id="etdSubmitWF">
|
@@ -41,7 +41,7 @@ describe Dor::WorkflowService do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
before
|
44
|
+
before do
|
45
45
|
@repo = 'dor'
|
46
46
|
@druid = 'druid:123'
|
47
47
|
@mock_logger = double('Logger')
|
@@ -49,13 +49,13 @@ describe Dor::WorkflowService do
|
|
49
49
|
allow(@mock_logger).to receive(:info) # silence log output
|
50
50
|
allow(@mock_logger).to receive(:debug) # silence log output
|
51
51
|
allow(@mock_logger).to receive(:warn) # silence log output
|
52
|
-
allow(
|
52
|
+
allow(described_class).to receive(:default_logger).and_return(@mock_logger)
|
53
53
|
|
54
|
-
|
54
|
+
described_class.configure mock_http_connection
|
55
55
|
end
|
56
56
|
|
57
57
|
describe '#configure' do
|
58
|
-
let(:conn) {
|
58
|
+
let(:conn) { described_class.configure 'http://externalhost/', timeout: 99 }
|
59
59
|
|
60
60
|
it 'has a timeout' do
|
61
61
|
expect(conn).to be_a(Faraday::Connection)
|
@@ -79,20 +79,20 @@ describe Dor::WorkflowService do
|
|
79
79
|
end
|
80
80
|
|
81
81
|
it 'should pass workflow xml to the DOR workflow service and return the URL to the workflow' do
|
82
|
-
|
82
|
+
described_class.create_workflow(@repo, @druid, 'etdSubmitWF', wf_xml)
|
83
83
|
end
|
84
84
|
|
85
85
|
it 'should log an error and retry upon a targetted Faraday exception' do
|
86
86
|
expect(@mock_logger).to receive(:warn).with(/\[Attempt 1\] Faraday::ClientError: the server responded with status 418/)
|
87
|
-
expect {
|
87
|
+
expect { described_class.create_workflow(@repo, @druid, 'httpException', wf_xml) }.to raise_error Dor::WorkflowException
|
88
88
|
end
|
89
89
|
|
90
90
|
it 'should raise on an unexpected Exception' do
|
91
|
-
expect {
|
91
|
+
expect { described_class.create_workflow(@repo, @druid, 'raiseException', wf_xml) }.to raise_error(Exception, 'broken')
|
92
92
|
end
|
93
93
|
|
94
94
|
it 'sets the create-ds param to the value of the passed in options hash' do
|
95
|
-
|
95
|
+
described_class.create_workflow(@repo, @druid, 'noCreateDsWF', wf_xml, create_ds: false)
|
96
96
|
end
|
97
97
|
|
98
98
|
it 'adds lane_id attributes to all steps if passed in as an option' do
|
@@ -111,7 +111,7 @@ describe Dor::WorkflowService do
|
|
111
111
|
<process name="start-accession" status="waiting" laneId="lane1"/>
|
112
112
|
</workflow>
|
113
113
|
XML
|
114
|
-
expect(
|
114
|
+
expect(described_class.send(:add_lane_id_to_workflow_xml, 'lane1', wf_xml)).to be_equivalent_to(expected)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
@@ -134,21 +134,21 @@ describe Dor::WorkflowService do
|
|
134
134
|
end
|
135
135
|
|
136
136
|
it 'should update workflow status and return true if successful' do
|
137
|
-
expect(
|
137
|
+
expect(described_class.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'completed', version: 2, note: 'annotation', lane_id: 'lane2')).to be true
|
138
138
|
end
|
139
139
|
|
140
140
|
it 'should return false if the PUT to the DOR workflow service throws an exception' do
|
141
|
-
expect {
|
141
|
+
expect { described_class.update_workflow_status(@repo, @druid, 'errorWF', 'reader-approval', 'completed') }.to raise_error(Dor::WorkflowException, /status 400/)
|
142
142
|
end
|
143
143
|
|
144
144
|
it 'performs a conditional update when current-status is passed as a parameter' do
|
145
145
|
expect(mock_http_connection).to receive(:put).with("#{@repo}/objects/#{@druid}/workflows/etdSubmitWF/reader-approval?current-status=queued").and_call_original
|
146
146
|
|
147
|
-
expect(
|
147
|
+
expect(described_class.update_workflow_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'completed', version: 2, note: 'annotation', lane_id: 'lane1', current_status: 'queued')).to be true
|
148
148
|
end
|
149
149
|
|
150
150
|
it 'should throw exception if invalid status provided' do
|
151
|
-
expect {
|
151
|
+
expect { described_class.update_workflow_status(@repo, @druid, 'accessionWF', 'publish', 'NOT_VALID_STATUS') }.to raise_error(ArgumentError)
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
@@ -167,14 +167,29 @@ describe Dor::WorkflowService do
|
|
167
167
|
end
|
168
168
|
|
169
169
|
it 'should update workflow status to error and return true if successful' do
|
170
|
-
|
170
|
+
described_class.update_workflow_error_status(@repo, @druid, 'etdSubmitWF', 'reader-approval', 'Some exception', error_text: 'The optional stacktrace')
|
171
171
|
end
|
172
172
|
it 'should return false if the PUT to the DOR workflow service throws an exception' do
|
173
|
-
expect {
|
173
|
+
expect { described_class.update_workflow_status(@repo, @druid, 'errorWF', 'reader-approval', 'completed') }.to raise_error(Dor::WorkflowException, /status 400/)
|
174
174
|
end
|
175
175
|
end
|
176
176
|
|
177
177
|
describe '#get_workflow_status' do
|
178
|
+
subject(:get_workflow_status) { described_class.get_workflow_status(repo, druid, workflow_name, step_name) }
|
179
|
+
|
180
|
+
let(:step_name) { 'registrar-approval' }
|
181
|
+
let(:workflow_name) { 'etdSubmitWF' }
|
182
|
+
let(:repo) { 'dor' }
|
183
|
+
let(:druid) { 'druid:123' }
|
184
|
+
|
185
|
+
it 'calls workflow_status' do
|
186
|
+
expect(Deprecation).to receive(:warn)
|
187
|
+
expect(described_class).to receive(:workflow_status)
|
188
|
+
get_workflow_status
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
describe '#workflow_status' do
|
178
193
|
let(:repo) { @repo }
|
179
194
|
let(:druid) { @druid }
|
180
195
|
let(:stubs) do
|
@@ -185,7 +200,7 @@ describe Dor::WorkflowService do
|
|
185
200
|
end
|
186
201
|
end
|
187
202
|
|
188
|
-
subject {
|
203
|
+
subject { described_class.workflow_status(repo, druid, workflow_name, step_name) }
|
189
204
|
let(:step_name) { 'registrar-approval' }
|
190
205
|
let(:workflow_name) { 'etdSubmitWF' }
|
191
206
|
let(:status) { 200 }
|
@@ -246,21 +261,87 @@ describe Dor::WorkflowService do
|
|
246
261
|
end
|
247
262
|
|
248
263
|
describe '#get_workflow_xml' do
|
249
|
-
|
264
|
+
subject(:get_workflow_xml) { described_class.get_workflow_xml(repo, druid, workflow_name) }
|
265
|
+
|
266
|
+
let(:workflow_name) { 'etdSubmitWF' }
|
267
|
+
let(:repo) { 'dor' }
|
268
|
+
let(:druid) { 'druid:123' }
|
269
|
+
|
270
|
+
it 'calls workflow_xml' do
|
271
|
+
expect(Deprecation).to receive(:warn)
|
272
|
+
expect(described_class).to receive(:workflow_xml)
|
273
|
+
get_workflow_xml
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe '#workflow_xml' do
|
278
|
+
subject(:workflow_xml) { described_class.workflow_xml('dor', 'druid:123', workflow) }
|
279
|
+
|
280
|
+
context 'when a workflow name is provided' do
|
281
|
+
let(:workflow) { 'etdSubmitWF' }
|
282
|
+
let(:xml) { '<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>' }
|
283
|
+
let(:stubs) do
|
284
|
+
Faraday::Adapter::Test::Stubs.new do |stub|
|
285
|
+
stub.get('dor/objects/druid:123/workflows/etdSubmitWF') do |_env|
|
286
|
+
[200, {}, xml]
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
it 'returns the xml for a given repository, druid, and workflow' do
|
292
|
+
expect(workflow_xml).to eq(xml)
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'when no workflow name is provided' do
|
297
|
+
let(:workflow) { nil }
|
298
|
+
|
299
|
+
it 'calls all_workflows' do
|
300
|
+
expect(Deprecation).to receive(:warn)
|
301
|
+
expect(described_class).to receive(:all_workflows_xml).with('druid:123')
|
302
|
+
workflow_xml
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
describe '#get_workflows' do
|
308
|
+
subject(:get_workflows) { described_class.get_workflows(druid) }
|
309
|
+
|
310
|
+
let(:druid) { 'druid:123' }
|
311
|
+
|
312
|
+
it 'calls workflows' do
|
313
|
+
expect(Deprecation).to receive(:warn)
|
314
|
+
expect(described_class).to receive(:workflows)
|
315
|
+
get_workflows
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe '#all_workflows_xml' do
|
320
|
+
subject(:all_workflows_xml) { described_class.all_workflows_xml('druid:123') }
|
321
|
+
|
322
|
+
let(:workflow) { 'etdSubmitWF' }
|
323
|
+
let(:xml) do
|
324
|
+
<<~XML
|
325
|
+
<workflows>
|
326
|
+
<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>
|
327
|
+
<workflow id="etdSubmitWF"><process name="registrar-approval" status="completed" /></workflow>
|
328
|
+
</workflows>
|
329
|
+
XML
|
330
|
+
end
|
250
331
|
let(:stubs) do
|
251
332
|
Faraday::Adapter::Test::Stubs.new do |stub|
|
252
|
-
stub.get('
|
333
|
+
stub.get('objects/druid:123/workflows') do |_env|
|
253
334
|
[200, {}, xml]
|
254
335
|
end
|
255
336
|
end
|
256
337
|
end
|
257
338
|
|
258
|
-
it 'returns the xml for a given
|
259
|
-
expect(
|
339
|
+
it 'returns the xml for a given druid' do
|
340
|
+
expect(all_workflows_xml).to eq(xml)
|
260
341
|
end
|
261
342
|
end
|
262
343
|
|
263
|
-
describe '#
|
344
|
+
describe '#workflows' do
|
264
345
|
let(:xml) { '<workflow id="accessionWF"><process name="publish" status="completed" /></workflow>' }
|
265
346
|
let(:stubs) do
|
266
347
|
Faraday::Adapter::Test::Stubs.new do |stub|
|
@@ -271,11 +352,21 @@ describe Dor::WorkflowService do
|
|
271
352
|
end
|
272
353
|
|
273
354
|
it 'returns the workflows associated with druid' do
|
274
|
-
expect(
|
355
|
+
expect(described_class.workflows(@druid)).to eq(['accessionWF'])
|
275
356
|
end
|
276
357
|
end
|
277
358
|
|
278
359
|
describe '#get_lifecycle' do
|
360
|
+
subject(:get_lifecycle) { described_class.get_lifecycle('dor', 'druid:123', 'released') }
|
361
|
+
|
362
|
+
it 'calls lifecycle' do
|
363
|
+
expect(Deprecation).to receive(:warn)
|
364
|
+
expect(described_class).to receive(:lifecycle)
|
365
|
+
get_lifecycle
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
describe '#lifecycle' do
|
279
370
|
let(:stubs) do
|
280
371
|
Faraday::Adapter::Test::Stubs.new do |stub|
|
281
372
|
stub.get('dor/objects/druid:123/lifecycle') do |_env|
|
@@ -297,15 +388,25 @@ describe Dor::WorkflowService do
|
|
297
388
|
end
|
298
389
|
|
299
390
|
it 'returns a Time object reprenting when the milestone was reached' do
|
300
|
-
expect(
|
391
|
+
expect(described_class.lifecycle('dor', 'druid:123', 'released').beginning_of_day).to eq(Time.parse('2010-06-15T16:08:58-0700').beginning_of_day)
|
301
392
|
end
|
302
393
|
|
303
394
|
it "returns nil if the milestone hasn't been reached yet" do
|
304
|
-
expect(
|
395
|
+
expect(described_class.lifecycle('dor', 'druid:abc', 'inprocess')).to be_nil
|
305
396
|
end
|
306
397
|
end
|
307
398
|
|
308
399
|
describe '#get_active_lifecycle' do
|
400
|
+
subject(:get_active_lifecycle) { described_class.get_active_lifecycle('dor', 'druid:123', 'released') }
|
401
|
+
|
402
|
+
it 'calls active_lifecycle' do
|
403
|
+
expect(Deprecation).to receive(:warn)
|
404
|
+
expect(described_class).to receive(:active_lifecycle)
|
405
|
+
get_active_lifecycle
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
describe '#active_lifecycle' do
|
309
410
|
let(:stubs) do
|
310
411
|
Faraday::Adapter::Test::Stubs.new do |stub|
|
311
412
|
stub.get("dor/objects/#{@druid}/lifecycle") do |_env|
|
@@ -327,16 +428,26 @@ describe Dor::WorkflowService do
|
|
327
428
|
end
|
328
429
|
|
329
430
|
it 'parses out the active lifecycle' do
|
330
|
-
expect(
|
431
|
+
expect(described_class.active_lifecycle('dor', @druid, 'released').beginning_of_day).to eq(Time.parse('2010-06-15T16:08:58-0700').beginning_of_day)
|
331
432
|
end
|
332
433
|
|
333
434
|
it 'handles missing lifecycle' do
|
334
|
-
expect(
|
435
|
+
expect(described_class.active_lifecycle('dor', @druid, 'NOT_FOUND')).to be_nil
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
describe '#get_objects_for_workstep' do
|
440
|
+
subject(:get_objects_for_workstep) { described_class.get_objects_for_workstep('google-download', 'process-content', 'default', default_repository: 'dor', default_workflow: 'googleScannedBookWF') }
|
441
|
+
|
442
|
+
it 'calls objects_for_workstep' do
|
443
|
+
expect(Deprecation).to receive(:warn)
|
444
|
+
expect(described_class).to receive(:objects_for_workstep)
|
445
|
+
get_objects_for_workstep
|
335
446
|
end
|
336
447
|
end
|
337
448
|
|
338
|
-
context '#
|
339
|
-
before
|
449
|
+
context '#objects_for_workstep' do
|
450
|
+
before(:all) do
|
340
451
|
@repository = 'dor'
|
341
452
|
@workflow = 'googleScannedBookWF'
|
342
453
|
@completed = 'google-download'
|
@@ -353,7 +464,7 @@ describe Dor::WorkflowService do
|
|
353
464
|
|
354
465
|
describe 'a query with one step completed and one waiting' do
|
355
466
|
it 'creates the URI string with only the one completed step' do
|
356
|
-
expect(
|
467
|
+
expect(described_class.objects_for_workstep(@completed, @waiting, 'default', default_repository: @repository, default_workflow: @workflow)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
357
468
|
end
|
358
469
|
end
|
359
470
|
|
@@ -362,7 +473,7 @@ describe Dor::WorkflowService do
|
|
362
473
|
second_completed = 'google-convert'
|
363
474
|
xml = %(<objects count="1"><object id="druid:ab123de4567"/><object id="druid:ab123de9012"/></objects>)
|
364
475
|
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@repository}:#{@workflow}:#{@waiting}&completed=#{@repository}:#{@workflow}:#{@completed}&completed=#{@repository}:#{@workflow}:#{second_completed}&lane-id=default").and_return(double(Faraday::Response, body: xml))
|
365
|
-
expect(
|
476
|
+
expect(described_class.objects_for_workstep([@completed, second_completed], @waiting, 'default', default_repository: @repository, default_workflow: @workflow)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
366
477
|
end
|
367
478
|
end
|
368
479
|
|
@@ -380,7 +491,7 @@ describe Dor::WorkflowService do
|
|
380
491
|
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&completed=#{@qualified_completed}&completed=#{qualified_completed2}&completed=#{qualified_completed3}&lane-id=#{laneid}").and_return(double(Faraday::Response, body: xml))
|
381
492
|
args = [[@qualified_completed, qualified_completed2, qualified_completed3], @qualified_waiting]
|
382
493
|
args << laneid if laneid != 'default'
|
383
|
-
expect(
|
494
|
+
expect(described_class.objects_for_workstep(*args)).to eq(['druid:ab123de4567', 'druid:ab123de9012'])
|
384
495
|
end
|
385
496
|
end
|
386
497
|
|
@@ -401,15 +512,15 @@ describe Dor::WorkflowService do
|
|
401
512
|
end
|
402
513
|
it 'with only one completed step passed in as a String' do
|
403
514
|
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&completed=#{@qualified_completed}&lane-id=default").and_return(double(Faraday::Response, body: @xml))
|
404
|
-
expect(
|
515
|
+
expect(described_class.objects_for_workstep(@qualified_completed, @qualified_waiting)).to eq(['druid:ab123de4567'])
|
405
516
|
end
|
406
517
|
it 'without any completed steps, only waiting' do
|
407
518
|
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&lane-id=default").and_return(double(Faraday::Response, body: @xml))
|
408
|
-
expect(
|
519
|
+
expect(described_class.objects_for_workstep(nil, @qualified_waiting)).to eq(['druid:ab123de4567'])
|
409
520
|
end
|
410
521
|
it 'same but with lane_id' do
|
411
522
|
allow(mock_http_connection).to receive(:get).with("workflow_queue?waiting=#{@qualified_waiting}&lane-id=lane1").and_return(double(Faraday::Response, body: @xml))
|
412
|
-
expect(
|
523
|
+
expect(described_class.objects_for_workstep(nil, @qualified_waiting, 'lane1')).to eq(['druid:ab123de4567'])
|
413
524
|
end
|
414
525
|
end
|
415
526
|
end
|
@@ -432,7 +543,7 @@ describe Dor::WorkflowService do
|
|
432
543
|
end
|
433
544
|
|
434
545
|
it 'returns an empty list if it encounters an empty workflow queue' do
|
435
|
-
expect(
|
546
|
+
expect(described_class.objects_for_workstep(@completed, @waiting, 'default', default_repository: @repository, default_workflow: @workflow)).to eq([])
|
436
547
|
end
|
437
548
|
end
|
438
549
|
|
@@ -455,12 +566,26 @@ describe Dor::WorkflowService do
|
|
455
566
|
end
|
456
567
|
end
|
457
568
|
|
458
|
-
|
459
|
-
|
569
|
+
describe 'get_errored_objects_for_workstep' do
|
570
|
+
subject(:get_errored_objects_for_workstep) { described_class.get_errored_objects_for_workstep(@workflow, @step, @repository) }
|
571
|
+
|
572
|
+
it 'calls errored_objects_for_workstep' do
|
573
|
+
expect(Deprecation).to receive(:warn)
|
574
|
+
expect(described_class).to receive(:errored_objects_for_workstep)
|
575
|
+
get_errored_objects_for_workstep
|
576
|
+
end
|
460
577
|
end
|
461
578
|
|
462
|
-
|
463
|
-
|
579
|
+
describe 'errored_objects_for_workstep' do
|
580
|
+
it 'returns error messages for errored objects' do
|
581
|
+
expect(described_class.errored_objects_for_workstep(@workflow, @step, @repository)).to eq('druid:ab123cd4567' => 'This is an error message')
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
describe 'count_errored_for_workstep' do
|
586
|
+
it 'counts how many steps are errored out' do
|
587
|
+
expect(described_class.count_errored_for_workstep(@workflow, @step, @repository)).to eq(1)
|
588
|
+
end
|
464
589
|
end
|
465
590
|
end
|
466
591
|
|
@@ -484,7 +609,7 @@ describe Dor::WorkflowService do
|
|
484
609
|
end
|
485
610
|
|
486
611
|
it 'counts how many steps are errored out' do
|
487
|
-
expect(
|
612
|
+
expect(described_class.count_queued_for_workstep(@workflow, @step, @repository)).to eq(1)
|
488
613
|
end
|
489
614
|
end
|
490
615
|
|
@@ -505,7 +630,8 @@ describe Dor::WorkflowService do
|
|
505
630
|
end
|
506
631
|
|
507
632
|
it 'counts how many workflows are archived' do
|
508
|
-
expect(
|
633
|
+
expect(Deprecation).to receive(:warn)
|
634
|
+
expect(described_class.count_archived_for_workflow(@workflow, @repository)).to eq(20)
|
509
635
|
end
|
510
636
|
end
|
511
637
|
|
@@ -530,7 +656,7 @@ describe Dor::WorkflowService do
|
|
530
656
|
end
|
531
657
|
|
532
658
|
it 'counts how many objects are at the type of step' do
|
533
|
-
expect(
|
659
|
+
expect(described_class.count_objects_in_step(@workflow, @step, @type, @repository)).to eq(1)
|
534
660
|
end
|
535
661
|
end
|
536
662
|
|
@@ -545,20 +671,31 @@ describe Dor::WorkflowService do
|
|
545
671
|
|
546
672
|
it 'sends a delete request to the workflow service' do
|
547
673
|
expect(mock_http_connection).to receive(:delete).with(url).and_call_original
|
548
|
-
|
674
|
+
described_class.delete_workflow(@repo, @druid, 'accessionWF')
|
549
675
|
end
|
550
676
|
end
|
551
|
-
|
552
|
-
|
677
|
+
|
678
|
+
describe 'milestones' do
|
679
|
+
it 'includes the version in with the milestones' do
|
553
680
|
xml = '<?xml version="1.0" encoding="UTF-8"?><lifecycle objectId="druid:gv054hp4128"><milestone date="2012-01-26T21:06:54-0800" version="2">published</milestone></lifecycle>'
|
554
681
|
xml = Nokogiri::XML(xml)
|
555
|
-
allow(
|
556
|
-
milestones =
|
682
|
+
allow(described_class).to receive(:query_lifecycle).and_return(xml)
|
683
|
+
milestones = described_class.milestones(@repo, @druid)
|
557
684
|
expect(milestones.first[:milestone]).to eq('published')
|
558
685
|
expect(milestones.first[:version]).to eq('2')
|
559
686
|
end
|
560
687
|
end
|
561
688
|
|
689
|
+
describe 'get_milestones' do
|
690
|
+
subject(:get_milestones) { described_class.get_milestones('dor', 'abc:1233') }
|
691
|
+
|
692
|
+
it 'calls milestones' do
|
693
|
+
expect(Deprecation).to receive(:warn)
|
694
|
+
expect(described_class).to receive(:milestones)
|
695
|
+
get_milestones
|
696
|
+
end
|
697
|
+
end
|
698
|
+
|
562
699
|
describe '.get_active_workflows' do
|
563
700
|
it 'it returns an array of active workflows only' do
|
564
701
|
xml = <<-XML
|
@@ -572,9 +709,9 @@ describe Dor::WorkflowService do
|
|
572
709
|
</workflow>
|
573
710
|
</workflows>
|
574
711
|
XML
|
575
|
-
allow(
|
712
|
+
allow(described_class).to receive(:get_workflow_xml) { xml }
|
576
713
|
expect(Deprecation).to receive(:warn)
|
577
|
-
expect(
|
714
|
+
expect(described_class.get_active_workflows('dor', 'druid:mw971zk1113')).to eq(['accessionWF'])
|
578
715
|
end
|
579
716
|
end
|
580
717
|
|
@@ -587,11 +724,11 @@ describe Dor::WorkflowService do
|
|
587
724
|
XML
|
588
725
|
end
|
589
726
|
before do
|
590
|
-
allow(
|
727
|
+
allow(described_class).to receive(:get_workflow_xml) { xml }
|
591
728
|
end
|
592
729
|
|
593
730
|
it 'it returns a workflow' do
|
594
|
-
expect(
|
731
|
+
expect(described_class.workflow(pid: 'druid:mw971zk1113', workflow_name: 'accessionWF')).to be_kind_of Dor::Workflow::Response::Workflow
|
595
732
|
end
|
596
733
|
end
|
597
734
|
|
@@ -610,16 +747,16 @@ describe Dor::WorkflowService do
|
|
610
747
|
|
611
748
|
let(:url) { 'dor/objects/druid:123/versionClose' }
|
612
749
|
it 'calls the versionClose endpoint with druid' do
|
613
|
-
|
750
|
+
described_class.close_version(@repo, @druid)
|
614
751
|
end
|
615
752
|
|
616
753
|
it 'optionally prevents creation of accessionWF' do
|
617
754
|
expect(mock_http_connection).to receive(:post).with('dor/objects/druid:123/versionClose?create-accession=false').and_call_original
|
618
|
-
|
755
|
+
described_class.close_version(@repo, @druid, false)
|
619
756
|
end
|
620
757
|
end
|
621
758
|
|
622
|
-
describe '.
|
759
|
+
describe '.stale_queued_workflows' do
|
623
760
|
let(:stubs) do
|
624
761
|
Faraday::Adapter::Test::Stubs.new do |stub|
|
625
762
|
stub.get('workflow_queue/all_queued?repository=dor&hours-ago=24&limit=100') do |_env|
|
@@ -634,7 +771,7 @@ describe Dor::WorkflowService do
|
|
634
771
|
end
|
635
772
|
|
636
773
|
it 'returns an Array of Hashes containing each workflow step' do
|
637
|
-
ah =
|
774
|
+
ah = described_class.stale_queued_workflows 'dor', hours_ago: 24, limit: 100
|
638
775
|
expected = [
|
639
776
|
{ workflow: 'accessionWF', step: 'content-metadata', druid: 'dr:123', lane_id: 'lane1' },
|
640
777
|
{ workflow: 'assemblyWF', step: 'jp2-create', druid: 'dr:456', lane_id: 'lane2' }
|
@@ -643,6 +780,16 @@ describe Dor::WorkflowService do
|
|
643
780
|
end
|
644
781
|
end
|
645
782
|
|
783
|
+
describe '.get_stale_queued_workflows' do
|
784
|
+
subject(:get_stale_queued_workflows) { described_class.get_stale_queued_workflows('dor', hours_ago: 24, limit: 100) }
|
785
|
+
|
786
|
+
it 'calls stale_queued_workflows' do
|
787
|
+
expect(Deprecation).to receive(:warn)
|
788
|
+
expect(described_class).to receive(:stale_queued_workflows)
|
789
|
+
get_stale_queued_workflows
|
790
|
+
end
|
791
|
+
end
|
792
|
+
|
646
793
|
describe '.count_stale_queued_workflows' do
|
647
794
|
let(:stubs) do
|
648
795
|
Faraday::Adapter::Test::Stubs.new do |stub|
|
@@ -653,11 +800,11 @@ describe Dor::WorkflowService do
|
|
653
800
|
end
|
654
801
|
|
655
802
|
it 'returns the number of queued workflow steps' do
|
656
|
-
expect(
|
803
|
+
expect(described_class.count_stale_queued_workflows('dor', hours_ago: 48)).to eq(10)
|
657
804
|
end
|
658
805
|
end
|
659
806
|
|
660
|
-
describe '.
|
807
|
+
describe '.lane_ids' do
|
661
808
|
let(:stubs) do
|
662
809
|
Faraday::Adapter::Test::Stubs.new do |stub|
|
663
810
|
stub.get('workflow_queue/lane_ids?lane_ids?step=dor:accessionWF:shelve') do |_env|
|
@@ -672,7 +819,17 @@ describe Dor::WorkflowService do
|
|
672
819
|
end
|
673
820
|
|
674
821
|
it 'returns the lane ids for a given workflow step' do
|
675
|
-
expect(
|
822
|
+
expect(described_class.lane_ids('dor', 'accessionWF', 'shelve')).to eq(%w[lane1 lane2])
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
826
|
+
describe '.get_lane_ids' do
|
827
|
+
subject(:get_lane_ids) { described_class.get_lane_ids('dor', 'accessionWF', 'shelve') }
|
828
|
+
|
829
|
+
it 'calls lane_ids' do
|
830
|
+
expect(Deprecation).to receive(:warn)
|
831
|
+
expect(described_class).to receive(:lane_ids)
|
832
|
+
get_lane_ids
|
676
833
|
end
|
677
834
|
end
|
678
835
|
|
@@ -686,7 +843,7 @@ describe Dor::WorkflowService do
|
|
686
843
|
end
|
687
844
|
|
688
845
|
it 'uses the flat params encoder' do
|
689
|
-
response =
|
846
|
+
response = described_class.send(:send_workflow_resource_request, 'x?complete=a&complete=b')
|
690
847
|
|
691
848
|
expect(response.body).to eq 'ab'
|
692
849
|
expect(response.env.url.query).to eq 'complete=a&complete=b'
|
@@ -695,11 +852,11 @@ describe Dor::WorkflowService do
|
|
695
852
|
|
696
853
|
describe '.workflow_resource' do
|
697
854
|
before do
|
698
|
-
|
855
|
+
described_class.configure 'http://example.com'
|
699
856
|
end
|
700
857
|
|
701
858
|
it 'defaults to using the flat params encoder' do
|
702
|
-
expect(
|
859
|
+
expect(described_class.workflow_resource.options.params_encoder).to eq Faraday::FlatParamsEncoder
|
703
860
|
end
|
704
861
|
end
|
705
862
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dor-workflow-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Willy Mene
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2019-04-
|
12
|
+
date: 2019-04-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|