adhearsion 2.2.1 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Adhearsion
4
- VERSION = '2.2.1'
4
+ VERSION = '2.3.0'
5
5
  end
@@ -9,27 +9,47 @@ module Adhearsion
9
9
  include CallControllerTestHelpers
10
10
 
11
11
  describe "#play_sound_files_for_menu" do
12
+ let(:renderer_options) { { renderer: nil } }
12
13
  let(:options) { Hash.new }
13
14
  let(:menu_instance) { MenuDSL::Menu.new(options) }
14
15
  let(:sound_file) { "press a button" }
15
16
  let(:sound_files) { [sound_file] }
16
17
 
17
18
  it "should play the sound files for the menu" do
18
- subject.should_receive(:interruptible_play).with(sound_file).and_return("1")
19
+ subject.should_receive(:interruptible_play).with(sound_file, renderer_options).and_return("1")
19
20
  subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
20
21
  end
21
22
 
22
23
  it "should wait for digit if nothing is pressed during playback" do
23
- subject.should_receive(:interruptible_play).with(sound_file).and_return(nil)
24
+ subject.should_receive(:interruptible_play).with(sound_file, renderer_options).and_return(nil)
24
25
  subject.should_receive(:wait_for_digit).with(menu_instance.timeout).and_return("1")
25
26
  subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
26
27
  end
27
28
 
29
+ context "with a renderer specified" do
30
+ let(:options) { { :renderer => :native } }
31
+ let(:renderer_options) { { renderer: :native } }
32
+ it "should play the sound files for the menu" do
33
+ subject.should_receive(:interruptible_play).with(sound_file, renderer_options).and_return("1")
34
+ subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
35
+ end
36
+
37
+ end
38
+
28
39
  context "when the menu is not interruptible" do
29
40
  let(:options) { { :interruptible => false } }
30
-
31
41
  it "should play the sound files and wait for digit" do
32
- subject.should_receive(:play).with(sound_file).and_return true
42
+ subject.should_receive(:play).with(sound_file, renderer_options).and_return true
43
+ subject.should_receive(:wait_for_digit).with(menu_instance.timeout).and_return("1")
44
+ subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
45
+ end
46
+ end
47
+
48
+ context "with a renderer specified and not interruptible" do
49
+ let(:options) { { :renderer => :native, :interruptible => false } }
50
+ let(:renderer_options) { { renderer: :native } }
51
+ it "should pass the renderer option to #play" do
52
+ subject.should_receive(:play).with(sound_file, renderer_options).and_return true
33
53
  subject.should_receive(:wait_for_digit).with(menu_instance.timeout).and_return("1")
34
54
  subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
35
55
  end
@@ -117,6 +117,22 @@ module Adhearsion
117
117
  end
118
118
  end
119
119
 
120
+ context 'when renderer is not specified' do
121
+ it 'should have a nil renderer' do
122
+ subject.renderer.should be nil
123
+ end
124
+ end
125
+
126
+ context 'when renderer is specified' do
127
+ let(:options) {
128
+ {:renderer => :native}
129
+ }
130
+
131
+ it 'should have the specified renderer' do
132
+ subject.renderer.should == :native
133
+ end
134
+ end
135
+
120
136
  context 'when matchers are specified' do
121
137
  subject do
122
138
  Menu.new do
@@ -347,6 +363,24 @@ module Adhearsion
347
363
  menu_instance.result.should be == '242'
348
364
  end
349
365
  end
366
+
367
+ context "when a digit limit and validator is defined" do
368
+ let(:menu_instance) do
369
+ Menu.new options.merge(:limit => 3) do
370
+ validator { |buffer| buffer == "242" }
371
+ end
372
+ end
373
+
374
+ it "applies the validator before checking the digit limit" do
375
+ menu_instance << 2
376
+ menu_instance << 4
377
+ menu_instance << 2
378
+ menu_instance.continue.should be_a Menu::MenuValidatorTerminated
379
+ menu_instance.continue.should be_a Menu::MenuResultDone
380
+ menu_instance.status.should be == :validator_terminated
381
+ menu_instance.result.should be == '242'
382
+ end
383
+ end
350
384
  end
351
385
 
352
386
  end#continue
@@ -69,6 +69,14 @@ module Adhearsion
69
69
  subject.play_audio(audio_file, :fallback => fallback).should be true
70
70
  end
71
71
  end
72
+
73
+ context "with a media engine" do
74
+ let(:media_engine) { :native }
75
+ it "should use the specified media engine in the component" do
76
+ expect_ssml_output ssml, renderer: media_engine
77
+ subject.play_audio(audio_file, renderer: media_engine).should be true
78
+ end
79
+ end
72
80
  end
73
81
 
