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.
Files changed (161) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -0
  3. data/app/concerns/rails_workflow/operation_status.rb +2 -0
  4. data/app/concerns/rails_workflow/operation_templates/assignments.rb +3 -1
  5. data/app/concerns/rails_workflow/operation_templates/dependencies.rb +18 -18
  6. data/app/concerns/rails_workflow/operations/assignments.rb +7 -5
  7. data/app/concerns/rails_workflow/operations/dependencies.rb +2 -0
  8. data/app/concerns/rails_workflow/status.rb +11 -15
  9. data/app/concerns/rails_workflow/user/assignment.rb +2 -0
  10. data/app/concerns/rails_workflow/uuid.rb +2 -0
  11. data/app/controllers/rails_workflow/application_controller.rb +2 -0
  12. data/app/controllers/rails_workflow/errors_controller.rb +2 -0
  13. data/app/controllers/rails_workflow/operation_templates_controller.rb +3 -1
  14. data/app/controllers/rails_workflow/operations_controller.rb +3 -1
  15. data/app/controllers/rails_workflow/process_templates_controller.rb +10 -8
  16. data/app/controllers/rails_workflow/processes_controller.rb +10 -8
  17. data/app/decorators/rails_workflow/context_decorator.rb +2 -0
  18. data/app/decorators/rails_workflow/decorator.rb +2 -0
  19. data/app/decorators/rails_workflow/operation_decorator.rb +2 -0
  20. data/app/decorators/rails_workflow/operation_helper_decorator.rb +2 -0
  21. data/app/decorators/rails_workflow/operation_template_decorator.rb +2 -0
  22. data/app/decorators/rails_workflow/paginating_decorator.rb +2 -0
  23. data/app/decorators/rails_workflow/process_decorator.rb +2 -0
  24. data/app/decorators/rails_workflow/process_template_decorator.rb +2 -0
  25. data/app/decorators/rails_workflow/status_decorator.rb +2 -0
  26. data/app/helpers/rails_workflow/application_helper.rb +2 -0
  27. data/app/jobs/rails_workflow/operation_execution_job.rb +11 -1
  28. data/app/models/rails_workflow/context.rb +3 -1
  29. data/app/models/rails_workflow/error.rb +23 -50
  30. data/app/models/rails_workflow/operation.rb +39 -3
  31. data/app/models/rails_workflow/operation_template.rb +2 -2
  32. data/app/models/rails_workflow/process.rb +34 -5
  33. data/app/models/rails_workflow/process_template.rb +12 -8
  34. data/app/models/rails_workflow/user_by_group_operation.rb +2 -0
  35. data/app/models/rails_workflow/user_by_role_operation.rb +2 -0
  36. data/app/models/rails_workflow/user_operation.rb +2 -0
  37. data/app/serializers/rails_workflow/operation_template_serializer.rb +2 -0
  38. data/app/serializers/rails_workflow/process_template_serializer.rb +2 -0
  39. data/app/services/rails_workflow/default_importer_preprocessor.rb +2 -0
  40. data/app/services/rails_workflow/process_importer.rb +2 -0
  41. data/app/views/rails_workflow/processes/index.html.slim +5 -5
  42. data/config/initializers/rails_workflow.rb +3 -3
  43. data/config/routes.rb +4 -2
  44. data/db/migrate/20150630174700_create_workflow_processes.rb +86 -84
  45. data/lib/generators/rails_workflow/install/install_generator.rb +2 -0
  46. data/lib/generators/rails_workflow/install/templates/create_workflow_processes.rb +86 -84
  47. data/lib/rails_workflow/config.rb +65 -24
  48. data/lib/rails_workflow/db/mysql.rb +3 -1
  49. data/lib/rails_workflow/db/pg.rb +3 -1
  50. data/lib/rails_workflow/dependency_resolver.rb +74 -0
  51. data/lib/rails_workflow/engine.rb +3 -1
  52. data/lib/rails_workflow/error_builder.rb +57 -0
  53. data/lib/rails_workflow/error_resolver.rb +72 -0
  54. data/lib/rails_workflow/operation_builder.rb +95 -0
  55. data/lib/rails_workflow/operation_runner.rb +113 -0
  56. data/lib/rails_workflow/process_builder.rb +57 -0
  57. data/lib/rails_workflow/process_manager.rb +66 -0
  58. data/lib/rails_workflow/process_runner.rb +72 -0
  59. data/lib/rails_workflow/version.rb +3 -1
  60. data/lib/rails_workflow.rb +2 -0
  61. data/lib/tasks/rails_workflow_tasks.rake +1 -0
  62. data/spec/concerns/status_spec.rb +25 -0
  63. data/spec/controllers/rails_workflow/operation_templates_controller_spec.rb +2 -0
  64. data/spec/controllers/rails_workflow/operations_controller_spec.rb +2 -0
  65. data/spec/controllers/rails_workflow/process_templates_controller_spec.rb +2 -0
  66. data/spec/controllers/rails_workflow/processes_controller_spec.rb +3 -1
  67. data/spec/dummy/Rakefile +2 -0
  68. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  69. data/spec/dummy/app/controllers/leads_controller.rb +2 -0
  70. data/spec/dummy/app/controllers/sales_contacts_controller.rb +2 -0
  71. data/spec/dummy/app/decorators/lead_decorator.rb +2 -0
  72. data/spec/dummy/app/decorators/sales_contact_decorator.rb +2 -0
  73. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  74. data/spec/dummy/app/helpers/leads_helper.rb +2 -0
  75. data/spec/dummy/app/helpers/sales_contacts_helper.rb +2 -0
  76. data/spec/dummy/app/models/bad_operation.rb +2 -0
  77. data/spec/dummy/app/models/bad_operation_template.rb +2 -0
  78. data/spec/dummy/app/models/lead.rb +2 -0
  79. data/spec/dummy/app/models/sales_contact.rb +2 -0
  80. data/spec/dummy/app/models/user.rb +2 -0
  81. data/spec/dummy/bin/bundle +2 -0
  82. data/spec/dummy/bin/rails +2 -0
  83. data/spec/dummy/bin/rake +2 -0
  84. data/spec/dummy/config/application.rb +2 -0
  85. data/spec/dummy/config/boot.rb +2 -0
  86. data/spec/dummy/config/database.yml.semaphore +2 -2
  87. data/spec/dummy/config/environment.rb +2 -0
  88. data/spec/dummy/config/environments/development.rb +2 -0
  89. data/spec/dummy/config/environments/production.rb +2 -0
  90. data/spec/dummy/config/environments/test.rb +2 -0
  91. data/spec/dummy/config/initializers/assets.rb +2 -0
  92. data/spec/dummy/config/initializers/backtrace_silencers.rb +1 -0
  93. data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
  94. data/spec/dummy/config/initializers/devise.rb +2 -0
  95. data/spec/dummy/config/initializers/filter_parameter_logging.rb +2 -0
  96. data/spec/dummy/config/initializers/inflections.rb +1 -0
  97. data/spec/dummy/config/initializers/mime_types.rb +1 -0
  98. data/spec/dummy/config/initializers/session_store.rb +2 -0
  99. data/spec/dummy/config/initializers/workflow.rb +2 -0
  100. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -0
  101. data/spec/dummy/config/routes.rb +2 -0
  102. data/spec/dummy/config.ru +2 -0
  103. data/spec/dummy/db/migrate/20150127171613_devise_create_users.rb +2 -0
  104. data/spec/dummy/db/migrate/20150130042852_create_sales_contacts.rb +2 -0
  105. data/spec/dummy/db/migrate/20150130043008_create_leads.rb +2 -0
  106. data/spec/dummy/log/development.log +110 -0
  107. data/spec/dummy/log/test.log +0 -0
  108. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7O/7O5OddMZvWFGpj71BCdc0vA55rhj4YPoL0XjBV4_OYk.cache +1 -0
  109. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Cy/CyixQwp8QvorgpRadtYf6_zY35nZZp0JmrhkDN16XPM.cache +1 -0
  110. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/FW/FWR5Q7EP17cTcY35R1MscF6MX2HYiH5I2ZII89YLYxc.cache +1 -0
  111. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/HQ/HQuQO1k4kOyLSDXJEc8p-XR2agdkPF7mIFyh2noiNrU.cache +1 -0
  112. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/N4/N4e3G5QNTts2OVqkL0kxoP1xnAdDWnumpnH1m6WAsuY.cache +0 -0
  113. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rs/RsIG_ias53xeb4WHWRodcMcDmVyz1QvLQNy4gV2iBSo.cache +1 -0
  114. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/WI/WI2XYMfwCaPWcjvvouKVltl9oKqKZL-BHePPLhC-rzw.cache +1 -0
  115. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Yc/YcbQRZWzddLfawePxNTEXcFFiS7asAyrujZzciT99l0.cache +1 -0
  116. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ai/aihcJWCIJGiHDpamul8bzy4jMsxnhewX6XWtkdsQ9dc.cache +1 -0
  117. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fR/fRVQN4mU7z3MVJD9u1LMq8idpOH8o2tFh_YouMYGAM8.cache +1 -0
  118. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gU/gUFNMb7SgxFyz5ZZcGfp-VYRVIw711HUeiWonMzYrcU.cache +1 -0
  119. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/h8/h86FNb4MxO5dq40P8KcCgGwZ_uqd8nn_O2fMWGDApW8.cache +1 -0
  120. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q7/q7cZDJXZFXTklMF8JAQSMr-MBxOKc7q1vZAPPR5RBf4.cache +2 -0
  121. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/s9/s98GbJDqEe4PG3moRH6h-ukIZmQz9Frq4LO_Z9vCBLM.cache +1 -0
  122. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xX/xXCd205lXu7u_BuyBL0kfZwkBGJLvocHDItBfU6tMm4.cache +2 -0
  123. data/spec/factories/context.rb +2 -0
  124. data/spec/factories/operation_templates.rb +2 -0
  125. data/spec/factories/operations.rb +3 -1
  126. data/spec/factories/process_templates.rb +2 -0
  127. data/spec/factories/processes.rb +3 -1
  128. data/spec/factories/user.rb +2 -0
  129. data/spec/factories/workflow_errors.rb +2 -0
  130. data/spec/features/operations_spec.rb +2 -0
  131. data/spec/features/process_template_spec.rb +2 -0
  132. data/spec/lib/error_builder_spec.rb +137 -0
  133. data/spec/lib/error_resolver_spec.rb +182 -0
  134. data/spec/lib/operation_builder_spec.rb +69 -0
  135. data/spec/lib/process_builder_spec.rb +19 -0
  136. data/spec/{core/rails_workflow → lib}/process_manager_spec.rb +17 -27
  137. data/spec/models/rails_workflow/context_spec.rb +6 -3
  138. data/spec/models/rails_workflow/error_spec.rb +20 -147
  139. data/spec/models/rails_workflow/operation_spec.rb +64 -97
  140. data/spec/models/rails_workflow/operation_template_spec.rb +24 -11
  141. data/spec/models/rails_workflow/process_spec.rb +5 -2
  142. data/spec/models/rails_workflow/process_template_spec.rb +2 -36
  143. data/spec/rails_helper.rb +2 -0
  144. data/spec/serializers/process_template_serializer_spec.rb +2 -0
  145. data/spec/services/process_importer_spec.rb +2 -0
  146. data/spec/spec_helper.rb +2 -0
  147. data/spec/support/controller_macros.rb +2 -0
  148. data/spec/support/pages/operations.rb +2 -0
  149. data/spec/support/rails_workflow/custom_operation.rb +2 -0
  150. data/spec/support/rails_workflow/custom_operation_template.rb +2 -0
  151. data/spec/{core → support}/rails_workflow/prepare_template.rb +3 -1
  152. data/spec/support/workflow_helper.rb +2 -0
  153. metadata +54 -28
  154. data/app/concerns/rails_workflow/operation_templates/default_builder.rb +0 -56
  155. data/app/concerns/rails_workflow/operations/default_runner.rb +0 -121
  156. data/app/concerns/rails_workflow/process_templates/default_builder.rb +0 -52
  157. data/app/concerns/rails_workflow/processes/default_runner.rb +0 -64
  158. data/app/concerns/rails_workflow/processes/dependency_resolver.rb +0 -54
  159. data/app/concerns/rails_workflow/reset_cache.rb +0 -13
  160. data/app/jobs/rails_workflow/operation_error_job.rb +0 -40
  161. 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
