adhearsion 2.2.1 → 2.3.0

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.
@@ -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