74
82
  describe "#play_audio!" do
@@ -100,6 +108,14 @@ module Adhearsion
100
108
  subject.play_audio!(audio_file, :fallback => fallback).should be_a Punchblock::Component::Output
101
109
  end
102
110
  end
111
+
112
+ context "with a media engine" do
113
+ let(:media_engine) { :native }
114
+ it "should use the specified media engine in the SSML" do
115
+ expect_async_ssml_output ssml, renderer: media_engine
116
+ subject.play_audio!(audio_file, renderer: media_engine).should be_a Punchblock::Component::Output
117
+ end
118
+ end
103
119
  end
104
120
 
105
121
  describe "#play_numeric" do
@@ -319,6 +335,9 @@ module Adhearsion
319
335
  end
320
336
 
321
337
  describe '#play' do
338
+ let(:extra_options) do
339
+ { renderer: :native }
340
+ end
322
341
  describe "with a single string" do
323
342
  let(:audio_file) { "/foo/bar.wav" }
324
343
  let :ssml do
@@ -330,6 +349,11 @@ module Adhearsion
330
349
  expect_ssml_output ssml
331
350
  subject.play(audio_file).should be true
332
351
  end
352
+
353
+ it 'plays the audio file with the specified extra options if present' do
354
+ expect_ssml_output ssml, extra_options
355
+ subject.play(audio_file, extra_options).should be true
356
+ end
333
357
  end
334
358
 
335
359
  describe "with multiple arguments" do
@@ -349,6 +373,12 @@ module Adhearsion
349
373
  expect_ssml_output ssml
350
374
  subject.play(*args).should be true
351
375
  end
376
+
377
+ it 'plays all arguments in one document with the extra options if present' do
378
+ expect_ssml_output ssml, extra_options
379
+ args << extra_options
380
+ subject.play(*args).should be true
381
+ end
352
382
  end
353
383
 
354
384
  describe "with a collection of arguments" do
@@ -463,6 +493,9 @@ module Adhearsion
463
493
  end
464
494
 
465
495
  describe '#play!' do
496
+ let(:extra_options) do
497
+ { renderer: :native }
498
+ end
466
499
  describe "with a single string" do
467
500
  let(:audio_file) { "/foo/bar.wav" }
468
501
  let :ssml do
@@ -474,6 +507,11 @@ module Adhearsion
474
507
  expect_async_ssml_output ssml
475
508
  subject.play!(audio_file).should be_a Punchblock::Component::Output
476
509
  end
510
+
511
+ it 'plays the audio file with the specified extra options if present' do
512
+ expect_async_ssml_output ssml, extra_options
513
+ subject.play!(audio_file, extra_options)
514
+ end
477
515
  end
478
516
 
479
517
  describe "with multiple arguments" do
@@ -493,6 +531,12 @@ module Adhearsion
493
531
  expect_async_ssml_output ssml
494
532
  subject.play!(*args).should be_a Punchblock::Component::Output
495
533
  end
534
+
535
+ it 'plays all arguments in one document with the extra options if present' do
536
+ expect_async_ssml_output ssml, extra_options
537
+ args << extra_options
538
+ subject.play!(*args)
539
+ end
496
540
  end
497
541
 
498
542
  describe "with a number" do
@@ -591,6 +635,7 @@ module Adhearsion
591
635
  let(:output1) { "one two" }
592
636
  let(:output2) { "three four" }
593
637
  let(:non_existing) { "http://adhearsion.com/nonexistingfile.mp3" }
638
+ let(:extra_options) { {renderer: :native } }
594
639
 
595
640
  it "plays two outputs in succession" do
596
641
  subject.should_receive(:stream_file).twice
@@ -604,6 +649,13 @@ module Adhearsion
604
649
  digit.should be == 2
605
650
  end
606
651
 
652
+ it "passes options on to #stream_file" do
653
+ subject.should_receive(:stream_file).once.with(output1, '0123456789#*', extra_options)
654
+ subject.should_receive(:stream_file).once.with(output2, '0123456789#*', extra_options)
655
+ digit = subject.interruptible_play output1, output2, extra_options
656
+ digit.should be_nil
657
+ end
658
+
607
659
  it 'raises an exception when output is unsuccessful' do
608
660
  subject.should_receive(:stream_file).once.and_raise Output::PlaybackError, "Output failed"
609
661
  expect { subject.interruptible_play non_existing }.to raise_error(Output::PlaybackError)
@@ -669,6 +721,19 @@ module Adhearsion
669
721
  expect_component_execution output_component
670
722
  subject.stream_file(prompt, allowed_digits).should be == '5'
671
723
  end
