rails_workflow 0.3.9 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +2 -0
- data/app/concerns/rails_workflow/operation_status.rb +2 -0
- data/app/concerns/rails_workflow/operation_templates/assignments.rb +3 -1
- data/app/concerns/rails_workflow/operation_templates/dependencies.rb +18 -18
- data/app/concerns/rails_workflow/operations/assignments.rb +7 -5
- data/app/concerns/rails_workflow/operations/dependencies.rb +2 -0
- data/app/concerns/rails_workflow/status.rb +11 -15
- data/app/concerns/rails_workflow/user/assignment.rb +2 -0
- data/app/concerns/rails_workflow/uuid.rb +2 -0
- data/app/controllers/rails_workflow/application_controller.rb +2 -0
- data/app/controllers/rails_workflow/errors_controller.rb +2 -0
- data/app/controllers/rails_workflow/operation_templates_controller.rb +3 -1
- data/app/controllers/rails_workflow/operations_controller.rb +3 -1
- data/app/controllers/rails_workflow/process_templates_controller.rb +10 -8
- data/app/controllers/rails_workflow/processes_controller.rb +10 -8
- data/app/decorators/rails_workflow/context_decorator.rb +2 -0
- data/app/decorators/rails_workflow/decorator.rb +2 -0
- data/app/decorators/rails_workflow/operation_decorator.rb +2 -0
- data/app/decorators/rails_workflow/operation_helper_decorator.rb +2 -0
- data/app/decorators/rails_workflow/operation_template_decorator.rb +2 -0
- data/app/decorators/rails_workflow/paginating_decorator.rb +2 -0
- data/app/decorators/rails_workflow/process_decorator.rb +2 -0
- data/app/decorators/rails_workflow/process_template_decorator.rb +2 -0
- data/app/decorators/rails_workflow/status_decorator.rb +2 -0
- data/app/helpers/rails_workflow/application_helper.rb +2 -0
- data/app/jobs/rails_workflow/operation_execution_job.rb +11 -1
- data/app/models/rails_workflow/context.rb +3 -1
- data/app/models/rails_workflow/error.rb +23 -50
- data/app/models/rails_workflow/operation.rb +39 -3
- data/app/models/rails_workflow/operation_template.rb +2 -2
- data/app/models/rails_workflow/process.rb +34 -5
- data/app/models/rails_workflow/process_template.rb +12 -8
- data/app/models/rails_workflow/user_by_group_operation.rb +2 -0
- data/app/models/rails_workflow/user_by_role_operation.rb +2 -0
- data/app/models/rails_workflow/user_operation.rb +2 -0
- data/app/serializers/rails_workflow/operation_template_serializer.rb +2 -0
- data/app/serializers/rails_workflow/process_template_serializer.rb +2 -0
- data/app/services/rails_workflow/default_importer_preprocessor.rb +2 -0
- data/app/services/rails_workflow/process_importer.rb +2 -0
- data/app/views/rails_workflow/processes/index.html.slim +5 -5
- data/config/initializers/rails_workflow.rb +3 -3
- data/config/routes.rb +4 -2
- data/db/migrate/20150630174700_create_workflow_processes.rb +86 -84
- data/lib/generators/rails_workflow/install/install_generator.rb +2 -0
- data/lib/generators/rails_workflow/install/templates/create_workflow_processes.rb +86 -84
- data/lib/rails_workflow/config.rb +65 -24
- data/lib/rails_workflow/db/mysql.rb +3 -1
- data/lib/rails_workflow/db/pg.rb +3 -1
- data/lib/rails_workflow/dependency_resolver.rb +74 -0
- data/lib/rails_workflow/engine.rb +3 -1
- data/lib/rails_workflow/error_builder.rb +57 -0
- data/lib/rails_workflow/error_resolver.rb +72 -0
- data/lib/rails_workflow/operation_builder.rb +95 -0
- data/lib/rails_workflow/operation_runner.rb +113 -0
- data/lib/rails_workflow/process_builder.rb +57 -0
- data/lib/rails_workflow/process_manager.rb +66 -0
- data/lib/rails_workflow/process_runner.rb +72 -0
- data/lib/rails_workflow/version.rb +3 -1
- data/lib/rails_workflow.rb +2 -0
- data/lib/tasks/rails_workflow_tasks.rake +1 -0
- data/spec/concerns/status_spec.rb +25 -0
- data/spec/controllers/rails_workflow/operation_templates_controller_spec.rb +2 -0
- data/spec/controllers/rails_workflow/operations_controller_spec.rb +2 -0
- data/spec/controllers/rails_workflow/process_templates_controller_spec.rb +2 -0
- data/spec/controllers/rails_workflow/processes_controller_spec.rb +3 -1
- data/spec/dummy/Rakefile +2 -0
- data/spec/dummy/app/controllers/application_controller.rb +2 -0
- data/spec/dummy/app/controllers/leads_controller.rb +2 -0
- data/spec/dummy/app/controllers/sales_contacts_controller.rb +2 -0
- data/spec/dummy/app/decorators/lead_decorator.rb +2 -0
- data/spec/dummy/app/decorators/sales_contact_decorator.rb +2 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/helpers/leads_helper.rb +2 -0
- data/spec/dummy/app/helpers/sales_contacts_helper.rb +2 -0
- data/spec/dummy/app/models/bad_operation.rb +2 -0
- data/spec/dummy/app/models/bad_operation_template.rb +2 -0
- data/spec/dummy/app/models/lead.rb +2 -0
- data/spec/dummy/app/models/sales_contact.rb +2 -0
- data/spec/dummy/app/models/user.rb +2 -0
- data/spec/dummy/bin/bundle +2 -0
- data/spec/dummy/bin/rails +2 -0
- data/spec/dummy/bin/rake +2 -0
- data/spec/dummy/config/application.rb +2 -0
- data/spec/dummy/config/boot.rb +2 -0
- data/spec/dummy/config/database.yml.semaphore +2 -2
- data/spec/dummy/config/environment.rb +2 -0
- data/spec/dummy/config/environments/development.rb +2 -0
- data/spec/dummy/config/environments/production.rb +2 -0
- data/spec/dummy/config/environments/test.rb +2 -0
- data/spec/dummy/config/initializers/assets.rb +2 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
- data/spec/dummy/config/initializers/devise.rb +2 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +2 -0
- data/spec/dummy/config/initializers/inflections.rb +1 -0
- data/spec/dummy/config/initializers/mime_types.rb +1 -0
- data/spec/dummy/config/initializers/session_store.rb +2 -0
- data/spec/dummy/config/initializers/workflow.rb +2 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
- data/spec/dummy/config/routes.rb +2 -0
- data/spec/dummy/config.ru +2 -0
- data/spec/dummy/db/migrate/20150127171613_devise_create_users.rb +2 -0
- data/spec/dummy/db/migrate/20150130042852_create_sales_contacts.rb +2 -0
- data/spec/dummy/db/migrate/20150130043008_create_leads.rb +2 -0
- data/spec/dummy/log/development.log +110 -0
- data/spec/dummy/log/test.log +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7O/7O5OddMZvWFGpj71BCdc0vA55rhj4YPoL0XjBV4_OYk.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Cy/CyixQwp8QvorgpRadtYf6_zY35nZZp0JmrhkDN16XPM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FW/FWR5Q7EP17cTcY35R1MscF6MX2HYiH5I2ZII89YLYxc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HQ/HQuQO1k4kOyLSDXJEc8p-XR2agdkPF7mIFyh2noiNrU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/N4/N4e3G5QNTts2OVqkL0kxoP1xnAdDWnumpnH1m6WAsuY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rs/RsIG_ias53xeb4WHWRodcMcDmVyz1QvLQNy4gV2iBSo.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/WI/WI2XYMfwCaPWcjvvouKVltl9oKqKZL-BHePPLhC-rzw.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Yc/YcbQRZWzddLfawePxNTEXcFFiS7asAyrujZzciT99l0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ai/aihcJWCIJGiHDpamul8bzy4jMsxnhewX6XWtkdsQ9dc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fR/fRVQN4mU7z3MVJD9u1LMq8idpOH8o2tFh_YouMYGAM8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gU/gUFNMb7SgxFyz5ZZcGfp-VYRVIw711HUeiWonMzYrcU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/h8/h86FNb4MxO5dq40P8KcCgGwZ_uqd8nn_O2fMWGDApW8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q7/q7cZDJXZFXTklMF8JAQSMr-MBxOKc7q1vZAPPR5RBf4.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/s9/s98GbJDqEe4PG3moRH6h-ukIZmQz9Frq4LO_Z9vCBLM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xX/xXCd205lXu7u_BuyBL0kfZwkBGJLvocHDItBfU6tMm4.cache +2 -0
- data/spec/factories/context.rb +2 -0
- data/spec/factories/operation_templates.rb +2 -0
- data/spec/factories/operations.rb +3 -1
- data/spec/factories/process_templates.rb +2 -0
- data/spec/factories/processes.rb +3 -1
- data/spec/factories/user.rb +2 -0
- data/spec/factories/workflow_errors.rb +2 -0
- data/spec/features/operations_spec.rb +2 -0
- data/spec/features/process_template_spec.rb +2 -0
- data/spec/lib/error_builder_spec.rb +137 -0
- data/spec/lib/error_resolver_spec.rb +182 -0
- data/spec/lib/operation_builder_spec.rb +69 -0
- data/spec/lib/process_builder_spec.rb +19 -0
- data/spec/{core/rails_workflow → lib}/process_manager_spec.rb +17 -27
- data/spec/models/rails_workflow/context_spec.rb +6 -3
- data/spec/models/rails_workflow/error_spec.rb +20 -147
- data/spec/models/rails_workflow/operation_spec.rb +64 -97
- data/spec/models/rails_workflow/operation_template_spec.rb +24 -11
- data/spec/models/rails_workflow/process_spec.rb +5 -2
- data/spec/models/rails_workflow/process_template_spec.rb +2 -36
- data/spec/rails_helper.rb +2 -0
- data/spec/serializers/process_template_serializer_spec.rb +2 -0
- data/spec/services/process_importer_spec.rb +2 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/support/controller_macros.rb +2 -0
- data/spec/support/pages/operations.rb +2 -0
- data/spec/support/rails_workflow/custom_operation.rb +2 -0
- data/spec/support/rails_workflow/custom_operation_template.rb +2 -0
- data/spec/{core → support}/rails_workflow/prepare_template.rb +3 -1
- data/spec/support/workflow_helper.rb +2 -0
- metadata +54 -28
- data/app/concerns/rails_workflow/operation_templates/default_builder.rb +0 -56
- data/app/concerns/rails_workflow/operations/default_runner.rb +0 -121
- data/app/concerns/rails_workflow/process_templates/default_builder.rb +0 -52
- data/app/concerns/rails_workflow/processes/default_runner.rb +0 -64
- data/app/concerns/rails_workflow/processes/dependency_resolver.rb +0 -54
- data/app/concerns/rails_workflow/reset_cache.rb +0 -13
- data/app/jobs/rails_workflow/operation_error_job.rb +0 -40
- data/app/managers/rails_workflow/process_manager.rb +0 -40
data/spec/dummy/log/test.log
CHANGED
Binary file
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7O/7O5OddMZvWFGpj71BCdc0vA55rhj4YPoL0XjBV4_OYk.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%����"m�J���S��E�j!�/�d�]�/[���
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Cy/CyixQwp8QvorgpRadtYf6_zY35nZZp0JmrhkDN16XPM.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%�Q)��MI-���{�h�⃯�\�WUD ���
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FW/FWR5Q7EP17cTcY35R1MscF6MX2HYiH5I2ZII89YLYxc.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%]���:ǚ G�z#�X��oD^O��ެp8R
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HQ/HQuQO1k4kOyLSDXJEc8p-XR2agdkPF7mIFyh2noiNrU.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%���NO|�Z�����?ʼ�P(v�o�J�9��1
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/N4/N4e3G5QNTts2OVqkL0kxoP1xnAdDWnumpnH1m6WAsuY.cache
ADDED
Binary file
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rs/RsIG_ias53xeb4WHWRodcMcDmVyz1QvLQNy4gV2iBSo.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%���}�Tk�d\��@H��`�vB�'B���I
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/WI/WI2XYMfwCaPWcjvvouKVltl9oKqKZL-BHePPLhC-rzw.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%������S��h�˯Wu;&�V�#�Y��
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Yc/YcbQRZWzddLfawePxNTEXcFFiS7asAyrujZzciT99l0.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%>��.��l�;T��_2��IT���Ɣc�ḩ
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ai/aihcJWCIJGiHDpamul8bzy4jMsxnhewX6XWtkdsQ9dc.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%�U7��r��� ����ڥ�2�)d*�d��/po�
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fR/fRVQN4mU7z3MVJD9u1LMq8idpOH8o2tFh_YouMYGAM8.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%��P�k7}�i�Ur�����Փa!�����@�a
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gU/gUFNMb7SgxFyz5ZZcGfp-VYRVIw711HUeiWonMzYrcU.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%���h��;����*���b(��n��Gn��L
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/h8/h86FNb4MxO5dq40P8KcCgGwZ_uqd8nn_O2fMWGDApW8.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%K�@Ĝ(�2T�J��s�)iW�8���4�
|
data/spec/dummy/tmp/cache/assets/sprockets/v3.0/s9/s98GbJDqEe4PG3moRH6h-ukIZmQz9Frq4LO_Z9vCBLM.cache
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
"%��}�������J�d���p�A,#G�� �j��
|
data/spec/factories/context.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
FactoryGirl.define do
|
2
4
|
factory :operation, class: 'RailsWorkflow::Operation' do
|
3
5
|
title 'Test Operation'
|
4
|
-
status RailsWorkflow::
|
6
|
+
status RailsWorkflow::Status::NOT_STARTED
|
5
7
|
|
6
8
|
factory :operation_with_context do
|
7
9
|
context { create :context, data: { msg: 'Test' } }
|
data/spec/factories/processes.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
FactoryGirl.define do
|
2
4
|
factory :process, class: 'RailsWorkflow::Process' do
|
3
|
-
status RailsWorkflow::
|
5
|
+
status RailsWorkflow::Status::NOT_STARTED
|
4
6
|
context { create :context, data: { msg: 'Test message' } }
|
5
7
|
end
|
6
8
|
end
|
data/spec/factories/user.rb
CHANGED
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
module RailsWorkflow
|
6
|
+
RSpec.describe ErrorBuilder do
|
7
|
+
# TODO: add process builder failures tests
|
8
|
+
let(:process_template) { create :process_template }
|
9
|
+
let(:process) { create(:process, template: process_template) }
|
10
|
+
let(:operation) { create :operation, process: process }
|
11
|
+
let(:operation_runner) { OperationRunner.new(operation) }
|
12
|
+
let(:test_message) { 'Test message' }
|
13
|
+
|
14
|
+
let(:error) { operation.workflow_errors.first }
|
15
|
+
let(:error_parent) { operation }
|
16
|
+
let(:error_target) { operation }
|
17
|
+
let(:error_args) { nil }
|
18
|
+
let(:error_parent_type) { RailsWorkflow::Operation }
|
19
|
+
let(:error_method) { 'start_process' }
|
20
|
+
|
21
|
+
shared_context 'workflow failed' do
|
22
|
+
specify do
|
23
|
+
expect { failing_method_call }
|
24
|
+
.to change { RailsWorkflow::Error.count }.by(1)
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'manager creates error' do
|
28
|
+
before { failing_method_call }
|
29
|
+
it_behaves_like 'has workflow error'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
shared_examples 'has workflow error' do
|
34
|
+
it { expect(process.reload.status).to eq RailsWorkflow::Status::ERROR }
|
35
|
+
|
36
|
+
it { expect(error_parent.workflow_errors.count).to eq 1 }
|
37
|
+
it { expect(error_parent.status).to eq RailsWorkflow::Status::ERROR }
|
38
|
+
|
39
|
+
it { expect(error.message).to eq test_message }
|
40
|
+
|
41
|
+
# TODO: check with custom operation / process types
|
42
|
+
it { expect(error.parent).to be_a_kind_of(error_parent_type) }
|
43
|
+
|
44
|
+
it { expect(error.data[:target]).to eq error_target }
|
45
|
+
it { expect(error.data[:method]).to eq error_method }
|
46
|
+
it { expect(error.data[:args]).to eq error_args }
|
47
|
+
end
|
48
|
+
|
49
|
+
def raise_error(target, method_name)
|
50
|
+
allow(target).to receive(method_name).and_raise(test_message)
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when operation fails to start' do
|
54
|
+
let(:error_target) { 'operation_runner' }
|
55
|
+
before { raise_error operation, :can_start? }
|
56
|
+
let(:failing_method_call) { operation.start }
|
57
|
+
let(:error_method) { 'start' }
|
58
|
+
|
59
|
+
it_behaves_like 'workflow failed'
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when operation fails to start waiting' do
|
63
|
+
let(:error_target) { 'operation_runner' }
|
64
|
+
before { raise_error operation, :update_attribute }
|
65
|
+
let(:failing_method_call) { operation_runner.waiting }
|
66
|
+
let(:error_method) { 'waiting' }
|
67
|
+
|
68
|
+
it_behaves_like 'workflow failed'
|
69
|
+
end
|
70
|
+
|
71
|
+
# TODO: cover other errors in execute_in_transitions
|
72
|
+
context 'when operation execution fails' do
|
73
|
+
let(:error_method) { 'execute_in_transaction' }
|
74
|
+
let(:error_target) { 'operation_runner' }
|
75
|
+
before { raise_error(operation, :execute) }
|
76
|
+
let(:failing_method_call) { operation_runner.execute_in_transaction }
|
77
|
+
|
78
|
+
it_behaves_like 'workflow failed'
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'when operation build fails' do
|
82
|
+
let(:operation_template) { create :operation_template }
|
83
|
+
let(:error) { process.workflow_errors.first }
|
84
|
+
let(:error_target) { 'operation_builder' }
|
85
|
+
let(:error_parent) { process }
|
86
|
+
let(:error_parent_type) { RailsWorkflow::Process }
|
87
|
+
let(:error_method) { 'create_operation' }
|
88
|
+
let(:error_args) { [process, operation_template, []] }
|
89
|
+
let(:operation_builder) do
|
90
|
+
OperationBuilder.new(process, operation_template)
|
91
|
+
end
|
92
|
+
|
93
|
+
before { raise_error operation_builder, :create_operation! }
|
94
|
+
let(:failing_method_call) do
|
95
|
+
operation_builder.create_operation
|
96
|
+
end
|
97
|
+
|
98
|
+
it_behaves_like 'workflow failed'
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when new operations build fails' do
|
102
|
+
let(:error) { process.workflow_errors.first }
|
103
|
+
let(:error_target) { 'dependency_resolver' }
|
104
|
+
let(:error_parent) { process }
|
105
|
+
let(:error_method) { 'build_new_operations' }
|
106
|
+
let(:error_parent_type) { RailsWorkflow::Process }
|
107
|
+
let(:error_args) { [operation] }
|
108
|
+
let(:dependency_resolver) { DependencyResolver.new(process) }
|
109
|
+
|
110
|
+
before { raise_error dependency_resolver, :matched_templates }
|
111
|
+
let(:failing_method_call) do
|
112
|
+
dependency_resolver.build_new_operations(operation)
|
113
|
+
end
|
114
|
+
|
115
|
+
it_behaves_like 'workflow failed'
|
116
|
+
end
|
117
|
+
|
118
|
+
context 'when process manager fails to start process' do
|
119
|
+
let(:process_manager) { RailsWorkflow::ProcessManager.new(process) }
|
120
|
+
let(:process_runner) { RailsWorkflow::ProcessRunner.new(process) }
|
121
|
+
let(:error) { process.workflow_errors.first }
|
122
|
+
let(:error_target) { 'process_manager' }
|
123
|
+
let(:error_parent) { process }
|
124
|
+
let(:error_parent_type) { RailsWorkflow::Process }
|
125
|
+
|
126
|
+
let(:failing_method_call) { process_manager.start_process }
|
127
|
+
before do
|
128
|
+
allow(RailsWorkflow::ProcessRunner).to receive(:new)
|
129
|
+
.and_return(process_runner)
|
130
|
+
|
131
|
+
raise_error process_runner, :start
|
132
|
+
end
|
133
|
+
|
134
|
+
it_behaves_like 'workflow failed'
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,182 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
require_relative '../support/rails_workflow/prepare_template'
|
5
|
+
|
6
|
+
module RailsWorkflow
|
7
|
+
RSpec.describe ErrorResolver do
|
8
|
+
include PrepareTemplate
|
9
|
+
|
10
|
+
let(:template) { prepare_template }
|
11
|
+
let(:process_manager) do
|
12
|
+
ProcessManager.new(
|
13
|
+
template_id: template.id, context: { msg: 'Test' }
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:process) { process_manager.create_process }
|
18
|
+
let(:process_runner) { RailsWorkflow::ProcessRunner.new(process) }
|
19
|
+
|
20
|
+
context 'operation fails' do
|
21
|
+
let(:operation) { process.operations.first }
|
22
|
+
let(:error) { operation.workflow_errors.first }
|
23
|
+
let(:error_resolver) { described_class.new(error) }
|
24
|
+
|
25
|
+
context 'to start' do
|
26
|
+
before do
|
27
|
+
with_failing_instance(Operation, :execute) do
|
28
|
+
process_runner.start
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'set proper process status after retry' do
|
33
|
+
expect { error_resolver.retry }
|
34
|
+
.to change { process.reload.status }
|
35
|
+
.from(Status::ERROR).to(Status::DONE)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'set proper operation status after retry' do
|
39
|
+
expect { error_resolver.retry }
|
40
|
+
.to change { process.reload.operations.first.status }
|
41
|
+
.from(Status::ERROR).to(Status::DONE)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'to wait' do
|
46
|
+
before do
|
47
|
+
allow_any_instance_of(Operation)
|
48
|
+
.to receive(:can_start?).and_return(false)
|
49
|
+
|
50
|
+
with_failing_instance(Operation, :update_attribute) do
|
51
|
+
process_runner.start
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'set proper process status' do
|
56
|
+
expect { error_resolver.retry }
|
57
|
+
.to change { process.reload.status }
|
58
|
+
.from(Status::ERROR).to(Status::IN_PROGRESS)
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'set proper operation status' do
|
62
|
+
expect { error_resolver.retry }
|
63
|
+
.to change { process.reload.operations.first.status }
|
64
|
+
.from(Status::ERROR).to(Status::WAITING)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context 'execution fails' do
|
69
|
+
before do
|
70
|
+
with_failing_instance(Operation, :execute) do
|
71
|
+
process_runner.start
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'set proper process status' do
|
76
|
+
expect { error_resolver.retry }
|
77
|
+
.to change { process.reload.status }
|
78
|
+
.from(Status::ERROR).to(Status::DONE)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'set proper operation status' do
|
82
|
+
expect { error_resolver.retry }
|
83
|
+
.to change { process.reload.operations.first.status }
|
84
|
+
.from(Status::ERROR).to(Status::DONE)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'operation building fails' do
|
90
|
+
let(:operation) { process.operations.first }
|
91
|
+
let(:error) { process.workflow_errors.first }
|
92
|
+
let(:error_resolver) { described_class.new(error) }
|
93
|
+
|
94
|
+
context 'when operation build fails' do
|
95
|
+
before do
|
96
|
+
with_failing(Operation, :create) do
|
97
|
+
process_runner.start
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'set proper process status' do
|
102
|
+
expect { error_resolver.retry }
|
103
|
+
.to change { process.reload.status }
|
104
|
+
.from(Status::ERROR).to(Status::DONE)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'set proper operation status' do
|
108
|
+
expect { error_resolver.retry }
|
109
|
+
.to change { process.reload.operations&.first&.status }
|
110
|
+
.to(Status::DONE)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context 'process runner fails to start' do
|
116
|
+
let(:error) { Error.first }
|
117
|
+
let(:error_resolver) { described_class.new(error) }
|
118
|
+
|
119
|
+
context 'when operation build fails' do
|
120
|
+
before do
|
121
|
+
with_failing_instance(ProcessRunner, :start) do
|
122
|
+
process_manager.create_process
|
123
|
+
process_manager.start_process
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'set proper process status' do
|
128
|
+
expect { error_resolver.retry }
|
129
|
+
.to change { Process.first.status }
|
130
|
+
.from(Status::ERROR).to(Status::DONE)
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'creates and completes operations' do
|
134
|
+
expect { error_resolver.retry }
|
135
|
+
.to change { Process.first.operations.count }
|
136
|
+
.from(1).to(2)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
context 'dependency resolver' do
|
142
|
+
let(:operation) { process.operations.first }
|
143
|
+
let(:error) { process.workflow_errors.first }
|
144
|
+
let(:error_resolver) { described_class.new(error) }
|
145
|
+
|
146
|
+
context 'when operation build fails' do
|
147
|
+
before do
|
148
|
+
with_failing_instance(DependencyResolver, :matched_templates) do
|
149
|
+
process_runner.start
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'set proper process status' do
|
154
|
+
expect { error_resolver.retry }
|
155
|
+
.to change { Process.first.status }
|
156
|
+
.from(Status::ERROR).to(Status::DONE)
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'set proper operation status' do
|
160
|
+
expect { error_resolver.retry }
|
161
|
+
.to change { Process.first.operations.count }
|
162
|
+
.from(1).to(2)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def with_failing_instance(target_class, method)
|
168
|
+
allow_any_instance_of(target_class)
|
169
|
+
.to receive(method) { raise 'Some error' }
|
170
|
+
|
171
|
+
yield
|
172
|
+
|
173
|
+
allow_any_instance_of(target_class).to receive(method).and_call_original
|
174
|
+
end
|
175
|
+
|
176
|
+
def with_failing(target, method)
|
177
|
+
allow(target).to receive(method) { raise 'Some error' }
|
178
|
+
yield
|
179
|
+
allow(target).to receive(method).and_call_original
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|