call_center 0.0.7 → 0.0.8
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.
- data/VERSION +1 -1
- data/call_center.gemspec +2 -1
- data/lib/call_center.rb +5 -0
- data/lib/call_center/deferred_callbacks.rb +37 -0
- data/lib/call_center/flow_callback.rb +8 -1
- data/lib/call_center/state_machine_ext.rb +1 -1
- data/lib/call_center/test/dsl.rb +10 -0
- data/lib/call_center/test/minitest/dsl.rb +5 -0
- data/test/call_center_test.rb +90 -0
- metadata +4 -3
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
data/call_center.gemspec
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{call_center}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Henry Hsu"]
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
"init.rb",
|
32
32
|
"lib/call_center.rb",
|
33
33
|
"lib/call_center/core_ext/object_instance_exec.rb",
|
34
|
+
"lib/call_center/deferred_callbacks.rb",
|
34
35
|
"lib/call_center/flow_callback.rb",
|
35
36
|
"lib/call_center/state_machine_ext.rb",
|
36
37
|
"lib/call_center/test/dsl.rb",
|
data/lib/call_center.rb
CHANGED
@@ -2,6 +2,7 @@ require 'call_center/core_ext/object_instance_exec'
|
|
2
2
|
require 'state_machine'
|
3
3
|
require 'call_center/state_machine_ext'
|
4
4
|
require 'call_center/flow_callback'
|
5
|
+
require 'call_center/deferred_callbacks'
|
5
6
|
|
6
7
|
module CallCenter
|
7
8
|
def self.included(base)
|
@@ -75,6 +76,10 @@ module CallCenter
|
|
75
76
|
self.class.state_machines[state_machine_name]
|
76
77
|
end
|
77
78
|
|
79
|
+
def call_flow_state_machine_name
|
80
|
+
self.class.call_flow_state_machine_name
|
81
|
+
end
|
82
|
+
|
78
83
|
def current_state(state_machine_name)
|
79
84
|
send(state_machine_name).to_sym
|
80
85
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module CallCenter
|
2
|
+
module DeferredCallbacks
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
attr_accessor :call_flow_dfd_callbacks
|
6
|
+
|
7
|
+
def call_flow_callbacks_deferred?
|
8
|
+
true
|
9
|
+
end
|
10
|
+
|
11
|
+
def call_flow_defer_callback(callback, transition)
|
12
|
+
@call_flow_dfd_callbacks ||= {}
|
13
|
+
@call_flow_dfd_callbacks[call_flow_state_machine_name] ||= {}
|
14
|
+
@call_flow_dfd_callbacks[call_flow_state_machine_name][:before_transition] ||= []
|
15
|
+
@call_flow_dfd_callbacks[call_flow_state_machine_name][:after_transition] ||= []
|
16
|
+
@call_flow_dfd_callbacks[call_flow_state_machine_name][:after_failure] ||= []
|
17
|
+
|
18
|
+
|
19
|
+
@call_flow_dfd_callbacks[call_flow_state_machine_name][:before_transition] << [callback, transition] if callback.before
|
20
|
+
@call_flow_dfd_callbacks[call_flow_state_machine_name][:after_transition] << [callback, transition] if callback.after && callback.success
|
21
|
+
@call_flow_dfd_callbacks[call_flow_state_machine_name][:after_failure] << [callback, transition] if callback.after && callback.failure
|
22
|
+
end
|
23
|
+
|
24
|
+
def call_flow_run_deferred(group)
|
25
|
+
return unless all_callbacks = @call_flow_dfd_callbacks
|
26
|
+
return unless callbacks_groups = @call_flow_dfd_callbacks[call_flow_state_machine_name]
|
27
|
+
return unless callbacks = callbacks_groups[group]
|
28
|
+
callbacks.each do |set|
|
29
|
+
callback, transition = set
|
30
|
+
callback.run(self, transition)
|
31
|
+
end
|
32
|
+
callbacks_groups[group] = []
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -24,10 +24,17 @@ module CallCenter
|
|
24
24
|
flow.instance_exec(transition, &block) if should_run?
|
25
25
|
end
|
26
26
|
|
27
|
+
def run_deferred?(call, transition)
|
28
|
+
if call.respond_to?(:call_flow_callbacks_deferred?) && call.call_flow_callbacks_deferred?
|
29
|
+
call.call_flow_defer_callback(self, transition)
|
30
|
+
true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
27
34
|
def setup(context)
|
28
35
|
callback = self
|
29
36
|
context.send(transition_hook, transition_parameters(context)) do |call, transition|
|
30
|
-
callback.run(call, transition)
|
37
|
+
callback.run(call, transition) unless callback.run_deferred?(call, transition)
|
31
38
|
end
|
32
39
|
end
|
33
40
|
|
@@ -48,7 +48,7 @@ class StateMachine::Machine
|
|
48
48
|
event_names.each do |event_name|
|
49
49
|
after_failure :on => event_name do |call, transition|
|
50
50
|
callbacks = @callback_blocks.select { |callback| callback.after && callback.state_name == transition.to_name && callback.failure } || []
|
51
|
-
callbacks.each { |callback| callback.run(call, transition) }
|
51
|
+
callbacks.each { |callback| callback.run(call, transition) unless callback.run_deferred?(call, transition) }
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
data/lib/call_center/test/dsl.rb
CHANGED
@@ -31,6 +31,11 @@ module CallCenter
|
|
31
31
|
@call.send(:"#{state_field}=", from.to_s)
|
32
32
|
@call.send(:"#{event}")
|
33
33
|
assert_equal to, @call.send(:"#{state_field}_name"), "status should be :#{to}, not :#{@call.send(state_field)}"
|
34
|
+
if @call.respond_to?(:call_flow_run_deferred)
|
35
|
+
@call.call_flow_run_deferred(:before_transition)
|
36
|
+
@call.call_flow_run_deferred(:after_transition)
|
37
|
+
@call.call_flow_run_deferred(:after_failure)
|
38
|
+
end
|
34
39
|
end
|
35
40
|
|
36
41
|
if block.present?
|
@@ -40,6 +45,11 @@ module CallCenter
|
|
40
45
|
@call.send(:"#{state_field}=", from.to_s)
|
41
46
|
@call.send(:"#{event}")
|
42
47
|
body(@call.render) if @call.respond_to?(:render)
|
48
|
+
if @call.respond_to?(:call_flow_run_deferred)
|
49
|
+
@call.call_flow_run_deferred(:before_transition)
|
50
|
+
@call.call_flow_run_deferred(:after_transition)
|
51
|
+
@call.call_flow_run_deferred(:after_failure)
|
52
|
+
end
|
43
53
|
end
|
44
54
|
|
45
55
|
self.instance_eval(&block)
|
@@ -130,6 +130,11 @@ module CallCenter
|
|
130
130
|
subject.send(:"#{state_field}=", from)
|
131
131
|
subject.send(:"#{event}!")
|
132
132
|
subject.send(state_field).must_equal(to)
|
133
|
+
if subject.respond_to?(:call_flow_run_deferred)
|
134
|
+
subject.call_flow_run_deferred(:before_transition)
|
135
|
+
subject.call_flow_run_deferred(:after_transition)
|
136
|
+
subject.call_flow_run_deferred(:after_failure)
|
137
|
+
end
|
133
138
|
end
|
134
139
|
end
|
135
140
|
|
data/test/call_center_test.rb
CHANGED
@@ -166,6 +166,54 @@ class CallCenterTest < Test::Unit::TestCase
|
|
166
166
|
@call.customer_end!
|
167
167
|
end
|
168
168
|
|
169
|
+
should "defer callbacks" do
|
170
|
+
(class << @call; self; end).class_eval do
|
171
|
+
include CallCenter::DeferredCallbacks
|
172
|
+
end
|
173
|
+
@call.state = 'cancelled'
|
174
|
+
|
175
|
+
@call.expects(:notify).with(:before_always).never
|
176
|
+
@call.expects(:notify).with(:before_always_uniq).never
|
177
|
+
|
178
|
+
@call.expects(:notify).with(:after_always).never
|
179
|
+
@call.expects(:notify).with(:after_success).never
|
180
|
+
@call.expects(:notify).with(:after_failure).never
|
181
|
+
|
182
|
+
@call.expects(:notify).with(:after_always_uniq).never
|
183
|
+
@call.expects(:notify).with(:after_success_uniq, anything).never
|
184
|
+
|
185
|
+
@call.customer_end!
|
186
|
+
assert(!@call.customer_hangs_up)
|
187
|
+
|
188
|
+
# Ready for deferred callbacks
|
189
|
+
|
190
|
+
seq = sequence('callback_sequence')
|
191
|
+
|
192
|
+
@call.expects(:notify).with(:before_always)
|
193
|
+
@call.expects(:notify).with(:before_always_uniq)
|
194
|
+
|
195
|
+
@call.call_flow_run_deferred(:before_transition)
|
196
|
+
|
197
|
+
@call.expects(:notify).with(:after_always).times(2)
|
198
|
+
@call.expects(:notify).with(:after_success)
|
199
|
+
|
200
|
+
@call.expects(:notify).with(:after_always_uniq)
|
201
|
+
@call.expects(:notify).with(:after_success_uniq, anything)
|
202
|
+
|
203
|
+
@call.call_flow_run_deferred(:after_transition)
|
204
|
+
|
205
|
+
@call.expects(:notify).with(:after_always).times(2)
|
206
|
+
@call.expects(:notify).with(:after_failure)
|
207
|
+
@call.expects(:notify).with(:after_always_uniq)
|
208
|
+
|
209
|
+
@call.call_flow_run_deferred(:after_failure)
|
210
|
+
|
211
|
+
# Empty
|
212
|
+
@call.call_flow_run_deferred(:before_transition)
|
213
|
+
@call.call_flow_run_deferred(:after_transition)
|
214
|
+
@call.call_flow_run_deferred(:after_failure)
|
215
|
+
end
|
216
|
+
|
169
217
|
should "asynchronously perform event" do
|
170
218
|
@call.stubs(:agents_available?).returns(true)
|
171
219
|
@call.incoming_call!
|
@@ -228,6 +276,48 @@ class CallCenterTest < Test::Unit::TestCase
|
|
228
276
|
end
|
229
277
|
end
|
230
278
|
end
|
279
|
+
|
280
|
+
context "deferred and using test DSL:" do
|
281
|
+
setup do
|
282
|
+
(class << @call; self; end).class_eval do
|
283
|
+
include CallCenter::DeferredCallbacks
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
should_flow :on => :incoming_call, :initial => :voicemail, :when => Proc.new {
|
288
|
+
@call.stubs(:agents_available?).returns(false)
|
289
|
+
@call.stubs(:notify)
|
290
|
+
@call.stubs(:customer).returns('the_flow')
|
291
|
+
} do
|
292
|
+
should_also { assert_received(@call, :notify) { |e| e.with(:rendering_voicemail) } }
|
293
|
+
and_also { assert_received(@call, :customer) { |e| e.with(:voicemail_complete) } }
|
294
|
+
and_render { "Response>Say" }
|
295
|
+
and_render { "Response>Record[action=the_flow]" }
|
296
|
+
end
|
297
|
+
|
298
|
+
should_flow :on => :incoming_call, :initial => :routing, :when => Proc.new {
|
299
|
+
@call.stubs(:agents_available?).returns(true)
|
300
|
+
} do
|
301
|
+
should_render { "Response" }
|
302
|
+
end
|
303
|
+
|
304
|
+
should_flow :on => :customer_hangs_up, :routing => :cancelled, :when => Proc.new {
|
305
|
+
@call.stubs(:notify)
|
306
|
+
} do
|
307
|
+
should_also { assert_received(@call, :notify) { |e| e.with(:cancelled).once } }
|
308
|
+
and_also { assert @call.cancelled? }
|
309
|
+
|
310
|
+
should_flow :on => :customer_hangs_up, :cancelled => :cancelled do
|
311
|
+
should_also { assert_received(@call, :notify) { |e| e.with(:cancelled).once } } # For above
|
312
|
+
and_also { assert @call.cancelled? }
|
313
|
+
|
314
|
+
should_flow :on => :customer_hangs_up, :cancelled => :cancelled do
|
315
|
+
should_also { assert_received(@call, :notify) { |e| e.with(:cancelled).once } } # For above
|
316
|
+
and_also { assert @call.cancelled? }
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
231
321
|
end
|
232
322
|
|
233
323
|
context "non-standard call" do
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: call_center
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 15
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Henry Hsu
|
@@ -276,6 +276,7 @@ files:
|
|
276
276
|
- init.rb
|
277
277
|
- lib/call_center.rb
|
278
278
|
- lib/call_center/core_ext/object_instance_exec.rb
|
279
|
+
- lib/call_center/deferred_callbacks.rb
|
279
280
|
- lib/call_center/flow_callback.rb
|
280
281
|
- lib/call_center/state_machine_ext.rb
|
281
282
|
- lib/call_center/test/dsl.rb
|