724
+
725
+ context "with output options passed in" do
726
+ let(:extra_options) { {renderer: :native } }
727
+ it "plays the correct output with options" do
728
+ def controller.write_and_await_response(input_component)
729
+ # it is actually a no-op here
730
+ end
731
+
732
+ expect_component_complete_event
733
+ expect_component_execution Punchblock::Component::Output.new({:ssml => ssml.to_s}.merge(extra_options))
734
+ subject.stream_file prompt, allowed_digits, extra_options
735
+ end
736
+ end
672
737
  end
673
738
 
674
739
  describe "#say" do
@@ -117,6 +117,24 @@ module Adhearsion
117
117
  end
118
118
  end
119
119
 
120
+ context "with :interruptible => '123'" do
121
+ let(:interruptible) { '123' }
122
+
123
+ let :stopper_grammar do
124
+ RubySpeech::GRXML.draw :mode => 'dtmf', :root => 'inputdigits' do
125
+ rule id: 'inputdigits', scope: 'public' do
126
+ one_of do
127
+ item { '1' }
128
+ item { '2' }
129
+ item { '3' }
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ its(:stopper_component) { should == input_component }
136
+ end
137
+
120
138
  describe "setting completion handlers" do
121
139
  let(:complete_event) { Punchblock::Event::Complete.new }
122
140
 
@@ -94,7 +94,7 @@ module Adhearsion
94
94
  class InvokeController < CallController
95
95
  def run
96
96
  before
97
- invoke second_controller, :foo => 'bar'
97
+ metadata[:invoke_result] = invoke second_controller, :foo => 'bar'
98
98
  after
99
99
  end
100
100
 
@@ -114,7 +114,7 @@ module Adhearsion
114
114
  before do
115
115
  flexmock subject, :execute_component_and_await_completion => nil
116
116
  flexmock call.wrapped_object, :write_and_await_response => nil
117
- flexmock call, :register_controller! => nil
117
+ flexmock call, :register_controller => nil
118
118
  flexmock(Events).should_receive(:trigger).with(:exception, Exception).never
119
119
  end
120
120
 
@@ -126,6 +126,12 @@ module Adhearsion
126
126
  subject.execute!
127
127
  end
128
128
 
129
+ it "should return the outer controller's run method return value" do
130
+ flexmock(SecondController).new_instances.should_receive(:run).once.and_return(:run_result)
131
+ subject.execute!
132
+ subject.metadata[:invoke_result].should be == :run_result
133
+ end
134
+
129
135
  it "should invoke the new controller with metadata" do
130
136
  flexmock(SecondController).new_instances.should_receive(:md_check).once.with :foo => 'bar'
131
137
  subject.execute!
@@ -166,7 +172,7 @@ module Adhearsion
166
172
 
167
173
  before do
168
174
  flexmock call.wrapped_object, :write_and_await_response => nil
169
- flexmock call, :register_controller! => nil
175
+ flexmock call, :register_controller => nil
170
176
  flexmock subject, :execute_component_and_await_completion => nil
171
177
  flexmock(SecondController).new_instances.should_receive(:md_check).once.with :foo => 'bar'
172
178
  flexmock(Events).should_receive(:trigger).with(:exception, Exception).never
@@ -348,15 +354,11 @@ module Adhearsion
348
354
 
349
355
  describe "with an error response" do
350
356
  let(:response) do
351
- Punchblock::Event::Complete.new.tap do |complete|
352
- complete << error
353
- end
357
+ Punchblock::Event::Complete.new :reason => error
354
358
  end
355
359
 
356
- let(:error) do |error|
357
- Punchblock::Event::Complete::Error.new.tap do |e|
358
- e << details
359
- end
360
+ let(:error) do
361
+ Punchblock::Event::Complete::Error.new :details => details
360
362
  end
361
363
 
362
364
  let(:details) { "Oh noes, it's all borked" }
@@ -30,7 +30,7 @@ module Adhearsion
30
30
  end
31
31
 
32
32
  after do
33
- Adhearsion.active_calls.clear!
33
+ Adhearsion.active_calls.clear
34
34
  end
35
35
 
36
36
  it { should respond_to :<< }
@@ -236,9 +236,7 @@ module Adhearsion
236
236
 
237
237
  describe "for end events" do
238
238
  let :event do
239
- Punchblock::Event::End.new.tap do |e|
240
- flexmock e, :reason => :hangup
241
- end
239
+ Punchblock::Event::End.new :reason => :hangup
242
240
  end
243
241
 
244
242
  it "should trigger any on_end callbacks set" do
@@ -317,9 +315,7 @@ module Adhearsion
317
315
  describe "#<<" do
318
316
  describe "with a Punchblock End" do
319
317
  let :end_event do
320
- Punchblock::Event::End.new.tap do |e|
321
- flexmock e, :reason => :hangup
322
- end
318
+ Punchblock::Event::End.new :reason => :hangup
323
319
  end