- require_relative 'prepare_template'
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
- subject(:process) { described_class.build_process template.id, msg: 'Test' }
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::Process::NOT_STARTED
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::Operation::NOT_STARTED
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::Operation).to receive(:complete)
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::Process::IN_PROGRESS
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::Operation::IN_PROGRESS
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
- [:complete, :skip, :cancel].each do |method_name|
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::Operation::ERROR
85
+ operation = create :operation_with_context, status: RailsWorkflow::Status::ERROR
84
86
 
85
- child_operation =
86
- template.build_operation! process, [operation]
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
- # let(:process_template) { create :process_template }
6
- # let(:process) {
7
- # process = create :process, template: process_template
8
- # process.create_context data: {msg: "Test"}
9
- # process
10
- # }
11
- # let(:test_message) { "Test message" }
12
- # let(:operation) { create :operation, process: process }
13
- #
14
- #
15
- # it 'should create error if process build raised exception' do
16
- # allow_any_instance_of(Workflow::OperationTemplate).to receive(:build_operation!).and_raise(test_message)
17
- #
18
- # expect{
19
- # ProcessManager.start_process process_template.id, {}
20
- # }.to change { Workflow::Error.count }.by(1)
21
- #
22
- # error = Workflow::Error.last
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
- context 'Default Builder' do
6
- let(:template) do
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
- let(:operation) { template.build_operation! process }
14
-
15
- before :each do
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
- it 'sould fill title and async from template' do
20
- expect(operation.title).to eq template.title
21
- expect(operation.async).to eq template.async
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
- it 'should set status NOT STARTED' do
66
- expect(operation.status).to eq RailsWorkflow::Operation::NOT_STARTED
21
+ it { expect(subject).to be_completable }
67
22
  end
