dor-workflow-client 3.0.0.rc1

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.
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Dor::Workflow::Response::Workflow do
6
+ subject(:instance) { described_class.new(xml: xml) }
7
+
8
+ describe '#pid' do
9
+ subject { instance.pid }
10
+
11
+ let(:xml) do
12
+ <<~XML
13
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
14
+ </workflow>
15
+ XML
16
+ end
17
+ it { is_expected.to eq 'druid:mw971zk1113' }
18
+ end
19
+
20
+ describe '#workflow_name' do
21
+ subject { instance.workflow_name }
22
+
23
+ let(:xml) do
24
+ <<~XML
25
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
26
+ </workflow>
27
+ XML
28
+ end
29
+ it { is_expected.to eq 'assemblyWF' }
30
+ end
31
+
32
+ describe '#active?' do
33
+ subject { instance.active_for?(version: 2) }
34
+
35
+ context 'when the workflow has not been instantiated for the given version' do
36
+ let(:xml) do
37
+ <<~XML
38
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
39
+ <process version="1" laneId="default" elapsed="0.0" attempts="1" datetime="2013-02-18T14:40:25-0800" status="completed" name="start-assembly"/>
40
+ <process version="1" laneId="default" elapsed="0.509" attempts="1" datetime="2013-02-18T14:42:24-0800" status="completed" name="jp2-create"/>
41
+ </workflow>
42
+ XML
43
+ end
44
+ it { is_expected.to be false }
45
+ end
46
+
47
+ context 'when the workflow has been instantiated for the given version' do
48
+ let(:xml) do
49
+ <<~XML
50
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
51
+ <process version="1" laneId="default" elapsed="0.0" attempts="1" datetime="2013-02-18T14:40:25-0800" status="completed" name="start-assembly"/>
52
+ <process version="1" laneId="default" elapsed="0.509" attempts="1" datetime="2013-02-18T14:42:24-0800" status="completed" name="jp2-create"/>
53
+ <process version="2" laneId="default" elapsed="0.509" attempts="1" datetime="2013-02-18T14:42:24-0800" status="waiting" name="jp2-create"/>
54
+ </workflow>
55
+ XML
56
+ end
57
+ it { is_expected.to be true }
58
+ end
59
+ end
60
+
61
+ describe '#empty?' do
62
+ subject { instance.empty? }
63
+
64
+ context 'when there is xml' do
65
+ let(:xml) do
66
+ '<?xml version="1.0" encoding="UTF-8"?>
67
+ <workflow repository="dor" objectId="druid:oo201oo0001" id="accessionWF">
68
+ <process version="2" lifecycle="submitted" elapsed="0.0" archived="true" attempts="1"
69
+ datetime="2012-11-06T16:18:24-0800" status="completed" name="start-accession"/>
70
+ <process version="2" elapsed="0.0" archived="true" attempts="1"
71
+ datetime="2012-11-06T16:18:58-0800" status="completed" name="technical-metadata"/>
72
+ <process version="2" elapsed="0.0" archived="true" attempts="1"
73
+ datetime="2012-11-06T16:19:02-0800" status="completed" name="provenance-metadata"/>
74
+ <process version="2" elapsed="0.0" archived="true" attempts="1"
75
+ datetime="2012-11-06T16:19:05-0800" status="completed" name="remediate-object"/>
76
+ <process version="2" elapsed="0.0" archived="true" attempts="1"
77
+ datetime="2012-11-06T16:19:06-0800" status="completed" name="shelve"/>
78
+ <process version="2" lifecycle="published" elapsed="0.0" archived="true" attempts="1"
79
+ datetime="2012-11-06T16:19:07-0800" status="completed" name="publish"/>
80
+ <process version="2" elapsed="0.0" archived="true" attempts="1"
81
+ datetime="2012-11-06T16:19:09-0800" status="completed" name="sdr-ingest-transfer"/>
82
+ <process version="2" lifecycle="accessioned" elapsed="0.0" archived="true" attempts="1"
83
+ datetime="2012-11-06T16:19:10-0800" status="completed" name="cleanup"/>
84
+ <process version="2" elapsed="0.0" archived="true" attempts="1"
85
+ datetime="2012-11-06T16:19:13-0800" status="completed" name="rights-metadata"/>
86
+ <process version="2" lifecycle="described" elapsed="0.0" archived="true" attempts="1"
87
+ datetime="2012-11-06T16:19:15-0800" status="completed" name="descriptive-metadata"/>
88
+ <process version="2" elapsed="0.0" archived="true" attempts="2"
89
+ datetime="2012-11-06T16:19:16-0800" status="completed" name="content-metadata"/>
90
+ </workflow>'
91
+ end
92
+
93
+ it { is_expected.to be false }
94
+ end
95
+
96
+ context 'when the xml is empty' do
97
+ let(:xml) { '' }
98
+
99
+ it { is_expected.to be true }
100
+ end
101
+ end
102
+
103
+ describe '#process_for_recent_version' do
104
+ subject(:process) { instance.process_for_recent_version(name: 'jp2-create') }
105
+
106
+ context 'when the workflow has not been instantiated for the given version' do
107
+ let(:xml) do
108
+ <<~XML
109
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
110
+ <process version="1" laneId="default" elapsed="0.0" attempts="1" datetime="2013-02-18T14:40:25-0800" status="completed" name="start-assembly"/>
111
+ <process version="1" laneId="default" elapsed="0.509" attempts="1" datetime="2013-02-18T14:42:24-0800" status="completed" name="jp2-create"/>
112
+ </workflow>
113
+ XML
114
+ end
115
+
116
+ it 'returns a process' do
117
+ expect(process).to be_kind_of Dor::Workflow::Response::Process
118
+ expect(process.status).to eq 'completed'
119
+ expect(process.name).to eq 'jp2-create'
120
+ end
121
+ end
122
+
123
+ context 'when the workflow has been instantiated for the given version' do
124
+ let(:xml) do
125
+ <<~XML
126
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="assemblyWF">
127
+ <process version="1" laneId="default" elapsed="0.0" attempts="1" datetime="2013-02-18T14:40:25-0800" status="completed" name="start-assembly"/>
128
+ <process version="1" laneId="default" elapsed="0.509" attempts="1" datetime="2013-02-18T14:42:24-0800" status="completed" name="jp2-create"/>
129
+ <process version="2" laneId="default" elapsed="0.509" attempts="1" datetime="2013-02-18T14:42:24-0800" status="error" name="jp2-create" errorMessage="it just broke"/>
130
+ </workflow>
131
+ XML
132
+ end
133
+
134
+ it 'returns a process' do
135
+ expect(process).to be_kind_of Dor::Workflow::Response::Process
136
+ expect(process.status).to eq 'error'
137
+ expect(process.error_message).to eq 'it just broke'
138
+ expect(process.name).to eq 'jp2-create'
139
+ end
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'simplecov'
7
+ SimpleCov.start do
8
+ add_filter 'spec'
9
+ end
10
+
11
+ require 'byebug'
12
+ require 'dor/workflow/client'
13
+ require 'equivalent-xml'
14
+ require 'equivalent-xml/rspec_matchers'
15
+ require 'webmock/rspec'
16
+
17
+ # RSpec.configure do |conf|
18
+ # end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ # This test can take up to 15s to run because it does retries with exponential backoff
6
+ RSpec.describe Dor::Workflow::Client::ConnectionFactory do
7
+ let(:mock_logger) { double('Logger', info: true, debug: true, warn: true) }
8
+
9
+ let(:repo) { 'dor' }
10
+ let(:druid) { 'druid:123' }
11
+ before do
12
+ stub_request(:put, "http://example.com/#{repo}/objects/#{druid}/workflows/httpException?create-ds=true")
13
+ .to_return(status: 500, body: 'Internal error', headers: {})
14
+ end
15
+
16
+ let(:client) { Dor::Workflow::Client.new url: 'http://example.com', logger: mock_logger }
17
+
18
+ describe '#create_workflow' do
19
+ it 'logs an error and retry upon a targeted Faraday exception' do
20
+ expect(mock_logger).to receive(:warn).with('retrying connection (1 remaining) to http://example.com/dor/objects/druid:123/workflows/httpException?create-ds=true: (Faraday::RetriableResponse) 500')
21
+ expect(mock_logger).to receive(:warn).with('retrying connection (0 remaining) to http://example.com/dor/objects/druid:123/workflows/httpException?create-ds=true: (Faraday::RetriableResponse) 500')
22
+ expect { client.create_workflow(repo, druid, 'httpException', '<xml>') }.to raise_error Dor::WorkflowException
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Dor::Workflow::Client::LifecycleRoutes do
6
+ let(:mock_requestor) { instance_double(Dor::Workflow::Client::Requestor) }
7
+
8
+ let(:routes) { described_class.new(requestor: mock_requestor) }
9
+
10
+ describe '#milestones' do
11
+ let(:ng_xml) { Nokogiri::XML(xml) }
12
+ let(:xml) do
13
+ '<?xml version="1.0" encoding="UTF-8"?><lifecycle objectId="druid:gv054hp4128"><milestone date="2012-01-26T21:06:54-0800" version="2">published</milestone></lifecycle>'
14
+ end
15
+
16
+ before do
17
+ allow(routes).to receive(:query_lifecycle).and_return(ng_xml)
18
+ end
19
+
20
+ subject(:milestones) { routes.milestones('dor', 'druid:gv054hp4128') }
21
+
22
+ it 'includes the version in with the milestones' do
23
+ expect(milestones.first[:milestone]).to eq('published')
24
+ expect(milestones.first[:version]).to eq('2')
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Dor::Workflow::Client::Requestor do
6
+ let(:mock_http_connection) do
7
+ Faraday.new(url: 'http://example.com/') do |builder|
8
+ builder.use Faraday::Response::RaiseError
9
+ builder.options.params_encoder = Faraday::FlatParamsEncoder
10
+
11
+ builder.adapter :test, stubs
12
+ end
13
+ end
14
+
15
+ let(:requestor) { described_class.new(connection: mock_http_connection) }
16
+
17
+ describe '.send_workflow_resource_request' do
18
+ let(:stubs) do
19
+ Faraday::Adapter::Test::Stubs.new do |stub|
20
+ stub.get('x?complete=a&complete=b') do |_env|
21
+ [200, {}, 'ab']
22
+ end
23
+ end
24
+ end
25
+
26
+ it 'uses the flat params encoder' do
27
+ response = requestor.send(:send_workflow_resource_request, 'x?complete=a&complete=b')
28
+
29
+ expect(response.body).to eq 'ab'
30
+ expect(response.env.url.query).to eq 'complete=a&complete=b'
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Dor::Workflow::Client::WorkflowRoutes do
6
+ let(:mock_requestor) { instance_double(Dor::Workflow::Client::Requestor) }
7
+
8
+ let(:routes) { described_class.new(requestor: mock_requestor) }
9
+
10
+ let(:wf_xml) do
11
+ <<-EOXML
12
+ <workflow id="etdSubmitWF">
13
+ <process name="register-object" status="completed" attempts="1" />
14
+ <process name="submit" status="waiting" />
15
+ <process name="reader-approval" status="waiting" />
16
+ <process name="registrar-approval" status="waiting" />
17
+ <process name="start-accession" status="waiting" />
18
+ </workflow>
19
+ EOXML
20
+ end
21
+
22
+ describe '#add_lane_id_to_workflow_xml' do
23
+ it 'adds laneId attributes to all process elements' do
24
+ expected = <<-XML
25
+ <workflow id="etdSubmitWF">
26
+ <process name="register-object" status="completed" attempts="1" laneId="lane1"/>
27
+ <process name="submit" status="waiting" laneId="lane1"/>
28
+ <process name="reader-approval" status="waiting" laneId="lane1"/>
29
+ <process name="registrar-approval" status="waiting" laneId="lane1"/>
30
+ <process name="start-accession" status="waiting" laneId="lane1"/>
31
+ </workflow>
32
+ XML
33
+ expect(routes.send(:add_lane_id_to_workflow_xml, 'lane1', wf_xml)).to be_equivalent_to(expected)
34
+ end
35
+ end
36
+
37
+ describe '#workflow' do
38
+ let(:xml) do
39
+ <<~XML
40
+ <workflow repository="dor" objectId="druid:mw971zk1113" id="accessionWF">
41
+ <process laneId="default" lifecycle="submitted" elapsed="0.0" attempts="1" datetime="2013-02-18T15:08:10-0800" status="completed" name="start-accession"/>
42
+ </workflow>
43
+ XML
44
+ end
45
+ before do
46
+ allow(routes).to receive(:workflow_xml) { xml }
47
+ end
48
+
49
+ it 'it returns a workflow' do
50
+ expect(routes.workflow(pid: 'druid:mw971zk1113', workflow_name: 'accessionWF')).to be_kind_of Dor::Workflow::Response::Workflow
51
+ end
52
+ end
53
+ end