spec/adhearsion/call_controller/input_spec.rb in adhearsion-2.0.0.beta1 vs spec/adhearsion/call_controller/input_spec.rb in adhearsion-2.0.0.rc1
- old
+ new
@@ -1,70 +1,42 @@
+# encoding: utf-8
+
require 'spec_helper'
module Adhearsion
class CallController
describe Input do
include CallControllerTestHelpers
- describe "#grammar_digits" do
- let(:grxml) {
- RubySpeech::GRXML.draw :mode => 'dtmf', :root => 'inputdigits' do
- rule id: 'inputdigits', scope: 'public' do
- item repeat: '2' do
- one_of do
- 0.upto(9) { |d| item { d.to_s } }
- end
- end
- end
- end
- }
+ describe "#play_sound_files_for_menu" do
+ let(:options) { Hash.new }
+ let(:menu_instance) { Adhearsion::MenuDSL::Menu.new(options) }
+ let(:sound_file) { "press a button" }
+ let(:sound_files) { [sound_file] }
- it 'generates the correct GRXML grammar' do
- subject.grammar_digits(2).to_s.should == grxml.to_s
+ it "should play the sound files for the menu" do
+ subject.should_receive(:interruptible_play).with(sound_file).and_return("1")
+ subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
end
- end # describe #grammar_digits
-
- describe "#grammar_accept" do
- let(:grxml) {
- RubySpeech::GRXML.draw :mode => 'dtmf', :root => 'inputdigits' do
- rule id: 'inputdigits', scope: 'public' do
- one_of do
- item { '3' }
- item { '5' }
- end
- end
- end
- }
-
- it 'generates the correct GRXML grammar' do
- subject.grammar_accept('35').to_s.should == grxml.to_s
+ it "should wait for digit if nothing is pressed during playback" do
+ subject.should_receive(:interruptible_play).with(sound_file).and_return(nil)
+ subject.should_receive(:wait_for_digit).with(menu_instance.timeout).and_return("1")
+ subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
end
- it 'filters meaningless characters out' do
- subject.grammar_accept('3+5').to_s.should == grxml.to_s
- end
- end # grammar_accept
+ context "when the menu is not interruptible" do
+ let(:options) { { :interruptible => false } }
- describe "#parse_single_dtmf" do
- it "correctly returns the parsed input" do
- subject.parse_single_dtmf("dtmf-3").should == '3'
+ it "should play the sound files and wait for digit" do
+ subject.should_receive(:play).with(sound_file).and_return true
+ subject.should_receive(:wait_for_digit).with(menu_instance.timeout).and_return("1")
+ subject.play_sound_files_for_menu(menu_instance, sound_files).should be == '1'
+ end
end
+ end#play_sound_files_for_menu
- it "correctly returns star as *" do
- subject.parse_single_dtmf("dtmf-star").should == '*'
- end
-
- it "correctly returns pound as #" do
- subject.parse_single_dtmf("dtmf-pound").should == '#'
- end
-
- it "correctly returns nil when input is nil" do
- subject.parse_single_dtmf(nil).should == nil
- end
- end # describe #grammar_accept
-
describe "#wait_for_digit" do
let(:timeout) { 2 }
let(:timeout_ms) { 2000 }
let(:grxml) {
@@ -107,11 +79,11 @@
end
it "returns the correct pressed digit" do
expect_component_complete_event
subject.should_receive(:execute_component_and_await_completion).once.with(Punchblock::Component::Input).and_return input_component
- subject.wait_for_digit(timeout).should == '5'
+ subject.wait_for_digit(timeout).should be == '5'
end
context "with a nil timeout" do
let(:timeout) { nil }
let(:timeout_ms) { nil }
@@ -122,157 +94,208 @@
subject.wait_for_digit timeout
end
end
end # wait_for_digit
- describe "#input!" do
- describe "simple usage" do
- let(:timeout) { 3000 }
+ describe "#jump_to" do
+ let(:match_object) { flexmock(Class.new) }
+ let(:overrides) { Hash.new(:extension => "1") }
+ let(:block) { Proc.new {} }
- it "can be called with no arguments" do
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('1')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input!
- end
+ it "calls instance_exec if the match object has a block" do
+ match_object.should_receive(:block).and_return(block)
+ subject.should_receive(:instance_exec).with(overrides[:extension], block)
+ subject.jump_to(match_object, overrides)
+ end
- it "can be called with 1 digit as an argument" do
- subject.should_receive(:wait_for_digit).with(nil)
- subject.input! 1
- end
+ it "calls invoke if the match object does not have a block" do
+ match_object.should_receive(:block).and_return(false)
+ match_object.should_receive(:match_payload).and_return(:payload)
+ subject.should_receive(:invoke).with(:payload, overrides)
+ subject.jump_to(match_object, overrides)
+ end
+ end#jump_to
- it "accepts a timeout argument" do
- subject.should_receive(:wait_for_digit).with(3000)
- subject.input! :timeout => timeout
- end
+ describe "#menu" do
+ let(:sound_files) { ["press", "button"] }
+
+ let(:menu_instance) do
+ MenuDSL::Menu.new { match(1) {} }
end
- describe "any number of digits with a terminator" do
- let(:terminator) { '9' }
+ let(:result_done) { MenuDSL::Menu::MenuResultDone.new }
+ let(:result_terminated) { MenuDSL::Menu::MenuTerminated.new }
+ let(:result_limit_reached) { MenuDSL::Menu::MenuLimitReached.new }
+ let(:result_invalid) { MenuDSL::Menu::MenuResultInvalid.new }
+ let(:result_get_another_or_timeout) { MenuDSL::Menu::MenuGetAnotherDigitOrTimeout.new }
+ let(:result_get_another_or_finish) { MenuDSL::Menu::MenuGetAnotherDigitOrFinish.new(:match_object, :new_extension) }
+ let(:result_found) { MenuDSL::Menu::MenuResultFound.new(:match_object, :new_extension) }
- it "called with no arguments, it returns any number of digits taking a terminating digit" do
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('1')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input!.should == '1'
- end
+ let(:status) { :foo }
+ let(:response) { '1234' }
- it "allows to set a different terminator" do
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('1')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return(terminator)
- subject.input!(:terminator => terminator).should == '1'
- end
+ before do
+ flexmock menu_instance, :status => status, :result => response
+ flexmock(MenuDSL::Menu).should_receive(:new).and_return(menu_instance)
end
- describe "with a fixed number or digits" do
- it "accepts and returns three digits without a terminator" do
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('1')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('2')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('3')
- subject.input!(3).should == '123'
- end
+ it "exits the function if MenuResultDone" do
+ menu_instance.should_receive(:should_continue?).and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_done)
+ result = subject.menu sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
end
- describe "with play arguments" do
- let(:string_play) { "Thanks for calling" }
- let(:ssml_play) { RubySpeech::SSML.draw { string "Please stand by" } }
- let(:hash_play) { {:value => Time.parse("24/10/2011"), :strftime => "%H:%M"} }
- let(:hash_value) { Time.parse "24/10/2011" }
- let(:hash_options) { {:strftime => "%H:%M"} }
+ it "exits the function if MenuTerminated" do
+ menu_instance.should_receive(:should_continue?).and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_terminated)
+ result = subject.menu sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
+ end
- it "plays a string argument" do
- subject.should_receive(:interruptible_play!).with(string_play)
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input! :play => string_play
- end
+ it "exits the function if MenuLimitReached" do
+ menu_instance.should_receive(:should_continue?).and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_limit_reached)
+ result = subject.menu sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
+ end
- it "plays a SSML argument" do
- subject.should_receive(:interruptible_play!).with(ssml_play)
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input! :play => ssml_play
- end
+ it "executes failure hook and returns :failure if menu fails" do
+ menu_instance.should_receive(:should_continue?).and_return(false)
+ menu_instance.should_receive(:execute_failure_hook)
+ result = subject.menu sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
+ end
- it "plays a Hash argument" do
- subject.should_receive(:interruptible_play!).with([hash_value, hash_options])
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input! :play => hash_play
- end
+ it "executes invalid hook if input is invalid" do
+ menu_instance.should_receive(:should_continue?).twice.and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_invalid, result_done)
+ menu_instance.should_receive(:execute_invalid_hook)
+ menu_instance.should_receive(:restart!)
+ result = subject.menu sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
+ end
- it "plays an array of mixed arguments" do
- subject.should_receive(:interruptible_play!).with(string_play)
- subject.should_receive(:interruptible_play!).with(ssml_play)
- subject.should_receive(:interruptible_play!).with([hash_value, hash_options])
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input! :play => [string_play, ssml_play, hash_play]
- end
+ it "plays audio, then executes timeout hook if input times out" do
+ menu_instance.should_receive(:should_continue?).twice.and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_get_another_or_timeout, result_done)
+ subject.should_receive(:play_sound_files_for_menu).with(menu_instance, sound_files).and_return(nil)
+ menu_instance.should_receive(:execute_timeout_hook)
+ menu_instance.should_receive(:restart!)
+ subject.menu sound_files
+ end
- it "plays a string argument, takes 1 digit and returns the input" do
- subject.should_receive(:interruptible_play!).with(string_play).and_return('1')
- subject.input!(1, :play => string_play).should == '1'
- end
+ it "plays audio, then adds digit to digit buffer if input is received" do
+ menu_instance.should_receive(:should_continue?).twice.and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_get_another_or_timeout, result_done)
+ subject.should_receive(:play_sound_files_for_menu).with(menu_instance, sound_files).and_return("1")
+ menu_instance.should_receive(:<<).with("1")
+ subject.menu sound_files
+ end
- it "plays a string argument, takes 2 digits and returns the input" do
- subject.should_receive(:interruptible_play!).with(string_play).and_return('1')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('1')
- subject.input!(2, :play => string_play).should == '11'
- end
+ it "plays audio, then jumps to payload when input is finished" do
+ menu_instance.should_receive(:should_continue?).and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_get_another_or_finish)
+ subject.should_receive(:play_sound_files_for_menu).with(menu_instance, sound_files).and_return(nil)
+ subject.should_receive(:jump_to).with(:match_object, :extension => :new_extension)
+ subject.menu sound_files
+ end
- it "plays a string argument, allows for any number of digit and an accept key" do
- subject.should_receive(:interruptible_play!).with(string_play).and_return('1').ordered
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('2').ordered
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#').ordered
- subject.input!(:play => string_play).should == '12'
- end
+ it "jumps to payload when result is found" do
+ menu_instance.should_receive(:should_continue?).and_return(true)
+ menu_instance.should_receive(:continue).and_return(result_found)
+ subject.should_receive(:jump_to).with(:match_object, :extension => :new_extension)
+ result = subject.menu sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
+ end
- it "plays an array of mixed arguments, stops playing when a key is pressed, and returns the input" do
- subject.should_receive(:interruptible_play!).and_return(nil, '1', StandardError.new("should not be called"))
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input!(:play => [string_play, ssml_play, hash_play]).should == '1'
- end
- end # describe with play arguments
+ context "if a digit limit is specified" do
+ it "should raise an ArgumentError"
+ end
- describe "non interruptible play" do
- let(:string_play) { "Thanks for calling" }
+ context "if a terminator digit is specified" do
+ it "should raise an ArgumentError"
+ end
- it "calls play! when passed :interruptible => false" do
- subject.should_receive(:play!).with(string_play)
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input! :play => string_play, :interruptible => false
+ end#describe
+
+ describe "#ask" do
+ let(:sound_files) { ["press", "button"] }
+
+ context "mocking out the menu" do
+ let(:menu_instance) { MenuDSL::Menu.new :limit => 2 }
+
+ let(:result_done) { MenuDSL::Menu::MenuResultDone.new }
+ let(:result_terminated) { MenuDSL::Menu::MenuTerminated.new }
+ let(:result_limit_reached) { MenuDSL::Menu::MenuLimitReached.new }
+ let(:result_invalid) { MenuDSL::Menu::MenuResultInvalid.new }
+ let(:result_get_another_or_timeout) { MenuDSL::Menu::MenuGetAnotherDigitOrTimeout.new }
+ let(:result_get_another_or_finish) { MenuDSL::Menu::MenuGetAnotherDigitOrFinish.new(:match_object, :new_extension) }
+ let(:result_found) { MenuDSL::Menu::MenuResultFound.new(:match_object, :new_extension) }
+
+ let(:status) { :foo }
+ let(:response) { '1234' }
+
+ before do
+ flexmock menu_instance, :status => status, :result => response
+ flexmock(MenuDSL::Menu).should_receive(:new).and_return(menu_instance)
end
- it "still collects digits when passed :interruptible => false" do
- subject.should_receive(:play!).with(string_play)
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('1')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input!(:play => string_play, :interruptible => false).should == '1'
+ it "exits the function if MenuResultDone" do
+ menu_instance.should_receive(:continue).and_return(result_done)
+ result = subject.ask sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
end
- end # describe non interruptible play
- describe "speak functionality" do
- let(:string_speak) { "Thanks for calling" }
+ it "exits the function if MenuTerminated" do
+ menu_instance.should_receive(:continue).and_return(result_terminated)
+ result = subject.ask sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
+ end
- it "speaks passed text" do
- subject.should_receive(:interruptible_play!).with(string_speak, {})
- subject.input! :speak => {:text => string_speak }
+ it "exits the function if MenuLimitReached" do
+ menu_instance.should_receive(:continue).and_return(result_limit_reached)
+ result = subject.ask sound_files
+ result.menu.should be menu_instance
+ result.response.should be response
end
- it "speaks passed text and collect digits" do
- subject.should_receive(:interruptible_play!).with(string_speak, {}).and_return('1')
- subject.should_receive(:wait_for_digit).once.with(nil).and_return('#')
- subject.input!(:speak => {:text => string_speak }).should == '1'
+ it "plays audio, then executes timeout hook if input times out" do
+ menu_instance.should_receive(:continue).and_return(result_get_another_or_timeout, result_done)
+ subject.should_receive(:play_sound_files_for_menu).with(menu_instance, sound_files).and_return(nil)
+ menu_instance.should_receive(:execute_timeout_hook)
+ menu_instance.should_receive(:restart!)
+ subject.ask sound_files
end
+
+ it "plays audio, then adds digit to digit buffer if input is received" do
+ menu_instance.should_receive(:continue).and_return(result_get_another_or_timeout, result_done)
+ subject.should_receive(:play_sound_files_for_menu).with(menu_instance, sound_files).and_return("1")
+ menu_instance.should_receive(:<<).with("1")
+ subject.ask sound_files
+ end
end
- it 'throws an exception when playback fails'
- end # describe input!
-
- describe "#input" do
- let(:string_play) { "Thanks for calling" }
-
- it "just calls #input!" do
- subject.should_receive(:input!).with(:play => string_play).and_return(nil)
- subject.input! :play => string_play
+ context "with a block passed" do
+ it "should set that block as the buffer validator" do
+ foo = nil
+ subject.should_receive(:play_sound_files_for_menu).and_return("1")
+ subject.ask sound_files, :limit => 0 do |buffer|
+ foo = :bar
+ end.menu.execute_validator_hook
+ foo.should be == :bar
+ end
end
- it 'does not throw exceptions when playback fails'
- end # describe input
- end
+ end#describe
+
+ end#shared
end
end