call_center 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
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