punchblock 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +3 -3
- data/CHANGELOG.md +23 -0
- data/lib/punchblock.rb +24 -0
- data/lib/punchblock/command/reject.rb +10 -2
- data/lib/punchblock/component/record.rb +16 -0
- data/lib/punchblock/core_ext/blather/stanza.rb +3 -1
- data/lib/punchblock/dead_actor_safety.rb +9 -0
- data/lib/punchblock/event/complete.rb +9 -11
- data/lib/punchblock/rayo_node.rb +4 -0
- data/lib/punchblock/translator/asterisk.rb +65 -22
- data/lib/punchblock/translator/asterisk/call.rb +49 -30
- data/lib/punchblock/translator/asterisk/component.rb +6 -8
- data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +13 -20
- data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +1 -1
- data/lib/punchblock/translator/asterisk/component/input.rb +3 -6
- data/lib/punchblock/translator/asterisk/component/output.rb +40 -45
- data/lib/punchblock/translator/asterisk/component/record.rb +1 -1
- data/lib/punchblock/translator/asterisk/component/stop_by_redirect.rb +5 -2
- data/lib/punchblock/version.rb +1 -1
- data/punchblock.gemspec +5 -5
- data/spec/punchblock/command/reject_spec.rb +7 -1
- data/spec/punchblock/command_node_spec.rb +5 -2
- data/spec/punchblock/component/component_node_spec.rb +4 -0
- data/spec/punchblock/component/output_spec.rb +1 -1
- data/spec/punchblock/component/record_spec.rb +30 -0
- data/spec/punchblock/event/complete_spec.rb +10 -0
- data/spec/punchblock/translator/asterisk/call_spec.rb +191 -48
- data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +6 -39
- data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +3 -3
- data/spec/punchblock/translator/asterisk/component/input_spec.rb +8 -3
- data/spec/punchblock/translator/asterisk/component/output_spec.rb +153 -46
- data/spec/punchblock/translator/asterisk/component/record_spec.rb +6 -5
- data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +1 -2
- data/spec/punchblock/translator/asterisk/component_spec.rb +1 -0
- data/spec/punchblock/translator/asterisk_spec.rb +147 -12
- data/spec/punchblock_spec.rb +34 -0
- data/spec/spec_helper.rb +5 -1
- metadata +30 -20
@@ -9,6 +9,16 @@ module Punchblock
|
|
9
9
|
RayoNode.class_from_registration(:complete, 'urn:xmpp:rayo:ext:1').should be == Complete
|
10
10
|
end
|
11
11
|
|
12
|
+
describe "setting a reason" do
|
13
|
+
let(:reason) { Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new }
|
14
|
+
|
15
|
+
subject { described_class.new }
|
16
|
+
|
17
|
+
before { subject.reason = reason }
|
18
|
+
|
19
|
+
its(:reason) { should == reason }
|
20
|
+
end
|
21
|
+
|
12
22
|
describe "comparing for equality" do
|
13
23
|
subject do
|
14
24
|
Complete.new.tap do |c|
|
@@ -88,7 +88,7 @@ module Punchblock
|
|
88
88
|
:to => '1000',
|
89
89
|
:from => 'Jane Smith <sip:5678>',
|
90
90
|
:headers => sip_headers
|
91
|
-
translator.expects(:handle_pb_event
|
91
|
+
translator.expects(:handle_pb_event).with expected_offer
|
92
92
|
subject.send_offer
|
93
93
|
end
|
94
94
|
|
@@ -100,20 +100,19 @@ module Punchblock
|
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
|
-
describe '#
|
104
|
-
let(:answer_command) { Command::Answer.new.tap { |a| a.request! } }
|
103
|
+
describe '#send_progress' do
|
105
104
|
|
106
105
|
context "with a call that is already answered" do
|
107
|
-
it 'should not
|
106
|
+
it 'should not send the EXEC Progress command' do
|
108
107
|
subject.wrapped_object.expects(:'answered?').returns true
|
109
|
-
subject.wrapped_object.expects(:
|
110
|
-
subject.
|
108
|
+
subject.wrapped_object.expects(:send_agi_action).with("EXEC Progress").never
|
109
|
+
subject.send_progress
|
111
110
|
end
|
112
111
|
end
|
113
112
|
|
114
113
|
context "with an unanswered call" do
|
115
114
|
before do
|
116
|
-
subject.wrapped_object.expects(:'answered?').returns
|
115
|
+
subject.wrapped_object.expects(:'answered?').returns(false).at_least_once
|
117
116
|
end
|
118
117
|
|
119
118
|
context "with a call that is outbound" do
|
@@ -124,9 +123,9 @@ module Punchblock
|
|
124
123
|
subject.dial dial_command
|
125
124
|
end
|
126
125
|
|
127
|
-
it 'should not
|
128
|
-
subject.wrapped_object.expects(:
|
129
|
-
subject.
|
126
|
+
it 'should not send the EXEC Progress command' do
|
127
|
+
subject.wrapped_object.expects(:send_agi_action).with("EXEC Progress").never
|
128
|
+
subject.send_progress
|
130
129
|
end
|
131
130
|
end
|
132
131
|
|
@@ -135,9 +134,15 @@ module Punchblock
|
|
135
134
|
subject.send_offer
|
136
135
|
end
|
137
136
|
|
138
|
-
it 'should
|
139
|
-
subject.wrapped_object.expects(:
|
140
|
-
subject.
|
137
|
+
it 'should send the EXEC Progress command to a call that is inbound and not answered' do
|
138
|
+
subject.wrapped_object.expects(:send_agi_action).with("EXEC Progress")
|
139
|
+
subject.send_progress
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'should send the EXEC Progress command only once if called twice' do
|
143
|
+
subject.wrapped_object.expects(:send_agi_action).with("EXEC Progress").once
|
144
|
+
subject.send_progress
|
145
|
+
subject.send_progress
|
141
146
|
end
|
142
147
|
end
|
143
148
|
end
|
@@ -229,14 +234,19 @@ module Punchblock
|
|
229
234
|
let(:cause_txt) { 'Normal Clearing' }
|
230
235
|
|
231
236
|
it "should cause the actor to be terminated" do
|
232
|
-
translator.expects(:handle_pb_event
|
237
|
+
translator.expects(:handle_pb_event).twice
|
233
238
|
subject.process_ami_event ami_event
|
234
239
|
sleep 5.5
|
235
240
|
subject.should_not be_alive
|
236
241
|
end
|
237
242
|
|
243
|
+
it "de-registers the call from the translator" do
|
244
|
+
translator.stubs :handle_pb_event
|
245
|
+
translator.expects(:deregister_call).once.with(subject)
|
246
|
+
subject.process_ami_event ami_event
|
247
|
+
end
|
248
|
+
|
238
249
|
it "should cause all components to send complete events before sending end event" do
|
239
|
-
subject.expects :answer_if_not_answered
|
240
250
|
comp_command = Punchblock::Component::Input.new :grammar => {:value => '<grammar/>'}, :mode => :dtmf
|
241
251
|
comp_command.request!
|
242
252
|
component = subject.execute_command comp_command
|
@@ -245,8 +255,8 @@ module Punchblock
|
|
245
255
|
expected_complete_event.reason = Punchblock::Event::Complete::Hangup.new
|
246
256
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup, :target_call_id => subject.id
|
247
257
|
end_sequence = sequence 'end events'
|
248
|
-
translator.expects(:handle_pb_event
|
249
|
-
translator.expects(:handle_pb_event
|
258
|
+
translator.expects(:handle_pb_event).with(expected_complete_event).once.in_sequence(end_sequence)
|
259
|
+
translator.expects(:handle_pb_event).with(expected_end_event).once.in_sequence(end_sequence)
|
250
260
|
subject.process_ami_event ami_event
|
251
261
|
end
|
252
262
|
|
@@ -257,7 +267,7 @@ module Punchblock
|
|
257
267
|
it 'should send an end (hangup) event to the translator' do
|
258
268
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup,
|
259
269
|
:target_call_id => subject.id
|
260
|
-
translator.expects(:handle_pb_event
|
270
|
+
translator.expects(:handle_pb_event).with expected_end_event
|
261
271
|
subject.process_ami_event ami_event
|
262
272
|
end
|
263
273
|
end
|
@@ -269,7 +279,7 @@ module Punchblock
|
|
269
279
|
it 'should send an end (hangup) event to the translator' do
|
270
280
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup,
|
271
281
|
:target_call_id => subject.id
|
272
|
-
translator.expects(:handle_pb_event
|
282
|
+
translator.expects(:handle_pb_event).with expected_end_event
|
273
283
|
subject.process_ami_event ami_event
|
274
284
|
end
|
275
285
|
end
|
@@ -281,7 +291,7 @@ module Punchblock
|
|
281
291
|
it 'should send an end (busy) event to the translator' do
|
282
292
|
expected_end_event = Punchblock::Event::End.new :reason => :busy,
|
283
293
|
:target_call_id => subject.id
|
284
|
-
translator.expects(:handle_pb_event
|
294
|
+
translator.expects(:handle_pb_event).with expected_end_event
|
285
295
|
subject.process_ami_event ami_event
|
286
296
|
end
|
287
297
|
end
|
@@ -297,7 +307,7 @@ module Punchblock
|
|
297
307
|
it 'should send an end (timeout) event to the translator' do
|
298
308
|
expected_end_event = Punchblock::Event::End.new :reason => :timeout,
|
299
309
|
:target_call_id => subject.id
|
300
|
-
translator.expects(:handle_pb_event
|
310
|
+
translator.expects(:handle_pb_event).with expected_end_event
|
301
311
|
subject.process_ami_event ami_event
|
302
312
|
end
|
303
313
|
end
|
@@ -315,7 +325,7 @@ module Punchblock
|
|
315
325
|
it 'should send an end (reject) event to the translator' do
|
316
326
|
expected_end_event = Punchblock::Event::End.new :reason => :reject,
|
317
327
|
:target_call_id => subject.id
|
318
|
-
translator.expects(:handle_pb_event
|
328
|
+
translator.expects(:handle_pb_event).with expected_end_event
|
319
329
|
subject.process_ami_event ami_event
|
320
330
|
end
|
321
331
|
end
|
@@ -367,7 +377,7 @@ module Punchblock
|
|
367
377
|
it 'should send an end (error) event to the translator' do
|
368
378
|
expected_end_event = Punchblock::Event::End.new :reason => :error,
|
369
379
|
:target_call_id => subject.id
|
370
|
-
translator.expects(:handle_pb_event
|
380
|
+
translator.expects(:handle_pb_event).with expected_end_event
|
371
381
|
subject.process_ami_event ami_event
|
372
382
|
end
|
373
383
|
end
|
@@ -395,7 +405,7 @@ module Punchblock
|
|
395
405
|
end
|
396
406
|
|
397
407
|
it 'should send the event to the component' do
|
398
|
-
component.expects(:handle_ami_event
|
408
|
+
component.expects(:handle_ami_event).once.with ami_event
|
399
409
|
subject.process_ami_event ami_event
|
400
410
|
end
|
401
411
|
end
|
@@ -422,7 +432,7 @@ module Punchblock
|
|
422
432
|
it 'should send a ringing event' do
|
423
433
|
expected_ringing = Punchblock::Event::Ringing.new
|
424
434
|
expected_ringing.target_call_id = subject.id
|
425
|
-
translator.expects(:handle_pb_event
|
435
|
+
translator.expects(:handle_pb_event).with expected_ringing
|
426
436
|
subject.process_ami_event ami_event
|
427
437
|
end
|
428
438
|
|
@@ -439,7 +449,7 @@ module Punchblock
|
|
439
449
|
it 'should send a ringing event' do
|
440
450
|
expected_answered = Punchblock::Event::Answered.new
|
441
451
|
expected_answered.target_call_id = subject.id
|
442
|
-
translator.expects(:handle_pb_event
|
452
|
+
translator.expects(:handle_pb_event).with expected_answered
|
443
453
|
subject.process_ami_event ami_event
|
444
454
|
end
|
445
455
|
|
@@ -450,6 +460,55 @@ module Punchblock
|
|
450
460
|
end
|
451
461
|
end
|
452
462
|
|
463
|
+
context 'with an OriginateResponse event' do
|
464
|
+
let :ami_event do
|
465
|
+
RubyAMI::Event.new('OriginateResponse').tap do |e|
|
466
|
+
e['Privilege'] = 'call,all'
|
467
|
+
e['ActionID'] = '9d0c1aa4-5e3b-4cae-8aef-76a6119e2909'
|
468
|
+
e['Response'] = response
|
469
|
+
e['Channel'] = 'SIP/15557654321'
|
470
|
+
e['Context'] = ''
|
471
|
+
e['Exten'] = ''
|
472
|
+
e['Reason'] = '0'
|
473
|
+
e['Uniqueid'] = uniqueid
|
474
|
+
e['CallerIDNum'] = 'sip:5551234567'
|
475
|
+
e['CallerIDName'] = 'Bryan 100'
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
context 'sucessful' do
|
480
|
+
let(:response) { 'Success' }
|
481
|
+
let(:uniqueid) { '<null>' }
|
482
|
+
|
483
|
+
it 'should not send an end event' do
|
484
|
+
translator.expects(:handle_pb_event).once.with is_a(Punchblock::Event::Asterisk::AMI::Event)
|
485
|
+
subject.process_ami_event ami_event
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
context 'failed after being connected' do
|
490
|
+
let(:response) { 'Failure' }
|
491
|
+
let(:uniqueid) { '1235' }
|
492
|
+
|
493
|
+
it 'should not send an end event' do
|
494
|
+
translator.expects(:handle_pb_event).once.with is_a(Punchblock::Event::Asterisk::AMI::Event)
|
495
|
+
subject.process_ami_event ami_event
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
context 'failed without ever having connected' do
|
500
|
+
let(:response) { 'Failure' }
|
501
|
+
let(:uniqueid) { '<null>' }
|
502
|
+
|
503
|
+
it 'should send an error end event' do
|
504
|
+
expected_end_event = Punchblock::Event::End.new :reason => :error,
|
505
|
+
:target_call_id => subject.id
|
506
|
+
translator.expects(:handle_pb_event).with expected_end_event
|
507
|
+
subject.process_ami_event ami_event
|
508
|
+
end
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
453
512
|
context 'with a handler registered for a matching event' do
|
454
513
|
let :ami_event do
|
455
514
|
RubyAMI::Event.new('DTMF').tap do |e|
|
@@ -551,12 +610,12 @@ module Punchblock
|
|
551
610
|
end
|
552
611
|
|
553
612
|
it 'sends the Joined event when the call is the first channel' do
|
554
|
-
translator.expects(:handle_pb_event
|
613
|
+
translator.expects(:handle_pb_event).with expected_joined
|
555
614
|
subject.process_ami_event ami_event
|
556
615
|
end
|
557
616
|
|
558
617
|
it 'sends the Joined event when the call is the second channel' do
|
559
|
-
translator.expects(:handle_pb_event
|
618
|
+
translator.expects(:handle_pb_event).with expected_joined
|
560
619
|
subject.process_ami_event switched_ami_event
|
561
620
|
end
|
562
621
|
end
|
@@ -572,12 +631,12 @@ module Punchblock
|
|
572
631
|
end
|
573
632
|
|
574
633
|
it 'sends the Unjoined event when the call is the first channel' do
|
575
|
-
translator.expects(:handle_pb_event
|
634
|
+
translator.expects(:handle_pb_event).with expected_unjoined
|
576
635
|
subject.process_ami_event ami_event
|
577
636
|
end
|
578
637
|
|
579
638
|
it 'sends the Unjoined event when the call is the second channel' do
|
580
|
-
translator.expects(:handle_pb_event
|
639
|
+
translator.expects(:handle_pb_event).with expected_unjoined
|
581
640
|
subject.process_ami_event switched_ami_event
|
582
641
|
end
|
583
642
|
end
|
@@ -628,15 +687,43 @@ module Punchblock
|
|
628
687
|
end
|
629
688
|
|
630
689
|
it 'sends the Unjoined event when the call is the first channel' do
|
631
|
-
translator.expects(:handle_pb_event
|
690
|
+
translator.expects(:handle_pb_event).with expected_unjoined
|
632
691
|
subject.process_ami_event ami_event
|
633
692
|
end
|
634
693
|
|
635
694
|
it 'sends the Unjoined event when the call is the second channel' do
|
636
|
-
translator.expects(:handle_pb_event
|
695
|
+
translator.expects(:handle_pb_event).with expected_unjoined
|
637
696
|
subject.process_ami_event switched_ami_event
|
638
697
|
end
|
639
698
|
end
|
699
|
+
|
700
|
+
let :ami_event do
|
701
|
+
RubyAMI::Event.new('Foo').tap do |e|
|
702
|
+
e['Uniqueid'] = "1320842458.8"
|
703
|
+
e['Calleridnum'] = "5678"
|
704
|
+
e['Calleridname'] = "Jane Smith"
|
705
|
+
e['Cause'] = "0"
|
706
|
+
e['Cause-txt'] = "Unknown"
|
707
|
+
e['Channel'] = channel
|
708
|
+
end
|
709
|
+
end
|
710
|
+
|
711
|
+
let :expected_pb_event do
|
712
|
+
Event::Asterisk::AMI::Event.new :name => 'Foo',
|
713
|
+
:attributes => { :channel => channel,
|
714
|
+
:uniqueid => "1320842458.8",
|
715
|
+
:calleridnum => "5678",
|
716
|
+
:calleridname => "Jane Smith",
|
717
|
+
:cause => "0",
|
718
|
+
:'cause-txt' => "Unknown"},
|
719
|
+
:target_call_id => subject.id
|
720
|
+
end
|
721
|
+
|
722
|
+
it 'sends the AMI event to the connection as a PB event' do
|
723
|
+
translator.expects(:handle_pb_event).with expected_pb_event
|
724
|
+
subject.process_ami_event ami_event
|
725
|
+
end
|
726
|
+
|
640
727
|
end
|
641
728
|
|
642
729
|
describe '#execute_command' do
|
@@ -660,7 +747,6 @@ module Punchblock
|
|
660
747
|
component.internal.should be_true
|
661
748
|
agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
|
662
749
|
agi_command.name.should be == "EXEC RINGING"
|
663
|
-
agi_command.execute!
|
664
750
|
agi_command.add_event expected_agi_complete_event
|
665
751
|
command.response(0.5).should be true
|
666
752
|
end
|
@@ -675,7 +761,6 @@ module Punchblock
|
|
675
761
|
component.internal.should be_true
|
676
762
|
agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
|
677
763
|
agi_command.name.should be == "EXEC Busy"
|
678
|
-
agi_command.execute!
|
679
764
|
agi_command.add_event expected_agi_complete_event
|
680
765
|
command.response(0.5).should be true
|
681
766
|
end
|
@@ -686,7 +771,6 @@ module Punchblock
|
|
686
771
|
component.internal.should be_true
|
687
772
|
agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
|
688
773
|
agi_command.name.should be == "EXEC Busy"
|
689
|
-
agi_command.execute!
|
690
774
|
agi_command.add_event expected_agi_complete_event
|
691
775
|
command.response(0.5).should be true
|
692
776
|
end
|
@@ -697,7 +781,6 @@ module Punchblock
|
|
697
781
|
component.internal.should be_true
|
698
782
|
agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
|
699
783
|
agi_command.name.should be == "EXEC Congestion"
|
700
|
-
agi_command.execute!
|
701
784
|
agi_command.add_event expected_agi_complete_event
|
702
785
|
command.response(0.5).should be true
|
703
786
|
end
|
@@ -706,12 +789,11 @@ module Punchblock
|
|
706
789
|
context 'with an answer command' do
|
707
790
|
let(:command) { Command::Answer.new }
|
708
791
|
|
709
|
-
it "should send an
|
792
|
+
it "should send an ANSWER AGI command and set the command's response" do
|
710
793
|
component = subject.execute_command command
|
711
794
|
component.internal.should be_true
|
712
795
|
agi_command = subject.wrapped_object.instance_variable_get(:'@current_agi_command')
|
713
|
-
agi_command.name.should be == "
|
714
|
-
agi_command.execute!
|
796
|
+
agi_command.name.should be == "ANSWER"
|
715
797
|
agi_command.add_event expected_agi_complete_event
|
716
798
|
command.response(0.5).should be true
|
717
799
|
end
|
@@ -738,7 +820,7 @@ module Punchblock
|
|
738
820
|
|
739
821
|
it 'should create an AGI command component actor and execute it asynchronously' do
|
740
822
|
mock_action.expects(:internal=).never
|
741
|
-
Component::Asterisk::AGICommand.expects(:
|
823
|
+
Component::Asterisk::AGICommand.expects(:new_link).once.with(command, subject).returns mock_action
|
742
824
|
mock_action.expects(:execute!).once
|
743
825
|
subject.execute_command command
|
744
826
|
end
|
@@ -752,7 +834,7 @@ module Punchblock
|
|
752
834
|
let(:mock_action) { mock 'Component::Asterisk::Output', :id => 'foo' }
|
753
835
|
|
754
836
|
it 'should create an Output component and execute it asynchronously' do
|
755
|
-
Component::Output.expects(:
|
837
|
+
Component::Output.expects(:new_link).once.with(command, subject).returns mock_action
|
756
838
|
mock_action.expects(:internal=).never
|
757
839
|
mock_action.expects(:execute!).once
|
758
840
|
subject.execute_command command
|
@@ -767,7 +849,7 @@ module Punchblock
|
|
767
849
|
let(:mock_action) { mock 'Component::Asterisk::Input', :id => 'foo' }
|
768
850
|
|
769
851
|
it 'should create an Input component and execute it asynchronously' do
|
770
|
-
Component::Input.expects(:
|
852
|
+
Component::Input.expects(:new_link).once.with(command, subject).returns mock_action
|
771
853
|
mock_action.expects(:internal=).never
|
772
854
|
mock_action.expects(:execute!).once
|
773
855
|
subject.execute_command command
|
@@ -782,7 +864,7 @@ module Punchblock
|
|
782
864
|
let(:mock_action) { mock 'Component::Asterisk::Record', :id => 'foo' }
|
783
865
|
|
784
866
|
it 'should create a Record component and execute it asynchronously' do
|
785
|
-
Component::Record.expects(:
|
867
|
+
Component::Record.expects(:new_link).once.with(command, subject).returns mock_action
|
786
868
|
mock_action.expects(:internal=).never
|
787
869
|
mock_action.expects(:execute!).once
|
788
870
|
subject.execute_command command
|
@@ -804,15 +886,57 @@ module Punchblock
|
|
804
886
|
before { subject.register_component mock_component }
|
805
887
|
|
806
888
|
it 'should send the command to the component for execution' do
|
807
|
-
mock_component.expects(:execute_command
|
889
|
+
mock_component.expects(:execute_command).once
|
808
890
|
subject.execute_command command
|
809
891
|
end
|
810
892
|
end
|
811
893
|
|
894
|
+
context "for a component which began executing but crashed" do
|
895
|
+
let :component_command do
|
896
|
+
Punchblock::Component::Asterisk::AGI::Command.new :name => 'Wait'
|
897
|
+
end
|
898
|
+
|
899
|
+
let(:comp_id) { component_command.response.id }
|
900
|
+
|
901
|
+
let(:subsequent_command) { Punchblock::Component::Stop.new :component_id => comp_id }
|
902
|
+
|
903
|
+
let :expected_event do
|
904
|
+
Punchblock::Event::Complete.new.tap do |e|
|
905
|
+
e.target_call_id = subject.id
|
906
|
+
e.component_id = comp_id
|
907
|
+
e.reason = Punchblock::Event::Complete::Error.new
|
908
|
+
end
|
909
|
+
end
|
910
|
+
|
911
|
+
before do
|
912
|
+
component_command.request!
|
913
|
+
subject.execute_command component_command
|
914
|
+
end
|
915
|
+
|
916
|
+
it 'sends an error in response to the command' do
|
917
|
+
component = subject.component_with_id comp_id
|
918
|
+
|
919
|
+
component.wrapped_object.define_singleton_method(:oops) do
|
920
|
+
raise 'Woops, I died'
|
921
|
+
end
|
922
|
+
|
923
|
+
translator.expects(:handle_pb_event).once.with expected_event
|
924
|
+
|
925
|
+
lambda { component.oops }.should raise_error(/Woops, I died/)
|
926
|
+
sleep 0.1
|
927
|
+
component.should_not be_alive
|
928
|
+
subject.component_with_id(comp_id).should be_nil
|
929
|
+
|
930
|
+
subsequent_command.request!
|
931
|
+
subject.execute_command subsequent_command
|
932
|
+
subsequent_command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id)
|
933
|
+
end
|
934
|
+
end
|
935
|
+
|
812
936
|
context "for an unknown component ID" do
|
813
937
|
it 'sends an error in response to the command' do
|
814
938
|
subject.execute_command command
|
815
|
-
command.response.should be == ProtocolError.new.setup(
|
939
|
+
command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{component_id} for call #{subject.id}", subject.id, component_id)
|
816
940
|
end
|
817
941
|
end
|
818
942
|
end
|
@@ -877,6 +1001,9 @@ module Punchblock
|
|
877
1001
|
ami_action.headers['Exten'].should be == Punchblock::Translator::Asterisk::REDIRECT_EXTENSION
|
878
1002
|
ami_action.headers['Priority'].should be == Punchblock::Translator::Asterisk::REDIRECT_PRIORITY
|
879
1003
|
ami_action.headers['Context'].should be == Punchblock::Translator::Asterisk::REDIRECT_CONTEXT
|
1004
|
+
|
1005
|
+
ami_action << RubyAMI::Response.new
|
1006
|
+
command.response(1).should be_true
|
880
1007
|
end
|
881
1008
|
|
882
1009
|
it "executes the unjoin through redirection, on the subject call and the other call" do
|
@@ -894,6 +1021,22 @@ module Punchblock
|
|
894
1021
|
ami_action.headers['ExtraPriority'].should be == Punchblock::Translator::Asterisk::REDIRECT_PRIORITY
|
895
1022
|
ami_action.headers['ExtraContext'].should be == Punchblock::Translator::Asterisk::REDIRECT_CONTEXT
|
896
1023
|
end
|
1024
|
+
|
1025
|
+
it "handles redirect errors" do
|
1026
|
+
translator.expects(:call_with_id).with(other_call_id).returns(nil)
|
1027
|
+
subject.execute_command command
|
1028
|
+
ami_action = subject.wrapped_object.instance_variable_get(:'@current_ami_action')
|
1029
|
+
ami_action.name.should be == "redirect"
|
1030
|
+
ami_action.headers['Channel'].should be == channel
|
1031
|
+
ami_action.headers['Exten'].should be == Punchblock::Translator::Asterisk::REDIRECT_EXTENSION
|
1032
|
+
ami_action.headers['Priority'].should be == Punchblock::Translator::Asterisk::REDIRECT_PRIORITY
|
1033
|
+
ami_action.headers['Context'].should be == Punchblock::Translator::Asterisk::REDIRECT_CONTEXT
|
1034
|
+
|
1035
|
+
ami_action << RubyAMI::Error.new.tap { |e| e.message = 'FooBar' }
|
1036
|
+
response = command.response(1)
|
1037
|
+
response.should be_a ProtocolError
|
1038
|
+
response.text.should == 'FooBar'
|
1039
|
+
end
|
897
1040
|
end
|
898
1041
|
end#execute_command
|
899
1042
|
|
@@ -906,12 +1049,12 @@ module Punchblock
|
|
906
1049
|
end
|
907
1050
|
|
908
1051
|
describe '#send_ami_action' do
|
909
|
-
let(:component_id) {
|
910
|
-
before {
|
1052
|
+
let(:component_id) { Punchblock.new_uuid }
|
1053
|
+
before { stub_uuids component_id }
|
911
1054
|
|
912
1055
|
it 'should send the action to the AMI client' do
|
913
1056
|
action = RubyAMI::Action.new 'foo', :foo => :bar
|
914
|
-
translator.expects(:send_ami_action
|
1057
|
+
translator.expects(:send_ami_action).once.with action
|
915
1058
|
subject.send_ami_action 'foo', :foo => :bar
|
916
1059
|
end
|
917
1060
|
end
|