adhearsion 2.6.4 → 3.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/.travis.yml +6 -9
- data/CHANGELOG.md +22 -7
- data/Gemfile +2 -0
- data/README.markdown +4 -5
- data/Rakefile +1 -2
- data/adhearsion.gemspec +19 -8
- data/features/cli_create.feature +19 -3
- data/features/step_definitions/cli_steps.rb +0 -11
- data/features/support/env.rb +3 -4
- data/lib/adhearsion.rb +48 -27
- data/lib/adhearsion/call.rb +34 -50
- data/lib/adhearsion/call_controller.rb +6 -12
- data/lib/adhearsion/call_controller/dial.rb +15 -53
- data/lib/adhearsion/call_controller/input.rb +39 -162
- data/lib/adhearsion/call_controller/input/ask_grammar_builder.rb +44 -0
- data/lib/adhearsion/call_controller/input/menu_builder.rb +136 -0
- data/lib/adhearsion/call_controller/input/prompt_builder.rb +78 -0
- data/lib/adhearsion/call_controller/input/result.rb +46 -0
- data/lib/adhearsion/call_controller/output.rb +48 -67
- data/lib/adhearsion/call_controller/output/abstract_player.rb +3 -3
- data/lib/adhearsion/call_controller/output/async_player.rb +3 -3
- data/lib/adhearsion/call_controller/output/player.rb +1 -1
- data/lib/adhearsion/call_controller/record.rb +23 -8
- data/lib/adhearsion/calls.rb +1 -1
- data/lib/adhearsion/cli_commands/ahn_command.rb +2 -65
- data/lib/adhearsion/cli_commands/thor_errors.rb +0 -6
- data/lib/adhearsion/configuration.rb +91 -39
- data/lib/adhearsion/core_ext/blather/stanza.rb +41 -0
- data/lib/adhearsion/core_ext/blather/stanza/presence.rb +13 -0
- data/lib/adhearsion/error.rb +5 -0
- data/lib/adhearsion/event.rb +21 -0
- data/lib/adhearsion/event/active_speaker.rb +11 -0
- data/lib/adhearsion/event/answered.rb +11 -0
- data/lib/adhearsion/event/asterisk.rb +10 -0
- data/lib/adhearsion/event/asterisk/ami.rb +34 -0
- data/lib/adhearsion/event/complete.rb +75 -0
- data/lib/adhearsion/event/dtmf.rb +11 -0
- data/lib/adhearsion/event/end.rb +22 -0
- data/lib/adhearsion/event/input_timers_started.rb +9 -0
- data/lib/adhearsion/event/joined.rb +17 -0
- data/lib/adhearsion/event/offer.rb +14 -0
- data/lib/adhearsion/event/ringing.rb +11 -0
- data/lib/adhearsion/event/started_speaking.rb +13 -0
- data/lib/adhearsion/event/stopped_speaking.rb +13 -0
- data/lib/adhearsion/event/unjoined.rb +17 -0
- data/lib/adhearsion/events.rb +47 -66
- data/lib/adhearsion/foundation.rb +0 -1
- data/lib/adhearsion/foundation/object.rb +0 -5
- data/lib/adhearsion/generators/app/app_generator.rb +4 -1
- data/lib/adhearsion/generators/app/templates/Gemfile.erb +2 -10
- data/lib/adhearsion/generators/app/templates/adhearsion.erb +9 -9
- data/lib/adhearsion/generators/app/templates/config.ru +7 -0
- data/lib/adhearsion/generators/app/templates/en.yml +4 -0
- data/lib/adhearsion/generators/app/templates/events.erb +2 -2
- data/lib/adhearsion/generators/app/templates/hello_world.wav +0 -0
- data/lib/adhearsion/generators/app/templates/simon_game.rb +2 -1
- data/lib/adhearsion/generators/app/templates/simon_game_spec.rb +2 -2
- data/lib/adhearsion/has_headers.rb +34 -0
- data/lib/adhearsion/http_server.rb +37 -0
- data/lib/adhearsion/initializer.rb +19 -153
- data/lib/adhearsion/logging.rb +6 -25
- data/lib/adhearsion/outbound_call.rb +5 -5
- data/lib/adhearsion/plugin.rb +1 -0
- data/lib/adhearsion/protocol_error.rb +26 -0
- data/lib/adhearsion/rayo.rb +30 -0
- data/lib/adhearsion/rayo/client.rb +62 -0
- data/lib/adhearsion/rayo/client/component_registry.rb +33 -0
- data/lib/adhearsion/rayo/command.rb +21 -0
- data/lib/adhearsion/rayo/command/accept.rb +16 -0
- data/lib/adhearsion/rayo/command/answer.rb +16 -0
- data/lib/adhearsion/rayo/command/dial.rb +57 -0
- data/lib/adhearsion/rayo/command/hangup.rb +16 -0
- data/lib/adhearsion/rayo/command/join.rb +43 -0
- data/lib/adhearsion/rayo/command/mute.rb +13 -0
- data/lib/adhearsion/rayo/command/redirect.rb +23 -0
- data/lib/adhearsion/rayo/command/reject.rb +40 -0
- data/lib/adhearsion/rayo/command/unjoin.rb +24 -0
- data/lib/adhearsion/rayo/command/unmute.rb +13 -0
- data/lib/adhearsion/rayo/command_node.rb +47 -0
- data/lib/adhearsion/rayo/component.rb +21 -0
- data/lib/adhearsion/rayo/component/asterisk.rb +13 -0
- data/lib/adhearsion/rayo/component/asterisk/agi.rb +14 -0
- data/lib/adhearsion/rayo/component/asterisk/agi/command.rb +46 -0
- data/lib/adhearsion/rayo/component/asterisk/ami.rb +14 -0
- data/lib/adhearsion/rayo/component/asterisk/ami/action.rb +61 -0
- data/lib/adhearsion/rayo/component/component_node.rb +90 -0
- data/lib/adhearsion/rayo/component/input.rb +186 -0
- data/lib/adhearsion/rayo/component/output.rb +471 -0
- data/lib/adhearsion/rayo/component/prompt.rb +53 -0
- data/lib/adhearsion/rayo/component/receive_fax.rb +26 -0
- data/lib/adhearsion/rayo/component/record.rb +165 -0
- data/lib/adhearsion/rayo/component/send_fax.rb +64 -0
- data/lib/adhearsion/rayo/component/stop.rb +11 -0
- data/lib/adhearsion/rayo/connection.rb +12 -0
- data/lib/adhearsion/rayo/connection/asterisk.rb +74 -0
- data/lib/adhearsion/rayo/connection/connected.rb +22 -0
- data/lib/adhearsion/rayo/connection/generic_connection.rb +22 -0
- data/lib/adhearsion/rayo/connection/xmpp.rb +198 -0
- data/lib/adhearsion/rayo/disconnected_error.rb +22 -0
- data/lib/adhearsion/{punchblock_plugin → rayo}/initializer.rb +19 -19
- data/lib/adhearsion/rayo/rayo_node.rb +127 -0
- data/lib/adhearsion/rayo/ref.rb +57 -0
- data/lib/adhearsion/statistics.rb +1 -1
- data/lib/adhearsion/tasks.rb +1 -2
- data/lib/adhearsion/tasks/configuration.rb +1 -1
- data/lib/adhearsion/tasks/environment.rb +0 -2
- data/lib/adhearsion/tasks/i18n.rb +49 -0
- data/lib/adhearsion/translator.rb +11 -0
- data/lib/adhearsion/translator/asterisk.rb +234 -0
- data/lib/adhearsion/translator/asterisk/agi_app.rb +17 -0
- data/lib/adhearsion/translator/asterisk/agi_command.rb +45 -0
- data/lib/adhearsion/translator/asterisk/ami_error_converter.rb +20 -0
- data/lib/adhearsion/translator/asterisk/call.rb +416 -0
- data/lib/adhearsion/translator/asterisk/channel.rb +43 -0
- data/lib/adhearsion/translator/asterisk/component.rb +88 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk.rb +15 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk/agi_command.rb +42 -0
- data/lib/adhearsion/translator/asterisk/component/asterisk/ami_action.rb +68 -0
- data/lib/adhearsion/translator/asterisk/component/composed_prompt.rb +76 -0
- data/lib/adhearsion/translator/asterisk/component/dtmf_recognizer.rb +137 -0
- data/lib/adhearsion/translator/asterisk/component/input.rb +34 -0
- data/lib/adhearsion/translator/asterisk/component/input_component.rb +90 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_native_prompt.rb +71 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_prompt.rb +55 -0
- data/lib/adhearsion/translator/asterisk/component/mrcp_recog_prompt.rb +165 -0
- data/lib/adhearsion/translator/asterisk/component/output.rb +233 -0
- data/lib/adhearsion/translator/asterisk/component/record.rb +101 -0
- data/lib/adhearsion/translator/asterisk/component/stop_by_redirect.rb +30 -0
- data/lib/adhearsion/translator/asterisk/unimrcp_app.rb +28 -0
- data/lib/adhearsion/uri_list.rb +21 -0
- data/lib/adhearsion/version.rb +1 -1
- data/spec/adhearsion/call_controller/dial_spec.rb +79 -1420
- data/spec/adhearsion/call_controller/input_spec.rb +1141 -237
- data/spec/adhearsion/call_controller/output/async_player_spec.rb +10 -10
- data/spec/adhearsion/call_controller/output/player_spec.rb +8 -8
- data/spec/adhearsion/call_controller/output_spec.rb +162 -215
- data/spec/adhearsion/call_controller/record_spec.rb +15 -16
- data/spec/adhearsion/call_controller_spec.rb +23 -40
- data/spec/adhearsion/call_spec.rb +123 -129
- data/spec/adhearsion/calls_spec.rb +3 -3
- data/spec/adhearsion/configuration_spec.rb +94 -108
- data/spec/adhearsion/event/answered_spec.rb +50 -0
- data/spec/adhearsion/event/asterisk/Find Results +402 -0
- data/spec/adhearsion/event/asterisk/ami_spec.rb +81 -0
- data/spec/adhearsion/event/complete_spec.rb +176 -0
- data/spec/adhearsion/event/dtmf_spec.rb +35 -0
- data/spec/adhearsion/event/end_spec.rb +85 -0
- data/spec/adhearsion/event/input_timers_started_spec.rb +19 -0
- data/spec/adhearsion/event/joined_spec.rb +53 -0
- data/spec/adhearsion/event/offer_spec.rb +106 -0
- data/spec/adhearsion/event/ringing_spec.rb +50 -0
- data/spec/adhearsion/event/started_speaking_spec.rb +37 -0
- data/spec/adhearsion/event/stopped_speaking_spec.rb +37 -0
- data/spec/adhearsion/event/unjoined_spec.rb +48 -0
- data/spec/adhearsion/event/untitled +0 -0
- data/spec/adhearsion/events_spec.rb +19 -45
- data/spec/adhearsion/initializer_spec.rb +12 -184
- data/spec/adhearsion/logging_spec.rb +5 -20
- data/spec/adhearsion/outbound_call_spec.rb +13 -13
- data/spec/adhearsion/plugin_spec.rb +3 -4
- data/spec/adhearsion/protocol_error_spec.rb +91 -0
- data/spec/adhearsion/rayo/client/component_registry_spec.rb +26 -0
- data/spec/adhearsion/rayo/client_spec.rb +134 -0
- data/spec/adhearsion/rayo/command/accept_spec.rb +63 -0
- data/spec/adhearsion/rayo/command/answer_spec.rb +73 -0
- data/spec/adhearsion/rayo/command/dial_spec.rb +156 -0
- data/spec/adhearsion/rayo/command/hangup_spec.rb +63 -0
- data/spec/adhearsion/rayo/command/join_spec.rb +158 -0
- data/spec/adhearsion/rayo/command/mute_spec.rb +32 -0
- data/spec/adhearsion/rayo/command/redirect_spec.rb +89 -0
- data/spec/adhearsion/rayo/command/reject_spec.rb +117 -0
- data/spec/adhearsion/rayo/command/unjoin_spec.rb +82 -0
- data/spec/adhearsion/rayo/command/unmute_spec.rb +32 -0
- data/spec/adhearsion/rayo/command_node_spec.rb +101 -0
- data/spec/adhearsion/rayo/component/asterisk/agi/command_spec.rb +111 -0
- data/spec/adhearsion/rayo/component/asterisk/ami/action_spec.rb +173 -0
- data/spec/adhearsion/rayo/component/component_node_spec.rb +110 -0
- data/spec/adhearsion/rayo/component/input_spec.rb +715 -0
- data/spec/adhearsion/rayo/component/output_spec.rb +1030 -0
- data/spec/adhearsion/rayo/component/prompt_spec.rb +171 -0
- data/spec/adhearsion/rayo/component/receive_fax_spec.rb +136 -0
- data/spec/adhearsion/rayo/component/record_spec.rb +497 -0
- data/spec/adhearsion/rayo/component/send_fax_spec.rb +144 -0
- data/spec/adhearsion/rayo/connection/asterisk_spec.rb +118 -0
- data/spec/adhearsion/rayo/connection/xmpp_spec.rb +449 -0
- data/spec/adhearsion/rayo/initializer_spec.rb +353 -0
- data/spec/adhearsion/rayo/ref_spec.rb +168 -0
- data/spec/adhearsion/rayo_spec.rb +7 -0
- data/spec/adhearsion/router/route_spec.rb +1 -1
- data/spec/adhearsion/statistics_spec.rb +2 -5
- data/spec/adhearsion/translator/asterisk/call_spec.rb +2047 -0
- data/spec/adhearsion/translator/asterisk/component/asterisk/agi_command_spec.rb +256 -0
- data/spec/adhearsion/translator/asterisk/component/asterisk/ami_action_spec.rb +151 -0
- data/spec/adhearsion/translator/asterisk/component/composed_prompt_spec.rb +257 -0
- data/spec/adhearsion/translator/asterisk/component/input_spec.rb +571 -0
- data/spec/adhearsion/translator/asterisk/component/mrcp_native_prompt_spec.rb +774 -0
- data/spec/adhearsion/translator/asterisk/component/mrcp_prompt_spec.rb +1244 -0
- data/spec/adhearsion/translator/asterisk/component/output_spec.rb +1850 -0
- data/spec/adhearsion/translator/asterisk/component/record_spec.rb +426 -0
- data/spec/adhearsion/translator/asterisk/component/stop_by_redirect_spec.rb +62 -0
- data/spec/adhearsion/translator/asterisk/component_spec.rb +83 -0
- data/spec/adhearsion/translator/asterisk_spec.rb +685 -0
- data/spec/adhearsion/uri_list_spec.rb +88 -0
- data/spec/adhearsion_spec.rb +89 -14
- data/spec/fixtures/locale/en.yml +13 -0
- data/spec/fixtures/locale/it.yml +13 -0
- data/spec/spec_helper.rb +18 -5
- data/spec/support/call_controller_test_helpers.rb +3 -2
- data/spec/support/initializer_stubs.rb +3 -1
- data/spec/support/punchblock_examples.rb +65 -0
- data/spec/support/punchblock_mocks.rb +12 -0
- metadata +412 -70
- data/features/cli_daemon.feature +0 -20
- data/features/cli_restart.feature +0 -52
- data/features/cli_stop.feature +0 -50
- data/lib/adhearsion/call_controller/menu_dsl.rb +0 -21
- data/lib/adhearsion/call_controller/menu_dsl/array_match_calculator.rb +0 -26
- data/lib/adhearsion/call_controller/menu_dsl/calculated_match.rb +0 -43
- data/lib/adhearsion/call_controller/menu_dsl/calculated_match_collection.rb +0 -45
- data/lib/adhearsion/call_controller/menu_dsl/fixnum_match_calculator.rb +0 -11
- data/lib/adhearsion/call_controller/menu_dsl/match_calculator.rb +0 -40
- data/lib/adhearsion/call_controller/menu_dsl/menu.rb +0 -207
- data/lib/adhearsion/call_controller/menu_dsl/menu_builder.rb +0 -92
- data/lib/adhearsion/call_controller/menu_dsl/range_match_calculator.rb +0 -60
- data/lib/adhearsion/call_controller/menu_dsl/string_match_calculator.rb +0 -25
- data/lib/adhearsion/call_controller/utility.rb +0 -77
- data/lib/adhearsion/foundation/custom_daemonizer.rb +0 -52
- data/lib/adhearsion/punchblock_plugin.rb +0 -63
- data/scripts/cloc-1.64.pl +0 -10483
- data/spec/adhearsion/call_controller/menu_dsl/array_match_calculator_spec.rb +0 -76
- data/spec/adhearsion/call_controller/menu_dsl/calculated_match_collection_spec.rb +0 -60
- data/spec/adhearsion/call_controller/menu_dsl/calculated_match_spec.rb +0 -61
- data/spec/adhearsion/call_controller/menu_dsl/fixnum_match_calculator_spec.rb +0 -39
- data/spec/adhearsion/call_controller/menu_dsl/match_calculator_spec.rb +0 -17
- data/spec/adhearsion/call_controller/menu_dsl/menu_builder_spec.rb +0 -165
- data/spec/adhearsion/call_controller/menu_dsl/menu_spec.rb +0 -420
- data/spec/adhearsion/call_controller/menu_dsl/range_match_calculator_spec.rb +0 -32
- data/spec/adhearsion/call_controller/menu_dsl/string_match_calculator_spec.rb +0 -40
- data/spec/adhearsion/call_controller/utility_spec.rb +0 -90
- data/spec/adhearsion/punchblock_plugin/initializer_spec.rb +0 -356
- data/spec/adhearsion/punchblock_plugin_spec.rb +0 -59
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module Translator
|
|
7
|
+
class Asterisk
|
|
8
|
+
module Component
|
|
9
|
+
module Asterisk
|
|
10
|
+
describe AGICommand do
|
|
11
|
+
include HasMockCallbackConnection
|
|
12
|
+
|
|
13
|
+
let(:channel) { 'SIP/foo' }
|
|
14
|
+
let(:ami_client) { double('AMI Client').as_null_object }
|
|
15
|
+
let(:translator) { Translator::Asterisk.new ami_client, connection }
|
|
16
|
+
let(:mock_call) { Translator::Asterisk::Call.new channel, translator, ami_client, connection }
|
|
17
|
+
let(:component_id) { Adhearsion.new_uuid }
|
|
18
|
+
|
|
19
|
+
before { stub_uuids component_id }
|
|
20
|
+
|
|
21
|
+
let :original_command do
|
|
22
|
+
Adhearsion::Rayo::Component::Asterisk::AGI::Command.new :name => 'EXEC ANSWER'
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subject { AGICommand.new original_command, mock_call }
|
|
26
|
+
|
|
27
|
+
let :response do
|
|
28
|
+
RubyAMI::Response.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'initial execution' do
|
|
32
|
+
before { original_command.request! }
|
|
33
|
+
|
|
34
|
+
it 'should send the appropriate action' do
|
|
35
|
+
expect(ami_client).to receive(:send_action).once.with('AGI', 'Channel' => channel, 'Command' => 'EXEC ANSWER', 'CommandID' => component_id).and_return(response)
|
|
36
|
+
subject.execute
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context 'with some parameters' do
|
|
40
|
+
let(:params) { [1000, 'foo'] }
|
|
41
|
+
|
|
42
|
+
let :original_command do
|
|
43
|
+
Adhearsion::Rayo::Component::Asterisk::AGI::Command.new :name => 'WAIT FOR DIGIT', :params => params
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'should send the appropriate action' do
|
|
47
|
+
expect(ami_client).to receive(:send_action).once.with('AGI', 'Channel' => channel, 'Command' => 'WAIT FOR DIGIT "1000" "foo"', 'CommandID' => component_id).and_return(response)
|
|
48
|
+
subject.execute
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context 'when the AMI action completes' do
|
|
54
|
+
before do
|
|
55
|
+
original_command.request!
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
let :expected_response do
|
|
59
|
+
Adhearsion::Rayo::Ref.new uri: component_id
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
let :response do
|
|
63
|
+
RubyAMI::Response.new 'ActionID' => "552a9d9f-46d7-45d8-a257-06fe95f48d99",
|
|
64
|
+
'Message' => 'Added AGI original_command to queue'
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'should send the component node a ref with the action ID' do
|
|
68
|
+
expect(ami_client).to receive(:send_action).once.and_return response
|
|
69
|
+
subject.execute
|
|
70
|
+
expect(original_command.response(1)).to eq(expected_response)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
context 'with an error' do
|
|
74
|
+
let(:message) { 'Action failed' }
|
|
75
|
+
let :response do
|
|
76
|
+
RubyAMI::Error.new.tap { |e| e.message = message }
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
before { expect(ami_client).to receive(:send_action).once.and_raise response }
|
|
80
|
+
|
|
81
|
+
it 'should send the component node false' do
|
|
82
|
+
subject.execute
|
|
83
|
+
expect(original_command.response(1)).to be_falsey
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
context "which is 'No such channel'" do
|
|
87
|
+
let(:message) { 'No such channel' }
|
|
88
|
+
|
|
89
|
+
it "should return an :item_not_found error for the command" do
|
|
90
|
+
subject.execute
|
|
91
|
+
expect(original_command.response(0.5)).to eq(Adhearsion::ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{mock_call.id}", mock_call.id))
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "which is 'Channel SIP/nosuchchannel does not exist.'" do
|
|
96
|
+
let(:message) { 'Channel SIP/nosuchchannel does not exist.' }
|
|
97
|
+
|
|
98
|
+
it "should return an :item_not_found error for the command" do
|
|
99
|
+
subject.execute
|
|
100
|
+
expect(original_command.response(0.5)).to eq(Adhearsion::ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{mock_call.id}", mock_call.id))
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
describe 'when receiving an AsyncAGI event' do
|
|
107
|
+
before do
|
|
108
|
+
original_command.request!
|
|
109
|
+
original_command.execute!
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context 'of type start'
|
|
113
|
+
|
|
114
|
+
context 'of type Exec' do
|
|
115
|
+
let (:ami_event_result) { "200%20result=123%20(timeout)%0A" }
|
|
116
|
+
let(:ami_event) do
|
|
117
|
+
RubyAMI::Event.new 'AsyncAGI',
|
|
118
|
+
"SubEvent" => "Exec",
|
|
119
|
+
"Channel" => channel,
|
|
120
|
+
"CommandId" => component_id,
|
|
121
|
+
"Command" => "EXEC ANSWER",
|
|
122
|
+
"Result" => ami_event_result
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
let(:ami_event_ast13) do
|
|
126
|
+
RubyAMI::Event.new 'AsyncAGIExec',
|
|
127
|
+
"Channel" => channel,
|
|
128
|
+
"CommandId" => component_id,
|
|
129
|
+
"Command" => "EXEC ANSWER",
|
|
130
|
+
"Result" => ami_event_result
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
let :expected_complete_reason do
|
|
134
|
+
Adhearsion::Rayo::Component::Asterisk::AGI::Command::Complete::Success.new :code => 200,
|
|
135
|
+
:result => 123,
|
|
136
|
+
:data => 'timeout'
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def should_send_complete_event
|
|
140
|
+
subject.handle_ami_event ami_event
|
|
141
|
+
|
|
142
|
+
complete_event = original_command.complete_event 0.5
|
|
143
|
+
|
|
144
|
+
expect(original_command).to be_complete
|
|
145
|
+
|
|
146
|
+
expect(complete_event.component_id).to eq(component_id.to_s)
|
|
147
|
+
expect(complete_event.reason).to eq(expected_complete_reason)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it 'should send a complete event' do
|
|
151
|
+
should_send_complete_event
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
context 'with an AsyncAGIExec event' do
|
|
155
|
+
let(:ami_event) { ami_event_ast13 }
|
|
156
|
+
|
|
157
|
+
it 'should send a complete event' do
|
|
158
|
+
should_send_complete_event
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
context 'when the result contains illegal characters in the AGI response' do
|
|
163
|
+
let (:ami_event_result) { '$' }
|
|
164
|
+
let :expected_complete_reason do
|
|
165
|
+
Adhearsion::Rayo::Component::Asterisk::AGI::Command::Complete::Success.new :code => -1,
|
|
166
|
+
:result => nil,
|
|
167
|
+
:data => nil
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def treat_as_failure
|
|
171
|
+
subject.handle_ami_event ami_event
|
|
172
|
+
|
|
173
|
+
complete_event = original_command.complete_event 0.5
|
|
174
|
+
|
|
175
|
+
expect(original_command).to be_complete
|
|
176
|
+
|
|
177
|
+
expect(complete_event.component_id).to eq(component_id.to_s)
|
|
178
|
+
expect(complete_event.reason).to eq(expected_complete_reason)
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
it 'treats it as a failure with code -1' do
|
|
182
|
+
treat_as_failure
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
context 'with an AsyncAGIExec event' do
|
|
186
|
+
let(:ami_event) { ami_event_ast13 }
|
|
187
|
+
|
|
188
|
+
it 'treats it as a failure with code -1' do
|
|
189
|
+
treat_as_failure
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
context "when the command was ASYNCAGI BREAK" do
|
|
195
|
+
let :original_command do
|
|
196
|
+
Adhearsion::Rayo::Component::Asterisk::AGI::Command.new :name => 'ASYNCAGI BREAK'
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
let(:chan_var) { nil }
|
|
200
|
+
|
|
201
|
+
before do
|
|
202
|
+
response = RubyAMI::Response.new 'Value' => chan_var
|
|
203
|
+
expect(ami_client).to receive(:send_action).once.with('GetVar', 'Channel' => channel, 'Variable' => 'ADHEARSION_END_ON_ASYNCAGI_BREAK').and_return response
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it 'should not send an end (hangup) event to the translator' do
|
|
207
|
+
expect(translator).to receive(:handle_pb_event).once.with kind_of(Adhearsion::Event::Complete)
|
|
208
|
+
expect(translator).to receive(:handle_pb_event).never.with kind_of(Adhearsion::Event::End)
|
|
209
|
+
subject.handle_ami_event ami_event
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
context "when the ADHEARSION_END_ON_ASYNCAGI_BREAK channel var is set" do
|
|
213
|
+
let(:chan_var) { 'true' }
|
|
214
|
+
|
|
215
|
+
it 'should send an end (hungup) event to the translator' do
|
|
216
|
+
expected_end_event = Adhearsion::Event::End.new reason: :hungup,
|
|
217
|
+
platform_code: 16,
|
|
218
|
+
target_call_id: mock_call.id
|
|
219
|
+
|
|
220
|
+
expect(translator).to receive(:handle_pb_event).once.with kind_of(Adhearsion::Event::Complete)
|
|
221
|
+
expect(translator).to receive(:handle_pb_event).once.with expected_end_event
|
|
222
|
+
subject.handle_ami_event ami_event
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
context "when the AMI event has a timestamp" do
|
|
226
|
+
let :ami_event do
|
|
227
|
+
RubyAMI::Event.new 'AsyncAGI',
|
|
228
|
+
"SubEvent" => "Exec",
|
|
229
|
+
"Channel" => channel,
|
|
230
|
+
"CommandId" => component_id,
|
|
231
|
+
"Command" => "EXEC ANSWER",
|
|
232
|
+
"Result" => "200%20result=123%20(timeout)%0A",
|
|
233
|
+
'Timestamp' => '1393368380.572575'
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
it "should use the AMI timestamp for the Rayo event" do
|
|
237
|
+
expected_end_event = Adhearsion::Event::End.new reason: :hungup,
|
|
238
|
+
platform_code: 16,
|
|
239
|
+
target_call_id: mock_call.id,
|
|
240
|
+
timestamp: DateTime.new(2014, 2, 25, 22, 46, 20)
|
|
241
|
+
expect(translator).to receive(:handle_pb_event).once.with kind_of(Adhearsion::Event::Complete)
|
|
242
|
+
expect(translator).to receive(:handle_pb_event).once.with expected_end_event
|
|
243
|
+
|
|
244
|
+
subject.handle_ami_event ami_event
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module Translator
|
|
7
|
+
class Asterisk
|
|
8
|
+
module Component
|
|
9
|
+
module Asterisk
|
|
10
|
+
describe AMIAction do
|
|
11
|
+
include HasMockCallbackConnection
|
|
12
|
+
|
|
13
|
+
let(:ami_client) { double('AMI Client').as_null_object }
|
|
14
|
+
let(:mock_translator) { Translator::Asterisk.new ami_client, connection }
|
|
15
|
+
|
|
16
|
+
let :original_command do
|
|
17
|
+
Adhearsion::Rayo::Component::Asterisk::AMI::Action.new :name => 'ExtensionStatus', :params => { :context => 'default', :exten => 'idonno' }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
before do
|
|
21
|
+
original_command.request!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subject { AMIAction.new original_command, mock_translator, ami_client }
|
|
25
|
+
|
|
26
|
+
context 'initial execution' do
|
|
27
|
+
let(:component_id) { Adhearsion.new_uuid }
|
|
28
|
+
|
|
29
|
+
let :expected_response do
|
|
30
|
+
Adhearsion::Rayo::Ref.new uri: component_id
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
before { stub_uuids component_id }
|
|
34
|
+
|
|
35
|
+
it 'should send the appropriate RubyAMI::Action and send the component node a ref' do
|
|
36
|
+
expect(ami_client).to receive(:send_action).once.with('ExtensionStatus', 'Context' => 'default', 'Exten' => 'idonno').and_return(RubyAMI::Response.new)
|
|
37
|
+
subject.execute
|
|
38
|
+
expect(original_command.response(1)).to eq(expected_response)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
context 'when the AMI action completes' do
|
|
43
|
+
let :response do
|
|
44
|
+
RubyAMI::Response.new 'ActionID' => '552a9d9f-46d7-45d8-a257-06fe95f48d99',
|
|
45
|
+
'Message' => 'Channel status will follow',
|
|
46
|
+
'Exten' => 'idonno',
|
|
47
|
+
'Context' => 'default',
|
|
48
|
+
'Hint' => '',
|
|
49
|
+
'Status' => '-1'
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
before { response.text_body = 'Some text body' }
|
|
53
|
+
|
|
54
|
+
let :expected_complete_reason do
|
|
55
|
+
Adhearsion::Rayo::Component::Asterisk::AMI::Action::Complete::Success.new message: 'Channel status will follow', text_body: 'Some text body', headers: {'Exten' => "idonno", 'Context' => "default", 'Hint' => "", 'Status' => "-1"}
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
context 'for a non-causal action' do
|
|
59
|
+
it 'should send a complete event to the component node' do
|
|
60
|
+
expect(ami_client).to receive(:send_action).once.and_return response
|
|
61
|
+
expect(subject).to receive(:send_complete_event).once.with expected_complete_reason
|
|
62
|
+
subject.execute
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
context 'for a causal action' do
|
|
67
|
+
let :original_command do
|
|
68
|
+
Adhearsion::Rayo::Component::Asterisk::AMI::Action.new :name => 'CoreShowChannels'
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
let :expected_action do
|
|
72
|
+
RubyAMI::Action.new 'CoreShowChannels'
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
let :event do
|
|
76
|
+
RubyAMI::Event.new 'CoreShowChannel', 'ActionID' => "552a9d9f-46d7-45d8-a257-06fe95f48d99",
|
|
77
|
+
'Channel' => 'SIP/127.0.0.1-00000013',
|
|
78
|
+
'UniqueID' => '1287686437.19',
|
|
79
|
+
'Context' => 'adhearsion',
|
|
80
|
+
'Extension' => '23432',
|
|
81
|
+
'Priority' => '2',
|
|
82
|
+
'ChannelState' => '6',
|
|
83
|
+
'ChannelStateDesc' => 'Up'
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
let :terminating_event do
|
|
87
|
+
RubyAMI::Event.new 'CoreShowChannelsComplete', 'EventList' => 'Complete',
|
|
88
|
+
'ListItems' => '3',
|
|
89
|
+
'ActionID' => 'umtLtvSg-RN5n-GEay-Z786-YdiaSLNXkcYN'
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
let :event_node do
|
|
93
|
+
Adhearsion::Event::Asterisk::AMI.new name: 'CoreShowChannel', component_id: subject.id, source_uri: subject.id, headers: {
|
|
94
|
+
'Channel' => 'SIP/127.0.0.1-00000013',
|
|
95
|
+
'UniqueID' => '1287686437.19',
|
|
96
|
+
'Context' => 'adhearsion',
|
|
97
|
+
'Extension' => '23432',
|
|
98
|
+
'Priority' => '2',
|
|
99
|
+
'ChannelState' => '6',
|
|
100
|
+
'ChannelStateDesc' => 'Up'
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
let :expected_complete_reason do
|
|
105
|
+
Adhearsion::Rayo::Component::Asterisk::AMI::Action::Complete::Success.new message: 'Channel status will follow', text_body: 'Some text body', headers: {'Exten' => "idonno", 'Context' => "default", 'Hint' => "", 'Status' => "-1", 'EventList' => 'Complete', 'ListItems' => '3'}
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
before { expect(ami_client).to receive(:send_action).once.and_return response }
|
|
109
|
+
|
|
110
|
+
it 'should send events to the component node' do
|
|
111
|
+
event_node
|
|
112
|
+
original_command.register_handler :internal, Adhearsion::Event::Asterisk::AMI do |event|
|
|
113
|
+
@event = event
|
|
114
|
+
end
|
|
115
|
+
response.events << event << terminating_event
|
|
116
|
+
subject.execute
|
|
117
|
+
expect(@event).to eq(event_node)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
it 'should send a complete event to the component node' do
|
|
121
|
+
response.events << event << terminating_event
|
|
122
|
+
|
|
123
|
+
subject.execute
|
|
124
|
+
|
|
125
|
+
expect(original_command.complete_event(0.5).reason).to eq(expected_complete_reason)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
context 'with an error' do
|
|
130
|
+
let :error do
|
|
131
|
+
RubyAMI::Error.new.tap { |e| e.message = 'Action failed' }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
let :expected_complete_reason do
|
|
135
|
+
Adhearsion::Event::Complete::Error.new details: 'Action failed'
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
it 'should send a complete event to the component node' do
|
|
139
|
+
expect(ami_client).to receive(:send_action).once.and_raise error
|
|
140
|
+
expected_complete_reason
|
|
141
|
+
subject.execute
|
|
142
|
+
expect(original_command.complete_event(0.5).reason).to eq(expected_complete_reason)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module Translator
|
|
7
|
+
class Asterisk
|
|
8
|
+
module Component
|
|
9
|
+
describe ComposedPrompt do
|
|
10
|
+
class MockConnection
|
|
11
|
+
attr_reader :events
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@events = []
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def handle_event(event)
|
|
18
|
+
@events << event
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
let(:connection) { MockConnection.new }
|
|
23
|
+
let(:ami_client) { double('AMI') }
|
|
24
|
+
let(:translator) { Translator::Asterisk.new ami_client, connection }
|
|
25
|
+
let(:call) { Translator::Asterisk::Call.new 'foo', translator, ami_client, connection }
|
|
26
|
+
|
|
27
|
+
let :ssml_doc do
|
|
28
|
+
RubySpeech::SSML.draw do
|
|
29
|
+
audio src: 'tt-monkeys'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
let :dtmf_grammar do
|
|
34
|
+
RubySpeech::GRXML.draw mode: 'dtmf', root: 'digit' do
|
|
35
|
+
rule id: 'digit' do
|
|
36
|
+
one_of do
|
|
37
|
+
item { '1' }
|
|
38
|
+
item { '2' }
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
let :output_command_options do
|
|
45
|
+
{ render_document: {value: ssml_doc} }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let :input_command_options do
|
|
49
|
+
{
|
|
50
|
+
mode: :dtmf,
|
|
51
|
+
grammar: {value: dtmf_grammar}
|
|
52
|
+
}
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
let(:command_options) { {} }
|
|
56
|
+
|
|
57
|
+
let :output_command do
|
|
58
|
+
Adhearsion::Rayo::Component::Output.new output_command_options
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
let :input_command do
|
|
62
|
+
Adhearsion::Rayo::Component::Input.new input_command_options
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
let :original_command do
|
|
66
|
+
Adhearsion::Rayo::Component::Prompt.new output_command, input_command, command_options
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
subject { described_class.new original_command, call }
|
|
70
|
+
|
|
71
|
+
let(:playbackstatus) { 'SUCCESS' }
|
|
72
|
+
|
|
73
|
+
before do
|
|
74
|
+
allow(call).to receive_messages answered?: true, execute_agi_command: true
|
|
75
|
+
allow(call).to receive(:channel_var).with('PLAYBACKSTATUS').and_return playbackstatus
|
|
76
|
+
original_command.request!
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
let (:ast13mode) { false }
|
|
80
|
+
|
|
81
|
+
def ami_event_for_dtmf(digit, position)
|
|
82
|
+
if ast13mode
|
|
83
|
+
RubyAMI::Event.new 'DTMF' + (position == :start ? 'Begin' : '') + (position == :end ? 'End' : ''),
|
|
84
|
+
'Digit' => digit.to_s
|
|
85
|
+
else
|
|
86
|
+
RubyAMI::Event.new 'DTMF',
|
|
87
|
+
'Digit' => digit.to_s,
|
|
88
|
+
'Start' => position == :start ? 'Yes' : 'No',
|
|
89
|
+
'End' => position == :end ? 'Yes' : 'No'
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def send_ami_events_for_dtmf(digit)
|
|
94
|
+
call.process_ami_event ami_event_for_dtmf(digit, :start)
|
|
95
|
+
call.process_ami_event ami_event_for_dtmf(digit, :end)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
describe '#execute' do
|
|
99
|
+
context '#barge_in' do
|
|
100
|
+
context 'true' do
|
|
101
|
+
it "should execute an output component on the call and return a ref" do
|
|
102
|
+
expect(call).to receive(:execute_agi_command).once.with('EXEC Playback', 'tt-monkeys')
|
|
103
|
+
subject.execute
|
|
104
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
context "if output fails to start" do
|
|
108
|
+
it "should return the error returned by output"
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context "receiving dtmf during output" do
|
|
112
|
+
it "should stop the output"
|
|
113
|
+
|
|
114
|
+
it "should contribute to the input result"
|
|
115
|
+
|
|
116
|
+
it "should return a match complete event"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context "when not receiving any DTMF input at all" do
|
|
120
|
+
it "should not start the initial timer until output completes"
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
context 'false' do
|
|
125
|
+
it "should execute an output component on the call" do
|
|
126
|
+
expect(call).to receive(:execute_agi_command).once.with('EXEC Playback', 'tt-monkeys')
|
|
127
|
+
subject.execute
|
|
128
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "if output fails to start" do
|
|
132
|
+
let(:output_response) { Adhearsion::ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details.' }
|
|
133
|
+
|
|
134
|
+
let :ssml_doc do
|
|
135
|
+
RubySpeech::SSML.draw do
|
|
136
|
+
string "Foo Bar"
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
it "should return the error returned by output" do
|
|
141
|
+
subject.execute
|
|
142
|
+
expect(original_command.response(0.1)).to eq(output_response)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
context "receiving dtmf during output" do
|
|
147
|
+
it "should not stop the output"
|
|
148
|
+
|
|
149
|
+
it "should not contribute to the input result"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
context "receiving matching dtmf after output completes" do
|
|
153
|
+
let :expected_nlsml do
|
|
154
|
+
RubySpeech::NLSML.draw do
|
|
155
|
+
interpretation confidence: 1 do
|
|
156
|
+
instance "dtmf-1"
|
|
157
|
+
input "1", mode: :dtmf
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
let :expected_event do
|
|
163
|
+
Adhearsion::Event::Complete.new reason: expected_reason,
|
|
164
|
+
component_id: subject.id,
|
|
165
|
+
source_uri: subject.id,
|
|
166
|
+
target_call_id: call.id
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
let :expected_reason do
|
|
170
|
+
Adhearsion::Rayo::Component::Input::Complete::Match.new nlsml: expected_nlsml
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def should_return_a_match_complete_event
|
|
174
|
+
expected_event
|
|
175
|
+
subject.execute
|
|
176
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
177
|
+
send_ami_events_for_dtmf 1
|
|
178
|
+
|
|
179
|
+
expect(connection.events).to include(expected_event)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it "should return a match complete event" do
|
|
183
|
+
should_return_a_match_complete_event
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
context 'with Asterisk 13 DTMFEnd event' do
|
|
187
|
+
let (:ast13mode) { true }
|
|
188
|
+
|
|
189
|
+
it "should return a match complete event" do
|
|
190
|
+
should_return_a_match_complete_event
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
context "when not receiving any DTMF input at all" do
|
|
196
|
+
it "should not start the initial timer until output completes"
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
describe "#execute_command" do
|
|
203
|
+
context "with a command it does not understand" do
|
|
204
|
+
let(:command) { Adhearsion::Rayo::Component::Output::Pause.new }
|
|
205
|
+
|
|
206
|
+
before { command.request! }
|
|
207
|
+
it "returns a Adhearsion::ProtocolError response" do
|
|
208
|
+
subject.execute_command command
|
|
209
|
+
expect(command.response(0.1)).to be_a Adhearsion::ProtocolError
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
context "with a Stop command" do
|
|
214
|
+
let(:command) { Adhearsion::Rayo::Component::Stop.new }
|
|
215
|
+
let(:channel) { "SIP/1234-00000000" }
|
|
216
|
+
let :ami_event do
|
|
217
|
+
RubyAMI::Event.new 'AsyncAGI',
|
|
218
|
+
'SubEvent' => "Start",
|
|
219
|
+
'Channel' => channel,
|
|
220
|
+
'Env' => "agi_request%3A%20async%0Aagi_channel%3A%20SIP%2F1234-00000000%0Aagi_language%3A%20en%0Aagi_type%3A%20SIP%0Aagi_uniqueid%3A%201320835995.0%0Aagi_version%3A%201.8.4.1%0Aagi_callerid%3A%205678%0Aagi_calleridname%3A%20Jane%20Smith%0Aagi_callingpres%3A%200%0Aagi_callingani2%3A%200%0Aagi_callington%3A%200%0Aagi_callingtns%3A%200%0Aagi_dnid%3A%201000%0Aagi_rdnis%3A%20unknown%0Aagi_context%3A%20default%0Aagi_extension%3A%201000%0Aagi_priority%3A%201%0Aagi_enhanced%3A%200.0%0Aagi_accountcode%3A%20%0Aagi_threadid%3A%204366221312%0A%0A"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
before do
|
|
224
|
+
command.request!
|
|
225
|
+
original_command.execute!
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "sets the command response to true" do
|
|
229
|
+
expect(call).to receive(:redirect_back).once
|
|
230
|
+
subject.execute_command command
|
|
231
|
+
expect(command.response(0.1)).to eq(true)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
it "sends the correct complete event" do
|
|
235
|
+
expected_reason = Adhearsion::Event::Complete::Stop.new
|
|
236
|
+
expected_event = Adhearsion::Event::Complete.new reason: expected_reason,
|
|
237
|
+
component_id: subject.id,
|
|
238
|
+
source_uri: subject.id,
|
|
239
|
+
target_call_id: call.id
|
|
240
|
+
|
|
241
|
+
expect(call).to receive(:redirect_back)
|
|
242
|
+
subject.execute_command command
|
|
243
|
+
expect(original_command).not_to be_complete
|
|
244
|
+
call.process_ami_event ami_event
|
|
245
|
+
|
|
246
|
+
sleep 0.2
|
|
247
|
+
|
|
248
|
+
expect(connection.events).to include(expected_event)
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|