spec/punchblock/translator/asterisk/component/output_spec.rb in punchblock-1.7.0 vs spec/punchblock/translator/asterisk/component/output_spec.rb in punchblock-1.7.1
- old
+ new
@@ -353,410 +353,410 @@
end
end
end
end
- context 'with a media engine of :asterisk' do
- let(:media_engine) { :asterisk }
+ [:asterisk, nil].each do |media_engine|
+ context "with a media engine of #{media_engine.inspect}" do
+ def expect_playback(filename = audio_filename)
+ mock_call.should_receive(:send_agi_action!).once.with 'EXEC Playback', filename
+ end
- def expect_playback(filename = audio_filename)
- mock_call.should_receive(:send_agi_action!).once.with 'EXEC Playback', filename
- end
+ def expect_playback_noanswer
+ mock_call.should_receive(:send_agi_action!).once.with 'EXEC Playback', audio_filename + ',noanswer'
+ end
- def expect_playback_noanswer
- mock_call.should_receive(:send_agi_action!).once.with 'EXEC Playback', audio_filename + ',noanswer'
- end
+ let(:audio_filename) { 'http://foo.com/bar.mp3' }
- let(:audio_filename) { 'http://foo.com/bar.mp3' }
-
- let :ssml_doc do
- RubySpeech::SSML.draw do
- audio :src => audio_filename
+ let :ssml_doc do
+ RubySpeech::SSML.draw do
+ audio :src => audio_filename
+ end
end
- end
- let(:command_opts) { {} }
+ let(:command_opts) { {} }
- let :command_options do
- { :ssml => ssml_doc }.merge(command_opts)
- end
+ let :command_options do
+ { :ssml => ssml_doc }.merge(command_opts)
+ end
- let :original_command do
- Punchblock::Component::Output.new command_options
- end
-
- describe 'ssml' do
- context 'unset' do
- let(:command_opts) { { :ssml => nil } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'An SSML document is required.'
- original_command.response(0.1).should be == error
- end
+ let :original_command do
+ Punchblock::Component::Output.new command_options
end
- context 'with a single audio SSML node' do
- let(:audio_filename) { 'http://foo.com/bar.mp3' }
- let :command_options do
- {
- :ssml => RubySpeech::SSML.draw { audio :src => audio_filename }
- }
+ describe 'ssml' do
+ context 'unset' do
+ let(:command_opts) { { :ssml => nil } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'An SSML document is required.'
+ original_command.response(0.1).should be == error
+ end
end
- it 'should playback the audio file using Playback' do
- expect_answered
- expect_playback
- subject.execute
- end
+ context 'with a single audio SSML node' do
+ let(:audio_filename) { 'http://foo.com/bar.mp3' }
+ let :command_options do
+ {
+ :ssml => RubySpeech::SSML.draw { audio :src => audio_filename }
+ }
+ end
- it 'should send a complete event when the file finishes playback' do
- def mock_call.answered?
- true
+ it 'should playback the audio file using Playback' do
+ expect_answered
+ expect_playback
+ subject.execute
end
- def mock_call.send_agi_action!(*args, &block)
- block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
+
+ it 'should send a complete event when the file finishes playback' do
+ def mock_call.answered?
+ true
+ end
+ def mock_call.send_agi_action!(*args, &block)
+ block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
+ end
+ subject.execute
+ original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
end
- subject.execute
- original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
end
- end
- context 'with a single text node without spaces' do
- let(:audio_filename) { 'tt-monkeys' }
- let :command_options do
- {
- :ssml => RubySpeech::SSML.draw { string audio_filename }
- }
- end
-
- it 'should playback the audio file using Playback' do
- expect_answered
- expect_playback
- subject.execute
- end
-
- it 'should send a complete event when the file finishes playback' do
- expect_answered
- def mock_call.send_agi_action!(*args, &block)
- block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
+ context 'with a single text node without spaces' do
+ let(:audio_filename) { 'tt-monkeys' }
+ let :command_options do
+ {
+ :ssml => RubySpeech::SSML.draw { string audio_filename }
+ }
end
- subject.execute
- original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
- end
- context "with early media playback" do
- it "should play the file with Playback" do
- expect_answered false
- expect_playback_noanswer
- mock_call.should_receive(:send_progress)
+ it 'should playback the audio file using Playback' do
+ expect_answered
+ expect_playback
subject.execute
end
- context "with interrupt_on set to something that is not nil" do
- let(:audio_filename) { 'tt-monkeys' }
- let :command_options do
- {
- :ssml => RubySpeech::SSML.draw { string audio_filename },
- :interrupt_on => :any
- }
+ it 'should send a complete event when the file finishes playback' do
+ expect_answered
+ def mock_call.send_agi_action!(*args, &block)
+ block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
end
- it "should return an error when the output is interruptible and it is early media" do
+ subject.execute
+ original_command.complete_event(0.1).reason.should be_a Punchblock::Component::Output::Complete::Success
+ end
+
+ context "with early media playback" do
+ it "should play the file with Playback" do
expect_answered false
- error = ProtocolError.new.setup 'option error', 'Interrupt digits are not allowed with early media.'
+ expect_playback_noanswer
+ mock_call.should_receive(:send_progress)
subject.execute
- original_command.response(0.1).should be == error
end
+
+ context "with interrupt_on set to something that is not nil" do
+ let(:audio_filename) { 'tt-monkeys' }
+ let :command_options do
+ {
+ :ssml => RubySpeech::SSML.draw { string audio_filename },
+ :interrupt_on => :any
+ }
+ end
+ it "should return an error when the output is interruptible and it is early media" do
+ expect_answered false
+ error = ProtocolError.new.setup 'option error', 'Interrupt digits are not allowed with early media.'
+ subject.execute
+ original_command.response(0.1).should be == error
+ end
+ end
end
end
- end
- context 'with a string (not SSML)' do
- let :command_options do
- { :text => 'Foo Bar' }
- end
+ context 'with a string (not SSML)' do
+ let :command_options do
+ { :text => 'Foo Bar' }
+ end
- it "should return an unrenderable document error" do
- subject.execute
- error = ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details.'
- original_command.response(0.1).should be == error
+ it "should return an unrenderable document error" do
+ subject.execute
+ error = ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details.'
+ original_command.response(0.1).should be == error
+ end
end
- end
- context 'with multiple audio SSML nodes' do
- let(:audio_filename1) { 'http://foo.com/bar.mp3' }
- let(:audio_filename2) { 'http://foo.com/baz.mp3' }
- let :command_options do
- {
- :ssml => RubySpeech::SSML.draw do
- audio :src => audio_filename1
- audio :src => audio_filename2
- end
- }
- end
+ context 'with multiple audio SSML nodes' do
+ let(:audio_filename1) { 'http://foo.com/bar.mp3' }
+ let(:audio_filename2) { 'http://foo.com/baz.mp3' }
+ let :command_options do
+ {
+ :ssml => RubySpeech::SSML.draw do
+ audio :src => audio_filename1
+ audio :src => audio_filename2
+ end
+ }
+ end
- it 'should playback all audio files using Playback' do
- latch = CountDownLatch.new 2
- expect_playback [audio_filename1, audio_filename2].join('&')
- expect_answered
- subject.execute
- latch.wait 2
- sleep 2
- end
-
- it 'should send a complete event after the final file has finished playback' do
- expect_answered
- def mock_call.send_agi_action!(*args, &block)
- block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
+ it 'should playback all audio files using Playback' do
+ latch = CountDownLatch.new 2
+ expect_playback [audio_filename1, audio_filename2].join('&')
+ expect_answered
+ subject.execute
+ latch.wait 2
+ sleep 2
end
- latch = CountDownLatch.new 1
- original_command.should_receive(:add_event).once.with do |e|
- e.reason.should be_a Punchblock::Component::Output::Complete::Success
- latch.countdown!
- end
- subject.execute
- latch.wait(2).should be_true
- end
- end
- context "with an SSML document containing elements other than <audio/>" do
- let :command_options do
- {
- :ssml => RubySpeech::SSML.draw do
- string "Foo Bar"
+ it 'should send a complete event after the final file has finished playback' do
+ expect_answered
+ def mock_call.send_agi_action!(*args, &block)
+ block.call Punchblock::Component::Asterisk::AGI::Command::Complete::Success.new(:code => 200, :result => 1)
end
- }
+ latch = CountDownLatch.new 1
+ original_command.should_receive(:add_event).once.with do |e|
+ e.reason.should be_a Punchblock::Component::Output::Complete::Success
+ latch.countdown!
+ end
+ subject.execute
+ latch.wait(2).should be_true
+ end
end
- it "should return an unrenderable document error" do
- subject.execute
- error = ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details.'
- original_command.response(0.1).should be == error
- end
- end
- end
+ context "with an SSML document containing elements other than <audio/>" do
+ let :command_options do
+ {
+ :ssml => RubySpeech::SSML.draw do
+ string "Foo Bar"
+ end
+ }
+ end
- describe 'start-offset' do
- context 'unset' do
- let(:command_opts) { { :start_offset => nil } }
- it 'should not pass any options to Playback' do
- expect_answered
- expect_playback
- subject.execute
+ it "should return an unrenderable document error" do
+ subject.execute
+ error = ProtocolError.new.setup 'unrenderable document error', 'The provided document could not be rendered. See http://adhearsion.com/docs/common_problems#unrenderable-document-error for details.'
+ original_command.response(0.1).should be == error
+ end
end
end
- context 'set' do
- let(:command_opts) { { :start_offset => 10 } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'A start_offset value is unsupported on Asterisk.'
- original_command.response(0.1).should be == error
+ describe 'start-offset' do
+ context 'unset' do
+ let(:command_opts) { { :start_offset => nil } }
+ it 'should not pass any options to Playback' do
+ expect_answered
+ expect_playback
+ subject.execute
+ end
end
- end
- end
- describe 'start-paused' do
- context 'false' do
- let(:command_opts) { { :start_paused => false } }
- it 'should not pass any options to Playback' do
- expect_answered
- expect_playback
- subject.execute
+ context 'set' do
+ let(:command_opts) { { :start_offset => 10 } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'A start_offset value is unsupported on Asterisk.'
+ original_command.response(0.1).should be == error
+ end
end
end
- context 'true' do
- let(:command_opts) { { :start_paused => true } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'A start_paused value is unsupported on Asterisk.'
- original_command.response(0.1).should be == error
+ describe 'start-paused' do
+ context 'false' do
+ let(:command_opts) { { :start_paused => false } }
+ it 'should not pass any options to Playback' do
+ expect_answered
+ expect_playback
+ subject.execute
+ end
end
- end
- end
- describe 'repeat-interval' do
- context 'unset' do
- let(:command_opts) { { :repeat_interval => nil } }
- it 'should not pass any options to Playback' do
- expect_answered
- expect_playback
- subject.execute
+ context 'true' do
+ let(:command_opts) { { :start_paused => true } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'A start_paused value is unsupported on Asterisk.'
+ original_command.response(0.1).should be == error
+ end
end
end
- context 'set' do
- let(:command_opts) { { :repeat_interval => 10 } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'A repeat_interval value is unsupported on Asterisk.'
- original_command.response(0.1).should be == error
+ describe 'repeat-interval' do
+ context 'unset' do
+ let(:command_opts) { { :repeat_interval => nil } }
+ it 'should not pass any options to Playback' do
+ expect_answered
+ expect_playback
+ subject.execute
+ end
end
- end
- end
- describe 'repeat-times' do
- context 'unset' do
- let(:command_opts) { { :repeat_times => nil } }
- it 'should not pass any options to Playback' do
- expect_answered
- expect_playback
- subject.execute
+ context 'set' do
+ let(:command_opts) { { :repeat_interval => 10 } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'A repeat_interval value is unsupported on Asterisk.'
+ original_command.response(0.1).should be == error
+ end
end
end
- context 'set' do
- let(:command_opts) { { :repeat_times => 2 } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'A repeat_times value is unsupported on Asterisk.'
- original_command.response(0.1).should be == error
+ describe 'repeat-times' do
+ context 'unset' do
+ let(:command_opts) { { :repeat_times => nil } }
+ it 'should not pass any options to Playback' do
+ expect_answered
+ expect_playback
+ subject.execute
+ end
end
- end
- end
- describe 'max-time' do
- context 'unset' do
- let(:command_opts) { { :max_time => nil } }
- it 'should not pass any options to Playback' do
- expect_answered
- expect_playback
- subject.execute
+ context 'set' do
+ let(:command_opts) { { :repeat_times => 2 } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'A repeat_times value is unsupported on Asterisk.'
+ original_command.response(0.1).should be == error
+ end
end
end
- context 'set' do
- let(:command_opts) { { :max_time => 30 } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'A max_time value is unsupported on Asterisk.'
- original_command.response(0.1).should be == error
+ describe 'max-time' do
+ context 'unset' do
+ let(:command_opts) { { :max_time => nil } }
+ it 'should not pass any options to Playback' do
+ expect_answered
+ expect_playback
+ subject.execute
+ end
end
- end
- end
- describe 'voice' do
- context 'unset' do
- let(:command_opts) { { :voice => nil } }
- it 'should not pass the v option to Playback' do
- expect_answered
- expect_playback
- subject.execute
+ context 'set' do
+ let(:command_opts) { { :max_time => 30 } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'A max_time value is unsupported on Asterisk.'
+ original_command.response(0.1).should be == error
+ end
end
end
- context 'set' do
- let(:command_opts) { { :voice => 'alison' } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'A voice value is unsupported on Asterisk.'
- original_command.response(0.1).should be == error
+ describe 'voice' do
+ context 'unset' do
+ let(:command_opts) { { :voice => nil } }
+ it 'should not pass the v option to Playback' do
+ expect_answered
+ expect_playback
+ subject.execute
+ end
end
- end
- end
- describe 'interrupt_on' do
- def ami_event_for_dtmf(digit, position)
- RubyAMI::Event.new('DTMF').tap do |e|
- e['Digit'] = digit.to_s
- e['Start'] = position == :start ? 'Yes' : 'No'
- e['End'] = position == :end ? 'Yes' : 'No'
+ context 'set' do
+ let(:command_opts) { { :voice => 'alison' } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'A voice value is unsupported on Asterisk.'
+ original_command.response(0.1).should be == error
+ end
end
end
- def send_ami_events_for_dtmf(digit)
- mock_call.process_ami_event ami_event_for_dtmf(digit, :start)
- mock_call.process_ami_event ami_event_for_dtmf(digit, :end)
- end
-
- let(:reason) { original_command.complete_event(5).reason }
- let(:channel) { "SIP/1234-00000000" }
- let :ami_event do
- RubyAMI::Event.new('AsyncAGI').tap do |e|
- e['SubEvent'] = "Start"
- e['Channel'] = channel
- e['Env'] = "agi_request%3A%20async%0Aagi_channel%3A%20SIP%2F1234-00000000%0Aagi_language%3A%20en%0Aagi_type%3A%20SIP%0Aagi_uniqueid%3A%201320835995.0%0Aagi_version%3A%201.8.4.1%0Aagi_callerid%3A%205678%0Aagi_calleridname%3A%20Jane%20Smith%0Aagi_callingpres%3A%200%0Aagi_callingani2%3A%200%0Aagi_callington%3A%200%0Aagi_callingtns%3A%200%0Aagi_dnid%3A%201000%0Aagi_rdnis%3A%20unknown%0Aagi_context%3A%20default%0Aagi_extension%3A%201000%0Aagi_priority%3A%201%0Aagi_enhanced%3A%200.0%0Aagi_accountcode%3A%20%0Aagi_threadid%3A%204366221312%0A%0A"
+ describe 'interrupt_on' do
+ def ami_event_for_dtmf(digit, position)
+ RubyAMI::Event.new('DTMF').tap do |e|
+ e['Digit'] = digit.to_s
+ e['Start'] = position == :start ? 'Yes' : 'No'
+ e['End'] = position == :end ? 'Yes' : 'No'
+ end
end
- end
- context "set to nil" do
- let(:command_opts) { { :interrupt_on => nil } }
- it "does not redirect the call" do
- expect_answered
- expect_playback
- mock_call.should_receive(:redirect_back!).never
- subject.execute
- original_command.response(0.1).should be_a Ref
- send_ami_events_for_dtmf 1
+ def send_ami_events_for_dtmf(digit)
+ mock_call.process_ami_event ami_event_for_dtmf(digit, :start)
+ mock_call.process_ami_event ami_event_for_dtmf(digit, :end)
end
- end
- context "set to :any" do
- let(:command_opts) { { :interrupt_on => :any } }
-
- before do
- expect_answered
- expect_playback
+ let(:reason) { original_command.complete_event(5).reason }
+ let(:channel) { "SIP/1234-00000000" }
+ let :ami_event do
+ RubyAMI::Event.new('AsyncAGI').tap do |e|
+ e['SubEvent'] = "Start"
+ e['Channel'] = channel
+ e['Env'] = "agi_request%3A%20async%0Aagi_channel%3A%20SIP%2F1234-00000000%0Aagi_language%3A%20en%0Aagi_type%3A%20SIP%0Aagi_uniqueid%3A%201320835995.0%0Aagi_version%3A%201.8.4.1%0Aagi_callerid%3A%205678%0Aagi_calleridname%3A%20Jane%20Smith%0Aagi_callingpres%3A%200%0Aagi_callingani2%3A%200%0Aagi_callington%3A%200%0Aagi_callingtns%3A%200%0Aagi_dnid%3A%201000%0Aagi_rdnis%3A%20unknown%0Aagi_context%3A%20default%0Aagi_extension%3A%201000%0Aagi_priority%3A%201%0Aagi_enhanced%3A%200.0%0Aagi_accountcode%3A%20%0Aagi_threadid%3A%204366221312%0A%0A"
+ end
end
- context "when a DTMF digit is received" do
- it "sends the correct complete event" do
- mock_call.should_receive :redirect_back!
+ context "set to nil" do
+ let(:command_opts) { { :interrupt_on => nil } }
+ it "does not redirect the call" do
+ expect_answered
+ expect_playback
+ mock_call.should_receive(:redirect_back!).never
subject.execute
original_command.response(0.1).should be_a Ref
- original_command.should_not be_complete
send_ami_events_for_dtmf 1
- mock_call.process_ami_event! ami_event
- sleep 0.2
- original_command.should be_complete
- reason.should be_a Punchblock::Component::Output::Complete::Success
end
+ end
- it "redirects the call back to async AGI" do
- mock_call.should_receive(:redirect_back!).once
- subject.execute
- original_command.response(0.1).should be_a Ref
- send_ami_events_for_dtmf 1
+ context "set to :any" do
+ let(:command_opts) { { :interrupt_on => :any } }
+
+ before do
+ expect_answered
+ expect_playback
end
- end
- end
- context "set to :dtmf" do
- let(:command_opts) { { :interrupt_on => :dtmf } }
+ context "when a DTMF digit is received" do
+ it "sends the correct complete event" do
+ mock_call.should_receive :redirect_back!
+ subject.execute
+ original_command.response(0.1).should be_a Ref
+ original_command.should_not be_complete
+ send_ami_events_for_dtmf 1
+ mock_call.process_ami_event! ami_event
+ sleep 0.2
+ original_command.should be_complete
+ reason.should be_a Punchblock::Component::Output::Complete::Success
+ end
- before do
- expect_answered
- expect_playback
+ it "redirects the call back to async AGI" do
+ mock_call.should_receive(:redirect_back!).once
+ subject.execute
+ original_command.response(0.1).should be_a Ref
+ send_ami_events_for_dtmf 1
+ end
+ end
end
- context "when a DTMF digit is received" do
- it "sends the correct complete event" do
- mock_call.should_receive :redirect_back!
- subject.execute
- original_command.response(0.1).should be_a Ref
- original_command.should_not be_complete
- send_ami_events_for_dtmf 1
- mock_call.process_ami_event! ami_event
- sleep 0.2
- original_command.should be_complete
- reason.should be_a Punchblock::Component::Output::Complete::Success
+ context "set to :dtmf" do
+ let(:command_opts) { { :interrupt_on => :dtmf } }
+
+ before do
+ expect_answered
+ expect_playback
end
- it "redirects the call back to async AGI" do
- mock_call.should_receive(:redirect_back!).once
- subject.execute
- original_command.response(0.1).should be_a Ref
- send_ami_events_for_dtmf 1
+ context "when a DTMF digit is received" do
+ it "sends the correct complete event" do
+ mock_call.should_receive :redirect_back!
+ subject.execute
+ original_command.response(0.1).should be_a Ref
+ original_command.should_not be_complete
+ send_ami_events_for_dtmf 1
+ mock_call.process_ami_event! ami_event
+ sleep 0.2
+ original_command.should be_complete
+ reason.should be_a Punchblock::Component::Output::Complete::Success
+ end
+
+ it "redirects the call back to async AGI" do
+ mock_call.should_receive(:redirect_back!).once
+ subject.execute
+ original_command.response(0.1).should be_a Ref
+ send_ami_events_for_dtmf 1
+ end
end
end
- end
- context "set to :speech" do
- let(:command_opts) { { :interrupt_on => :speech } }
- it "should return an error and not execute any actions" do
- subject.execute
- error = ProtocolError.new.setup 'option error', 'An interrupt-on value of speech is unsupported.'
- original_command.response(0.1).should be == error
+ context "set to :speech" do
+ let(:command_opts) { { :interrupt_on => :speech } }
+ it "should return an error and not execute any actions" do
+ subject.execute
+ error = ProtocolError.new.setup 'option error', 'An interrupt-on value of speech is unsupported.'
+ original_command.response(0.1).should be == error
+ end
end
end
end
end