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 CHANGED
@@ -1 +1 @@
1
- 0.0.7
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.7"
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
@@ -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
 
@@ -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: 17
4
+ hash: 15
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 7
10
- version: 0.0.7
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