punchblock 1.9.4 → 2.0.0.beta1
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/.gitignore +1 -0
- data/.travis.yml +1 -2
- data/CHANGELOG.md +17 -0
- data/Gemfile +1 -0
- data/Guardfile +4 -0
- data/README.markdown +6 -0
- data/Rakefile +16 -0
- data/benchmarks/ami_event_name_comparison.rb +14 -0
- data/benchmarks/channel.rb +27 -0
- data/lib/punchblock/client.rb +2 -6
- data/lib/punchblock/command/accept.rb +3 -24
- data/lib/punchblock/command/answer.rb +3 -24
- data/lib/punchblock/command/dial.rb +24 -76
- data/lib/punchblock/command/hangup.rb +3 -19
- data/lib/punchblock/command/join.rb +21 -70
- data/lib/punchblock/command/mute.rb +3 -3
- data/lib/punchblock/command/redirect.rb +6 -39
- data/lib/punchblock/command/reject.rb +14 -54
- data/lib/punchblock/command/unjoin.rb +8 -40
- data/lib/punchblock/command/unmute.rb +3 -3
- data/lib/punchblock/command_node.rb +0 -17
- data/lib/punchblock/component/asterisk/agi/command.rb +20 -127
- data/lib/punchblock/component/asterisk/ami/action.rb +30 -117
- data/lib/punchblock/component/component_node.rb +1 -1
- data/lib/punchblock/component/input.rb +89 -268
- data/lib/punchblock/component/output.rb +106 -154
- data/lib/punchblock/component/prompt.rb +51 -0
- data/lib/punchblock/component/record.rb +41 -130
- data/lib/punchblock/component.rb +1 -0
- data/lib/punchblock/connection/asterisk.rb +31 -4
- data/lib/punchblock/connection/xmpp.rb +6 -14
- data/lib/punchblock/core_ext/blather/stanza.rb +1 -1
- data/lib/punchblock/event/active_speaker.rb +2 -10
- data/lib/punchblock/event/answered.rb +3 -3
- data/lib/punchblock/event/asterisk/ami/event.rb +15 -47
- data/lib/punchblock/event/complete.rb +26 -48
- data/lib/punchblock/event/dtmf.rb +3 -13
- data/lib/punchblock/event/end.rb +10 -11
- data/lib/punchblock/event/joined.rb +5 -25
- data/lib/punchblock/event/offer.rb +4 -25
- data/lib/punchblock/event/ringing.rb +3 -3
- data/lib/punchblock/event/unjoined.rb +5 -25
- data/lib/punchblock/event.rb +0 -10
- data/lib/punchblock/has_headers.rb +20 -26
- data/lib/punchblock/rayo_node.rb +46 -23
- data/lib/punchblock/ref.rb +39 -18
- data/lib/punchblock/translator/asterisk/agi_app.rb +15 -0
- data/lib/punchblock/translator/asterisk/agi_command.rb +3 -1
- data/lib/punchblock/translator/asterisk/ami_error_converter.rb +20 -0
- data/lib/punchblock/translator/asterisk/call.rb +60 -39
- data/lib/punchblock/translator/asterisk/channel.rb +41 -0
- data/lib/punchblock/translator/asterisk/component/asterisk/agi_command.rb +4 -1
- data/lib/punchblock/translator/asterisk/component/asterisk/ami_action.rb +4 -4
- data/lib/punchblock/translator/asterisk/component/composed_prompt.rb +62 -0
- data/lib/punchblock/translator/asterisk/component/input.rb +1 -0
- data/lib/punchblock/translator/asterisk/component/mrcp_native_prompt.rb +56 -0
- data/lib/punchblock/translator/asterisk/component/mrcp_prompt.rb +53 -0
- data/lib/punchblock/translator/asterisk/component/mrcp_recog_prompt.rb +99 -0
- data/lib/punchblock/translator/asterisk/component/output.rb +30 -22
- data/lib/punchblock/translator/asterisk/component/record.rb +8 -6
- data/lib/punchblock/translator/asterisk/component.rb +6 -5
- data/lib/punchblock/translator/asterisk/unimrcp_app.rb +26 -0
- data/lib/punchblock/translator/asterisk.rb +24 -28
- data/lib/punchblock/translator/dtmf_recognizer.rb +39 -20
- data/lib/punchblock/translator/freeswitch/call.rb +15 -14
- data/lib/punchblock/translator/freeswitch/component/abstract_output.rb +5 -4
- data/lib/punchblock/translator/freeswitch/component/flite_output.rb +1 -1
- data/lib/punchblock/translator/freeswitch/component/input.rb +5 -0
- data/lib/punchblock/translator/freeswitch/component/output.rb +2 -2
- data/lib/punchblock/translator/freeswitch/component/record.rb +19 -13
- data/lib/punchblock/translator/freeswitch/component/tts_output.rb +2 -2
- data/lib/punchblock/translator/freeswitch/component.rb +2 -5
- data/lib/punchblock/translator/freeswitch.rb +2 -2
- data/lib/punchblock/translator/input_component.rb +33 -13
- data/lib/punchblock/uri_list.rb +21 -0
- data/lib/punchblock/version.rb +1 -1
- data/lib/punchblock.rb +4 -3
- data/punchblock.gemspec +7 -3
- data/spec/punchblock/client/component_registry_spec.rb +1 -1
- data/spec/punchblock/client_spec.rb +10 -26
- data/spec/punchblock/command/accept_spec.rb +41 -7
- data/spec/punchblock/command/answer_spec.rb +51 -7
- data/spec/punchblock/command/dial_spec.rb +56 -14
- data/spec/punchblock/command/hangup_spec.rb +41 -7
- data/spec/punchblock/command/join_spec.rb +53 -11
- data/spec/punchblock/command/mute_spec.rb +19 -4
- data/spec/punchblock/command/redirect_spec.rb +40 -10
- data/spec/punchblock/command/reject_spec.rb +43 -11
- data/spec/punchblock/command/unjoin_spec.rb +40 -9
- data/spec/punchblock/command/unmute_spec.rb +19 -4
- data/spec/punchblock/command_node_spec.rb +0 -4
- data/spec/punchblock/component/asterisk/agi/command_spec.rb +16 -39
- data/spec/punchblock/component/asterisk/ami/action_spec.rb +50 -53
- data/spec/punchblock/component/component_node_spec.rb +3 -5
- data/spec/punchblock/component/input_spec.rb +194 -61
- data/spec/punchblock/component/output_spec.rb +194 -62
- data/spec/punchblock/component/prompt_spec.rb +132 -0
- data/spec/punchblock/component/record_spec.rb +70 -32
- data/spec/punchblock/connection/asterisk_spec.rb +17 -3
- data/spec/punchblock/connection/freeswitch_spec.rb +4 -4
- data/spec/punchblock/connection/xmpp_spec.rb +20 -38
- data/spec/punchblock/event/answered_spec.rb +12 -10
- data/spec/punchblock/event/asterisk/ami/event_spec.rb +27 -22
- data/spec/punchblock/event/complete_spec.rb +15 -19
- data/spec/punchblock/event/dtmf_spec.rb +5 -6
- data/spec/punchblock/event/end_spec.rb +20 -10
- data/spec/punchblock/event/joined_spec.rb +8 -7
- data/spec/punchblock/event/offer_spec.rb +41 -12
- data/spec/punchblock/event/ringing_spec.rb +12 -10
- data/spec/punchblock/event/started_speaking_spec.rb +5 -6
- data/spec/punchblock/event/stopped_speaking_spec.rb +5 -6
- data/spec/punchblock/event/unjoined_spec.rb +7 -7
- data/spec/punchblock/ref_spec.rb +86 -9
- data/spec/punchblock/translator/asterisk/call_spec.rb +317 -154
- data/spec/punchblock/translator/asterisk/component/asterisk/agi_command_spec.rb +28 -5
- data/spec/punchblock/translator/asterisk/component/asterisk/ami_action_spec.rb +15 -13
- data/spec/punchblock/translator/asterisk/component/composed_prompt_spec.rb +237 -0
- data/spec/punchblock/translator/asterisk/component/input_spec.rb +171 -14
- data/spec/punchblock/translator/asterisk/component/mrcp_native_prompt_spec.rb +652 -0
- data/spec/punchblock/translator/asterisk/component/mrcp_prompt_spec.rb +646 -0
- data/spec/punchblock/translator/asterisk/component/output_spec.rb +127 -77
- data/spec/punchblock/translator/asterisk/component/record_spec.rb +17 -8
- data/spec/punchblock/translator/asterisk/component/stop_by_redirect_spec.rb +2 -2
- data/spec/punchblock/translator/asterisk/component_spec.rb +3 -7
- data/spec/punchblock/translator/asterisk_spec.rb +20 -24
- data/spec/punchblock/translator/freeswitch/call_spec.rb +103 -99
- data/spec/punchblock/translator/freeswitch/component/flite_output_spec.rb +17 -8
- data/spec/punchblock/translator/freeswitch/component/input_spec.rb +26 -14
- data/spec/punchblock/translator/freeswitch/component/output_spec.rb +30 -52
- data/spec/punchblock/translator/freeswitch/component/record_spec.rb +23 -19
- data/spec/punchblock/translator/freeswitch/component/tts_output_spec.rb +18 -8
- data/spec/punchblock/translator/freeswitch/component_spec.rb +4 -8
- data/spec/punchblock/translator/freeswitch_spec.rb +11 -14
- data/spec/punchblock/uri_list_spec.rb +49 -0
- data/spec/punchblock_spec.rb +11 -1
- data/spec/spec_helper.rb +7 -11
- data/spec/support/mock_connection_with_event_handler.rb +1 -1
- metadata +104 -24
- data/lib/punchblock/header.rb +0 -9
- data/lib/punchblock/key_value_pair_node.rb +0 -51
- data/spec/punchblock/header_spec.rb +0 -11
|
@@ -7,8 +7,8 @@ module Punchblock
|
|
|
7
7
|
class Asterisk
|
|
8
8
|
describe Call do
|
|
9
9
|
let(:channel) { 'SIP/foo' }
|
|
10
|
-
let(:ami_client) {
|
|
11
|
-
let(:connection) {
|
|
10
|
+
let(:ami_client) { double('AMI Client').as_null_object }
|
|
11
|
+
let(:connection) { double('connection').as_null_object }
|
|
12
12
|
let(:translator) { Asterisk.new ami_client, connection }
|
|
13
13
|
let(:agi_env) do
|
|
14
14
|
{
|
|
@@ -37,26 +37,26 @@ module Punchblock
|
|
|
37
37
|
|
|
38
38
|
let :sip_headers do
|
|
39
39
|
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
40
|
+
'X-agi_request' => 'async',
|
|
41
|
+
'X-agi_channel' => 'SIP/1234-00000000',
|
|
42
|
+
'X-agi_language' => 'en',
|
|
43
|
+
'X-agi_type' => 'SIP',
|
|
44
|
+
'X-agi_uniqueid' => '1320835995.0',
|
|
45
|
+
'X-agi_version' => '1.8.4.1',
|
|
46
|
+
'X-agi_callerid' => '5678',
|
|
47
|
+
'X-agi_calleridname' => 'Jane Smith',
|
|
48
|
+
'X-agi_callingpres' => '0',
|
|
49
|
+
'X-agi_callingani2' => '0',
|
|
50
|
+
'X-agi_callington' => '0',
|
|
51
|
+
'X-agi_callingtns' => '0',
|
|
52
|
+
'X-agi_dnid' => 'unknown',
|
|
53
|
+
'X-agi_rdnis' => 'unknown',
|
|
54
|
+
'X-agi_context' => 'default',
|
|
55
|
+
'X-agi_extension' => '1000',
|
|
56
|
+
'X-agi_priority' => '1',
|
|
57
|
+
'X-agi_enhanced' => '0.0',
|
|
58
|
+
'X-agi_accountcode' => '',
|
|
59
|
+
'X-agi_threadid' => '4366221312'
|
|
60
60
|
}
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -80,7 +80,7 @@ module Punchblock
|
|
|
80
80
|
describe '#register_component' do
|
|
81
81
|
it 'should make the component accessible by ID' do
|
|
82
82
|
component_id = 'abc123'
|
|
83
|
-
component =
|
|
83
|
+
component = double 'Translator::Asterisk::Component', :id => component_id
|
|
84
84
|
subject.register_component component
|
|
85
85
|
subject.component_with_id(component_id).should be component
|
|
86
86
|
end
|
|
@@ -296,25 +296,24 @@ module Punchblock
|
|
|
296
296
|
it "should cause the actor to be terminated" do
|
|
297
297
|
translator.should_receive(:handle_pb_event).twice
|
|
298
298
|
subject.process_ami_event ami_event
|
|
299
|
-
sleep 5.5
|
|
300
299
|
subject.should_not be_alive
|
|
301
300
|
end
|
|
302
301
|
|
|
303
302
|
it "de-registers the call from the translator" do
|
|
304
303
|
translator.stub :handle_pb_event
|
|
305
|
-
translator.should_receive(:deregister_call).once.with(subject)
|
|
304
|
+
translator.should_receive(:deregister_call).once.with(subject.id, subject.channel)
|
|
306
305
|
subject.process_ami_event ami_event
|
|
307
306
|
end
|
|
308
307
|
|
|
309
308
|
it "should cause all components to send complete events before sending end event" do
|
|
310
309
|
subject.stub :send_progress
|
|
311
|
-
comp_command = Punchblock::Component::Input.new :grammar => {:value => '
|
|
310
|
+
comp_command = Punchblock::Component::Input.new :grammar => {:value => RubySpeech::GRXML.draw(root: 'foo') { rule id: 'foo' }}, :mode => :dtmf
|
|
312
311
|
comp_command.request!
|
|
313
312
|
component = subject.execute_command comp_command
|
|
314
313
|
comp_command.response(0.1).should be_a Ref
|
|
315
314
|
expected_complete_event = Punchblock::Event::Complete.new :target_call_id => subject.id, :component_id => component.id
|
|
316
315
|
expected_complete_event.reason = Punchblock::Event::Complete::Hangup.new
|
|
317
|
-
expected_end_event = Punchblock::Event::End.new :reason => :hangup, :target_call_id => subject.id
|
|
316
|
+
expected_end_event = Punchblock::Event::End.new :reason => :hangup, platform_code: cause, :target_call_id => subject.id
|
|
318
317
|
|
|
319
318
|
translator.should_receive(:handle_pb_event).with(expected_complete_event).once.ordered
|
|
320
319
|
translator.should_receive(:handle_pb_event).with(expected_end_event).once.ordered
|
|
@@ -322,18 +321,38 @@ module Punchblock
|
|
|
322
321
|
end
|
|
323
322
|
|
|
324
323
|
it "should not allow commands to be executed while components are shutting down" do
|
|
324
|
+
call_id = subject.id
|
|
325
|
+
|
|
325
326
|
subject.stub :send_progress
|
|
326
|
-
comp_command = Punchblock::Component::Input.new :grammar => {:value => '
|
|
327
|
+
comp_command = Punchblock::Component::Input.new :grammar => {:value => RubySpeech::GRXML.draw(root: 'foo') { rule id: 'foo' }}, :mode => :dtmf
|
|
327
328
|
comp_command.request!
|
|
328
329
|
component = subject.execute_command comp_command
|
|
329
330
|
comp_command.response(0.1).should be_a Ref
|
|
330
331
|
|
|
331
332
|
subject.async.process_ami_event ami_event
|
|
332
333
|
|
|
333
|
-
comp_command = Punchblock::Component::Input.new :grammar => {:value => '<grammar
|
|
334
|
+
comp_command = Punchblock::Component::Input.new :grammar => {:value => '<grammar root="foo"><rule id="foo"/></grammar>'}, :mode => :dtmf
|
|
334
335
|
comp_command.request!
|
|
335
336
|
subject.execute_command comp_command
|
|
336
|
-
comp_command.response(0.1).should == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{
|
|
337
|
+
comp_command.response(0.1).should == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{call_id}", call_id)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
context "after processing a hangup command" do
|
|
341
|
+
let(:command) { Command::Hangup.new }
|
|
342
|
+
|
|
343
|
+
before do
|
|
344
|
+
command.request!
|
|
345
|
+
subject.execute_command command
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
it 'should send an end (hangup_command) event to the translator' do
|
|
349
|
+
expected_end_event = Punchblock::Event::End.new :reason => :hangup_command,
|
|
350
|
+
platform_code: cause,
|
|
351
|
+
:target_call_id => subject.id
|
|
352
|
+
translator.should_receive(:handle_pb_event).with expected_end_event
|
|
353
|
+
|
|
354
|
+
subject.process_ami_event ami_event
|
|
355
|
+
end
|
|
337
356
|
end
|
|
338
357
|
|
|
339
358
|
context "with an undefined cause" do
|
|
@@ -342,6 +361,7 @@ module Punchblock
|
|
|
342
361
|
|
|
343
362
|
it 'should send an end (hangup) event to the translator' do
|
|
344
363
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup,
|
|
364
|
+
platform_code: cause,
|
|
345
365
|
:target_call_id => subject.id
|
|
346
366
|
translator.should_receive(:handle_pb_event).with expected_end_event
|
|
347
367
|
subject.process_ami_event ami_event
|
|
@@ -354,6 +374,7 @@ module Punchblock
|
|
|
354
374
|
|
|
355
375
|
it 'should send an end (hangup) event to the translator' do
|
|
356
376
|
expected_end_event = Punchblock::Event::End.new :reason => :hangup,
|
|
377
|
+
platform_code: cause,
|
|
357
378
|
:target_call_id => subject.id
|
|
358
379
|
translator.should_receive(:handle_pb_event).with expected_end_event
|
|
359
380
|
subject.process_ami_event ami_event
|
|
@@ -366,6 +387,7 @@ module Punchblock
|
|
|
366
387
|
|
|
367
388
|
it 'should send an end (busy) event to the translator' do
|
|
368
389
|
expected_end_event = Punchblock::Event::End.new :reason => :busy,
|
|
390
|
+
platform_code: cause,
|
|
369
391
|
:target_call_id => subject.id
|
|
370
392
|
translator.should_receive(:handle_pb_event).with expected_end_event
|
|
371
393
|
subject.process_ami_event ami_event
|
|
@@ -382,6 +404,7 @@ module Punchblock
|
|
|
382
404
|
|
|
383
405
|
it 'should send an end (timeout) event to the translator' do
|
|
384
406
|
expected_end_event = Punchblock::Event::End.new :reason => :timeout,
|
|
407
|
+
platform_code: cause,
|
|
385
408
|
:target_call_id => subject.id
|
|
386
409
|
translator.should_receive(:handle_pb_event).with expected_end_event
|
|
387
410
|
subject.process_ami_event ami_event
|
|
@@ -400,6 +423,7 @@ module Punchblock
|
|
|
400
423
|
|
|
401
424
|
it 'should send an end (reject) event to the translator' do
|
|
402
425
|
expected_end_event = Punchblock::Event::End.new :reason => :reject,
|
|
426
|
+
platform_code: cause,
|
|
403
427
|
:target_call_id => subject.id
|
|
404
428
|
translator.should_receive(:handle_pb_event).with expected_end_event
|
|
405
429
|
subject.process_ami_event ami_event
|
|
@@ -452,6 +476,7 @@ module Punchblock
|
|
|
452
476
|
|
|
453
477
|
it 'should send an end (error) event to the translator' do
|
|
454
478
|
expected_end_event = Punchblock::Event::End.new :reason => :error,
|
|
479
|
+
platform_code: cause,
|
|
455
480
|
:target_call_id => subject.id
|
|
456
481
|
translator.should_receive(:handle_pb_event).with expected_end_event
|
|
457
482
|
subject.process_ami_event ami_event
|
|
@@ -461,7 +486,7 @@ module Punchblock
|
|
|
461
486
|
end
|
|
462
487
|
|
|
463
488
|
context 'with an event for a known AGI command component' do
|
|
464
|
-
let(:mock_component_node) {
|
|
489
|
+
let(:mock_component_node) { Punchblock::Component::Asterisk::AGI::Command.new name: 'EXEC ANSWER', params: [] }
|
|
465
490
|
let :component do
|
|
466
491
|
Component::Asterisk::AGICommand.new mock_component_node, subject
|
|
467
492
|
end
|
|
@@ -592,7 +617,7 @@ module Punchblock
|
|
|
592
617
|
'Channel' => "SIP/1234-00000000"
|
|
593
618
|
end
|
|
594
619
|
|
|
595
|
-
let(:response) {
|
|
620
|
+
let(:response) { double 'Response' }
|
|
596
621
|
|
|
597
622
|
it 'should execute the handler' do
|
|
598
623
|
response.should_receive(:call).once.with ami_event
|
|
@@ -621,7 +646,7 @@ module Punchblock
|
|
|
621
646
|
|
|
622
647
|
let(:other_call_id) { other_call.id }
|
|
623
648
|
let :command do
|
|
624
|
-
Punchblock::Command::Join.new :
|
|
649
|
+
Punchblock::Command::Join.new call_uri: other_call_id
|
|
625
650
|
end
|
|
626
651
|
|
|
627
652
|
before do
|
|
@@ -702,10 +727,8 @@ module Punchblock
|
|
|
702
727
|
let(:state) { 'Link' }
|
|
703
728
|
|
|
704
729
|
let :expected_joined do
|
|
705
|
-
Punchblock::Event::Joined.new
|
|
706
|
-
|
|
707
|
-
joined.call_id = other_call_id
|
|
708
|
-
end
|
|
730
|
+
Punchblock::Event::Joined.new target_call_id: subject.id,
|
|
731
|
+
call_uri: other_call_id
|
|
709
732
|
end
|
|
710
733
|
|
|
711
734
|
it 'sends the Joined event when the call is the first channel' do
|
|
@@ -723,10 +746,8 @@ module Punchblock
|
|
|
723
746
|
let(:state) { 'Unlink' }
|
|
724
747
|
|
|
725
748
|
let :expected_unjoined do
|
|
726
|
-
Punchblock::Event::Unjoined.new
|
|
727
|
-
|
|
728
|
-
joined.call_id = other_call_id
|
|
729
|
-
end
|
|
749
|
+
Punchblock::Event::Unjoined.new target_call_id: subject.id,
|
|
750
|
+
call_uri: other_call_id
|
|
730
751
|
end
|
|
731
752
|
|
|
732
753
|
it 'sends the Unjoined event when the call is the first channel' do
|
|
@@ -777,10 +798,8 @@ module Punchblock
|
|
|
777
798
|
end
|
|
778
799
|
|
|
779
800
|
let :expected_unjoined do
|
|
780
|
-
Punchblock::Event::Unjoined.new
|
|
781
|
-
|
|
782
|
-
joined.call_id = other_call_id
|
|
783
|
-
end
|
|
801
|
+
Punchblock::Event::Unjoined.new target_call_id: subject.id,
|
|
802
|
+
call_uri: other_call_id
|
|
784
803
|
end
|
|
785
804
|
|
|
786
805
|
it 'sends the Unjoined event when the call is the first channel' do
|
|
@@ -821,14 +840,14 @@ module Punchblock
|
|
|
821
840
|
end
|
|
822
841
|
|
|
823
842
|
let :expected_pb_event do
|
|
824
|
-
Event::Asterisk::AMI::Event.new :
|
|
825
|
-
:
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
:
|
|
843
|
+
Event::Asterisk::AMI::Event.new name: 'Foo',
|
|
844
|
+
headers: { 'Channel' => channel,
|
|
845
|
+
'Uniqueid' => "1320842458.8",
|
|
846
|
+
'Calleridnum' => "5678",
|
|
847
|
+
'Calleridname' => "Jane Smith",
|
|
848
|
+
'Cause' => "0",
|
|
849
|
+
'Cause-txt' => "Unknown"},
|
|
850
|
+
target_call_id: subject.id
|
|
832
851
|
end
|
|
833
852
|
|
|
834
853
|
it 'sends the AMI event to the connection as a PB event' do
|
|
@@ -863,8 +882,8 @@ module Punchblock
|
|
|
863
882
|
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
|
|
864
883
|
end
|
|
865
884
|
|
|
866
|
-
context "
|
|
867
|
-
let(:
|
|
885
|
+
context "because the channel is gone" do
|
|
886
|
+
let(:error) { ChannelGoneError }
|
|
868
887
|
|
|
869
888
|
it "should return an :item_not_found event for the call" do
|
|
870
889
|
subject.execute_command command
|
|
@@ -884,9 +903,9 @@ module Punchblock
|
|
|
884
903
|
command.response(0.5).should be true
|
|
885
904
|
end
|
|
886
905
|
|
|
887
|
-
it "with a :decline reason should send
|
|
906
|
+
it "with a :decline reason should send a Hangup AMI command (cause 21) and set the command's response" do
|
|
888
907
|
command.reason = :decline
|
|
889
|
-
|
|
908
|
+
ami_client.should_receive(:send_action).once.with('Hangup', 'Channel' => channel, 'Cause' => 21).and_return RubyAMI::Response.new
|
|
890
909
|
subject.execute_command command
|
|
891
910
|
command.response(0.5).should be true
|
|
892
911
|
end
|
|
@@ -909,8 +928,8 @@ module Punchblock
|
|
|
909
928
|
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
|
|
910
929
|
end
|
|
911
930
|
|
|
912
|
-
context "
|
|
913
|
-
let(:
|
|
931
|
+
context "because the channel is gone" do
|
|
932
|
+
let(:error) { ChannelGoneError }
|
|
914
933
|
|
|
915
934
|
it "should return an :item_not_found event for the call" do
|
|
916
935
|
subject.execute_command command
|
|
@@ -935,7 +954,7 @@ module Punchblock
|
|
|
935
954
|
subject.should be_answered
|
|
936
955
|
end
|
|
937
956
|
|
|
938
|
-
context "when the AMI
|
|
957
|
+
context "when the AMI command raises an error" do
|
|
939
958
|
let(:message) { 'Some error' }
|
|
940
959
|
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
941
960
|
|
|
@@ -951,8 +970,8 @@ module Punchblock
|
|
|
951
970
|
subject.should_not be_answered
|
|
952
971
|
end
|
|
953
972
|
|
|
954
|
-
context "
|
|
955
|
-
let(:
|
|
973
|
+
context "because the channel is gone" do
|
|
974
|
+
let(:error) { ChannelGoneError }
|
|
956
975
|
|
|
957
976
|
it "should return an :item_not_found event for the call" do
|
|
958
977
|
subject.execute_command command
|
|
@@ -982,7 +1001,7 @@ module Punchblock
|
|
|
982
1001
|
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
|
|
983
1002
|
end
|
|
984
1003
|
|
|
985
|
-
context "
|
|
1004
|
+
context "which is 'No such channel'" do
|
|
986
1005
|
let(:message) { 'No such channel' }
|
|
987
1006
|
|
|
988
1007
|
it "should return an :item_not_found event for the call" do
|
|
@@ -990,6 +1009,140 @@ module Punchblock
|
|
|
990
1009
|
command.response(0.5).should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id)
|
|
991
1010
|
end
|
|
992
1011
|
end
|
|
1012
|
+
|
|
1013
|
+
context "which is 'Channel SIP/nosuchchannel does not exist.'" do
|
|
1014
|
+
let(:message) { 'Channel SIP/nosuchchannel does not exist.' }
|
|
1015
|
+
|
|
1016
|
+
it "should return an :item_not_found event for the call" do
|
|
1017
|
+
subject.execute_command command
|
|
1018
|
+
command.response(0.5).should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id)
|
|
1019
|
+
end
|
|
1020
|
+
end
|
|
1021
|
+
end
|
|
1022
|
+
end
|
|
1023
|
+
|
|
1024
|
+
context "with a join command" do
|
|
1025
|
+
let(:other_call_id) { "abc123" }
|
|
1026
|
+
let(:other_channel) { 'SIP/bar' }
|
|
1027
|
+
let(:other_translator) { double('Translator::Asterisk').as_null_object }
|
|
1028
|
+
|
|
1029
|
+
let :other_call do
|
|
1030
|
+
Call.new other_channel, other_translator, ami_client, connection
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
let :command do
|
|
1034
|
+
Punchblock::Command::Join.new call_uri: other_call_id
|
|
1035
|
+
end
|
|
1036
|
+
|
|
1037
|
+
before { translator.should_receive(:call_with_id).with(other_call_id).and_return(other_call) }
|
|
1038
|
+
|
|
1039
|
+
it "executes the proper dialplan Bridge application" do
|
|
1040
|
+
subject.wrapped_object.should_receive(:execute_agi_command).with('EXEC Bridge', other_channel).and_return code: 200
|
|
1041
|
+
subject.execute_command command
|
|
1042
|
+
end
|
|
1043
|
+
|
|
1044
|
+
context "when the AMI command raises an error" do
|
|
1045
|
+
let(:message) { 'Some error' }
|
|
1046
|
+
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1047
|
+
|
|
1048
|
+
before { subject.wrapped_object.should_receive(:execute_agi_command).and_raise error }
|
|
1049
|
+
|
|
1050
|
+
it "should return an error with the message" do
|
|
1051
|
+
subject.execute_command command
|
|
1052
|
+
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
|
|
1053
|
+
end
|
|
1054
|
+
|
|
1055
|
+
it "should not be answered" do
|
|
1056
|
+
subject.execute_command command
|
|
1057
|
+
subject.should_not be_answered
|
|
1058
|
+
end
|
|
1059
|
+
|
|
1060
|
+
context "because the channel is gone" do
|
|
1061
|
+
let(:error) { ChannelGoneError }
|
|
1062
|
+
|
|
1063
|
+
it "should return an :item_not_found event for the call" do
|
|
1064
|
+
subject.execute_command command
|
|
1065
|
+
command.response(0.5).should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id)
|
|
1066
|
+
end
|
|
1067
|
+
end
|
|
1068
|
+
end
|
|
1069
|
+
end
|
|
1070
|
+
|
|
1071
|
+
context "with an unjoin command" do
|
|
1072
|
+
let(:other_call_id) { "abc123" }
|
|
1073
|
+
let(:other_channel) { 'SIP/bar' }
|
|
1074
|
+
|
|
1075
|
+
let :other_call do
|
|
1076
|
+
Call.new other_channel, translator, ami_client, connection
|
|
1077
|
+
end
|
|
1078
|
+
|
|
1079
|
+
let :command do
|
|
1080
|
+
Punchblock::Command::Unjoin.new call_uri: other_call_id
|
|
1081
|
+
end
|
|
1082
|
+
|
|
1083
|
+
it "executes the unjoin through redirection" do
|
|
1084
|
+
translator.should_receive(:call_with_id).with(other_call_id).and_return(nil)
|
|
1085
|
+
|
|
1086
|
+
ami_client.should_receive(:send_action).once.with("Redirect",
|
|
1087
|
+
'Channel' => channel,
|
|
1088
|
+
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1089
|
+
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1090
|
+
'Context' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT,
|
|
1091
|
+
).and_return RubyAMI::Response.new
|
|
1092
|
+
|
|
1093
|
+
subject.execute_command command
|
|
1094
|
+
|
|
1095
|
+
command.response(1).should be_true
|
|
1096
|
+
end
|
|
1097
|
+
|
|
1098
|
+
it "executes the unjoin through redirection, on the subject call and the other call" do
|
|
1099
|
+
translator.should_receive(:call_with_id).with(other_call_id).and_return(other_call)
|
|
1100
|
+
|
|
1101
|
+
ami_client.should_receive(:send_action).once.with("Redirect",
|
|
1102
|
+
'Channel' => channel,
|
|
1103
|
+
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1104
|
+
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1105
|
+
'Context' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT,
|
|
1106
|
+
'ExtraChannel' => other_channel,
|
|
1107
|
+
'ExtraExten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1108
|
+
'ExtraPriority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1109
|
+
'ExtraContext' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT
|
|
1110
|
+
).and_return RubyAMI::Response.new
|
|
1111
|
+
|
|
1112
|
+
subject.execute_command command
|
|
1113
|
+
end
|
|
1114
|
+
|
|
1115
|
+
context "when the AMI commannd raises an error" do
|
|
1116
|
+
let(:message) { 'Some error' }
|
|
1117
|
+
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
|
|
1118
|
+
|
|
1119
|
+
before do
|
|
1120
|
+
translator.should_receive(:call_with_id).with(other_call_id).and_return(nil)
|
|
1121
|
+
ami_client.should_receive(:send_action).and_raise error
|
|
1122
|
+
end
|
|
1123
|
+
|
|
1124
|
+
it "should return an error with the message" do
|
|
1125
|
+
subject.execute_command command
|
|
1126
|
+
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
|
|
1127
|
+
end
|
|
1128
|
+
|
|
1129
|
+
context "which is 'No such channel'" do
|
|
1130
|
+
let(:message) { 'No such channel' }
|
|
1131
|
+
|
|
1132
|
+
it "should return an :item_not_found event for the call" do
|
|
1133
|
+
subject.execute_command command
|
|
1134
|
+
command.response(0.5).should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id)
|
|
1135
|
+
end
|
|
1136
|
+
end
|
|
1137
|
+
|
|
1138
|
+
context "which is 'Channel SIP/nosuchchannel does not exist.'" do
|
|
1139
|
+
let(:message) { 'Channel SIP/nosuchchannel does not exist.' }
|
|
1140
|
+
|
|
1141
|
+
it "should return an :item_not_found event for the call" do
|
|
1142
|
+
subject.execute_command command
|
|
1143
|
+
command.response(0.5).should be == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{subject.id}", subject.id)
|
|
1144
|
+
end
|
|
1145
|
+
end
|
|
993
1146
|
end
|
|
994
1147
|
end
|
|
995
1148
|
|
|
@@ -1035,6 +1188,81 @@ module Punchblock
|
|
|
1035
1188
|
end
|
|
1036
1189
|
end
|
|
1037
1190
|
|
|
1191
|
+
context 'with a Prompt component' do
|
|
1192
|
+
def grxml_doc(mode = :dtmf)
|
|
1193
|
+
RubySpeech::GRXML.draw :mode => mode.to_s, :root => 'digits' do
|
|
1194
|
+
rule id: 'digits' do
|
|
1195
|
+
one_of do
|
|
1196
|
+
0.upto(1) { |d| item { d.to_s } }
|
|
1197
|
+
end
|
|
1198
|
+
end
|
|
1199
|
+
end
|
|
1200
|
+
end
|
|
1201
|
+
|
|
1202
|
+
let :command do
|
|
1203
|
+
Punchblock::Component::Prompt.new(
|
|
1204
|
+
{
|
|
1205
|
+
render_document: {
|
|
1206
|
+
content_type: 'text/uri-list',
|
|
1207
|
+
value: ['http://example.com/hello.mp3']
|
|
1208
|
+
},
|
|
1209
|
+
renderer: renderer
|
|
1210
|
+
},
|
|
1211
|
+
{
|
|
1212
|
+
grammar: {
|
|
1213
|
+
value: grxml_doc,
|
|
1214
|
+
content_type: 'application/srgs+xml'
|
|
1215
|
+
},
|
|
1216
|
+
recognizer: recognizer
|
|
1217
|
+
})
|
|
1218
|
+
end
|
|
1219
|
+
|
|
1220
|
+
let(:mock_action) { Translator::Asterisk::Component::MRCPPrompt.new(command, subject) }
|
|
1221
|
+
|
|
1222
|
+
context "when the recognizer is unimrcp and the renderer is unimrcp" do
|
|
1223
|
+
let(:recognizer) { :unimrcp }
|
|
1224
|
+
let(:renderer) { :unimrcp }
|
|
1225
|
+
|
|
1226
|
+
it 'should create an MRCPPrompt component and execute it asynchronously' do
|
|
1227
|
+
Component::MRCPPrompt.should_receive(:new_link).once.with(command, subject).and_return mock_action
|
|
1228
|
+
mock_action.async.should_receive(:execute).once
|
|
1229
|
+
subject.execute_command command
|
|
1230
|
+
end
|
|
1231
|
+
end
|
|
1232
|
+
|
|
1233
|
+
context "when the recognizer is unimrcp and the renderer is asterisk" do
|
|
1234
|
+
let(:recognizer) { :unimrcp }
|
|
1235
|
+
let(:renderer) { :asterisk }
|
|
1236
|
+
|
|
1237
|
+
it 'should create an MRCPPrompt component and execute it asynchronously' do
|
|
1238
|
+
Component::MRCPNativePrompt.should_receive(:new_link).once.with(command, subject).and_return mock_action
|
|
1239
|
+
mock_action.async.should_receive(:execute).once
|
|
1240
|
+
subject.execute_command command
|
|
1241
|
+
end
|
|
1242
|
+
end
|
|
1243
|
+
|
|
1244
|
+
context "when the recognizer is unimrcp and the renderer is something we can't compose with unimrcp" do
|
|
1245
|
+
let(:recognizer) { :unimrcp }
|
|
1246
|
+
let(:renderer) { :swift }
|
|
1247
|
+
|
|
1248
|
+
it 'should return an error' do
|
|
1249
|
+
subject.execute_command command
|
|
1250
|
+
command.response(0.5).should be == ProtocolError.new.setup(:invalid_command, "Invalid recognizer/renderer combination", subject.id)
|
|
1251
|
+
end
|
|
1252
|
+
end
|
|
1253
|
+
|
|
1254
|
+
context "when the recognizer is something other than unimrcp" do
|
|
1255
|
+
let(:recognizer) { :asterisk }
|
|
1256
|
+
let(:renderer) { :unimrcp }
|
|
1257
|
+
|
|
1258
|
+
it 'should create a ComposedPrompt component and execute it asynchronously' do
|
|
1259
|
+
Component::ComposedPrompt.should_receive(:new_link).once.with(command, subject).and_return mock_action
|
|
1260
|
+
mock_action.async.should_receive(:execute).once
|
|
1261
|
+
subject.execute_command command
|
|
1262
|
+
end
|
|
1263
|
+
end
|
|
1264
|
+
end
|
|
1265
|
+
|
|
1038
1266
|
context 'with a Record component' do
|
|
1039
1267
|
let :command do
|
|
1040
1268
|
Punchblock::Component::Record.new
|
|
@@ -1057,7 +1285,7 @@ module Punchblock
|
|
|
1057
1285
|
end
|
|
1058
1286
|
|
|
1059
1287
|
let :mock_component do
|
|
1060
|
-
|
|
1288
|
+
double 'Component', :id => component_id
|
|
1061
1289
|
end
|
|
1062
1290
|
|
|
1063
1291
|
context "for a known component ID" do
|
|
@@ -1074,16 +1302,14 @@ module Punchblock
|
|
|
1074
1302
|
Punchblock::Component::Asterisk::AGI::Command.new :name => 'Wait'
|
|
1075
1303
|
end
|
|
1076
1304
|
|
|
1077
|
-
let(:comp_id) { component_command.response.
|
|
1305
|
+
let(:comp_id) { component_command.response.component_id }
|
|
1078
1306
|
|
|
1079
1307
|
let(:subsequent_command) { Punchblock::Component::Stop.new :component_id => comp_id }
|
|
1080
1308
|
|
|
1081
1309
|
let :expected_event do
|
|
1082
|
-
Punchblock::Event::Complete.new
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
e.reason = Punchblock::Event::Complete::Error.new
|
|
1086
|
-
end
|
|
1310
|
+
Punchblock::Event::Complete.new target_call_id: subject.id,
|
|
1311
|
+
component_id: comp_id,
|
|
1312
|
+
reason: Punchblock::Event::Complete::Error.new
|
|
1087
1313
|
end
|
|
1088
1314
|
|
|
1089
1315
|
before do
|
|
@@ -1141,89 +1367,6 @@ module Punchblock
|
|
|
1141
1367
|
command.response.should be == ProtocolError.new.setup('command-not-acceptable', "Did not understand command for call #{subject.id}", subject.id)
|
|
1142
1368
|
end
|
|
1143
1369
|
end
|
|
1144
|
-
|
|
1145
|
-
context "with a join command" do
|
|
1146
|
-
let(:other_call_id) { "abc123" }
|
|
1147
|
-
let(:other_channel) { 'SIP/bar' }
|
|
1148
|
-
let(:other_translator) { stub('Translator::Asterisk').as_null_object }
|
|
1149
|
-
|
|
1150
|
-
let :other_call do
|
|
1151
|
-
Call.new other_channel, other_translator, ami_client, connection
|
|
1152
|
-
end
|
|
1153
|
-
|
|
1154
|
-
let :command do
|
|
1155
|
-
Punchblock::Command::Join.new :call_id => other_call_id
|
|
1156
|
-
end
|
|
1157
|
-
|
|
1158
|
-
it "executes the proper dialplan Bridge application" do
|
|
1159
|
-
subject.wrapped_object.should_receive(:execute_agi_command).with('EXEC Bridge', other_channel).and_return code: 200
|
|
1160
|
-
translator.should_receive(:call_with_id).with(other_call_id).and_return(other_call)
|
|
1161
|
-
subject.execute_command command
|
|
1162
|
-
end
|
|
1163
|
-
end
|
|
1164
|
-
|
|
1165
|
-
context "with an unjoin command" do
|
|
1166
|
-
let(:other_call_id) { "abc123" }
|
|
1167
|
-
let(:other_channel) { 'SIP/bar' }
|
|
1168
|
-
|
|
1169
|
-
let :other_call do
|
|
1170
|
-
Call.new other_channel, translator, ami_client, connection
|
|
1171
|
-
end
|
|
1172
|
-
|
|
1173
|
-
let :command do
|
|
1174
|
-
Punchblock::Command::Unjoin.new :call_id => other_call_id
|
|
1175
|
-
end
|
|
1176
|
-
|
|
1177
|
-
it "executes the unjoin through redirection" do
|
|
1178
|
-
translator.should_receive(:call_with_id).with(other_call_id).and_return(nil)
|
|
1179
|
-
|
|
1180
|
-
ami_client.should_receive(:send_action).once.with("Redirect",
|
|
1181
|
-
'Channel' => channel,
|
|
1182
|
-
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1183
|
-
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1184
|
-
'Context' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT,
|
|
1185
|
-
).and_return RubyAMI::Response.new
|
|
1186
|
-
|
|
1187
|
-
subject.execute_command command
|
|
1188
|
-
|
|
1189
|
-
command.response(1).should be_true
|
|
1190
|
-
end
|
|
1191
|
-
|
|
1192
|
-
it "executes the unjoin through redirection, on the subject call and the other call" do
|
|
1193
|
-
translator.should_receive(:call_with_id).with(other_call_id).and_return(other_call)
|
|
1194
|
-
|
|
1195
|
-
ami_client.should_receive(:send_action).once.with("Redirect",
|
|
1196
|
-
'Channel' => channel,
|
|
1197
|
-
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1198
|
-
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1199
|
-
'Context' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT,
|
|
1200
|
-
'ExtraChannel' => other_channel,
|
|
1201
|
-
'ExtraExten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1202
|
-
'ExtraPriority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1203
|
-
'ExtraContext' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT
|
|
1204
|
-
).and_return RubyAMI::Response.new
|
|
1205
|
-
|
|
1206
|
-
subject.execute_command command
|
|
1207
|
-
end
|
|
1208
|
-
|
|
1209
|
-
it "handles redirect errors" do
|
|
1210
|
-
translator.should_receive(:call_with_id).with(other_call_id).and_return(nil)
|
|
1211
|
-
|
|
1212
|
-
error = RubyAMI::Error.new.tap { |e| e.message = 'FooBar' }
|
|
1213
|
-
|
|
1214
|
-
ami_client.should_receive(:send_action).once.with("Redirect",
|
|
1215
|
-
'Channel' => channel,
|
|
1216
|
-
'Exten' => Punchblock::Translator::Asterisk::REDIRECT_EXTENSION,
|
|
1217
|
-
'Priority' => Punchblock::Translator::Asterisk::REDIRECT_PRIORITY,
|
|
1218
|
-
'Context' => Punchblock::Translator::Asterisk::REDIRECT_CONTEXT,
|
|
1219
|
-
).and_raise error
|
|
1220
|
-
|
|
1221
|
-
subject.execute_command command
|
|
1222
|
-
response = command.response(1)
|
|
1223
|
-
response.should be_a ProtocolError
|
|
1224
|
-
response.text.should == 'FooBar'
|
|
1225
|
-
end
|
|
1226
|
-
end
|
|
1227
1370
|
end#execute_command
|
|
1228
1371
|
|
|
1229
1372
|
describe '#execute_agi_command' do
|
|
@@ -1251,14 +1394,34 @@ module Punchblock
|
|
|
1251
1394
|
end
|
|
1252
1395
|
|
|
1253
1396
|
context 'with an error' do
|
|
1397
|
+
let(:message) { 'Action failed' }
|
|
1398
|
+
|
|
1254
1399
|
let :error do
|
|
1255
|
-
RubyAMI::Error.new.tap { |e| e.message =
|
|
1400
|
+
RubyAMI::Error.new.tap { |e| e.message = message }
|
|
1256
1401
|
end
|
|
1257
1402
|
|
|
1258
1403
|
it 'should raise the error' do
|
|
1259
1404
|
ami_client.should_receive(:send_action).once.and_raise error
|
|
1260
1405
|
expect { subject.execute_agi_command 'EXEC ANSWER' }.to raise_error(RubyAMI::Error, 'Action failed')
|
|
1261
1406
|
end
|
|
1407
|
+
|
|
1408
|
+
context "which is 'No such channel'" do
|
|
1409
|
+
let(:message) { 'No such channel' }
|
|
1410
|
+
|
|
1411
|
+
it 'should raise ChannelGoneError' do
|
|
1412
|
+
ami_client.should_receive(:send_action).once.and_raise error
|
|
1413
|
+
expect { subject.execute_agi_command 'EXEC ANSWER' }.to raise_error(ChannelGoneError, message)
|
|
1414
|
+
end
|
|
1415
|
+
end
|
|
1416
|
+
|
|
1417
|
+
context "which is 'Channel SIP/nosuchchannel does not exist.'" do
|
|
1418
|
+
let(:message) { 'Channel SIP/nosuchchannel does not exist.' }
|
|
1419
|
+
|
|
1420
|
+
it 'should raise ChannelGoneError' do
|
|
1421
|
+
ami_client.should_receive(:send_action).once.and_raise error
|
|
1422
|
+
expect { subject.execute_agi_command 'EXEC ANSWER' }.to raise_error(ChannelGoneError, message)
|
|
1423
|
+
end
|
|
1424
|
+
end
|
|
1262
1425
|
end
|
|
1263
1426
|
|
|
1264
1427
|
describe 'when receiving an AsyncAGI event' do
|