adhearsion 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +3 -0
- data/CHANGELOG +12 -0
- data/README.markdown +1 -10
- data/Rakefile +6 -28
- data/adhearsion.gemspec +21 -38
- data/app_generators/ahn/ahn_generator.rb +3 -4
- data/app_generators/ahn/templates/config/environment.rb +4 -0
- data/app_generators/ahn/templates/config/startup.rb +11 -5
- data/app_generators/ahn/templates/script/ahn +8 -0
- data/lib/adhearsion/cli.rb +5 -298
- data/lib/adhearsion/commands.rb +308 -0
- data/lib/adhearsion/events_support.rb +0 -20
- data/lib/adhearsion/initializer/asterisk.rb +0 -1
- data/lib/adhearsion/initializer/configuration.rb +4 -1
- data/lib/adhearsion/logging.rb +18 -3
- data/lib/adhearsion/script_ahn_loader.rb +30 -0
- data/lib/adhearsion/tasks/testing.rb +39 -8
- data/lib/adhearsion/version.rb +2 -2
- data/lib/adhearsion/voip/asterisk/agi_server.rb +15 -8
- data/lib/adhearsion/voip/asterisk/commands.rb +340 -86
- data/lib/adhearsion/voip/asterisk/manager_interface.rb +0 -2
- data/lib/adhearsion/voip/call.rb +11 -3
- data/lib/adhearsion/voip/commands.rb +5 -1
- data/lib/adhearsion/voip/dial_plan.rb +4 -0
- data/lib/theatre/invocation.rb +3 -0
- data/spec/{ahn_command_spec.rb → adhearsion/cli_spec.rb} +11 -0
- data/spec/{component_manager_spec.rb → adhearsion/component_manager_spec.rb} +0 -0
- data/spec/{constants_spec.rb → adhearsion/constants_spec.rb} +0 -0
- data/spec/{drb_spec.rb → adhearsion/drb_spec.rb} +0 -0
- data/spec/{fixtures → adhearsion/fixtures}/dialplan.rb +0 -0
- data/spec/{foundation → adhearsion/foundation}/event_socket_spec.rb +0 -0
- data/spec/{host_definitions_spec.rb → adhearsion/host_definitions_spec.rb} +0 -0
- data/spec/{initializer → adhearsion/initializer}/configuration_spec.rb +21 -0
- data/spec/{initializer → adhearsion/initializer}/loading_spec.rb +0 -0
- data/spec/{initializer → adhearsion/initializer}/paths_spec.rb +0 -0
- data/spec/{initialization_spec.rb → adhearsion/initializer_spec.rb} +0 -0
- data/spec/{logging_spec.rb → adhearsion/logging_spec.rb} +6 -0
- data/spec/{relationship_properties_spec.rb → adhearsion/relationship_properties_spec.rb} +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/agi_server_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/ami/ami_spec.rb +1 -0
- data/spec/{voip → adhearsion/voip}/asterisk/ami/lexer/ami_fixtures.yml +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/ami/lexer/lexer_story +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/ami/lexer/lexer_story.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/ami/lexer/story_helper.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/commands_spec.rb +549 -47
- data/spec/{voip → adhearsion/voip}/asterisk/config_file_generators/agents_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/config_file_generators/queues_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/config_file_generators/voicemail_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/config_manager_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/menu_command/calculated_match_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/asterisk/menu_command/matchers_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/call_routing_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/dialplan_manager_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/dsl/dialing_dsl_spec.rb +1 -1
- data/spec/{voip → adhearsion/voip}/dsl/dispatcher_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/dsl/dispatcher_spec_helper.rb +0 -0
- data/spec/{voip → adhearsion/voip}/dsl/parser_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/freeswitch/basic_connection_manager_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/freeswitch/inbound_connection_manager_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/freeswitch/oes_server_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/numerical_string_spec.rb +0 -0
- data/spec/{voip → adhearsion/voip}/phone_number_spec.rb +0 -0
- data/spec/spec_helper.rb +36 -89
- data/spec/support/initializer_stubs.rb +47 -0
- data/spec/support/the_following_code.rb +3 -0
- data/{theatre-spec → spec/theatre}/dsl_examples/simple_before_call.rb +0 -0
- data/{theatre-spec → spec/theatre}/dsl_spec.rb +26 -0
- data/{theatre-spec → spec/theatre}/invocation_spec.rb +6 -10
- data/{theatre-spec → spec/theatre}/namespace_spec.rb +0 -0
- data/{theatre-spec → spec/theatre}/spec_helper_spec.rb +0 -0
- data/{theatre-spec → spec/theatre}/theatre_class_spec.rb +2 -5
- metadata +254 -271
- data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.rb +0 -104
- data/app_generators/ahn/templates/components/disabled/sandbox/sandbox.yml +0 -2
- data/lib/adhearsion/voip/asterisk/super_manager.rb +0 -19
- data/spec/silence.rb +0 -10
- data/spec/voip/asterisk/ami/old_tests.rb +0 -204
- data/spec/voip/asterisk/ami/super_manager/super_manager_story +0 -25
- data/spec/voip/asterisk/ami/super_manager/super_manager_story.rb +0 -15
- data/spec/voip/asterisk/ami/super_manager/super_manager_story_helper.rb +0 -5
- data/theatre-spec/dsl_examples/dynamic_stomp.rb +0 -7
- data/theatre-spec/spec_helper.rb +0 -37
@@ -25,8 +25,6 @@ module Adhearsion
|
|
25
25
|
# ManagerInterfaceResponse, ManagerInterfaceError, etc.) are relatively user-friendly, they're designed to be a
|
26
26
|
# building block on which to build higher-level abstractions of the Asterisk Manager Interface.
|
27
27
|
#
|
28
|
-
# For a higher-level abstraction of the Asterisk Manager Interface, see the SuperManager class.
|
29
|
-
#
|
30
28
|
class ManagerInterface
|
31
29
|
|
32
30
|
CAUSAL_EVENT_NAMES = %w[queuestatus sippeers iaxpeers parkedcalls
|
data/lib/adhearsion/voip/call.rb
CHANGED
@@ -55,7 +55,7 @@ module Adhearsion
|
|
55
55
|
end
|
56
56
|
end
|
57
57
|
|
58
|
-
# Searches all active calls by their unique_identifier. See Call#unique_identifier.
|
58
|
+
# Searches all active calls by their unique_identifier. See Call#unique_identifier.
|
59
59
|
# Is this actually by channel?
|
60
60
|
def find(id)
|
61
61
|
atomically do
|
@@ -90,6 +90,12 @@ module Adhearsion
|
|
90
90
|
calls
|
91
91
|
end
|
92
92
|
|
93
|
+
def method_missing(m, *args)
|
94
|
+
atomically do
|
95
|
+
calls.send(m.to_sym, *args)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
93
99
|
private
|
94
100
|
|
95
101
|
def atomically(&block)
|
@@ -146,8 +152,6 @@ module Adhearsion
|
|
146
152
|
raise Adhearsion::Call::CallMessageQueue::InboxClosedException, "The message queue for this call has aleady been disabled." if !@open
|
147
153
|
super
|
148
154
|
end
|
149
|
-
|
150
|
-
|
151
155
|
end
|
152
156
|
|
153
157
|
|
@@ -294,6 +298,10 @@ module Adhearsion
|
|
294
298
|
end
|
295
299
|
end
|
296
300
|
|
301
|
+
def ahn_log(*args)
|
302
|
+
Adhearsion::Logging::DefaultAdhearsionLogger.send Adhearsion::Logging::AdhearsionLogger.sanitized_logger_name(unique_identifier), *args
|
303
|
+
end
|
304
|
+
|
297
305
|
def define_variable_accessors(recipient=self)
|
298
306
|
variables.each do |key, value|
|
299
307
|
define_singleton_accessor_with_pair(key, value, recipient)
|
@@ -9,5 +9,9 @@ module Adhearsion
|
|
9
9
|
class PlaybackError < StandardError
|
10
10
|
# Represents failure to play audio, such as when the sound file cannot be found
|
11
11
|
end
|
12
|
+
|
13
|
+
class RecordError < StandardError
|
14
|
+
# Represents failure to record such as when a file cannot be written.
|
15
|
+
end
|
12
16
|
end
|
13
|
-
end
|
17
|
+
end
|
data/lib/theatre/invocation.rb
CHANGED
@@ -66,6 +66,10 @@ describe "A simulated use of the 'ahn' command" do
|
|
66
66
|
Adhearsion::CLI::AhnCommand.const_defined?('USAGE').should be true
|
67
67
|
end
|
68
68
|
|
69
|
+
before do
|
70
|
+
flexmock Adhearsion::ScriptAhnLoader, :in_ahn_application? => true
|
71
|
+
end
|
72
|
+
|
69
73
|
it "arguments to 'create' are executed properly" do
|
70
74
|
some_path = "/path/somewhere"
|
71
75
|
simulate_args "create", some_path
|
@@ -113,6 +117,13 @@ describe "A simulated use of the 'ahn' command" do
|
|
113
117
|
Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, project_path, :daemon, pid_file_path]
|
114
118
|
end
|
115
119
|
|
120
|
+
it 'should recognize start without daemon and with pid file properly' do
|
121
|
+
project_path = '/second/star/on/the/right'
|
122
|
+
pid_file_path = '/straight/on/til/morning'
|
123
|
+
arguments = ["start", project_path, "--pid-file=#{pid_file_path}"]
|
124
|
+
Adhearsion::CLI::AhnCommand.parse_arguments(arguments).should == [:start, project_path, :foreground, pid_file_path]
|
125
|
+
end
|
126
|
+
|
116
127
|
it 'parse_arguments should recognize start without daemon properly' do
|
117
128
|
path = '/path/to/somewhere'
|
118
129
|
arguments = ['start', path]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -87,6 +87,8 @@ describe 'Logging configuration' do
|
|
87
87
|
|
88
88
|
after :each do
|
89
89
|
Adhearsion::Logging.logging_level = :fatal
|
90
|
+
Adhearsion::Logging::AdhearsionLogger.outputters = [Log4r::Outputter.stdout]
|
91
|
+
Adhearsion::Logging::AdhearsionLogger.formatters = [Log4r::DefaultFormatter]
|
90
92
|
end
|
91
93
|
|
92
94
|
it 'the logging level should translate from symbols into Log4r constants' do
|
@@ -95,6 +97,25 @@ describe 'Logging configuration' do
|
|
95
97
|
Adhearsion::Logging.logging_level.should be Log4r::WARN
|
96
98
|
end
|
97
99
|
|
100
|
+
it 'outputters should be settable' do
|
101
|
+
Adhearsion::Logging::AdhearsionLogger.outputters.should == [Log4r::Outputter.stdout]
|
102
|
+
config.logging :outputters => Log4r::Outputter.stderr
|
103
|
+
Adhearsion::Logging::AdhearsionLogger.outputters.should == [Log4r::Outputter.stderr]
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'formatters should be settable' do
|
107
|
+
Adhearsion::Logging::AdhearsionLogger.formatters.map(&:class).should == [Log4r::DefaultFormatter]
|
108
|
+
config.logging :formatters => Log4r::ObjectFormatter
|
109
|
+
Adhearsion::Logging::AdhearsionLogger.formatters.map(&:class).should == [Log4r::ObjectFormatter]
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'a global formatter should be settable' do
|
113
|
+
Adhearsion::Logging::AdhearsionLogger.outputters << Log4r::Outputter.stdout
|
114
|
+
Adhearsion::Logging::AdhearsionLogger.formatters.map(&:class).should == [Log4r::DefaultFormatter, Log4r::DefaultFormatter]
|
115
|
+
config.logging :formatter => Log4r::ObjectFormatter
|
116
|
+
Adhearsion::Logging::AdhearsionLogger.formatters.map(&:class).should == [Log4r::ObjectFormatter, Log4r::ObjectFormatter]
|
117
|
+
end
|
118
|
+
|
98
119
|
end
|
99
120
|
|
100
121
|
describe "AMI configuration defaults" do
|
File without changes
|
File without changes
|
File without changes
|
@@ -41,6 +41,12 @@ describe 'The ahn_log command' do
|
|
41
41
|
ahn_log.qwerty.should be_a_kind_of Adhearsion::Logging::AdhearsionLogger
|
42
42
|
end
|
43
43
|
|
44
|
+
it "handles crazy logger names" do
|
45
|
+
ahn_log.send :'locals@DEMO_ca.ll&', "hey"
|
46
|
+
Log4r::Logger['locals@DEMO_ca.ll&'].should_not be nil
|
47
|
+
ahn_log.send(:'localsdemo_call').should == Log4r::Logger['locals@DEMO_ca.ll&']
|
48
|
+
end
|
49
|
+
|
44
50
|
end
|
45
51
|
|
46
52
|
# Essential for running the tests
|
File without changes
|
File without changes
|
@@ -252,6 +252,7 @@ describe "ManagerInterface" do
|
|
252
252
|
write_queue_mock = mocked_queue
|
253
253
|
|
254
254
|
manager = new_manager_with_events
|
255
|
+
flexmock(manager).should_receive(:start_actions_writer_loop).and_return true
|
255
256
|
manager.connect!
|
256
257
|
|
257
258
|
write_queue_mock.actions.first.name.should == "login"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -20,9 +20,19 @@ module DialplanCommandTestHelpers
|
|
20
20
|
call.should_receive(:to_pbx).and_return(output)
|
21
21
|
end
|
22
22
|
end
|
23
|
+
|
24
|
+
test_case.after do
|
25
|
+
pbx_output_should_be_empty
|
26
|
+
end
|
23
27
|
end
|
24
28
|
|
25
29
|
class MockCall
|
30
|
+
attr_accessor :variables
|
31
|
+
|
32
|
+
def initialize
|
33
|
+
@variables = {}
|
34
|
+
end
|
35
|
+
|
26
36
|
def with_command_lock
|
27
37
|
yield
|
28
38
|
end
|
@@ -30,6 +40,10 @@ module DialplanCommandTestHelpers
|
|
30
40
|
|
31
41
|
class MockSocket
|
32
42
|
|
43
|
+
def empty?
|
44
|
+
messages.empty?
|
45
|
+
end
|
46
|
+
|
33
47
|
def print(message)
|
34
48
|
messages << message
|
35
49
|
end
|
@@ -98,7 +112,7 @@ module DialplanCommandTestHelpers
|
|
98
112
|
end
|
99
113
|
|
100
114
|
def pbx_should_respond_with_value(value)
|
101
|
-
pbx_should_respond_with
|
115
|
+
pbx_should_respond_with pbx_value_response value
|
102
116
|
end
|
103
117
|
|
104
118
|
def pbx_should_respond_with_success(success_code = nil)
|
@@ -148,6 +162,14 @@ module DialplanCommandTestHelpers
|
|
148
162
|
"200 result=#{code || default_code} endpos=#{endpos || default_code}\n"
|
149
163
|
end
|
150
164
|
|
165
|
+
def pbx_value_response(value)
|
166
|
+
"200 result=1 (#{value})"
|
167
|
+
end
|
168
|
+
|
169
|
+
def pbx_result_response(value)
|
170
|
+
"200 result=#{value.ord}"
|
171
|
+
end
|
172
|
+
|
151
173
|
def default_success_code
|
152
174
|
'1'
|
153
175
|
end
|
@@ -192,6 +214,10 @@ module DialplanCommandTestHelpers
|
|
192
214
|
def pbx_was_asked_to_execute(application, *options)
|
193
215
|
output_stream_matches(/exec saydigits "#{options.join('|')}"/i)
|
194
216
|
end
|
217
|
+
|
218
|
+
def pbx_output_should_be_empty
|
219
|
+
output.messages.should be_empty, output.messages.inspect
|
220
|
+
end
|
195
221
|
end
|
196
222
|
include OutputStreamMatchers
|
197
223
|
|
@@ -248,7 +274,17 @@ describe 'hangup command' do
|
|
248
274
|
end
|
249
275
|
end
|
250
276
|
|
251
|
-
describe
|
277
|
+
describe "writing a command" do
|
278
|
+
include DialplanCommandTestHelpers
|
279
|
+
|
280
|
+
it "should strip out excess whitespace" do
|
281
|
+
pbx_should_respond_with_success
|
282
|
+
mock_call.should_receive(:write).with "EXEC Ringing"
|
283
|
+
mock_call.raw_response "EXEC \nRinging\n\n"
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
describe 'The #interruptible_play method' do
|
252
288
|
|
253
289
|
include DialplanCommandTestHelpers
|
254
290
|
|
@@ -257,7 +293,7 @@ describe 'interruptible_play command' do
|
|
257
293
|
file = "file_doesnt_matter"
|
258
294
|
digits.each { |digit| pbx_should_respond_with_stream_file_success digit }
|
259
295
|
digits.map { |digit| mock_call.interruptible_play file }.should == digits.map(&:chr)
|
260
|
-
pbx_was_asked_to_stream file
|
296
|
+
digits.size.times { pbx_was_asked_to_stream file }
|
261
297
|
end
|
262
298
|
|
263
299
|
it "should return nil if no digit was pressed" do
|
@@ -297,10 +333,9 @@ describe 'interruptible_play command' do
|
|
297
333
|
mock_call.interruptible_play(*play_files).should == '9'
|
298
334
|
pbx_was_asked_to_stream played_files
|
299
335
|
end
|
300
|
-
|
301
336
|
end
|
302
337
|
|
303
|
-
describe 'interruptible_play!
|
338
|
+
describe 'The #interruptible_play! method' do
|
304
339
|
include DialplanCommandTestHelpers
|
305
340
|
|
306
341
|
it 'should return a string for the digit that was pressed' do
|
@@ -308,7 +343,7 @@ describe 'interruptible_play! command' do
|
|
308
343
|
file = "file_doesnt_matter"
|
309
344
|
digits.each { |digit| pbx_should_respond_with_stream_file_success digit }
|
310
345
|
digits.map { |digit| mock_call.interruptible_play! file }.should == digits.map(&:chr)
|
311
|
-
pbx_was_asked_to_stream file
|
346
|
+
digits.size.times { pbx_was_asked_to_stream file }
|
312
347
|
end
|
313
348
|
|
314
349
|
it "should return nil if no digit was pressed" do
|
@@ -372,7 +407,7 @@ describe 'interruptible_play! command' do
|
|
372
407
|
end
|
373
408
|
end
|
374
409
|
|
375
|
-
describe 'wait_for_digit
|
410
|
+
describe 'The #wait_for_digit method' do
|
376
411
|
|
377
412
|
include DialplanCommandTestHelpers
|
378
413
|
|
@@ -380,16 +415,17 @@ describe 'wait_for_digit command' do
|
|
380
415
|
digits = %w{0 1 # * 9}.map{|c| c.ord}
|
381
416
|
digits.each { |digit| pbx_should_respond_with_success digit }
|
382
417
|
digits.map { |digit| mock_call.send(:wait_for_digit) }.should == digits.map(&:chr)
|
418
|
+
digits.size.times { pbx_should_have_been_sent 'WAIT FOR DIGIT "-1"' }
|
383
419
|
end
|
384
420
|
|
385
421
|
it "the timeout given must be converted to milliseconds" do
|
386
422
|
pbx_should_respond_with_success 0
|
387
423
|
mock_call.send(:wait_for_digit, 1)
|
388
|
-
|
424
|
+
pbx_should_have_been_sent 'WAIT FOR DIGIT "1000"'
|
389
425
|
end
|
390
426
|
end
|
391
427
|
|
392
|
-
describe 'answer' do
|
428
|
+
describe 'The #answer method' do
|
393
429
|
include DialplanCommandTestHelpers
|
394
430
|
|
395
431
|
it 'should send ANSWER over the AGI socket' do
|
@@ -400,18 +436,19 @@ describe 'answer' do
|
|
400
436
|
|
401
437
|
end
|
402
438
|
|
403
|
-
describe 'execute' do
|
439
|
+
describe 'The #execute method' do
|
404
440
|
include DialplanCommandTestHelpers
|
405
441
|
|
406
442
|
it 'execute writes exec and app name to the PBX' do
|
407
443
|
pbx_should_respond_with_success
|
408
444
|
assert_success mock_call.execute(:foo)
|
409
|
-
pbx_should_have_been_sent 'EXEC foo
|
445
|
+
pbx_should_have_been_sent 'EXEC foo'
|
410
446
|
end
|
411
447
|
|
412
448
|
it 'execute returns false if the command was not executed successfully by the PBX' do
|
413
449
|
pbx_should_respond_with_failure
|
414
450
|
mock_call.execute(:foo).should_not be true
|
451
|
+
pbx_should_have_been_sent 'EXEC foo'
|
415
452
|
end
|
416
453
|
|
417
454
|
it 'execute can accept arguments after the app name which get translated into pipe-delimited arguments to the PBX' do
|
@@ -425,6 +462,7 @@ describe 'execute' do
|
|
425
462
|
the_following_code {
|
426
463
|
mock_call.execute :foo, "bar"
|
427
464
|
}.should raise_error Adhearsion::Hangup
|
465
|
+
pbx_should_have_been_sent 'EXEC foo "bar"'
|
428
466
|
end
|
429
467
|
|
430
468
|
it "should raise a ArgumentError if given a null byte in the arguments" do
|
@@ -432,10 +470,121 @@ describe 'execute' do
|
|
432
470
|
mock_call.execute :foo, "bar\0"
|
433
471
|
}.should raise_error ArgumentError
|
434
472
|
end
|
473
|
+
end
|
474
|
+
|
475
|
+
describe 'The #inline_return_value method' do
|
476
|
+
include DialplanCommandTestHelpers
|
435
477
|
|
478
|
+
it 'should return nil when given false or nil' do
|
479
|
+
mock_call.inline_return_value(false).should be nil
|
480
|
+
mock_call.inline_return_value(nil).should be nil
|
481
|
+
end
|
482
|
+
|
483
|
+
it 'should return nil when given an empty AGI value (0)' do
|
484
|
+
mock_call.inline_return_value(pbx_result_response(0)).should be nil
|
485
|
+
end
|
486
|
+
|
487
|
+
|
488
|
+
it 'should raise AGIProtocolError with an invalid response' do
|
489
|
+
expect {
|
490
|
+
mock_call.inline_return_value("500 result=foo\n")
|
491
|
+
}.to raise_error Adhearsion::VoIP::Asterisk::AGIProtocolError
|
492
|
+
|
493
|
+
expect {
|
494
|
+
mock_call.inline_return_value('Hey man, not so loud!')
|
495
|
+
}.to raise_error Adhearsion::VoIP::Asterisk::AGIProtocolError
|
496
|
+
end
|
497
|
+
|
498
|
+
it 'should parse the return value' do
|
499
|
+
mock_call.inline_return_value(pbx_result_response(5)).should == '5'
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
describe 'The #inline_result_with_return_value method' do
|
504
|
+
include DialplanCommandTestHelpers
|
505
|
+
|
506
|
+
it 'should return nil when given false or nil' do
|
507
|
+
mock_call.inline_result_with_return_value(false).should be nil
|
508
|
+
mock_call.inline_result_with_return_value(nil).should be nil
|
509
|
+
end
|
510
|
+
|
511
|
+
it 'should return nil when given an empty AGI value (0)' do
|
512
|
+
mock_call.inline_result_with_return_value(pbx_result_response(0)).should be nil
|
513
|
+
end
|
514
|
+
|
515
|
+
it 'should raise AGIProtocolError with an invalid response' do
|
516
|
+
expect {
|
517
|
+
mock_call.inline_result_with_return_value("500 result=1 (foo)\n")
|
518
|
+
}.to raise_error Adhearsion::VoIP::Asterisk::AGIProtocolError
|
519
|
+
|
520
|
+
expect {
|
521
|
+
mock_call.inline_result_with_return_value('Hey man, not so loud!')
|
522
|
+
}.to raise_error Adhearsion::VoIP::Asterisk::AGIProtocolError
|
523
|
+
end
|
524
|
+
|
525
|
+
it 'should parse the return value' do
|
526
|
+
mock_call.inline_result_with_return_value(pbx_value_response(5)).should == '5'
|
527
|
+
end
|
436
528
|
end
|
437
529
|
|
438
|
-
describe '
|
530
|
+
describe 'The #play_or_speak method' do
|
531
|
+
include DialplanCommandTestHelpers
|
532
|
+
|
533
|
+
it 'should play a sound file if one exists' do
|
534
|
+
pbx_should_respond_with_playback_success
|
535
|
+
audio_file = "cents-per-minute"
|
536
|
+
mock_call.play_or_speak({audio_file => {}}).should be nil
|
537
|
+
pbx_was_asked_to_play audio_file
|
538
|
+
end
|
539
|
+
|
540
|
+
it 'should play a sound file via interruptible_play if file exists and interrupbible set and return key pressed and return the key press value' do
|
541
|
+
audio_file = "cents-per-minute"
|
542
|
+
mock_call.should_receive(:interruptible_play!).with(audio_file).once.and_return '#'
|
543
|
+
mock_call.play_or_speak({audio_file => {:interruptible => true}}).should == '#'
|
544
|
+
end
|
545
|
+
|
546
|
+
it 'should play a sound file via interruptible_play if file exists and interrupbible set' do
|
547
|
+
audio_file = "cents-per-minute"
|
548
|
+
mock_call.should_receive(:interruptible_play!).with(audio_file).once.and_return nil
|
549
|
+
mock_call.play_or_speak({audio_file => {:interruptible => true}}).should == nil
|
550
|
+
end
|
551
|
+
|
552
|
+
it 'should raise and error if a sound file does not exist and there is not text specified to fall back to' do
|
553
|
+
audio_file = "nixon tapes"
|
554
|
+
mock_call.should_receive(:play!).with(audio_file).and_raise Adhearsion::VoIP::PlaybackError
|
555
|
+
the_following_code {
|
556
|
+
mock_call.play_or_speak({audio_file => { :engine => :unimrcp}})
|
557
|
+
}.should raise_error ArgumentError
|
558
|
+
end
|
559
|
+
|
560
|
+
it 'should not send the command to play if the audio file is blank' do
|
561
|
+
mock_call.should_receive(:speak).with('hello', {:engine=>:unimrcp}).once.and_return nil
|
562
|
+
mock_call.play_or_speak({'' => { :text => 'hello', :engine => :unimrcp }}).should be nil
|
563
|
+
end
|
564
|
+
|
565
|
+
it 'should not send the command to play if the audio file is nil' do
|
566
|
+
mock_call.should_receive(:speak).with('hello', {:engine=>:unimrcp}).once.and_return nil
|
567
|
+
mock_call.play_or_speak({nil => { :text => 'hello', :engine => :unimrcp }}).should be nil
|
568
|
+
end
|
569
|
+
|
570
|
+
it 'should speak the text if a sound file does not exist' do
|
571
|
+
audio_file = "nixon tapes"
|
572
|
+
mock_call.should_receive(:play!).with(audio_file).and_raise Adhearsion::VoIP::PlaybackError
|
573
|
+
mock_call.should_receive(:speak).with('hello', {:engine=>:unimrcp}).once.and_return nil
|
574
|
+
mock_call.play_or_speak({audio_file => { :text => 'hello', :engine => :unimrcp }}).should be nil
|
575
|
+
end
|
576
|
+
|
577
|
+
it 'should speak the text if a sound file does not exist and pass back the entered text if a key is pressed' do
|
578
|
+
audio_file = "nixon tapes"
|
579
|
+
mock_call.should_receive(:interruptible_play!).with(audio_file).and_raise Adhearsion::VoIP::PlaybackError
|
580
|
+
mock_call.should_receive(:speak).with('hello', {:engine=>:unimrcp, :interruptible => true}).once.and_return '5'
|
581
|
+
mock_call.play_or_speak({audio_file => { :text => 'hello', :engine => :unimrcp, :interruptible => true
|
582
|
+
}}).should == '5'
|
583
|
+
end
|
584
|
+
|
585
|
+
end
|
586
|
+
|
587
|
+
describe 'The #play method' do
|
439
588
|
include DialplanCommandTestHelpers
|
440
589
|
|
441
590
|
it 'passing a single string to play results in the playback application being executed with that file name on the PBX' do
|
@@ -537,7 +686,7 @@ describe 'play command' do
|
|
537
686
|
end
|
538
687
|
end
|
539
688
|
|
540
|
-
describe 'play!
|
689
|
+
describe 'The #play! method' do
|
541
690
|
include DialplanCommandTestHelpers
|
542
691
|
|
543
692
|
it 'should accept multiple strings to play, causing multiple playback commands to be issued' do
|
@@ -570,12 +719,149 @@ describe 'play! command' do
|
|
570
719
|
end
|
571
720
|
end
|
572
721
|
|
573
|
-
describe '
|
722
|
+
describe 'the #record method' do
|
723
|
+
include DialplanCommandTestHelpers
|
724
|
+
|
725
|
+
it 'should return the recorded file name if the user hangs up during the recording' do
|
726
|
+
mock_call.should_receive(:response).once.with('RECORD FILE', 'foo', 'gsm', '#', -1, 0, 'BEEP').and_return("200 result=-1 (hangup) endpos=167840\n")
|
727
|
+
mock_call.record('foo').should == 'foo.gsm'
|
728
|
+
end
|
729
|
+
|
730
|
+
it 'create a default filename if no file is specifed and icrement it on subsequent calls' do
|
731
|
+
mock_call.call.variables.delete :recording_counter
|
732
|
+
mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_0', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
733
|
+
mock_call.should_receive(:response).once.with('RECORD FILE', '/tmp/recording_1', 'gsm', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
734
|
+
mock_call.record(:beep => nil, :escapedigits => '26').should == '/tmp/recording_0.gsm'
|
735
|
+
mock_call.record(:beep => nil, :escapedigits => '26').should == '/tmp/recording_1.gsm'
|
736
|
+
end
|
737
|
+
|
738
|
+
it 'determine the format from the filename' do
|
739
|
+
mock_call.should_receive(:response).once.with('RECORD FILE', 'foo', 'wav', '26', -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
740
|
+
mock_call.record('foo.wav', :beep => nil, :escapedigits => '26').should == 'foo.wav'
|
741
|
+
end
|
742
|
+
|
743
|
+
it 'set the format of a file via the :format option' do
|
744
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
745
|
+
mock_call.record('foo', :beep => nil, :maxduration => 2, :format => 'wav').should == 'foo.wav'
|
746
|
+
end
|
747
|
+
|
748
|
+
it 'set the format of a file via the :format option over-riding a implicit format' do
|
749
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo.wav", "mpeg", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
750
|
+
mock_call.record('foo.wav', :beep => nil, :maxduration => 2, :format => 'mpeg').should == 'foo.wav.mpeg'
|
751
|
+
end
|
752
|
+
end
|
753
|
+
|
754
|
+
describe 'the #record_to_file method' do
|
755
|
+
include DialplanCommandTestHelpers
|
756
|
+
|
757
|
+
it 'should return :hangup if the user hangs up during the recording' do
|
758
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=-1 (hangup) endpos=167840\n")
|
759
|
+
mock_call.record_to_file('foo').should == :hangup
|
760
|
+
end
|
761
|
+
|
762
|
+
it 'should return :write error if the recording had a problem writing the file' do
|
763
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=-1 (writefile) endpos=167840\n")
|
764
|
+
mock_call.record_to_file('foo').should == :write_error
|
765
|
+
end
|
766
|
+
|
767
|
+
it 'should return :success_dtmf if the recording was completed successfully with a dtmf tone to end' do
|
768
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=35 (dtmf) endpos=29120\n")
|
769
|
+
mock_call.record_to_file('foo').should == :success_dtmf
|
770
|
+
end
|
771
|
+
|
772
|
+
it 'should return :success_timeout if the recording was completed successfully by timing out with silence' do
|
773
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=0 (timeout) endpos=21600\n")
|
774
|
+
mock_call.record_to_file('foo').should == :success_timeout
|
775
|
+
end
|
776
|
+
|
777
|
+
it 'not send a beep if a :beep=>nil is passed in' do
|
778
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
779
|
+
mock_call.record_to_file('foo', :beep => nil).should == :success_timeout
|
780
|
+
end
|
781
|
+
|
782
|
+
it 'set the silence if it is passed in' do
|
783
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, 's=2').and_return("200 result=0 (timeout) endpos=21600\n")
|
784
|
+
mock_call.record_to_file('foo', :beep => nil, :silence => 2).should == :success_timeout
|
785
|
+
end
|
786
|
+
|
787
|
+
it 'set the maxduration if it is passed in' do
|
788
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
789
|
+
mock_call.record_to_file('foo', :beep => nil, :maxduration => 2).should == :success_timeout
|
790
|
+
end
|
791
|
+
|
792
|
+
it 'set the format of a file via the :format option' do
|
793
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
794
|
+
mock_call.record_to_file('foo', :beep => nil, :maxduration => 2, :format => 'wav').should == :success_timeout
|
795
|
+
end
|
796
|
+
|
797
|
+
it 'set the format of a file via the :format option over-riding a implicit format' do
|
798
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo.wav", "mpeg", "#", 2000, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
799
|
+
mock_call.record_to_file('foo.wav', :beep => nil, :maxduration => 2, :format => 'mpeg').should == :success_timeout
|
800
|
+
end
|
801
|
+
|
802
|
+
it 'set the escapedigits if it is passed in' do
|
803
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
804
|
+
mock_call.record_to_file('foo', :beep => nil, :escapedigits => '26').should == :success_timeout
|
805
|
+
end
|
806
|
+
|
807
|
+
it 'play a passed in beep file if it is passed in' do
|
808
|
+
mock_call.should_receive(:execute).once.with(:playback, 'my_awesome_beep.wav').and_return(true)
|
809
|
+
pbx_should_respond_with_playback_success
|
810
|
+
pbx_should_respond_with_playback_success
|
811
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
812
|
+
mock_call.record_to_file('foo', :beep => 'my_awesome_beep.wav', :escapedigits => '26').should == :success_timeout
|
813
|
+
end
|
814
|
+
|
815
|
+
it "should silently fail if the beep file passed in can't be played" do
|
816
|
+
mock_call.should_receive(:execute).once.with(:playback, 'my_awesome_beep.wav').and_return(true)
|
817
|
+
pbx_should_respond_with_playback_failure
|
818
|
+
pbx_should_respond_with_playback_failure
|
819
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
820
|
+
mock_call.record_to_file('foo', :beep => 'my_awesome_beep.wav', :escapedigits => '26').should == :success_timeout
|
821
|
+
end
|
822
|
+
|
823
|
+
it 'determine the format from the filename' do
|
824
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
825
|
+
mock_call.record_to_file('foo.wav', :beep => nil, :escapedigits => '26').should == :success_timeout
|
826
|
+
end
|
827
|
+
|
828
|
+
it 'create a default filename if no file is specifed and icrement it on subsequent calls' do
|
829
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "/tmp/recording_0", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
830
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "/tmp/recording_1", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
831
|
+
mock_call.record_to_file(:beep => nil, :escapedigits => '26').should == :success_timeout
|
832
|
+
mock_call.record_to_file(:beep => nil, :escapedigits => '26').should == :success_timeout
|
833
|
+
end
|
834
|
+
end
|
574
835
|
|
836
|
+
describe 'The #record_to_file! method' do
|
575
837
|
include DialplanCommandTestHelpers
|
576
838
|
|
577
|
-
|
578
|
-
|
839
|
+
it "should throw an exception the beep file passed in can't be played" do
|
840
|
+
mock_call.should_receive(:execute).once.with(:playback, 'my_awesome_beep.wav').and_return(false)
|
841
|
+
pbx_should_respond_with_playback_failure
|
842
|
+
pbx_should_respond_with_playback_failure
|
843
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
844
|
+
the_following_code {
|
845
|
+
mock_call.record_to_file!('foo', :beep => 'my_awesome_beep.wav', :escapedigits => '26').should == :success_timeout
|
846
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
847
|
+
end
|
848
|
+
|
849
|
+
it 'should throw RecordError if the recording had a problem writing the file' do
|
850
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "gsm", "#", -1, 0, "BEEP").and_return("200 result=-1 (writefile) endpos=167840\n")
|
851
|
+
the_following_code {
|
852
|
+
mock_call.record_to_file!('foo').should == :write_error
|
853
|
+
}.should raise_error Adhearsion::VoIP::RecordError
|
854
|
+
end
|
855
|
+
|
856
|
+
it 'should be able get a response from a successfull call' do
|
857
|
+
mock_call.should_receive(:response).once.with("RECORD FILE", "foo", "wav", "26", -1, 0).and_return("200 result=0 (timeout) endpos=21600\n")
|
858
|
+
mock_call.record_to_file!('foo.wav', :beep => nil, :escapedigits => '26').should == :success_timeout
|
859
|
+
end
|
860
|
+
end
|
861
|
+
|
862
|
+
describe 'The #input method' do
|
863
|
+
|
864
|
+
include DialplanCommandTestHelpers
|
579
865
|
|
580
866
|
it 'should raise an error when the number of digits expected is -1 (this is deprecated behavior)' do
|
581
867
|
the_following_code {
|
@@ -608,6 +894,7 @@ describe 'input command' do
|
|
608
894
|
the_following_code {
|
609
895
|
mock_call.input(:accept_key => false)
|
610
896
|
}.should raise_error ArgumentError
|
897
|
+
pbx_should_have_been_sent 'WAIT FOR DIGIT "-1"'
|
611
898
|
end
|
612
899
|
|
613
900
|
it 'when :accept_key is false and input() is collecting a finite number of digits, it should allow all DTMFs' do
|
@@ -618,6 +905,18 @@ describe 'input command' do
|
|
618
905
|
}.should_not raise_error ArgumentError
|
619
906
|
end
|
620
907
|
|
908
|
+
it 'should terminate early when the passed block returns something truthy' do
|
909
|
+
three_digits = %w[9 3 0]
|
910
|
+
mock_call.should_receive(:wait_for_digit).times(2).and_return(*three_digits)
|
911
|
+
mock_call.input(3, :accept_key => false) { |buffer| buffer.size == 2 }.should == '93'
|
912
|
+
end
|
913
|
+
|
914
|
+
it "Input timing out when digits are pressed returns only the collected digits" do
|
915
|
+
timeout = 1.day
|
916
|
+
mock_call.should_receive(:wait_for_digit).twice.with(timeout).and_return '5', nil
|
917
|
+
mock_call.input(9, :timeout => timeout).should == '5'
|
918
|
+
end
|
919
|
+
|
621
920
|
it 'passes wait_for_digit the :timeout option when one is given' do
|
622
921
|
mock_call.should_receive(:interruptible_play!).never
|
623
922
|
mock_call.should_receive(:wait_for_digit).twice.and_return '1', '2'
|
@@ -633,6 +932,15 @@ describe 'input command' do
|
|
633
932
|
mock_call.input(2, :play => sound_files).should == '#*'
|
634
933
|
end
|
635
934
|
|
935
|
+
it 'executes #play! when :interruptible is set to false' do
|
936
|
+
sound_files = %w[foo bar qaz]
|
937
|
+
mock_call.should_receive(:play!).once.with('foo').and_return true
|
938
|
+
mock_call.should_receive(:play!).once.with('bar').and_return true
|
939
|
+
mock_call.should_receive(:play!).once.with('qaz').and_return true
|
940
|
+
mock_call.should_receive(:wait_for_digit).once.and_return '*'
|
941
|
+
mock_call.input(1, :play => sound_files, :interruptible => false).should == '*'
|
942
|
+
end
|
943
|
+
|
636
944
|
it 'pressing the terminating key before any other digits returns an empty string' do
|
637
945
|
mock_call.should_receive(:wait_for_digit).once.and_return '*'
|
638
946
|
mock_call.input(:accept_key => '*').should == ''
|
@@ -650,7 +958,7 @@ describe 'input command' do
|
|
650
958
|
mock_call.input(9, :timeout => timeout).should == '5'
|
651
959
|
end
|
652
960
|
|
653
|
-
it 'should execute wait_for_digit, even if some sound files are not found' do
|
961
|
+
it 'should execute wait_for_digit, even if some interruptible sound files are not found' do
|
654
962
|
pbx_should_respond_with_stream_file_failure_on_open
|
655
963
|
file = 'foobar'
|
656
964
|
timeout = 1.hour
|
@@ -659,6 +967,15 @@ describe 'input command' do
|
|
659
967
|
pbx_was_asked_to_stream file
|
660
968
|
end
|
661
969
|
|
970
|
+
it 'should execute wait_for_digit with, even if some uninterruptible sound files are not found' do
|
971
|
+
pbx_should_respond_with_playback_failure
|
972
|
+
file = 'foobar'
|
973
|
+
timeout = 1.hour
|
974
|
+
mock_call.should_receive(:wait_for_digit).twice.with(timeout).and_return '8', '9'
|
975
|
+
mock_call.input(2, :timeout => timeout, :play => file, :interruptible => false).should == '89'
|
976
|
+
pbx_was_asked_to_play file
|
977
|
+
end
|
978
|
+
|
662
979
|
it 'should return an empty string if no keys are pressed, even if the sound file is not found' do
|
663
980
|
pbx_should_respond_with_stream_file_failure_on_open
|
664
981
|
file = 'foobar'
|
@@ -682,7 +999,7 @@ describe 'input command' do
|
|
682
999
|
pbx_was_asked_to_stream played_files
|
683
1000
|
end
|
684
1001
|
|
685
|
-
it 'should play a series of 4
|
1002
|
+
it 'should play a series of 4 interruptible sounds, collecting digits even if some of the sound files cannot be found' do
|
686
1003
|
pbx_should_respond_with_stream_file_success 0
|
687
1004
|
pbx_should_respond_with_stream_file_success 0
|
688
1005
|
pbx_should_respond_with_stream_file_failure_on_open
|
@@ -697,9 +1014,57 @@ describe 'input command' do
|
|
697
1014
|
pbx_was_asked_to_stream played_files
|
698
1015
|
end
|
699
1016
|
|
1017
|
+
it 'should not raise an exception if the sound file is unplayable' do
|
1018
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
1019
|
+
file = 'foobar'
|
1020
|
+
mock_call.should_receive(:wait_for_digit).once
|
1021
|
+
the_following_code {
|
1022
|
+
mock_call.input 1, :play => file
|
1023
|
+
}.should_not raise_error
|
1024
|
+
pbx_was_asked_to_stream file
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
it 'should default to playing interruptible prompts' do
|
1028
|
+
mock_call.should_receive(:interruptible_play!).once.with('does_not_matter')
|
1029
|
+
mock_call.should_receive(:wait_for_digit).once
|
1030
|
+
mock_call.input(1, :play => 'does_not_matter')
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
it 'should render uninterruptible prompts' do
|
1034
|
+
mock_call.should_receive(:play!).once.with('does_not_matter')
|
1035
|
+
mock_call.should_receive(:wait_for_digit).once
|
1036
|
+
mock_call.input(1, :play => 'does_not_matter', :interruptible => false)
|
1037
|
+
end
|
1038
|
+
|
1039
|
+
it 'should fall back to speaking TTS if sound file is unplayable' do
|
1040
|
+
pbx_should_respond_with_stream_file_failure_on_open
|
1041
|
+
mock_call.should_receive(:speak).once.with("The sound file was not available", :interruptible => true)
|
1042
|
+
mock_call.should_receive(:wait_for_digit).once
|
1043
|
+
mock_call.input(1, :play => 'unavailable sound file', :speak => {:text => "The sound file was not available"})
|
1044
|
+
@output.read.should == "STREAM FILE \"unavailable sound file\" \"1234567890*#\"\n"
|
1045
|
+
end
|
1046
|
+
|
1047
|
+
it 'should allow uninterruptible TTS prompts' do
|
1048
|
+
mock_call.should_receive(:speak).once.with("The sound file was not available", :interruptible => false)
|
1049
|
+
mock_call.should_receive(:wait_for_digit).once
|
1050
|
+
mock_call.input(1, :speak => {:text => "The sound file was not available"}, :interruptible => false)
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
it 'should play a series of 4 uninterruptible sounds, collecting digits even if some of the sound files cannot be found' do
|
1054
|
+
pbx_should_respond_with_playback_success
|
1055
|
+
pbx_should_respond_with_playback_failure
|
1056
|
+
pbx_should_respond_with_playback_success
|
1057
|
+
|
1058
|
+
files = ('sound1'..'sound3').map &:to_s
|
1059
|
+
timeout = 1.second
|
1060
|
+
mock_call.should_receive(:wait_for_digit).twice.with(timeout).and_return '6', '7'
|
1061
|
+
mock_call.input(2, :timeout => timeout, :play => files, :interruptible => false).should == '67'
|
1062
|
+
pbx_was_asked_to_play files
|
1063
|
+
end
|
1064
|
+
|
700
1065
|
end
|
701
1066
|
|
702
|
-
describe 'input!
|
1067
|
+
describe 'The #input! method' do
|
703
1068
|
|
704
1069
|
include DialplanCommandTestHelpers
|
705
1070
|
|
@@ -727,6 +1092,15 @@ describe 'input! command' do
|
|
727
1092
|
mock_call.input!(2, :play => sound_files).should == '#*'
|
728
1093
|
end
|
729
1094
|
|
1095
|
+
it 'executes play!() with all of the files given to :play' do
|
1096
|
+
sound_files = %w[foo bar qaz]
|
1097
|
+
mock_call.should_receive(:play!).once.with('foo').and_return true
|
1098
|
+
mock_call.should_receive(:play!).once.with('bar').and_return true
|
1099
|
+
mock_call.should_receive(:play!).once.with('qaz').and_return true
|
1100
|
+
mock_call.should_receive(:wait_for_digit).once.and_return '*'
|
1101
|
+
mock_call.input!(1, :play => sound_files, :interruptible => false).should == '*'
|
1102
|
+
end
|
1103
|
+
|
730
1104
|
it 'should execute wait_for_digit first if no sound files are given' do
|
731
1105
|
mock_call.should_receive(:interruptible_play!).never
|
732
1106
|
mock_call.should_receive(:wait_for_digit).once.and_throw :digit_request
|
@@ -743,7 +1117,7 @@ describe 'input! command' do
|
|
743
1117
|
pbx_was_asked_to_stream file
|
744
1118
|
end
|
745
1119
|
|
746
|
-
it 'should play a series of files, raising an error if a sound file cannot be found' do
|
1120
|
+
it 'should play a series of interruptible files, raising an error if a sound file cannot be found' do
|
747
1121
|
pbx_should_respond_with_stream_file_success 0
|
748
1122
|
pbx_should_respond_with_stream_file_failure_on_open
|
749
1123
|
mock_call.should_receive(:wait_for_digit).never
|
@@ -756,9 +1130,21 @@ describe 'input! command' do
|
|
756
1130
|
pbx_was_asked_to_stream played_files
|
757
1131
|
end
|
758
1132
|
|
1133
|
+
it 'should play a series of uninterruptible files, raising an error if a sound file cannot be found' do
|
1134
|
+
pbx_should_respond_with_playback_success
|
1135
|
+
pbx_should_respond_with_playback_failure
|
1136
|
+
|
1137
|
+
play_files = ('sound1'..'sound6').map &:to_s
|
1138
|
+
played_files = ('sound1'..'sound2').map &:to_s
|
1139
|
+
the_following_code {
|
1140
|
+
mock_call.input! 10, :play => play_files, :timeout => 5.seconds, :interruptible => false
|
1141
|
+
}.should raise_error Adhearsion::VoIP::PlaybackError
|
1142
|
+
pbx_was_asked_to_play played_files
|
1143
|
+
end
|
1144
|
+
|
759
1145
|
end
|
760
1146
|
|
761
|
-
describe "The variable
|
1147
|
+
describe "The #variable method" do
|
762
1148
|
|
763
1149
|
include DialplanCommandTestHelpers
|
764
1150
|
|
@@ -795,7 +1181,7 @@ describe "The variable() command" do
|
|
795
1181
|
|
796
1182
|
end
|
797
1183
|
|
798
|
-
describe "
|
1184
|
+
describe "The #set_variable method" do
|
799
1185
|
|
800
1186
|
include DialplanCommandTestHelpers
|
801
1187
|
|
@@ -811,7 +1197,7 @@ describe "the set_variable method" do
|
|
811
1197
|
|
812
1198
|
end
|
813
1199
|
|
814
|
-
describe "
|
1200
|
+
describe "The #sip_add_header method" do
|
815
1201
|
include DialplanCommandTestHelpers
|
816
1202
|
|
817
1203
|
it "values are properly quoted" do
|
@@ -820,21 +1206,23 @@ describe "the sip_add_header method" do
|
|
820
1206
|
end
|
821
1207
|
end
|
822
1208
|
|
823
|
-
describe "
|
1209
|
+
describe "The #sip_get_header method" do
|
824
1210
|
include DialplanCommandTestHelpers
|
825
1211
|
|
826
|
-
it "
|
827
|
-
|
828
|
-
mock_call.
|
1212
|
+
it "properly formats the AGI request" do
|
1213
|
+
value = 'jason-was-here'
|
1214
|
+
mock_call.should_receive(:raw_response).once.with('GET VARIABLE "SIP_HEADER(x-ahn-header)"').and_return "200 result=1 (#{value})"
|
1215
|
+
mock_call.sip_get_header("x-ahn-header").should == value
|
829
1216
|
end
|
830
1217
|
|
831
|
-
it "
|
832
|
-
|
833
|
-
mock_call.
|
1218
|
+
it "properly formats the AGI request using the method alias" do
|
1219
|
+
value = 'jason-was-here'
|
1220
|
+
mock_call.should_receive(:raw_response).once.with('GET VARIABLE "SIP_HEADER(x-ahn-header)"').and_return "200 result=1 (#{value})"
|
1221
|
+
mock_call.sip_header("x-ahn-header").should == value
|
834
1222
|
end
|
835
1223
|
end
|
836
1224
|
|
837
|
-
describe '
|
1225
|
+
describe 'The #voicemail command' do
|
838
1226
|
|
839
1227
|
include DialplanCommandTestHelpers
|
840
1228
|
|
@@ -857,12 +1245,13 @@ describe 'the voicemail command' do
|
|
857
1245
|
end
|
858
1246
|
|
859
1247
|
it 'should combine mailbox numbers with the context name given when both are given' do
|
860
|
-
|
1248
|
+
pbx_should_respond_with_value 'SUCCESS'
|
861
1249
|
context = "lolcats"
|
862
1250
|
mailboxes = [1,2,3,4,5]
|
863
1251
|
mailboxes_with_context = mailboxes.map { |mailbox| "#{mailbox}@#{context}"}
|
864
1252
|
mock_call.should_receive(:execute).once.with('voicemail', mailboxes_with_context.join('&'), '')
|
865
1253
|
mock_call.voicemail context => mailboxes
|
1254
|
+
pbx_should_have_been_sent 'GET VARIABLE "VMSTATUS"'
|
866
1255
|
end
|
867
1256
|
|
868
1257
|
it 'should raise an argument error if the mailbox number is not numerical' do
|
@@ -1047,12 +1436,14 @@ describe "The queue management abstractions" do
|
|
1047
1436
|
does_not_read_data_back
|
1048
1437
|
mock_call.should_receive(:get_variable).once.with("QUEUESTATUS").and_return "TIMEOUT"
|
1049
1438
|
mock_call.queue('monkey').join!.should be :timeout
|
1439
|
+
pbx_should_have_been_sent 'EXEC queue "monkey"|""|""|""|""|""'
|
1050
1440
|
end
|
1051
1441
|
|
1052
1442
|
it 'should return :completed after joining the queue and being connected' do
|
1053
1443
|
does_not_read_data_back
|
1054
1444
|
mock_call.should_receive(:get_variable).once.with("QUEUESTATUS").and_return nil
|
1055
1445
|
mock_call.queue('monkey').join!.should be :completed
|
1446
|
+
pbx_should_have_been_sent 'EXEC queue "monkey"|""|""|""|""|""'
|
1056
1447
|
end
|
1057
1448
|
|
1058
1449
|
it 'should join a queue with a timeout properly' do
|
@@ -1204,6 +1595,7 @@ describe "The queue management abstractions" do
|
|
1204
1595
|
the_following_code {
|
1205
1596
|
mock_call.queue('this_should_not_exist').agents.new 'Agent/911'
|
1206
1597
|
}.should raise_error Adhearsion::VoIP::Asterisk::Commands::QueueProxy::QueueDoesNotExistError
|
1598
|
+
pbx_should_have_been_sent 'EXEC AddQueueMember "this_should_not_exist"|"Agent/911"|""|""|""|""'
|
1207
1599
|
end
|
1208
1600
|
|
1209
1601
|
it 'when a queue agent is dynamiaclly added and the adding was successful, an AgentProxy should be returned' do
|
@@ -1284,6 +1676,7 @@ describe "The queue management abstractions" do
|
|
1284
1676
|
|
1285
1677
|
agents = mock_call.queue('lolcats').agents :cache => true
|
1286
1678
|
agents.last.pause!.should be true
|
1679
|
+
pbx_should_have_been_sent 'EXEC PauseQueueMember "lolcats"|"Agent/008"'
|
1287
1680
|
end
|
1288
1681
|
|
1289
1682
|
it 'should pause an agent properly from a certain queue and return false when the agent did not exist' do
|
@@ -1442,6 +1835,7 @@ describe 'the menu() method' do
|
|
1442
1835
|
link.other 543
|
1443
1836
|
end
|
1444
1837
|
end
|
1838
|
+
3.times { pbx_should_have_been_sent 'WAIT FOR DIGIT "5000"' }
|
1445
1839
|
end
|
1446
1840
|
|
1447
1841
|
it "when the 'extension' variable is changed, it should be an instance of PhoneNumber" do
|
@@ -1455,6 +1849,7 @@ describe 'the menu() method' do
|
|
1455
1849
|
end
|
1456
1850
|
5.should === mock_call.extension
|
1457
1851
|
mock_call.extension.__real_string.should == "5"
|
1852
|
+
pbx_should_have_been_sent 'WAIT FOR DIGIT "5000"'
|
1458
1853
|
end
|
1459
1854
|
|
1460
1855
|
end
|
@@ -1511,9 +1906,6 @@ describe 'the Menu class' do
|
|
1511
1906
|
end
|
1512
1907
|
|
1513
1908
|
it "should default the timeout to five seconds" do
|
1514
|
-
pbx_should_respond_with_successful_background_response ?2.ord
|
1515
|
-
pbx_should_respond_with_a_wait_for_digit_timeout
|
1516
|
-
|
1517
1909
|
mock_call.should_receive(:wait_for_digit).once.with(5).and_return nil
|
1518
1910
|
mock_call.menu { |link| link.foobar 22 }
|
1519
1911
|
end
|
@@ -1536,6 +1928,7 @@ describe 'the Menu class' do
|
|
1536
1928
|
end
|
1537
1929
|
end
|
1538
1930
|
times_timed_out.should be tries
|
1931
|
+
30.times { pbx_should_have_been_sent 'WAIT FOR DIGIT "5000"' }
|
1539
1932
|
end
|
1540
1933
|
|
1541
1934
|
it "when matches fail due to invalid input, the menu should repeat :tries times" do
|
@@ -1555,6 +1948,7 @@ describe 'the Menu class' do
|
|
1555
1948
|
end
|
1556
1949
|
end
|
1557
1950
|
times_invalid.should be tries
|
1951
|
+
10.times { pbx_should_have_been_sent 'WAIT FOR DIGIT "5000"' }
|
1558
1952
|
end
|
1559
1953
|
|
1560
1954
|
it "invoke on_invalid callback when an invalid extension was entered" do
|
@@ -1567,6 +1961,7 @@ describe 'the Menu class' do
|
|
1567
1961
|
link.on_invalid { throw :inside_invalid_callback }
|
1568
1962
|
end
|
1569
1963
|
end
|
1964
|
+
pbx_should_have_been_sent 'WAIT FOR DIGIT "5000"'
|
1570
1965
|
end
|
1571
1966
|
|
1572
1967
|
it "invoke on_premature_timeout when a timeout is encountered" do
|
@@ -1579,6 +1974,7 @@ describe 'the Menu class' do
|
|
1579
1974
|
link.on_premature_timeout { throw :inside_timeout }
|
1580
1975
|
end
|
1581
1976
|
end
|
1977
|
+
2.times { pbx_should_have_been_sent 'WAIT FOR DIGIT "1000"' }
|
1582
1978
|
end
|
1583
1979
|
|
1584
1980
|
end
|
@@ -1603,6 +1999,7 @@ describe "the Menu class's high-level judgment" do
|
|
1603
1999
|
end
|
1604
2000
|
end
|
1605
2001
|
111.should === mock_call.extension
|
2002
|
+
4.times { pbx_should_have_been_sent 'WAIT FOR DIGIT "5000"' }
|
1606
2003
|
end
|
1607
2004
|
|
1608
2005
|
it 'should match things in a range when there are many other non-matching patterns' do
|
@@ -1621,6 +2018,7 @@ describe "the Menu class's high-level judgment" do
|
|
1621
2018
|
link.conferences 900..999
|
1622
2019
|
end
|
1623
2020
|
end
|
2021
|
+
3.times { pbx_should_have_been_sent 'WAIT FOR DIGIT "5000"' }
|
1624
2022
|
end
|
1625
2023
|
|
1626
2024
|
end
|
@@ -1938,11 +2336,13 @@ describe "get variable command" do
|
|
1938
2336
|
it "Getting a variable that isn't set returns nothing" do
|
1939
2337
|
pbx_should_respond_with "200 result=0"
|
1940
2338
|
mock_call.get_variable('OMGURFACE').should be nil
|
2339
|
+
pbx_should_have_been_sent 'GET VARIABLE "OMGURFACE"'
|
1941
2340
|
end
|
1942
2341
|
|
1943
2342
|
it 'An empty variable should return an empty String' do
|
1944
2343
|
pbx_should_respond_with_value ""
|
1945
2344
|
mock_call.get_variable('kablamm').should == ""
|
2345
|
+
pbx_should_have_been_sent 'GET VARIABLE "kablamm"'
|
1946
2346
|
end
|
1947
2347
|
|
1948
2348
|
it "Getting a variable that is set returns its value" do
|
@@ -1950,6 +2350,7 @@ describe "get variable command" do
|
|
1950
2350
|
pbx_should_respond_with_value unique_id
|
1951
2351
|
variable_value_returned = mock_call.get_variable('UNIQUEID')
|
1952
2352
|
variable_value_returned.should == unique_id
|
2353
|
+
pbx_should_have_been_sent 'GET VARIABLE "UNIQUEID"'
|
1953
2354
|
end
|
1954
2355
|
end
|
1955
2356
|
|
@@ -1991,6 +2392,7 @@ describe "Dial command" do
|
|
1991
2392
|
does_not_read_data_back
|
1992
2393
|
mock_call.should_receive(:set_caller_id_number).once
|
1993
2394
|
mock_call.dial 123, :caller_id => "1234678901"
|
2395
|
+
pbx_should_have_been_sent 'EXEC Dial "123"|""|""'
|
1994
2396
|
end
|
1995
2397
|
|
1996
2398
|
it 'should raise an exception when unknown hash key arguments are given to it' do
|
@@ -2004,6 +2406,7 @@ describe "Dial command" do
|
|
2004
2406
|
name = "Jay Phillips"
|
2005
2407
|
mock_call.should_receive(:set_caller_id_name).once.with(name)
|
2006
2408
|
mock_call.dial "BlahBlahBlah", :name => name
|
2409
|
+
pbx_should_have_been_sent 'EXEC Dial "BlahBlahBlah"|""|""'
|
2007
2410
|
end
|
2008
2411
|
|
2009
2412
|
it "should raise an exception when a non-numerical caller_id is specified" do
|
@@ -2012,11 +2415,19 @@ describe "Dial command" do
|
|
2012
2415
|
}.should raise_error ArgumentError
|
2013
2416
|
end
|
2014
2417
|
|
2418
|
+
it "should not raise an exception when a caller_id is specified in E.164 format (with '+' sign)" do
|
2419
|
+
the_following_code {
|
2420
|
+
mock_call.dial 911, :caller_id => "+123456789"
|
2421
|
+
}.should_not raise_error ArgumentError
|
2422
|
+
pbx_should_have_been_sent 'SET VARIABLE "CALLERID(num)" "+123456789"'
|
2423
|
+
end
|
2424
|
+
|
2015
2425
|
it 'should pass the value of the :confirm key to dial_macro_option_compiler()' do
|
2016
2426
|
does_not_read_data_back
|
2017
2427
|
value_of_confirm_key = {:play => "ohai", :timeout => 30}
|
2018
2428
|
mock_call.should_receive(:dial_macro_option_compiler).once.with value_of_confirm_key
|
2019
2429
|
mock_call.dial 123, :confirm => value_of_confirm_key
|
2430
|
+
pbx_should_have_been_sent 'EXEC Dial "123"|""|""'
|
2020
2431
|
end
|
2021
2432
|
|
2022
2433
|
it "should add the return value of dial_macro_option_compiler to the :options key's value given to the dial command" do
|
@@ -2248,33 +2659,124 @@ describe 'set_caller_id_name command' do
|
|
2248
2659
|
end
|
2249
2660
|
end
|
2250
2661
|
|
2251
|
-
describe "
|
2662
|
+
describe "speak command" do
|
2252
2663
|
include DialplanCommandTestHelpers
|
2253
2664
|
|
2665
|
+
before :all do
|
2666
|
+
@speech_engines = Adhearsion::VoIP::Asterisk::Commands::SpeechEngines
|
2667
|
+
end
|
2668
|
+
|
2254
2669
|
it "executes the command SpeechEngine gives it based on the engine name" do
|
2255
|
-
|
2256
|
-
flexmock(
|
2257
|
-
|
2258
|
-
mock_call.should_receive(:execute).once.with(mock_speak_command)
|
2259
|
-
mock_call.speak "Spoken text doesn't matter", :cepstral
|
2670
|
+
pbx_should_respond_with_success
|
2671
|
+
flexmock(@speech_engines).should_receive(:cepstral).once
|
2672
|
+
mock_call.speak "Spoken text doesn't matter", :engine => :cepstral
|
2260
2673
|
end
|
2261
2674
|
|
2262
2675
|
it "raises an InvalidSpeechEngine exception when the engine is 'none'" do
|
2263
2676
|
the_following_code {
|
2264
|
-
mock_call.speak("o hai!", :none)
|
2265
|
-
}.should raise_error
|
2677
|
+
mock_call.speak("o hai!", :engine => :none)
|
2678
|
+
}.should raise_error @speech_engines::InvalidSpeechEngine
|
2266
2679
|
end
|
2267
2680
|
|
2268
2681
|
it "should default its engine to :none" do
|
2269
2682
|
the_following_code {
|
2270
|
-
flexmock(
|
2271
|
-
and_raise(
|
2683
|
+
flexmock(@speech_engines).should_receive(:none).once.
|
2684
|
+
and_raise(@speech_engines::InvalidSpeechEngine)
|
2272
2685
|
mock_call.speak "ruby ruby ruby ruby!"
|
2273
|
-
}.should raise_error
|
2686
|
+
}.should raise_error @speech_engines::InvalidSpeechEngine
|
2687
|
+
end
|
2688
|
+
|
2689
|
+
it 'should default to a configured TTS engine' do
|
2690
|
+
Adhearsion::Configuration.configure {|c| c.asterisk.speech_engine = :unimrcp }
|
2691
|
+
flexmock(@speech_engines).should_receive(:unimrcp).once
|
2692
|
+
mock_call.speak 'What say you, sir?'
|
2693
|
+
end
|
2694
|
+
|
2695
|
+
it 'should allow the caller to override the default configured TTS engine' do
|
2696
|
+
Adhearsion::Configuration.configure {|c| c.asterisk.speech_engine = :unimrcp }
|
2697
|
+
flexmock(@speech_engines).should_receive(:cepstral).once
|
2698
|
+
mock_call.speak 'What say you now, sir?', :engine => :cepstral
|
2699
|
+
end
|
2700
|
+
|
2701
|
+
it 'should default to uninterruptible TTS rendering' do
|
2702
|
+
flexmock(@speech_engines).should_receive(:cepstral).once.with(mock_call, 'hello', {:interruptible => false})
|
2703
|
+
mock_call.speak 'hello', :engine => :cepstral
|
2704
|
+
end
|
2705
|
+
|
2706
|
+
it 'should allow setting TTS rendering interruptible' do
|
2707
|
+
flexmock(@speech_engines).should_receive(:cepstral).once.with(mock_call, 'hello', {:interruptible => true})
|
2708
|
+
mock_call.speak 'hello', :engine => :cepstral, :interruptible => true
|
2274
2709
|
end
|
2275
2710
|
|
2276
|
-
|
2711
|
+
it "should stringify the text" do
|
2712
|
+
flexmock(@speech_engines).should_receive(:cepstral).once.with(mock_call, 'hello', {:interruptible => false})
|
2713
|
+
mock_call.speak :hello, :engine => :cepstral
|
2714
|
+
end
|
2715
|
+
|
2716
|
+
context "with the engine :cepstral" do
|
2717
|
+
it "should execute Swift"do
|
2718
|
+
pbx_should_respond_with_value 0
|
2719
|
+
mock_call.should_receive(:execute).with('Swift', 'hello')
|
2720
|
+
@speech_engines.cepstral(mock_call, 'hello')
|
2721
|
+
@output.read.should == "GET VARIABLE \"SWIFT_DTMF\"\n"
|
2722
|
+
end
|
2723
|
+
|
2724
|
+
it "should properly escape commas in the TTS string" do
|
2725
|
+
pbx_should_respond_with_value 0
|
2726
|
+
mock_call.should_receive(:execute).with('Swift', 'Once\\\\, a long\\\\, long time ago\\\\, ...')
|
2727
|
+
@speech_engines.cepstral(mock_call, 'Once, a long, long time ago, ...')
|
2728
|
+
@output.read.should == "GET VARIABLE \"SWIFT_DTMF\"\n"
|
2729
|
+
end
|
2730
|
+
|
2731
|
+
it "should properly escape double-quotes (for XML) in the TTS string" do
|
2732
|
+
mock_call.should_receive(:raw_response).once.with('EXEC MRCPSynth "<speak xmlns=\\\\\"http://www.w3.org/2001/10/synthesis\\\\\" version=\\\\\"1.0\\\\\" xml:lang=\\\\\"en-US\\\\\"> <voice name=\\\\\"Paul\\\\\"> <prosody rate=\\\\\"1.0\\\\\">Howdy, stranger. How are you today?</prosody> </voice> </speak>"').and_return pbx_success_response
|
2733
|
+
@speech_engines.unimrcp(mock_call, '<speak xmlns="http://www.w3.org/2001/10/synthesis" version="1.0" xml:lang="en-US"> <voice name="Paul"> <prosody rate="1.0">Howdy, stranger. How are you today?</prosody> </voice> </speak>')
|
2734
|
+
end
|
2735
|
+
|
2736
|
+
context "with barge in digits set" do
|
2737
|
+
it "should return the digit when :interruptible = true" do
|
2738
|
+
mock_call.should_receive(:execute).once.with('Swift', 'hello', 1, 1).and_return pbx_success_response
|
2739
|
+
mock_call.should_receive(:get_variable).once.with('SWIFT_DTMF').and_return ?1
|
2740
|
+
@speech_engines.cepstral(mock_call, 'hello', :interruptible => true).should == ?1
|
2741
|
+
end
|
2742
|
+
end
|
2743
|
+
end
|
2744
|
+
|
2745
|
+
context "with the engine :unimrcp" do
|
2746
|
+
it "should execute MRCPSynth" do
|
2747
|
+
pbx_should_respond_with_success
|
2748
|
+
mock_call.should_receive(:execute).with('MRCPSynth', 'hello').once.and_return pbx_success_response
|
2749
|
+
@speech_engines.unimrcp(mock_call, 'hello')
|
2750
|
+
end
|
2751
|
+
|
2752
|
+
context "with barge in digits set" do
|
2753
|
+
it "should pass the i option for MRCPSynth" do
|
2754
|
+
mock_call.should_receive(:execute).with('MRCPSynth', 'hello', 'i=any').once.and_return pbx_result_response 0
|
2755
|
+
@speech_engines.unimrcp(mock_call, 'hello', :interrupt_digits => 'any')
|
2756
|
+
end
|
2757
|
+
end
|
2758
|
+
end
|
2759
|
+
|
2760
|
+
context "with the engine :tropo" do
|
2761
|
+
it "should execute tropo" do
|
2762
|
+
pbx_should_respond_with_success
|
2763
|
+
response = '200 result=' + {:interpretation => '1'}.to_json
|
2764
|
+
mock_call.should_receive(:raw_response).with(/Ask/i, 'hello').once.and_return response
|
2765
|
+
@speech_engines.tropo(mock_call, 'hello').should == "1"
|
2766
|
+
end
|
2767
|
+
|
2768
|
+
context "with :interruptible set to false"do
|
2769
|
+
it "should pass the :bargein => false option for Tropo Ask" do
|
2770
|
+
response = '200 result=' + {:interpretation => '1'}.to_json
|
2771
|
+
mock_call.should_receive(:raw_response).with(/Ask/i, 'hello', {:bargein => false}.to_json).once.and_return response
|
2772
|
+
@speech_engines.tropo(mock_call, 'hello', :interruptible => false)
|
2773
|
+
end
|
2774
|
+
end
|
2775
|
+
end
|
2277
2776
|
|
2777
|
+
it "properly escapes spoken text" do
|
2778
|
+
pending 'What are the escaping needs?'
|
2779
|
+
end
|
2278
2780
|
end
|
2279
2781
|
|
2280
2782
|
describe 'The join command' do
|