324
320
 
325
321
  it "should mark the call as ended" do
@@ -43,9 +43,9 @@ describe Adhearsion::Initializer do
43
43
 
44
44
  it "should create a pid file in the app's path when given 'true' as the pid_file hash key argument" do
45
45
  stub_behavior_for_initializer_with_no_path_changing_behavior do
46
- flexmock(File).should_receive(:open).with(File.join(path, 'adhearsion.pid'), 'w', Proc).at_least.once
47
- ahn = Adhearsion::Initializer.start :pid_file => true
48
- ahn.pid_file[0, path.length].should be == path
46
+ flexmock(File).should_receive(:open).with(File.join(path, 'adhearsion.pid'), 'w', Proc).at_least.once
47
+ ahn = Adhearsion::Initializer.start :pid_file => true
48
+ ahn.pid_file[0, path.length].should be == path
49
49
  end
50
50
  end
51
51
 
@@ -58,6 +58,7 @@ describe Adhearsion::Initializer do
58
58
 
59
59
  it "should create a pid file in the app's path by default when daemonizing" do
60
60
  stub_behavior_for_initializer_with_no_path_changing_behavior do
61
+ flexmock(Adhearsion::CustomDaemonizer).should_receive(:daemonize).and_yield
61
62
  flexmock(File).should_receive(:open).once.with(File.join(path, 'adhearsion.pid'), 'w', Proc)
62
63
  ahn = Adhearsion::Initializer.start :mode => :daemon
63
64
  ahn.pid_file[0, path.size].should be == path
@@ -66,7 +67,8 @@ describe Adhearsion::Initializer do
66
67
 
67
68
  it "should NOT create a pid file in the app's path when daemonizing and :pid_file is given as false" do
68
69
  stub_behavior_for_initializer_with_no_path_changing_behavior do
69
- ahn = Adhearsion::Initializer.start :daemon => true, :pid_file => false
70
+ flexmock(Adhearsion::CustomDaemonizer).should_receive(:daemonize).and_yield
71
+ ahn = Adhearsion::Initializer.start :mode => :daemon, :pid_file => false
70
72
  ahn.pid_file.should be nil
71
73
  end
72
74
  end
@@ -146,7 +146,7 @@ describe Adhearsion::Plugin do
146
146
  it "should add a initializer when Plugin defines it" do
147
147
  FooBar = Class.new Adhearsion::Plugin do
148
148
  init :foo_bar do
149
- FooBar.log "foo bar"
149
+ log "foo bar"
150
150
  end
151
151
  def self.log
152
152
  end
@@ -245,7 +245,7 @@ describe Adhearsion::Plugin do
245
245
  it "should add a runner when Plugin defines it" do
246
246
  FooBar = Class.new Adhearsion::Plugin do
247
247
  run :foo_bar do
248
- FooBar.log "foo bar"
248
+ log "foo bar"
249
249
  end
250
250
  def self.log
251
251
  end
@@ -50,7 +50,7 @@ module Adhearsion
50
50
  it "should hang up active calls" do
51
51
  3.times do
52
52
  fake_call = flexmock Call.new, :id => random_call_id
53
- flexmock(fake_call).should_receive(:hangup!).once
53
+ flexmock(fake_call).should_receive(:hangup).once
54
54
  Adhearsion.active_calls << fake_call
55
55
  end
56
56
 
@@ -54,7 +54,7 @@ module Adhearsion
54
54
  end
55
55
 
56
56
  let(:call_id) { rand }
57
- let(:offer) { Punchblock::Event::Offer.new.tap { |o| o.target_call_id = call_id } }
57
+ let(:offer) { Punchblock::Event::Offer.new :target_call_id => call_id }
58
58
  let(:mock_call) { flexmock Call.new, :id => call_id }
59
59
 
60
60
  describe "starts the client with the default values" do
@@ -224,14 +224,16 @@ module Adhearsion
224
224
  end
225
225
  end
226
226
 
227
- context "when when Adhearsion::Process is in :running" do
228
- let(:process_state) { :running }
227
+ [ :running, :stopping ].each do |state|
228
+ context "when when Adhearsion::Process is in :#{state}" do
229
+ let(:process_state) { state }
229
230
 
230
- it "should dispatch via the router" do
231
- Adhearsion.router do
232
- route 'foobar', Class.new
231
+ it "should dispatch via the router" do
232
+ Adhearsion.router do
233
+ route 'foobar', Class.new
234
+ end
235
+ flexmock(Adhearsion.router).should_receive(:handle).once.with mock_call
233
236
  end
234
- flexmock(Adhearsion.router).should_receive(:handle).once.with mock_call
235
237
  end
236
238
  end
237
239