rails_workflow 0.3.9 → 0.4.0

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.
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