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
@@ -0,0 +1,69 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
module RailsWorkflow
|
6
|
+
RSpec.describe OperationBuilder do
|
7
|
+
let(:operation_runner) { OperationRunner }
|
8
|
+
let(:manager) { ProcessManager.new(process) }
|
9
|
+
let(:process) { create :process }
|
10
|
+
let(:operation) { described_class.new(process, template).create_operation }
|
11
|
+
|
12
|
+
let(:template) do
|
13
|
+
create :operation_template,
|
14
|
+
operation_class: 'RailsWorkflow::UserByGroupOperation'
|
15
|
+
end
|
16
|
+
|
17
|
+
before do
|
18
|
+
allow_any_instance_of(RailsWorkflow::Process)
|
19
|
+
.to receive(:manager).and_return(manager)
|
20
|
+
end
|
21
|
+
|
22
|
+
it { expect(operation.title).to eq template.title }
|
23
|
+
it { expect(operation.async).to eq template.async }
|
24
|
+
it { expect(operation.is_background).to eq template.is_background }
|
25
|
+
it { expect(operation).to be_kind_of UserByGroupOperation }
|
26
|
+
it { expect(operation.template).to eq template }
|
27
|
+
it { expect(operation.process).to eq process }
|
28
|
+
it { expect(operation.manager).to eq manager }
|
29
|
+
it { expect(operation.status).to eq Status::NOT_STARTED }
|
30
|
+
it { expect(operation.persisted?).to be true }
|
31
|
+
|
32
|
+
context 'sets dependencies' do
|
33
|
+
context 'from template' do
|
34
|
+
let(:operation) { create :operation, status: Status::ERROR }
|
35
|
+
let(:dependencies) do
|
36
|
+
[
|
37
|
+
{ 'operation_id' => operation.id, 'status' => operation.status }
|
38
|
+
]
|
39
|
+
end
|
40
|
+
let(:operation_with_dependencies) do
|
41
|
+
described_class.new(process, template, [operation]).create_operation
|
42
|
+
end
|
43
|
+
|
44
|
+
it do
|
45
|
+
expect(operation_with_dependencies.dependencies).to eq dependencies
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'when no dependencies' do
|
50
|
+
expect(operation.dependencies).to eq []
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context 'should build child process' do
|
55
|
+
let(:parent_template) { create :parent_operation_template }
|
56
|
+
|
57
|
+
let(:parent_operation) do
|
58
|
+
described_class.new(
|
59
|
+
process, parent_template, [operation]
|
60
|
+
).create_operation
|
61
|
+
end
|
62
|
+
|
63
|
+
it do
|
64
|
+
expect(parent_operation.child_process)
|
65
|
+
.to be_a_kind_of RailsWorkflow::Process
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
|
5
|
+
module RailsWorkflow
|
6
|
+
RSpec.describe ProcessBuilder do
|
7
|
+
let(:template) do
|
8
|
+
create :process_template, process_class: 'RailsWorkflow::TestProcess'
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:new_process) { described_class.new(template, {}).create_process! }
|
12
|
+
|
13
|
+
it { expect(new_process).to be_instance_of TestProcess }
|
14
|
+
it { expect(new_process.template).to eq template }
|
15
|
+
end
|
16
|
+
|
17
|
+
class TestProcess < RailsWorkflow::Process
|
18
|
+
end
|
19
|
+
end
|
@@ -1,4 +1,7 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'rails_helper'
|
4
|
+
require_relative '../support/rails_workflow/prepare_template'
|
2
5
|
|
3
6
|
module RailsWorkflow
|
4
7
|
RSpec.describe ProcessManager do
|
@@ -6,13 +9,14 @@ module RailsWorkflow
|
|
6
9
|
|
7
10
|
let(:template) { prepare_template }
|
8
11
|
|
9
|
-
|
12
|
+
let(:process) { described_class.create_process template.id, msg: 'Test' }
|
13
|
+
let(:operation_runner) { RailsWorkflow::OperationRunner }
|
10
14
|
|
11
15
|
context 'build process' do
|
12
16
|
it 'should create new process' do
|
13
17
|
expect(process).to be
|
14
18
|
expect(process).to be_kind_of(Process)
|
15
|
-
expect(process.status).to eq RailsWorkflow::
|
19
|
+
expect(process.status).to eq RailsWorkflow::Status::NOT_STARTED
|
16
20
|
end
|
17
21
|
|
18
22
|
it 'with reference to template' do
|
@@ -22,7 +26,7 @@ module RailsWorkflow
|
|
22
26
|
it 'should create new process operations' do
|
23
27
|
expect(process.operations.size).to eq 1
|
24
28
|
expect(process.operations.first.status)
|
25
|
-
.to eq RailsWorkflow::
|
29
|
+
.to eq RailsWorkflow::Status::NOT_STARTED
|
26
30
|
end
|
27
31
|
|
28
32
|
it 'should create process context' do
|
@@ -35,21 +39,6 @@ module RailsWorkflow
|
|
35
39
|
expect(context).to be
|
36
40
|
expect(context.data[:msg]).to eq 'Test'
|
37
41
|
end
|
38
|
-
|
39
|
-
end
|
40
|
-
|
41
|
-
context 'caching' do
|
42
|
-
before do
|
43
|
-
RailsWorkflow.config.cache.clear
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'should use cached templates version' do
|
47
|
-
relation = RailsWorkflow::ProcessTemplate.eager_load(:operations)
|
48
|
-
allow(RailsWorkflow::ProcessTemplate).to receive(:eager_load).and_return(relation)
|
49
|
-
|
50
|
-
expect(relation).to receive(:find).once.and_call_original
|
51
|
-
described_class.build_process template.id, msg: 'Test'
|
52
|
-
end
|
53
42
|
end
|
54
43
|
|
55
44
|
context 'start process' do
|
@@ -57,18 +46,18 @@ module RailsWorkflow
|
|
57
46
|
before :each do
|
58
47
|
allow_any_instance_of(RailsWorkflow::ProcessManager)
|
59
48
|
.to receive(:complete_process)
|
60
|
-
allow_any_instance_of(RailsWorkflow::
|
49
|
+
allow_any_instance_of(RailsWorkflow::OperationRunner).to receive(:complete)
|
61
50
|
process_manager = RailsWorkflow::ProcessManager.new process
|
62
51
|
process_manager.start_process
|
63
52
|
end
|
64
53
|
|
65
54
|
it 'should start new process' do
|
66
|
-
expect(process.status).to eq RailsWorkflow::
|
55
|
+
expect(process.status).to eq RailsWorkflow::Status::IN_PROGRESS
|
67
56
|
end
|
68
57
|
|
69
58
|
it 'should start first operations' do
|
70
59
|
expect(process.operations.first.status)
|
71
|
-
.to eq RailsWorkflow::
|
60
|
+
.to eq RailsWorkflow::Status::IN_PROGRESS
|
72
61
|
end
|
73
62
|
end
|
74
63
|
end
|
@@ -81,12 +70,13 @@ module RailsWorkflow
|
|
81
70
|
allow_any_instance_of(RailsWorkflow::OperationTemplate)
|
82
71
|
.to receive(:resolve_dependency).and_return(false)
|
83
72
|
manager.start_process
|
84
|
-
process.operations.first.complete
|
73
|
+
operation_runner.new(process.operations.first).complete
|
85
74
|
expect(process.operations.size).to eq 1
|
86
75
|
end
|
76
|
+
|
87
77
|
it 'should not be created when dependencies is not sutisfied' do
|
88
78
|
manager.start_process
|
89
|
-
process.operations.first.complete
|
79
|
+
operation_runner.new(process.operations.first).complete
|
90
80
|
expect(process.operations.size).to eq 2
|
91
81
|
end
|
92
82
|
end
|
@@ -94,13 +84,13 @@ module RailsWorkflow
|
|
94
84
|
context 'after first operation done' do
|
95
85
|
before do
|
96
86
|
manager.start_process
|
97
|
-
process.operations.first.complete
|
87
|
+
operation_runner.new(process.operations.first).complete
|
98
88
|
end
|
99
89
|
|
100
|
-
[
|
90
|
+
%i[complete skip cancel].each do |method_name|
|
101
91
|
new_method = <<-METHOD
|
102
92
|
it 'should complete process if last operation #{method_name}' do
|
103
|
-
process.operations.last.#{method_name}
|
93
|
+
operation_runner.new(process.operations.last).#{method_name}
|
104
94
|
expect(process.status).to eq Process::DONE
|
105
95
|
end
|
106
96
|
METHOD
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails_helper'
|
2
4
|
|
3
5
|
module RailsWorkflow
|
@@ -80,10 +82,11 @@ module RailsWorkflow
|
|
80
82
|
end
|
81
83
|
|
82
84
|
it 'should be build using operation dependencies contexts' do
|
83
|
-
operation = create :operation_with_context, status: RailsWorkflow::
|
85
|
+
operation = create :operation_with_context, status: RailsWorkflow::Status::ERROR
|
84
86
|
|
85
|
-
child_operation =
|
86
|
-
|
87
|
+
child_operation = OperationBuilder.new(
|
88
|
+
process, template, [operation]
|
89
|
+
).create_operation
|
87
90
|
|
88
91
|
expect(child_operation.context.data).to match(msg: 'Test')
|
89
92
|
end
|
@@ -1,153 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails_helper'
|
2
4
|
|
3
5
|
module RailsWorkflow
|
4
6
|
RSpec.describe Error, type: :model do
|
5
|
-
#
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# expect(error.message).to eq test_message
|
24
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Process)
|
25
|
-
# expect(error.parent.status).to eq Workflow::Process::ERROR
|
26
|
-
# end
|
27
|
-
#
|
28
|
-
# it 'should create error if process failed to start' do
|
29
|
-
# manager = Workflow::ProcessManager.new process
|
30
|
-
# allow(process).to receive(:start).and_raise(test_message)
|
31
|
-
#
|
32
|
-
# expect {
|
33
|
-
# manager.start_process
|
34
|
-
# }.to change { Workflow::Error.count }.by(1)
|
35
|
-
#
|
36
|
-
# error = Workflow::Error.last
|
37
|
-
# expect(error.message).to eq test_message
|
38
|
-
# expect(error.parent).to eq process
|
39
|
-
# expect(error.parent.status).to eq Workflow::Process::ERROR
|
40
|
-
# end
|
41
|
-
#
|
42
|
-
# it 'should create error if process manager init fails' do
|
43
|
-
# allow_any_instance_of(Workflow::OperationTemplate).to receive(:build_operation!).and_raise(test_message)
|
44
|
-
#
|
45
|
-
# expect{
|
46
|
-
# ProcessManager.start_process process_template.id, {}
|
47
|
-
# }.to change { Workflow::Error.count }.by(1)
|
48
|
-
#
|
49
|
-
# error = Workflow::Error.last
|
50
|
-
# expect(error.message).to eq test_message
|
51
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Process)
|
52
|
-
# expect(error.parent.status).to eq Workflow::Process::ERROR
|
53
|
-
# end
|
54
|
-
#
|
55
|
-
# it 'should create error if process manager build process fails' do
|
56
|
-
# allow_any_instance_of(Workflow::OperationTemplate).to receive(:build_operation!).and_raise(test_message)
|
57
|
-
#
|
58
|
-
# expect{
|
59
|
-
# ProcessManager.start_process process_template.id, {}
|
60
|
-
# }.to change { Workflow::Error.count }.by(1)
|
61
|
-
#
|
62
|
-
# error = Workflow::Error.last
|
63
|
-
# expect(error.message).to eq test_message
|
64
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Process)
|
65
|
-
# expect(error.parent.status).to eq Workflow::Process::ERROR
|
66
|
-
# end
|
67
|
-
#
|
68
|
-
# it 'should creaete error if operation start fails' do
|
69
|
-
# allow_any_instance_of(Workflow::Operation).to receive(:can_start?).and_raise(test_message)
|
70
|
-
#
|
71
|
-
# expect{
|
72
|
-
# operation.start
|
73
|
-
# }.to change { Workflow::Error.count }.by(1)
|
74
|
-
#
|
75
|
-
# error = Workflow::Error.last
|
76
|
-
# expect(error.message).to eq test_message
|
77
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Operation)
|
78
|
-
# expect(error.parent.status).to eq Workflow::Operation::ERROR
|
79
|
-
# operaiton.reload
|
80
|
-
# expect(operation.process.status).to eq Workflow::Process::ERROR
|
81
|
-
# end
|
82
|
-
#
|
83
|
-
# it 'should create error if operation waiting fails' do
|
84
|
-
# allow_any_instance_of(Workflow::Operation).to receive(:start_waiting).and_raise(test_message)
|
85
|
-
#
|
86
|
-
# expect{
|
87
|
-
# operation.waiting
|
88
|
-
# }.to change { Workflow::Error.count }.by(1)
|
89
|
-
#
|
90
|
-
# error = Workflow::Error.last
|
91
|
-
# expect(error.message).to eq test_message
|
92
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Operation)
|
93
|
-
# expect(error.parent.status).to eq Workflow::Operation::ERROR
|
94
|
-
# end
|
95
|
-
#
|
96
|
-
# it 'should create error if operation execute fails' do
|
97
|
-
# allow_any_instance_of(Workflow::Operation).to receive(:execute).and_raise(test_message)
|
98
|
-
#
|
99
|
-
# expect{
|
100
|
-
# operation.start
|
101
|
-
# }.to change { Workflow::Error.count }.by(1)
|
102
|
-
#
|
103
|
-
# error = Workflow::Error.last
|
104
|
-
# expect(error.message).to eq test_message
|
105
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Operation)
|
106
|
-
# expect(error.parent.status).to eq Workflow::Operation::ERROR
|
107
|
-
# end
|
108
|
-
#
|
109
|
-
# it 'should create error if operation complete fails' do
|
110
|
-
# allow_any_instance_of(Workflow::ProcessManager).to receive(:operation_complete).and_raise(test_message)
|
111
|
-
#
|
112
|
-
# expect{
|
113
|
-
# operation.manager = Workflow::ProcessManager.new process
|
114
|
-
# operation.complete
|
115
|
-
# }.to change { Workflow::Error.count }.by(1)
|
116
|
-
#
|
117
|
-
# error = Workflow::Error.last
|
118
|
-
# expect(error.message).to eq test_message
|
119
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Operation)
|
120
|
-
# expect(error.parent.status).to eq Workflow::Operation::ERROR
|
121
|
-
# end
|
122
|
-
#
|
123
|
-
# it 'should create error if operation build failed' do
|
124
|
-
#
|
125
|
-
# operation_template = create :operation_template
|
126
|
-
# allow_any_instance_of(Workflow::OperationTemplate).to receive(:operation_class).and_return("NotExistingClass")
|
127
|
-
#
|
128
|
-
# expect {
|
129
|
-
# operation =
|
130
|
-
# operation_template.build_operation! process
|
131
|
-
# }.to change { Workflow::Error.count }.by(1)
|
132
|
-
#
|
133
|
-
# error = Workflow::Error.last
|
134
|
-
# expect(error.message).to eq "undefined method `create' for \"NotExistingClass\":String"
|
135
|
-
# expect(error.parent).to be_a_kind_of(Workflow::Process)
|
136
|
-
# expect(error.parent.status).to eq Workflow::Process::ERROR
|
137
|
-
#
|
138
|
-
# end
|
139
|
-
#
|
140
|
-
# it 'should set default class to parent operation' do
|
141
|
-
#
|
142
|
-
# allow_any_instance_of(Workflow::CustomOperation).to receive(:execute).and_raise("Some exception")
|
143
|
-
# operation = create :custom_operation
|
144
|
-
#
|
145
|
-
# expect {
|
146
|
-
# operation.start
|
147
|
-
# }.to change { Workflow::Error.count }.by(1)
|
148
|
-
#
|
149
|
-
# expect(operation.workflow_errors.first.parent_type).to eq "Workflow::Operation"
|
150
|
-
# end
|
151
|
-
#
|
7
|
+
describe '#can_restart_process?' do
|
8
|
+
let(:process) { RailsWorkflow::Process.create }
|
9
|
+
before do
|
10
|
+
allow(subject).to receive(:process).and_return(process)
|
11
|
+
end
|
12
|
+
|
13
|
+
it { expect(subject.can_restart_process?).to eq true }
|
14
|
+
|
15
|
+
context 'with errors' do
|
16
|
+
before do
|
17
|
+
allow(process).to receive(
|
18
|
+
:unresolved_errors
|
19
|
+
).and_return ['some_error']
|
20
|
+
end
|
21
|
+
|
22
|
+
it { expect(subject.can_restart_process?).to eq false }
|
23
|
+
end
|
24
|
+
end
|
152
25
|
end
|
153
26
|
end
|
@@ -1,93 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'rails_helper'
|
4
|
+
require_relative '../../concerns/status_spec.rb'
|
2
5
|
|
3
6
|
module RailsWorkflow
|
4
7
|
RSpec.describe Operation, type: :model do
|
5
|
-
|
6
|
-
|
7
|
-
create :operation_template, async: true, operation_class: 'RailsWorkflow::UserByGroupOperation'
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:manager) { manager = RailsWorkflow::ProcessManager.new(process) }
|
11
|
-
let(:process) { process = create :process }
|
8
|
+
it_behaves_like 'Status'
|
9
|
+
let(:operation_runner) { OperationRunner }
|
12
10
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
allow_any_instance_of(RailsWorkflow::Process).to receive(:manager).and_return(manager)
|
11
|
+
context '#completable?' do
|
12
|
+
describe 'no child process' do
|
13
|
+
it { expect(subject).to be_completable }
|
17
14
|
end
|
18
15
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
expect(operation.is_background).to eq template.is_background
|
23
|
-
end
|
24
|
-
|
25
|
-
context 'should set dependencies' do
|
26
|
-
it 'from template' do
|
27
|
-
operation = create :operation, status: RailsWorkflow::Operation::ERROR
|
28
|
-
|
29
|
-
operation_with_dependencies =
|
30
|
-
template.build_operation! process, [operation]
|
31
|
-
|
32
|
-
dependencies = [
|
33
|
-
{
|
34
|
-
'operation_id' => operation.id,
|
35
|
-
'status' => operation.status
|
36
|
-
}
|
37
|
-
]
|
38
|
-
|
39
|
-
expect(operation_with_dependencies.dependencies).to eq dependencies
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'when template dependencies is blank' do
|
43
|
-
expect(operation.dependencies).to eq []
|
16
|
+
describe 'completed child process' do
|
17
|
+
before do
|
18
|
+
subject.child_process = Process.create(status: Status::DONE)
|
44
19
|
end
|
45
|
-
end
|
46
|
-
|
47
|
-
it 'should build correct class' do
|
48
|
-
expect(operation).to be_kind_of RailsWorkflow::UserByGroupOperation
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'should set reference to operation template' do
|
52
|
-
expect(operation.template).to eq template
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'should set process' do
|
56
|
-
expect(operation.process).to eq process
|
57
|
-
expect(operation.process_id).to eq process.id
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'should set manager' do
|
61
|
-
expect(operation.manager).to eq manager
|
62
|
-
operation.manager = manager
|
63
|
-
end
|
64
20
|
|
65
|
-
|
66
|
-
expect(operation.status).to eq RailsWorkflow::Operation::NOT_STARTED
|
21
|
+
it { expect(subject).to be_completable }
|
67
22
|
end
|
68
23
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
expect(parent_operation.child_process).to be_a_kind_of RailsWorkflow::Process
|
75
|
-
end
|
24
|
+
describe 'non-completed child process' do
|
25
|
+
before do
|
26
|
+
subject.child_process = Process.create(status: Status::WAITING)
|
27
|
+
end
|
76
28
|
|
77
|
-
|
78
|
-
expect(operation.persisted?).to be true
|
29
|
+
it { expect(subject).not_to be_completable }
|
79
30
|
end
|
80
31
|
end
|
81
32
|
|
33
|
+
# TODO: move to separate spec for OperationAssignment
|
82
34
|
context 'Operation Assignment' do
|
83
|
-
let(:operation)
|
84
|
-
|
85
|
-
end
|
86
|
-
|
87
|
-
let(:other_user) do
|
88
|
-
create :user, email: 'other@user.com'
|
89
|
-
end
|
90
|
-
|
35
|
+
let(:operation) { create :operation }
|
36
|
+
let(:other_user) { create :user, email: 'other@user.com' }
|
91
37
|
let(:user) { create :user }
|
92
38
|
|
93
39
|
it 'should assigns operation to user' do
|
@@ -142,72 +88,93 @@ module RailsWorkflow
|
|
142
88
|
role_template = create :operation_template, role: :admin
|
143
89
|
group_template = create :operation_template, group: 'some_group'
|
144
90
|
|
145
|
-
group_operation = create :operation,
|
146
|
-
|
91
|
+
group_operation = create :operation,
|
92
|
+
status: Status::WAITING,
|
93
|
+
template: group_template
|
94
|
+
|
95
|
+
role_operation = create :operation,
|
96
|
+
status: Status::WAITING,
|
97
|
+
template: role_template
|
147
98
|
|
148
99
|
user = create :user, role: :admin
|
149
100
|
|
150
|
-
role_operations =
|
101
|
+
role_operations = Operation.available_for_user(user)
|
151
102
|
expect(role_operations).to match_array([role_operation])
|
152
103
|
|
153
104
|
fake_user = create :user, email: 'fake@email.com', role: 'fake'
|
154
|
-
expect(
|
105
|
+
expect(Operation.available_for_user(fake_user)).to eq []
|
155
106
|
|
156
107
|
role_operation.assign user
|
157
|
-
expect(
|
108
|
+
expect(Operation.unassigned)
|
109
|
+
.to match_array [group_operation]
|
158
110
|
end
|
159
111
|
end
|
160
112
|
|
113
|
+
# TODO: move to separate spec for Operation Runner
|
161
114
|
context 'Operation Runner' do
|
162
115
|
let(:operation) { create :operation_with_context }
|
163
|
-
let(:process) {
|
116
|
+
let(:process) { create :process }
|
164
117
|
|
165
118
|
it 'should be set to WAITING if can not start' do
|
166
119
|
allow(operation).to receive(:can_start?).and_return(false)
|
167
|
-
operation.start
|
168
|
-
expect(operation.status).to eq
|
120
|
+
operation_runner.new(operation).start
|
121
|
+
expect(operation.status).to eq Status::WAITING
|
169
122
|
end
|
170
123
|
|
171
124
|
it 'should start child process' do
|
172
|
-
allow_any_instance_of(RailsWorkflow::Process)
|
173
|
-
|
125
|
+
allow_any_instance_of(RailsWorkflow::Process)
|
126
|
+
.to receive(:can_start?).and_return(true)
|
127
|
+
|
128
|
+
allow_any_instance_of(RailsWorkflow::ProcessRunner)
|
129
|
+
.to receive(:completable?).and_return(false)
|
174
130
|
|
175
131
|
parent_operation = create :operation
|
176
132
|
|
177
133
|
parent_operation.child_process = process
|
178
134
|
parent_operation.save
|
179
|
-
parent_operation.start
|
135
|
+
operation_runner.new(parent_operation).start
|
180
136
|
|
181
|
-
expect(parent_operation.status).to eq
|
137
|
+
expect(parent_operation.status).to eq Status::IN_PROGRESS
|
182
138
|
parent_operation.child_process.reload
|
183
|
-
expect(parent_operation.child_process.status).to eq RailsWorkflow::Process::IN_PROGRESS
|
184
|
-
end
|
185
139
|
|
186
|
-
|
140
|
+
expect(parent_operation.child_process.status).to eq Status::IN_PROGRESS
|
141
|
+
end
|
187
142
|
end
|
188
143
|
|
189
144
|
context 'complete operation ' do
|
190
145
|
before :each do
|
191
|
-
@manager =
|
192
|
-
|
146
|
+
@manager = ProcessManager.new
|
147
|
+
@process = RailsWorkflow::Process.new
|
148
|
+
@dependency_resolver = DependencyResolver.new(@process)
|
149
|
+
|
150
|
+
allow(@dependency_resolver).to receive(:build_new_operations)
|
151
|
+
allow(DependencyResolver).to receive(:new)
|
152
|
+
.and_return(@dependency_resolver)
|
153
|
+
|
154
|
+
# TODO: REWORK
|
155
|
+
allow_any_instance_of(Operation)
|
156
|
+
.to receive(:manager).and_return(@manager)
|
157
|
+
|
158
|
+
allow_any_instance_of(Operation)
|
159
|
+
.to receive(:process).and_return(@process)
|
193
160
|
end
|
194
161
|
|
195
162
|
it 'should change state to DONE on complete' do
|
196
|
-
expect(@manager).to receive(:operation_completed)
|
163
|
+
# expect(@manager).to receive(:operation_completed)
|
197
164
|
subject.complete
|
198
|
-
expect(subject.status).to eq
|
165
|
+
expect(subject.status).to eq Status::DONE
|
199
166
|
end
|
200
167
|
|
201
168
|
it 'should change state to SKIP on skip' do
|
202
|
-
expect(@manager).to receive(:operation_completed)
|
169
|
+
# expect(@manager).to receive(:operation_completed)
|
203
170
|
subject.skip
|
204
|
-
expect(subject.status).to eq
|
171
|
+
expect(subject.status).to eq Status::SKIPPED
|
205
172
|
end
|
206
173
|
|
207
174
|
it 'should change state to DONE on complete' do
|
208
|
-
expect(@manager).to receive(:operation_completed)
|
175
|
+
# expect(@manager).to receive(:operation_completed)
|
209
176
|
subject.cancel
|
210
|
-
expect(subject.status).to eq
|
177
|
+
expect(subject.status).to eq Status::CANCELED
|
211
178
|
end
|
212
179
|
end
|
213
180
|
end
|