68
23
 
69
- it 'should build child process' do
70
- parent_template = create :parent_operation_template
71
-
72
- parent_operation = parent_template.build_operation! process, [operation]
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
- it 'should save operation' do
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) do
84
- operation = create :operation
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, status: Operation::WAITING, template: group_template
146
- role_operation = create :operation, status: Operation::WAITING, template: role_template
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 = RailsWorkflow::Operation.available_for_user(user)
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(RailsWorkflow::Operation.available_for_user(fake_user)).to eq []
105
+ expect(Operation.available_for_user(fake_user)).to eq []
155
106
 
156
107
  role_operation.assign user
157
- expect(RailsWorkflow::Operation.unassigned).to match_array [group_operation]
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) { process = create :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 RailsWorkflow::Operation::WAITING
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).to receive(:can_start?).and_return(true)
173
- allow_any_instance_of(RailsWorkflow::Process).to receive(:can_complete?).and_return(false)
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 RailsWorkflow::Operation::IN_PROGRESS
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
- it 'should not complete if child process is in progress'
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 = RailsWorkflow::ProcessManager.new
192
- allow_any_instance_of(RailsWorkflow::Operation).to receive(:manager).and_return(@manager)
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 RailsWorkflow::Operation::DONE
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 RailsWorkflow::Operation::SKIPPED
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 RailsWorkflow::Operation::CANCELED
177
+ expect(subject.status).to eq Status::CANCELED
211
178
  end
212
179
  end
213
180
  end