bumbleworks 0.0.92 → 0.0.93
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.
- checksums.yaml +4 -4
- data/README.md +2 -0
- data/lib/bumbleworks/entity.rb +5 -1
- data/lib/bumbleworks/participants/storage_participant.rb +9 -1
- data/lib/bumbleworks/task.rb +3 -1
- data/lib/bumbleworks/version.rb +1 -1
- data/lib/bumbleworks/worker.rb +16 -3
- data/spec/lib/bumbleworks/entity_spec.rb +1 -1
- data/spec/lib/bumbleworks/{participant → participants}/base_spec.rb +0 -0
- data/spec/lib/bumbleworks/{participant → participants}/entity_interactor_spec.rb +0 -0
- data/spec/lib/bumbleworks/{participant → participants}/error_dispatcher_spec.rb +0 -0
- data/spec/lib/bumbleworks/{participant → participants}/local_participant_spec.rb +0 -0
- data/spec/lib/bumbleworks/participants/storage_participant_spec.rb +39 -0
- data/spec/lib/bumbleworks/process_definition_spec.rb +1 -1
- data/spec/lib/bumbleworks/process_spec.rb +1 -1
- data/spec/lib/bumbleworks/storage_adapter_spec.rb +2 -2
- data/spec/lib/bumbleworks/task_spec.rb +118 -157
- data/spec/lib/bumbleworks/worker/info_spec.rb +5 -0
- data/spec/lib/bumbleworks/worker_spec.rb +54 -0
- metadata +12 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f902dbdee4b72458152553662a223f201f63f0c
|
4
|
+
data.tar.gz: f8f5690483301d7e49cd40f2c3105d95ad54cf8f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc5843ef1b0b19af4e4c56acef982dfb59b198415f2b20c2551181bf872688ee0a5c65fbfd3a444f961baf47daec5756c4fdcdd36271e532da6b353ace5023a1
|
7
|
+
data.tar.gz: e7a9d498569fe88c6c1d7c298d425959628530a5c26d38270f52acc68d3a33c1eabe50a0cf88db0759b2a361e3cfc60d0e0cd85b084aafde524577916098f4e7
|
data/README.md
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# Bumbleworks
|
2
2
|
|
3
|
+
[](http://badge.fury.io/rb/bumbleworks) [](https://travis-ci.org/bumbleworks/bumbleworks) [](https://codeclimate.com/github/bumbleworks/bumbleworks) [](https://gemnasium.com/bumbleworks/bumbleworks) [](http://inch-ci.org/github/bumbleworks/bumbleworks)
|
4
|
+
|
3
5
|
**NOTE**: This product is still pre-release, and implementation is *not* in sync with documentation yet - hence the pre-release version. We'll follow [the Semantic Versioning Specification (Semver)](http://semver.org/), so you can assume anything at 0.x.x still has an unstable API. But we *are* actively developing this.
|
4
6
|
|
5
7
|
Bumbleworks is a gem that adds a workflow engine (via [ruote](http://github.com/jmettraux/ruote)) to your Ruby application, and adds tools for task authorization and locking. It also establishes conventions for easily loading process definitions and registering participant classes based on configurable file locations.
|
data/lib/bumbleworks/entity.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Bumbleworks
|
2
2
|
module Entity
|
3
|
+
class ProcessNotRegistered < StandardError; end
|
4
|
+
|
3
5
|
def self.included(klass)
|
4
6
|
unless Bumbleworks.entity_classes.include? klass
|
5
7
|
Bumbleworks.entity_classes << klass
|
@@ -68,7 +70,9 @@ module Bumbleworks
|
|
68
70
|
end
|
69
71
|
|
70
72
|
def attribute_for_process_name(name)
|
71
|
-
self.class.processes[name]
|
73
|
+
process_config = self.class.processes[name]
|
74
|
+
raise ProcessNotRegistered.new(name) unless process_config
|
75
|
+
process_config && process_config[:attribute]
|
72
76
|
end
|
73
77
|
|
74
78
|
def tasks(nickname = nil)
|
@@ -2,8 +2,16 @@ module Bumbleworks
|
|
2
2
|
class StorageParticipant < ::Ruote::StorageParticipant
|
3
3
|
def on_workitem
|
4
4
|
return_value = super
|
5
|
-
|
5
|
+
trigger_on_dispatch
|
6
6
|
return return_value
|
7
7
|
end
|
8
|
+
|
9
|
+
def trigger_on_dispatch
|
10
|
+
Bumbleworks::Task.new(current_workitem).on_dispatch
|
11
|
+
end
|
12
|
+
|
13
|
+
def current_workitem
|
14
|
+
self[workitem.sid]
|
15
|
+
end
|
8
16
|
end
|
9
17
|
end
|
data/lib/bumbleworks/task.rb
CHANGED
@@ -124,7 +124,9 @@ module Bumbleworks
|
|
124
124
|
|
125
125
|
# proceed workitem (saving changes to fields)
|
126
126
|
def complete(metadata = {}, options = {})
|
127
|
-
|
127
|
+
unless completable? || options.fetch(:force, false)
|
128
|
+
raise NotCompletable.new(not_completable_error_message)
|
129
|
+
end
|
128
130
|
with_hooks(:update, metadata, options) do
|
129
131
|
with_hooks(:complete, metadata, options) do
|
130
132
|
proceed_workitem
|
data/lib/bumbleworks/version.rb
CHANGED
data/lib/bumbleworks/worker.rb
CHANGED
@@ -31,7 +31,7 @@ class Bumbleworks::Worker < Ruote::Worker
|
|
31
31
|
def active_worker_states
|
32
32
|
info.inject({}) { |hsh, info|
|
33
33
|
id, state = info.id, info.state
|
34
|
-
unless info.
|
34
|
+
unless info.in_stopped_state?
|
35
35
|
hsh[id] = state
|
36
36
|
end
|
37
37
|
hsh
|
@@ -60,10 +60,23 @@ class Bumbleworks::Worker < Ruote::Worker
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
def toggle_worker_state_enabled(switch)
|
64
|
+
unless [true, false].include?(switch)
|
65
|
+
raise ArgumentError, "Must call with true or false"
|
66
|
+
end
|
67
|
+
Bumbleworks.dashboard.context['worker_state_enabled'] = switch
|
68
|
+
end
|
69
|
+
|
70
|
+
def worker_state_enabled?
|
71
|
+
!!Bumbleworks.dashboard.context['worker_state_enabled']
|
72
|
+
end
|
73
|
+
|
63
74
|
def with_worker_state_enabled
|
64
|
-
|
75
|
+
was_already_enabled = worker_state_enabled?
|
76
|
+
toggle_worker_state_enabled(true) unless was_already_enabled
|
65
77
|
yield
|
66
|
-
|
78
|
+
ensure
|
79
|
+
toggle_worker_state_enabled(false) unless was_already_enabled
|
67
80
|
end
|
68
81
|
|
69
82
|
def control_document
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,39 @@
|
|
1
|
+
describe Bumbleworks::StorageParticipant do
|
2
|
+
let(:workitem) {
|
3
|
+
double(:sid => :storage_id, :to_h => {
|
4
|
+
'fei' => { 'wfid' => :the_workflow_id }
|
5
|
+
})
|
6
|
+
}
|
7
|
+
subject { described_class.new(Bumbleworks.dashboard.context) }
|
8
|
+
|
9
|
+
describe "#on_workitem" do
|
10
|
+
it "stores workitem and triggers on dispatch" do
|
11
|
+
expect(subject).to receive(:trigger_on_dispatch)
|
12
|
+
expect {
|
13
|
+
subject._on_workitem(workitem)
|
14
|
+
}.to change {
|
15
|
+
Bumbleworks.dashboard.context.storage.get_many("workitems").count
|
16
|
+
}.by(1)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "#trigger_on_dispatch" do
|
21
|
+
it "calls on_dispatch on a new Bumbleworks Task" do
|
22
|
+
allow(subject).to receive(:current_workitem).and_return(workitem)
|
23
|
+
new_task = double(Bumbleworks::Task)
|
24
|
+
expect(Bumbleworks::Task).to receive(:new).
|
25
|
+
with(workitem).
|
26
|
+
and_return(new_task)
|
27
|
+
expect(new_task).to receive(:on_dispatch)
|
28
|
+
subject.trigger_on_dispatch
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#current_workitem" do
|
33
|
+
it "reloads the workitem from the storage" do
|
34
|
+
allow(subject).to receive(:workitem).and_return(workitem)
|
35
|
+
allow(subject).to receive(:[]).with(:storage_id).and_return(:the_workitem)
|
36
|
+
expect(subject.current_workitem).to eq(:the_workitem)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -155,7 +155,7 @@ describe Bumbleworks::ProcessDefinition do
|
|
155
155
|
})
|
156
156
|
expect {
|
157
157
|
described_class.create_all_from_directory!(definitions_path)
|
158
|
-
}.to raise_error
|
158
|
+
}.to raise_error(described_class::Invalid)
|
159
159
|
expect(Bumbleworks.dashboard.variables['test_process']).to be_nil
|
160
160
|
expect(Bumbleworks.dashboard.variables['keep_me']).to eq('top_secret_cat_pics')
|
161
161
|
end
|
@@ -25,13 +25,13 @@ describe Bumbleworks::StorageAdapter do
|
|
25
25
|
|
26
26
|
describe '.storage_class' do
|
27
27
|
it 'is a subclass responsibility' do
|
28
|
-
expect { described_class.storage_class }.to raise_error
|
28
|
+
expect { described_class.storage_class }.to raise_error(StandardError, "Subclass responsibility")
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
describe '.driver' do
|
33
33
|
it 'is a subclass responsibility' do
|
34
|
-
expect { described_class.driver }.to raise_error
|
34
|
+
expect { described_class.driver }.to raise_error(StandardError, "Subclass responsibility")
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
@@ -1,8 +1,10 @@
|
|
1
1
|
describe Bumbleworks::Task do
|
2
|
+
subject { described_class.new(workflow_item) }
|
3
|
+
|
2
4
|
let(:workflow_item) {
|
3
5
|
Ruote::Workitem.new({
|
4
6
|
'fields' => {
|
5
|
-
'params' => {'task' => 'go_to_work'},
|
7
|
+
'params' => {'task' => 'go_to_work', 'claimant' => 'employee'},
|
6
8
|
'dispatched_at' => 'some time ago'
|
7
9
|
}
|
8
10
|
})
|
@@ -19,7 +21,6 @@ describe Bumbleworks::Task do
|
|
19
21
|
end
|
20
22
|
|
21
23
|
it_behaves_like "comparable" do
|
22
|
-
subject { described_class.new(workflow_item) }
|
23
24
|
let(:other) { described_class.new(workflow_item) }
|
24
25
|
before(:each) do
|
25
26
|
allow(workflow_item).to receive(:sid).and_return('blah-123-blah')
|
@@ -61,14 +62,13 @@ describe Bumbleworks::Task do
|
|
61
62
|
|
62
63
|
describe '#dispatched_at' do
|
63
64
|
it 'returns dispatched_at timestamp from workitem' do
|
64
|
-
|
65
|
-
expect(task.dispatched_at).to eq 'some time ago'
|
65
|
+
expect(subject.dispatched_at).to eq 'some time ago'
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
69
|
describe '#completable?' do
|
70
70
|
it 'defaults to true on base task' do
|
71
|
-
expect(
|
71
|
+
expect(subject).to be_completable
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -99,12 +99,11 @@ describe Bumbleworks::Task do
|
|
99
99
|
|
100
100
|
describe '#reload' do
|
101
101
|
it 'reloads the workitem from the storage participant' do
|
102
|
-
|
103
|
-
allow(task).to receive(:sid).and_return(:the_sid)
|
102
|
+
allow(subject).to receive(:sid).and_return(:the_sid)
|
104
103
|
expect(Bumbleworks.dashboard.storage_participant).to receive(
|
105
104
|
:[]).with(:the_sid).and_return(:amazing_workitem)
|
106
|
-
|
107
|
-
expect(
|
105
|
+
subject.reload
|
106
|
+
expect(subject.instance_variable_get(:@workitem)).to eq(:amazing_workitem)
|
108
107
|
end
|
109
108
|
end
|
110
109
|
|
@@ -113,89 +112,84 @@ describe Bumbleworks::Task do
|
|
113
112
|
it "calls #{phase} hooks on task and all observers" do
|
114
113
|
observer1, observer2 = double('observer1'), double('observer2')
|
115
114
|
Bumbleworks.observers = [observer1, observer2]
|
116
|
-
|
117
|
-
expect(task).to receive(:"#{phase}_snoogle").with(:chachunga, :faloop)
|
115
|
+
expect(subject).to receive(:"#{phase}_snoogle").with(:chachunga, :faloop)
|
118
116
|
expect(observer1).to receive(:"#{phase}_snoogle").with(:chachunga, :faloop)
|
119
117
|
expect(observer2).to receive(:"#{phase}_snoogle").with(:chachunga, :faloop)
|
120
|
-
|
118
|
+
subject.send(:"call_#{phase}_hooks", :snoogle, :chachunga, :faloop)
|
121
119
|
end
|
122
120
|
end
|
123
121
|
end
|
124
122
|
|
125
|
-
describe
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
123
|
+
describe "#log" do
|
124
|
+
it "creates a log entry with information from the task" do
|
125
|
+
allow(subject).to receive(:id).and_return(:the_id)
|
126
|
+
expect(Bumbleworks.logger).to receive(:info).with({
|
127
|
+
:actor => "employee",
|
128
|
+
:action => :did_a_thing,
|
129
|
+
:target_type => "Task",
|
130
|
+
:target_id => :the_id,
|
131
|
+
:metadata => {
|
132
|
+
:extra_stuff => "nothing special",
|
133
|
+
:current_fields => {
|
134
|
+
"params" => { "task" => "go_to_work", "claimant" => "employee" },
|
135
|
+
"dispatched_at" => "some time ago"
|
136
|
+
}
|
137
|
+
}
|
138
|
+
})
|
139
|
+
subject.log(:did_a_thing, :extra_stuff => "nothing special")
|
138
140
|
end
|
141
|
+
end
|
139
142
|
|
143
|
+
describe '#on_dispatch' do
|
140
144
|
it 'logs dispatch' do
|
141
|
-
|
142
|
-
|
143
|
-
task = described_class.for_role('horse_feeder').first
|
144
|
-
log_entry = Bumbleworks.logger.entries.last[:entry]
|
145
|
-
expect(log_entry[:action]).to eq(:dispatch)
|
146
|
-
expect(log_entry[:target_type]).to eq('Task')
|
147
|
-
expect(log_entry[:target_id]).to eq(task.id)
|
145
|
+
expect(subject).to receive(:log).with(:dispatch)
|
146
|
+
subject.on_dispatch
|
148
147
|
end
|
149
148
|
|
150
149
|
it 'calls after hooks' do
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
task.on_dispatch
|
150
|
+
allow(subject).to receive(:log)
|
151
|
+
expect(subject).to receive(:call_after_hooks).with(:dispatch)
|
152
|
+
subject.on_dispatch
|
155
153
|
end
|
156
154
|
end
|
157
155
|
|
158
156
|
describe '#extend_module' do
|
159
157
|
it 'extends with base module and task module' do
|
160
|
-
|
161
|
-
expect(
|
162
|
-
expect(
|
163
|
-
|
164
|
-
task.extend_module
|
158
|
+
expect(subject).to receive(:task_module).and_return(:task_module_double)
|
159
|
+
expect(subject).to receive(:extend).with(Bumbleworks::Task::Base).ordered
|
160
|
+
expect(subject).to receive(:extend).with(:task_module_double).ordered
|
161
|
+
subject.extend_module
|
165
162
|
end
|
166
163
|
|
167
164
|
it 'extends only with base module if no nickname' do
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
task.extend_module
|
165
|
+
allow(subject).to receive(:nickname).and_return(nil)
|
166
|
+
expect(subject).to receive(:extend).with(Bumbleworks::Task::Base)
|
167
|
+
subject.extend_module
|
172
168
|
end
|
173
169
|
|
174
170
|
it 'extends only with base module if task module does not exist' do
|
175
|
-
|
176
|
-
|
177
|
-
task.extend_module
|
171
|
+
expect(subject).to receive(:extend).with(Bumbleworks::Task::Base)
|
172
|
+
subject.extend_module
|
178
173
|
end
|
179
174
|
end
|
180
175
|
|
181
176
|
describe '#task_module' do
|
182
177
|
it 'returns nil if no nickname' do
|
183
|
-
|
184
|
-
|
185
|
-
expect(task.task_module).to be_nil
|
178
|
+
allow(subject).to receive(:nickname).and_return(nil)
|
179
|
+
expect(subject.task_module).to be_nil
|
186
180
|
end
|
187
181
|
|
188
182
|
it 'returns constantized task nickname with "Task" appended' do
|
189
|
-
|
183
|
+
subject
|
190
184
|
allow(Bumbleworks::Support).to receive(:constantize).with("GoToWorkTask").and_return(:the_task_module)
|
191
|
-
expect(
|
185
|
+
expect(subject.task_module).to eq(:the_task_module)
|
192
186
|
end
|
193
187
|
end
|
194
188
|
|
195
189
|
describe '#id' do
|
196
190
|
it 'returns the sid from the workitem' do
|
197
191
|
allow(workflow_item).to receive(:sid).and_return(:an_exciting_id)
|
198
|
-
expect(
|
192
|
+
expect(subject.id).to eq(:an_exciting_id)
|
199
193
|
end
|
200
194
|
end
|
201
195
|
|
@@ -620,7 +614,6 @@ describe Bumbleworks::Task do
|
|
620
614
|
end
|
621
615
|
|
622
616
|
describe '#[], #[]=' do
|
623
|
-
subject{described_class.new(workflow_item)}
|
624
617
|
it 'sets values on workitem fields' do
|
625
618
|
subject['hive'] = 'bees at work'
|
626
619
|
expect(workflow_item.fields['hive']).to eq('bees at work')
|
@@ -634,14 +627,13 @@ describe Bumbleworks::Task do
|
|
634
627
|
|
635
628
|
describe '#nickname' do
|
636
629
|
it 'returns the "task" param' do
|
637
|
-
expect(
|
630
|
+
expect(subject.nickname).to eq('go_to_work')
|
638
631
|
end
|
639
632
|
|
640
633
|
it 'is immutable; cannot be changed by modifying the param' do
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
expect(task.nickname).to eq('go_to_work')
|
634
|
+
expect(subject.nickname).to eq('go_to_work')
|
635
|
+
subject.params['task'] = 'what_is_wrong_with_you?'
|
636
|
+
expect(subject.nickname).to eq('go_to_work')
|
645
637
|
end
|
646
638
|
end
|
647
639
|
|
@@ -779,27 +771,25 @@ describe Bumbleworks::Task do
|
|
779
771
|
end
|
780
772
|
|
781
773
|
it 'calls before_claim and after_claim callbacks' do
|
782
|
-
|
783
|
-
|
784
|
-
expect(
|
785
|
-
expect(
|
786
|
-
|
787
|
-
task.claim(:doctor_claim)
|
774
|
+
allow(subject).to receive(:log)
|
775
|
+
expect(subject).to receive(:before_claim).with(:doctor_claim).ordered
|
776
|
+
expect(subject).to receive(:set_claimant).ordered
|
777
|
+
expect(subject).to receive(:after_claim).with(:doctor_claim).ordered
|
778
|
+
subject.claim(:doctor_claim)
|
788
779
|
end
|
789
780
|
|
790
781
|
it 'skips callbacks if requested' do
|
791
|
-
|
792
|
-
|
793
|
-
expect(
|
794
|
-
expect(
|
795
|
-
|
796
|
-
task.claim(:doctor_claim, :skip_callbacks => true)
|
782
|
+
allow(subject).to receive(:log)
|
783
|
+
expect(subject).to receive(:before_claim).never
|
784
|
+
expect(subject).to receive(:set_claimant)
|
785
|
+
expect(subject).to receive(:after_claim).never
|
786
|
+
subject.claim(:doctor_claim, :skip_callbacks => true)
|
797
787
|
end
|
798
788
|
|
799
789
|
it 'logs event' do
|
800
|
-
|
801
|
-
expect(
|
802
|
-
|
790
|
+
@task.release
|
791
|
+
expect(@task).to receive(:log).with(:claim)
|
792
|
+
@task.claim(:whatever)
|
803
793
|
end
|
804
794
|
end
|
805
795
|
|
@@ -853,10 +843,8 @@ describe Bumbleworks::Task do
|
|
853
843
|
end
|
854
844
|
|
855
845
|
it 'logs event' do
|
846
|
+
expect(@task).to receive(:log).with(:release)
|
856
847
|
@task.release
|
857
|
-
log_entry = Bumbleworks.logger.entries.last[:entry]
|
858
|
-
expect(log_entry[:action]).to eq(:release)
|
859
|
-
expect(log_entry[:actor]).to eq('boss')
|
860
848
|
end
|
861
849
|
end
|
862
850
|
end
|
@@ -883,21 +871,19 @@ describe Bumbleworks::Task do
|
|
883
871
|
end
|
884
872
|
|
885
873
|
it 'calls with hooks' do
|
886
|
-
|
887
|
-
|
888
|
-
expect(
|
889
|
-
expect(
|
890
|
-
|
891
|
-
task.update(:argue_mints)
|
874
|
+
allow(subject).to receive(:log)
|
875
|
+
expect(subject).to receive(:call_before_hooks).with(:update, :argue_mints).ordered
|
876
|
+
expect(subject).to receive(:update_workitem).ordered
|
877
|
+
expect(subject).to receive(:call_after_hooks).with(:update, :argue_mints).ordered
|
878
|
+
subject.update(:argue_mints)
|
892
879
|
end
|
893
880
|
|
894
881
|
it 'skips callbacks if requested' do
|
895
|
-
|
896
|
-
|
897
|
-
expect(
|
898
|
-
expect(
|
899
|
-
|
900
|
-
task.update({:actual => :params}, {:skip_callbacks => true})
|
882
|
+
allow(subject).to receive(:log)
|
883
|
+
expect(subject).to receive(:call_before_hooks).never
|
884
|
+
expect(subject).to receive(:update_workitem)
|
885
|
+
expect(subject).to receive(:call_after_hooks).never
|
886
|
+
subject.update({:actual => :params}, {:skip_callbacks => true})
|
901
887
|
end
|
902
888
|
|
903
889
|
it 'reloads after updating workitem' do
|
@@ -913,19 +899,8 @@ describe Bumbleworks::Task do
|
|
913
899
|
event = Bumbleworks.dashboard.wait_for :dog_mouth
|
914
900
|
task = described_class.for_role('dog_mouth').first
|
915
901
|
task.params['claimant'] = :some_user
|
902
|
+
expect(task).to receive(:log).with(:update, :extra_data => :fancy)
|
916
903
|
task.update(:extra_data => :fancy)
|
917
|
-
expect(Bumbleworks.logger.entries.last).to eq({
|
918
|
-
:level => :info, :entry => {
|
919
|
-
:actor => "some_user", # claimant is a string after #reload
|
920
|
-
:action => :update,
|
921
|
-
:target_type => 'Task',
|
922
|
-
:target_id => task.id,
|
923
|
-
:metadata => {
|
924
|
-
:extra_data => :fancy,
|
925
|
-
:current_fields => task.fields
|
926
|
-
}
|
927
|
-
}
|
928
|
-
})
|
929
904
|
end
|
930
905
|
end
|
931
906
|
|
@@ -959,43 +934,38 @@ describe Bumbleworks::Task do
|
|
959
934
|
expect(described_class.for_role('dog_mouth')).not_to be_empty
|
960
935
|
end
|
961
936
|
|
937
|
+
it 'allows completion for non-completable tasks if given force option' do
|
938
|
+
event = Bumbleworks.dashboard.wait_for :dog_mouth
|
939
|
+
task = described_class.for_role('dog_mouth').first
|
940
|
+
allow(task).to receive(:completable?).and_return(false)
|
941
|
+
expect(task).to receive(:proceed_workitem)
|
942
|
+
task.complete({:actual => :params}, {:force => true})
|
943
|
+
end
|
944
|
+
|
962
945
|
it 'calls update and complete callbacks' do
|
963
|
-
|
964
|
-
|
965
|
-
expect(
|
966
|
-
expect(
|
967
|
-
expect(
|
968
|
-
expect(
|
969
|
-
|
970
|
-
task.complete(:argue_mints)
|
946
|
+
allow(subject).to receive(:log)
|
947
|
+
expect(subject).to receive(:call_before_hooks).with(:update, :argue_mints).ordered
|
948
|
+
expect(subject).to receive(:call_before_hooks).with(:complete, :argue_mints).ordered
|
949
|
+
expect(subject).to receive(:proceed_workitem).ordered
|
950
|
+
expect(subject).to receive(:call_after_hooks).with(:complete, :argue_mints).ordered
|
951
|
+
expect(subject).to receive(:call_after_hooks).with(:update, :argue_mints).ordered
|
952
|
+
subject.complete(:argue_mints)
|
971
953
|
end
|
972
954
|
|
973
955
|
it 'skips callbacks if requested' do
|
974
|
-
|
975
|
-
|
976
|
-
expect(
|
977
|
-
expect(
|
978
|
-
|
979
|
-
task.complete({:actual => :params}, {:skip_callbacks => true})
|
956
|
+
allow(subject).to receive(:log)
|
957
|
+
expect(subject).to receive(:call_before_hooks).never
|
958
|
+
expect(subject).to receive(:proceed_workitem)
|
959
|
+
expect(subject).to receive(:call_after_hooks).never
|
960
|
+
subject.complete({:actual => :params}, {:skip_callbacks => true})
|
980
961
|
end
|
981
962
|
|
982
963
|
it 'logs event' do
|
983
964
|
event = Bumbleworks.dashboard.wait_for :dog_mouth
|
984
965
|
task = described_class.for_role('dog_mouth').first
|
985
966
|
task.params['claimant'] = :some_user
|
967
|
+
expect(task).to receive(:log).with(:complete, :extra_data => :fancy)
|
986
968
|
task.complete(:extra_data => :fancy)
|
987
|
-
expect(Bumbleworks.logger.entries.last).to eq({
|
988
|
-
:level => :info, :entry => {
|
989
|
-
:actor => :some_user,
|
990
|
-
:action => :complete,
|
991
|
-
:target_type => 'Task',
|
992
|
-
:target_id => task.id,
|
993
|
-
:metadata => {
|
994
|
-
:extra_data => :fancy,
|
995
|
-
:current_fields => task.fields
|
996
|
-
}
|
997
|
-
}
|
998
|
-
})
|
999
969
|
end
|
1000
970
|
end
|
1001
971
|
end
|
@@ -1080,7 +1050,7 @@ describe Bumbleworks::Task do
|
|
1080
1050
|
it 'falls back to method missing if no finder method' do
|
1081
1051
|
expect {
|
1082
1052
|
described_class.kerplunk!(:oh_no)
|
1083
|
-
}.to raise_error
|
1053
|
+
}.to raise_error(NoMethodError)
|
1084
1054
|
end
|
1085
1055
|
end
|
1086
1056
|
|
@@ -1122,64 +1092,55 @@ describe Bumbleworks::Task do
|
|
1122
1092
|
|
1123
1093
|
describe '#humanize' do
|
1124
1094
|
it "returns humanized version of task name when no entity" do
|
1125
|
-
|
1126
|
-
expect(task.humanize).to eq('Go to work')
|
1095
|
+
expect(subject.humanize).to eq('Go to work')
|
1127
1096
|
end
|
1128
1097
|
|
1129
1098
|
it "returns humanized version of task name with entity" do
|
1130
|
-
|
1131
|
-
|
1132
|
-
|
1133
|
-
expect(task.humanize).to eq('Go to work: Rhubarb sandwich 45')
|
1099
|
+
subject[:entity_id] = '45'
|
1100
|
+
subject[:entity_type] = 'RhubarbSandwich'
|
1101
|
+
expect(subject.humanize).to eq('Go to work: Rhubarb sandwich 45')
|
1134
1102
|
end
|
1135
1103
|
|
1136
1104
|
it "returns humanized version of task name without entity if requested" do
|
1137
|
-
|
1138
|
-
|
1139
|
-
|
1140
|
-
expect(task.humanize(:entity => false)).to eq('Go to work')
|
1105
|
+
subject[:entity_id] = '45'
|
1106
|
+
subject[:entity_type] = 'RhubarbSandwich'
|
1107
|
+
expect(subject.humanize(:entity => false)).to eq('Go to work')
|
1141
1108
|
end
|
1142
1109
|
end
|
1143
1110
|
|
1144
1111
|
describe '#to_s' do
|
1145
1112
|
it "is aliased to #titleize" do
|
1146
|
-
|
1147
|
-
|
1148
|
-
expect(task.to_s(:the_args)).to eq(:see_i_told_you_so)
|
1113
|
+
allow(subject).to receive(:titleize).with(:the_args).and_return(:see_i_told_you_so)
|
1114
|
+
expect(subject.to_s(:the_args)).to eq(:see_i_told_you_so)
|
1149
1115
|
end
|
1150
1116
|
end
|
1151
1117
|
|
1152
1118
|
describe '#titleize' do
|
1153
1119
|
it "returns titleized version of task name when no entity" do
|
1154
|
-
|
1155
|
-
expect(task.titleize).to eq('Go To Work')
|
1120
|
+
expect(subject.titleize).to eq('Go To Work')
|
1156
1121
|
end
|
1157
1122
|
|
1158
1123
|
it "returns titleized version of task name with entity" do
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
expect(task.titleize).to eq('Go To Work: Rhubarb Sandwich 45')
|
1124
|
+
subject[:entity_id] = '45'
|
1125
|
+
subject[:entity_type] = 'RhubarbSandwich'
|
1126
|
+
expect(subject.titleize).to eq('Go To Work: Rhubarb Sandwich 45')
|
1163
1127
|
end
|
1164
1128
|
|
1165
1129
|
it "returns titleized version of task name without entity if requested" do
|
1166
|
-
|
1167
|
-
|
1168
|
-
|
1169
|
-
expect(task.titleize(:entity => false)).to eq('Go To Work')
|
1130
|
+
subject[:entity_id] = '45'
|
1131
|
+
subject[:entity_type] = 'RhubarbSandwich'
|
1132
|
+
expect(subject.titleize(:entity => false)).to eq('Go To Work')
|
1170
1133
|
end
|
1171
1134
|
end
|
1172
1135
|
|
1173
1136
|
describe '#temporary_storage' do
|
1174
1137
|
it 'returns an empty hash by default' do
|
1175
|
-
|
1176
|
-
expect(task.temporary_storage).to eq({})
|
1138
|
+
expect(subject.temporary_storage).to eq({})
|
1177
1139
|
end
|
1178
1140
|
|
1179
1141
|
it 'persists stored values' do
|
1180
|
-
|
1181
|
-
|
1182
|
-
expect(task.temporary_storage[:foo]).to eq(:bar)
|
1142
|
+
subject.temporary_storage[:foo] = :bar
|
1143
|
+
expect(subject.temporary_storage[:foo]).to eq(:bar)
|
1183
1144
|
end
|
1184
1145
|
end
|
1185
1146
|
|
@@ -202,6 +202,11 @@ describe Bumbleworks::Worker::Info do
|
|
202
202
|
allow(subject).to receive(:updated_at).and_return(frozen_time - 3)
|
203
203
|
expect(subject).not_to be_updated_since(frozen_time - 2)
|
204
204
|
end
|
205
|
+
|
206
|
+
it "returns true if updated_at same as given time" do
|
207
|
+
allow(subject).to receive(:updated_at).and_return(frozen_time - 3)
|
208
|
+
expect(subject).to be_updated_since(frozen_time - 3)
|
209
|
+
end
|
205
210
|
end
|
206
211
|
|
207
212
|
describe "#updated_recently?" do
|
@@ -73,6 +73,25 @@ describe Bumbleworks::Worker do
|
|
73
73
|
described_class.refresh_worker_info
|
74
74
|
}.not_to raise_error
|
75
75
|
end
|
76
|
+
|
77
|
+
it 'return worker state enabled setting to off' do
|
78
|
+
expect(described_class.worker_state_enabled?).to eq(false)
|
79
|
+
described_class.refresh_worker_info
|
80
|
+
expect(described_class.worker_state_enabled?).to eq(false)
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when worker state enabled setting is already on" do
|
84
|
+
after(:each) do
|
85
|
+
described_class.toggle_worker_state_enabled(false)
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'leaves setting on' do
|
89
|
+
described_class.toggle_worker_state_enabled(true)
|
90
|
+
expect(described_class.worker_state_enabled?).to eq(true)
|
91
|
+
described_class.refresh_worker_info
|
92
|
+
expect(described_class.worker_state_enabled?).to eq(true)
|
93
|
+
end
|
94
|
+
end
|
76
95
|
end
|
77
96
|
|
78
97
|
describe '.change_worker_state' do
|
@@ -106,6 +125,41 @@ describe Bumbleworks::Worker do
|
|
106
125
|
described_class.change_worker_state('paused')
|
107
126
|
}.not_to raise_error
|
108
127
|
end
|
128
|
+
|
129
|
+
it 'return worker state enabled setting to off' do
|
130
|
+
expect(described_class.worker_state_enabled?).to eq(false)
|
131
|
+
described_class.change_worker_state('paused')
|
132
|
+
expect(described_class.worker_state_enabled?).to eq(false)
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when worker state enabled setting is already on" do
|
136
|
+
after(:each) do
|
137
|
+
described_class.toggle_worker_state_enabled(false)
|
138
|
+
end
|
139
|
+
|
140
|
+
it 'leaves setting on' do
|
141
|
+
described_class.toggle_worker_state_enabled(true)
|
142
|
+
expect(described_class.worker_state_enabled?).to eq(true)
|
143
|
+
described_class.change_worker_state('paused')
|
144
|
+
expect(described_class.worker_state_enabled?).to eq(true)
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
describe ".toggle_worker_state_enabled" do
|
151
|
+
it "turns on or off worker_state_enabled setting" do
|
152
|
+
expect(described_class.worker_state_enabled?).to eq(false)
|
153
|
+
described_class.toggle_worker_state_enabled(true)
|
154
|
+
expect(described_class.worker_state_enabled?).to eq(true)
|
155
|
+
described_class.toggle_worker_state_enabled(false)
|
156
|
+
expect(described_class.worker_state_enabled?).to eq(false)
|
157
|
+
end
|
158
|
+
|
159
|
+
it "raises exception if given non-Boolean argument" do
|
160
|
+
expect {
|
161
|
+
described_class.toggle_worker_state_enabled(:horse)
|
162
|
+
}.to raise_error(ArgumentError)
|
109
163
|
end
|
110
164
|
end
|
111
165
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bumbleworks
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.93
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maher Hawash
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2015-
|
14
|
+
date: 2015-09-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: ruote
|
@@ -219,11 +219,12 @@ files:
|
|
219
219
|
- spec/lib/bumbleworks/error_logger_spec.rb
|
220
220
|
- spec/lib/bumbleworks/expression_spec.rb
|
221
221
|
- spec/lib/bumbleworks/hash_storage_spec.rb
|
222
|
-
- spec/lib/bumbleworks/participant/base_spec.rb
|
223
|
-
- spec/lib/bumbleworks/participant/entity_interactor_spec.rb
|
224
|
-
- spec/lib/bumbleworks/participant/error_dispatcher_spec.rb
|
225
|
-
- spec/lib/bumbleworks/participant/local_participant_spec.rb
|
226
222
|
- spec/lib/bumbleworks/participant_registration_spec.rb
|
223
|
+
- spec/lib/bumbleworks/participants/base_spec.rb
|
224
|
+
- spec/lib/bumbleworks/participants/entity_interactor_spec.rb
|
225
|
+
- spec/lib/bumbleworks/participants/error_dispatcher_spec.rb
|
226
|
+
- spec/lib/bumbleworks/participants/local_participant_spec.rb
|
227
|
+
- spec/lib/bumbleworks/participants/storage_participant_spec.rb
|
227
228
|
- spec/lib/bumbleworks/process/error_record_spec.rb
|
228
229
|
- spec/lib/bumbleworks/process_definition_spec.rb
|
229
230
|
- spec/lib/bumbleworks/process_spec.rb
|
@@ -308,11 +309,12 @@ test_files:
|
|
308
309
|
- spec/lib/bumbleworks/error_logger_spec.rb
|
309
310
|
- spec/lib/bumbleworks/expression_spec.rb
|
310
311
|
- spec/lib/bumbleworks/hash_storage_spec.rb
|
311
|
-
- spec/lib/bumbleworks/participant/base_spec.rb
|
312
|
-
- spec/lib/bumbleworks/participant/entity_interactor_spec.rb
|
313
|
-
- spec/lib/bumbleworks/participant/error_dispatcher_spec.rb
|
314
|
-
- spec/lib/bumbleworks/participant/local_participant_spec.rb
|
315
312
|
- spec/lib/bumbleworks/participant_registration_spec.rb
|
313
|
+
- spec/lib/bumbleworks/participants/base_spec.rb
|
314
|
+
- spec/lib/bumbleworks/participants/entity_interactor_spec.rb
|
315
|
+
- spec/lib/bumbleworks/participants/error_dispatcher_spec.rb
|
316
|
+
- spec/lib/bumbleworks/participants/local_participant_spec.rb
|
317
|
+
- spec/lib/bumbleworks/participants/storage_participant_spec.rb
|
316
318
|
- spec/lib/bumbleworks/process/error_record_spec.rb
|
317
319
|
- spec/lib/bumbleworks/process_definition_spec.rb
|
318
320
|
- spec/lib/bumbleworks/process_spec.rb
|