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,426 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module Translator
|
|
7
|
+
class Asterisk
|
|
8
|
+
module Component
|
|
9
|
+
describe Record do
|
|
10
|
+
include HasMockCallbackConnection
|
|
11
|
+
|
|
12
|
+
let(:channel) { 'SIP/foo' }
|
|
13
|
+
let(:ami_client) { double('AMI Client').as_null_object }
|
|
14
|
+
let(:translator) { Translator::Asterisk.new ami_client, connection }
|
|
15
|
+
let(:mock_call) { Translator::Asterisk::Call.new channel, translator, ami_client, connection }
|
|
16
|
+
|
|
17
|
+
let :original_command do
|
|
18
|
+
Adhearsion::Rayo::Component::Record.new command_options
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
let :command_options do
|
|
22
|
+
{}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
subject { Record.new original_command, mock_call }
|
|
26
|
+
|
|
27
|
+
describe '#execute' do
|
|
28
|
+
let(:reason) { original_command.complete_event(5).reason }
|
|
29
|
+
let(:recording) { original_command.complete_event(5).recording }
|
|
30
|
+
|
|
31
|
+
before { original_command.request! }
|
|
32
|
+
|
|
33
|
+
it "returns an error if the call is not answered yet" do
|
|
34
|
+
expect(mock_call).to receive(:answered?).and_return(false)
|
|
35
|
+
subject.execute
|
|
36
|
+
error = Adhearsion::ProtocolError.new.setup 'option error', 'Record cannot be used on a call that is not answered.'
|
|
37
|
+
expect(original_command.response(0.1)).to eq(error)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
before { allow(mock_call).to receive(:answered?).and_return(true) }
|
|
41
|
+
|
|
42
|
+
it "sets command response to a reference to the component" do
|
|
43
|
+
expect(ami_client).to receive(:send_action)
|
|
44
|
+
subject.execute
|
|
45
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
46
|
+
expect(original_command.component_id).to eq(subject.id)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "starts a recording via AMI, using the component ID as the filename" do
|
|
50
|
+
filename = "#{Record::RECORDING_BASE_PATH}/#{subject.id}"
|
|
51
|
+
expect(ami_client).to receive(:send_action).once.with('Monitor', 'Channel' => channel, 'File' => filename, 'Format' => 'wav', 'Mix' => true)
|
|
52
|
+
subject.execute
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
it "sends a max duration complete event when the recording ends" do
|
|
56
|
+
full_filename = "file://#{Record::RECORDING_BASE_PATH}/#{subject.id}.wav"
|
|
57
|
+
expect(ami_client).to receive(:send_action)
|
|
58
|
+
subject.execute
|
|
59
|
+
monitor_stop_event = RubyAMI::Event.new 'MonitorStop', 'Channel' => channel
|
|
60
|
+
mock_call.process_ami_event monitor_stop_event
|
|
61
|
+
expect(reason).to be_a Adhearsion::Rayo::Component::Record::Complete::MaxDuration
|
|
62
|
+
expect(recording.uri).to eq(full_filename)
|
|
63
|
+
expect(original_command).to be_complete
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it "can be called multiple times on the same call" do
|
|
67
|
+
expect(ami_client).to receive(:send_action).twice
|
|
68
|
+
subject.execute
|
|
69
|
+
|
|
70
|
+
monitor_stop_event = RubyAMI::Event.new 'MonitorStop', 'Channel' => channel
|
|
71
|
+
|
|
72
|
+
mock_call.process_ami_event monitor_stop_event
|
|
73
|
+
|
|
74
|
+
Record.new(original_command, mock_call).execute
|
|
75
|
+
Adhearsion::Rayo::Component::Record.new(command_options).request!
|
|
76
|
+
mock_call.process_ami_event monitor_stop_event
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
describe 'start_paused' do
|
|
80
|
+
context "set to nil" do
|
|
81
|
+
let(:command_options) { { :start_paused => nil } }
|
|
82
|
+
it "should execute normally" do
|
|
83
|
+
expect(ami_client).to receive(:send_action).once
|
|
84
|
+
subject.execute
|
|
85
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
context "set to false" do
|
|
90
|
+
let(:command_options) { { :start_paused => false } }
|
|
91
|
+
it "should execute normally" do
|
|
92
|
+
expect(ami_client).to receive(:send_action).once
|
|
93
|
+
subject.execute
|
|
94
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
context "set to true" do
|
|
99
|
+
let(:command_options) { { :start_paused => true } }
|
|
100
|
+
it "should return an error and not execute any actions" do
|
|
101
|
+
expect(mock_call).to receive(:execute_agi_command).never
|
|
102
|
+
subject.execute
|
|
103
|
+
error = Adhearsion::ProtocolError.new.setup 'option error', 'A start-paused value of true is unsupported.'
|
|
104
|
+
expect(original_command.response(0.1)).to eq(error)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
describe 'initial_timeout' do
|
|
110
|
+
context "set to nil" do
|
|
111
|
+
let(:command_options) { { :initial_timeout => nil } }
|
|
112
|
+
it "should execute normally" do
|
|
113
|
+
expect(ami_client).to receive(:send_action).once
|
|
114
|
+
subject.execute
|
|
115
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
context "set to -1" do
|
|
120
|
+
let(:command_options) { { :initial_timeout => -1 } }
|
|
121
|
+
it "should execute normally" do
|
|
122
|
+
expect(ami_client).to receive(:send_action).once
|
|
123
|
+
subject.execute
|
|
124
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
context "set to a positive number" do
|
|
129
|
+
let(:command_options) { { :initial_timeout => 10 } }
|
|
130
|
+
it "should return an error and not execute any actions" do
|
|
131
|
+
expect(mock_call).to receive(:execute_agi_command).never
|
|
132
|
+
subject.execute
|
|
133
|
+
error = Adhearsion::ProtocolError.new.setup 'option error', 'An initial-timeout value is unsupported.'
|
|
134
|
+
expect(original_command.response(0.1)).to eq(error)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
describe 'final_timeout' do
|
|
140
|
+
context "set to nil" do
|
|
141
|
+
let(:command_options) { { :final_timeout => nil } }
|
|
142
|
+
it "should execute normally" do
|
|
143
|
+
expect(ami_client).to receive(:send_action).once
|
|
144
|
+
subject.execute
|
|
145
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
context "set to -1" do
|
|
150
|
+
let(:command_options) { { :final_timeout => -1 } }
|
|
151
|
+
it "should execute normally" do
|
|
152
|
+
expect(ami_client).to receive(:send_action).once
|
|
153
|
+
subject.execute
|
|
154
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context "set to a positive number" do
|
|
159
|
+
let(:command_options) { { :final_timeout => 10 } }
|
|
160
|
+
it "should return an error and not execute any actions" do
|
|
161
|
+
expect(mock_call).to receive(:execute_agi_command).never
|
|
162
|
+
subject.execute
|
|
163
|
+
error = Adhearsion::ProtocolError.new.setup 'option error', 'A final-timeout value is unsupported.'
|
|
164
|
+
expect(original_command.response(0.1)).to eq(error)
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
describe 'format' do
|
|
170
|
+
context "set to nil" do
|
|
171
|
+
let(:command_options) { { :format => nil } }
|
|
172
|
+
it "should execute as 'wav'" do
|
|
173
|
+
expect(ami_client).to receive(:send_action).once.with('Monitor', hash_including('Format' => 'wav'))
|
|
174
|
+
subject.execute
|
|
175
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "provides the correct filename in the recording" do
|
|
179
|
+
expect(ami_client).to receive(:send_action)
|
|
180
|
+
subject.execute
|
|
181
|
+
monitor_stop_event = RubyAMI::Event.new 'MonitorStop', 'Channel' => channel
|
|
182
|
+
mock_call.process_ami_event monitor_stop_event
|
|
183
|
+
expect(recording.uri).to match(/.*\.wav$/)
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
context "set to 'mp3'" do
|
|
188
|
+
let(:command_options) { { :format => 'mp3' } }
|
|
189
|
+
it "should execute as 'mp3'" do
|
|
190
|
+
expect(ami_client).to receive(:send_action).once.with('Monitor', hash_including('Format' => 'mp3'))
|
|
191
|
+
subject.execute
|
|
192
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "provides the correct filename in the recording" do
|
|
196
|
+
expect(ami_client).to receive(:send_action)
|
|
197
|
+
subject.execute
|
|
198
|
+
monitor_stop_event = RubyAMI::Event.new 'MonitorStop', 'Channel' => channel
|
|
199
|
+
mock_call.process_ami_event monitor_stop_event
|
|
200
|
+
expect(recording.uri).to match(/.*\.mp3$/)
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
describe 'start_beep' do
|
|
206
|
+
context "set to nil" do
|
|
207
|
+
let(:command_options) { { :start_beep => nil } }
|
|
208
|
+
it "should execute normally" do
|
|
209
|
+
expect(mock_call).to receive(:execute_agi_command).never.with('STREAM FILE', 'beep', '""')
|
|
210
|
+
expect(ami_client).to receive(:send_action).once
|
|
211
|
+
subject.execute
|
|
212
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context "set to false" do
|
|
217
|
+
let(:command_options) { { :start_beep => false } }
|
|
218
|
+
it "should execute normally" do
|
|
219
|
+
expect(mock_call).to receive(:execute_agi_command).never.with('STREAM FILE', 'beep', '""')
|
|
220
|
+
expect(ami_client).to receive(:send_action).once
|
|
221
|
+
subject.execute
|
|
222
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
context "set to true" do
|
|
227
|
+
let(:command_options) { { :start_beep => true } }
|
|
228
|
+
|
|
229
|
+
it "should play a beep before recording" do
|
|
230
|
+
expect(mock_call).to receive(:execute_agi_command).once.with('STREAM FILE', 'beep', '""').ordered.and_return code: 200
|
|
231
|
+
expect(ami_client).to receive(:send_action).once.ordered
|
|
232
|
+
subject.execute
|
|
233
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
context "when we get a RubyAMI Error" do
|
|
237
|
+
it "should send an error response" do
|
|
238
|
+
error = RubyAMI::Error.new.tap { |e| e.message = 'FooBar' }
|
|
239
|
+
expect(mock_call).to receive(:execute_agi_command).and_raise error
|
|
240
|
+
expect(ami_client).to receive(:send_action).never
|
|
241
|
+
subject.execute
|
|
242
|
+
error = Adhearsion::ProtocolError.new.setup :platform_error, "Terminated due to AMI error 'FooBar'"
|
|
243
|
+
expect(original_command.response(0.1)).to eq(error)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
context "when the channel is no longer available" do
|
|
248
|
+
it "should send an error complete event" do
|
|
249
|
+
expect(mock_call).to receive(:execute_agi_command).and_raise ChannelGoneError
|
|
250
|
+
expect(ami_client).to receive(:send_action).never
|
|
251
|
+
subject.execute
|
|
252
|
+
error = Adhearsion::ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{mock_call.id}", mock_call.id)
|
|
253
|
+
expect(original_command.response(0.1)).to eq(error)
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
describe 'max_duration' do
|
|
260
|
+
context "set to nil" do
|
|
261
|
+
let(:command_options) { { :max_duration => nil } }
|
|
262
|
+
it "should execute normally" do
|
|
263
|
+
expect(ami_client).to receive(:send_action).once
|
|
264
|
+
subject.execute
|
|
265
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
context "set to -1" do
|
|
270
|
+
let(:command_options) { { :max_duration => -1 } }
|
|
271
|
+
it "should execute normally" do
|
|
272
|
+
expect(ami_client).to receive(:send_action).once
|
|
273
|
+
subject.execute
|
|
274
|
+
expect(original_command.response(0.1)).to be_a Adhearsion::Rayo::Ref
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
context 'a negative number other than -1' do
|
|
279
|
+
let(:command_options) { { :max_duration => -1000 } }
|
|
280
|
+
|
|
281
|
+
it "should return an error and not execute any actions" do
|
|
282
|
+
subject.execute
|
|
283
|
+
error = Adhearsion::ProtocolError.new.setup 'option error', 'A max-duration value that is negative (and not -1) is invalid.'
|
|
284
|
+
expect(original_command.response(0.1)).to eq(error)
|
|
285
|
+
end
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
context 'a positive number' do
|
|
289
|
+
let(:reason) { original_command.complete_event(5).reason }
|
|
290
|
+
let(:recording) { original_command.complete_event(5).recording }
|
|
291
|
+
let(:command_options) { { :max_duration => 1000 } }
|
|
292
|
+
|
|
293
|
+
it "executes a StopMonitor action" do
|
|
294
|
+
expect(ami_client).to receive :send_action
|
|
295
|
+
expect(ami_client).to receive(:send_action).once.with('StopMonitor', 'Channel' => channel)
|
|
296
|
+
subject.execute
|
|
297
|
+
sleep 1.2
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
it "should not kill the translator if the channel is down" do
|
|
301
|
+
expect(ami_client).to receive :send_action
|
|
302
|
+
error = RubyAMI::Error.new.tap { |e| e.message = 'No such channel' }
|
|
303
|
+
expect(ami_client).to receive(:send_action).once.with('StopMonitor', 'Channel' => channel).and_raise error
|
|
304
|
+
subject.execute
|
|
305
|
+
sleep 1.2
|
|
306
|
+
expect(translator).to be_alive
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
it "sends the correct complete event" do
|
|
310
|
+
full_filename = "file://#{Record::RECORDING_BASE_PATH}/#{subject.id}.wav"
|
|
311
|
+
subject.execute
|
|
312
|
+
sleep 1.2
|
|
313
|
+
|
|
314
|
+
monitor_stop_event = RubyAMI::Event.new 'MonitorStop', 'Channel' => channel
|
|
315
|
+
mock_call.process_ami_event monitor_stop_event
|
|
316
|
+
|
|
317
|
+
expect(reason).to be_a Adhearsion::Rayo::Component::Record::Complete::MaxDuration
|
|
318
|
+
expect(recording.uri).to eq(full_filename)
|
|
319
|
+
expect(original_command).to be_complete
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
describe "#execute_command" do
|
|
326
|
+
let(:reason) { original_command.complete_event(5).reason }
|
|
327
|
+
let(:recording) { original_command.complete_event(5).recording }
|
|
328
|
+
|
|
329
|
+
context "with a command it does not understand" do
|
|
330
|
+
let(:command) { Adhearsion::Rayo::Component::Output::Pause.new }
|
|
331
|
+
|
|
332
|
+
before { command.request! }
|
|
333
|
+
it "returns a Adhearsion::ProtocolError response" do
|
|
334
|
+
subject.execute_command command
|
|
335
|
+
expect(command.response(0.1)).to be_a Adhearsion::ProtocolError
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
context "with a Stop command" do
|
|
340
|
+
let(:command) { Adhearsion::Rayo::Component::Stop.new }
|
|
341
|
+
|
|
342
|
+
before do
|
|
343
|
+
expect(ami_client).to receive :send_action
|
|
344
|
+
expect(mock_call).to receive(:answered?).and_return(true)
|
|
345
|
+
command.request!
|
|
346
|
+
original_command.request!
|
|
347
|
+
subject.execute
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
let :send_stop_event do
|
|
351
|
+
monitor_stop_event = RubyAMI::Event.new 'MonitorStop', 'Channel' => channel
|
|
352
|
+
mock_call.process_ami_event monitor_stop_event
|
|
353
|
+
end
|
|
354
|
+
|
|
355
|
+
it "sets the command response to true" do
|
|
356
|
+
expect(ami_client).to receive :send_action
|
|
357
|
+
subject.execute_command command
|
|
358
|
+
send_stop_event
|
|
359
|
+
expect(command.response(0.1)).to eq(true)
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
it "executes a StopMonitor action" do
|
|
363
|
+
expect(ami_client).to receive(:send_action).once.with('StopMonitor', 'Channel' => channel)
|
|
364
|
+
subject.execute_command command
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
it "sends the correct complete event" do
|
|
368
|
+
expect(ami_client).to receive(:send_action).and_return RubyAMI::Response.new
|
|
369
|
+
|
|
370
|
+
full_filename = "file://#{Record::RECORDING_BASE_PATH}/#{subject.id}.wav"
|
|
371
|
+
subject.execute_command command
|
|
372
|
+
send_stop_event
|
|
373
|
+
expect(reason).to be_a Adhearsion::Event::Complete::Stop
|
|
374
|
+
expect(recording.uri).to eq(full_filename)
|
|
375
|
+
expect(original_command).to be_complete
|
|
376
|
+
end
|
|
377
|
+
end
|
|
378
|
+
|
|
379
|
+
context "with a Pause command" do
|
|
380
|
+
let(:command) { Adhearsion::Rayo::Component::Record::Pause.new }
|
|
381
|
+
|
|
382
|
+
before do
|
|
383
|
+
command.request!
|
|
384
|
+
original_command.request!
|
|
385
|
+
original_command.execute!
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
it "sets the command response to true" do
|
|
389
|
+
expect(ami_client).to receive(:send_action).and_return RubyAMI::Response.new
|
|
390
|
+
subject.execute_command command
|
|
391
|
+
expect(command.response(0.1)).to eq(true)
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
it "pauses the recording via AMI" do
|
|
395
|
+
expect(ami_client).to receive(:send_action).once.with('PauseMonitor', 'Channel' => channel)
|
|
396
|
+
subject.execute_command command
|
|
397
|
+
end
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
context "with a Resume command" do
|
|
401
|
+
let(:command) { Adhearsion::Rayo::Component::Record::Resume.new }
|
|
402
|
+
|
|
403
|
+
before do
|
|
404
|
+
command.request!
|
|
405
|
+
original_command.request!
|
|
406
|
+
original_command.execute!
|
|
407
|
+
end
|
|
408
|
+
|
|
409
|
+
it "sets the command response to true" do
|
|
410
|
+
expect(ami_client).to receive(:send_action).and_return RubyAMI::Response.new
|
|
411
|
+
subject.execute_command command
|
|
412
|
+
expect(command.response(0.1)).to eq(true)
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
it "resumes the recording via AMI" do
|
|
416
|
+
expect(ami_client).to receive(:send_action).once.with('ResumeMonitor', 'Channel' => channel)
|
|
417
|
+
subject.execute_command command
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
module Adhearsion
|
|
6
|
+
module Translator
|
|
7
|
+
class Asterisk
|
|
8
|
+
module Component
|
|
9
|
+
describe StopByRedirect do
|
|
10
|
+
|
|
11
|
+
class MockComponent < Component
|
|
12
|
+
include StopByRedirect
|
|
13
|
+
def set_complete
|
|
14
|
+
@complete = true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
let(:connection) { double 'Connection' }
|
|
19
|
+
let(:ami_client) { double('AMI Client').as_null_object }
|
|
20
|
+
let(:translator) { Translator::Asterisk.new ami_client, connection }
|
|
21
|
+
let(:mock_call) { Call.new 'SIP/foo', translator, ami_client, connection }
|
|
22
|
+
|
|
23
|
+
subject { MockComponent.new Hash.new, mock_call }
|
|
24
|
+
|
|
25
|
+
describe "#execute_command" do
|
|
26
|
+
context "with a command it does not understand" do
|
|
27
|
+
let(:command) { Adhearsion::Rayo::Component::Output::Pause.new }
|
|
28
|
+
|
|
29
|
+
before { command.request! }
|
|
30
|
+
it "returns a Adhearsion::ProtocolError response" do
|
|
31
|
+
subject.execute_command command
|
|
32
|
+
expect(command.response(0.1)).to be_a Adhearsion::ProtocolError
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
context "with a Stop command" do
|
|
37
|
+
let(:command) { Adhearsion::Rayo::Component::Stop.new }
|
|
38
|
+
|
|
39
|
+
before do
|
|
40
|
+
command.request!
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "sets the command response to true" do
|
|
44
|
+
expect(mock_call).to receive(:redirect_back)
|
|
45
|
+
expect(mock_call).to receive(:register_handler).once.with(:ami, [{:name => 'AsyncAGI', [:[], 'SubEvent']=>'Start'}, {:name => 'AsyncAGIExec'}])
|
|
46
|
+
|
|
47
|
+
subject.execute_command command
|
|
48
|
+
expect(command.response(0.1)).to eq(true)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "returns an error if the component is already complete" do
|
|
52
|
+
subject.set_complete
|
|
53
|
+
subject.execute_command command
|
|
54
|
+
expect(command.response(0.1)).to be_a Adhearsion::ProtocolError
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|