spec/punchblock/translator/asterisk/call_spec.rb in punchblock-2.1.1 vs spec/punchblock/translator/asterisk/call_spec.rb in punchblock-2.2.0
- old
+ new
@@ -67,18 +67,10 @@
its(:translator) { should be translator }
its(:agi_env) { should be == agi_env }
before { translator.stub :handle_pb_event }
- describe '#shutdown' do
- it 'should terminate the actor' do
- subject.shutdown
- sleep 0.5
- subject.should_not be_alive
- end
- end
-
describe '#register_component' do
it 'should make the component accessible by ID' do
component_id = 'abc123'
component = double 'Translator::Asterisk::Component', :id => component_id
subject.register_component component
@@ -121,19 +113,19 @@
end
describe '#send_progress' do
context "with a call that is already answered" do
it 'should not send the EXEC Progress command' do
- subject.wrapped_object.should_receive(:'answered?').and_return true
- subject.wrapped_object.should_receive(:execute_agi_command).with("EXEC Progress").never
+ subject.should_receive(:'answered?').and_return true
+ subject.should_receive(:execute_agi_command).with("EXEC Progress").never
subject.send_progress
end
end
context "with an unanswered call" do
before do
- subject.wrapped_object.should_receive(:'answered?').at_least(:once).and_return(false)
+ subject.should_receive(:'answered?').at_least(:once).and_return(false)
end
context "with a call that is outbound" do
let(:dial_command) { Command::Dial.new }
@@ -141,27 +133,27 @@
dial_command.request!
subject.dial dial_command
end
it 'should not send the EXEC Progress command' do
- subject.wrapped_object.should_receive(:execute_agi_command).with("EXEC Progress").never
+ subject.should_receive(:execute_agi_command).with("EXEC Progress").never
subject.send_progress
end
end
context "with a call that is inbound" do
before do
subject.send_offer
end
it 'should send the EXEC Progress command to a call that is inbound and not answered' do
- subject.wrapped_object.should_receive(:execute_agi_command).with("EXEC Progress").and_return code: 200, result: 0
+ subject.should_receive(:execute_agi_command).with("EXEC Progress").and_return code: 200, result: 0
subject.send_progress
end
it 'should send the EXEC Progress command only once if called twice' do
- subject.wrapped_object.should_receive(:execute_agi_command).with("EXEC Progress").once.and_return code: 200, result: 0
+ subject.should_receive(:execute_agi_command).with("EXEC Progress").once.and_return code: 200, result: 0
subject.send_progress
subject.send_progress
end
end
end
@@ -274,11 +266,11 @@
it 'causes accepting the call to be a null operation' do
subject.dial dial_command
accept_command = Command::Accept.new
accept_command.request!
- subject.wrapped_object.should_receive(:execute_agi_command).never
+ subject.should_receive(:execute_agi_command).never
subject.execute_command accept_command
accept_command.response(0.5).should be true
end
end
@@ -295,17 +287,10 @@
end
let(:cause) { '16' }
let(:cause_txt) { 'Normal Clearing' }
- it "should cause the actor to be terminated" do
- translator.should_receive(:handle_pb_event).twice
- subject.process_ami_event ami_event
- Celluloid::Actor.join(subject, 1)
- subject.should_not be_alive
- end
-
it "de-registers the call from the translator" do
translator.stub :handle_pb_event
translator.should_receive(:deregister_call).once.with(subject.id, subject.channel)
subject.process_ami_event ami_event
end
@@ -332,11 +317,11 @@
comp_command = Punchblock::Component::Input.new :grammar => {:value => RubySpeech::GRXML.draw(root: 'foo') { rule id: 'foo' }}, :mode => :dtmf
comp_command.request!
component = subject.execute_command comp_command
comp_command.response(0.1).should be_a Ref
- subject.async.process_ami_event ami_event
+ subject.process_ami_event ami_event
comp_command = Punchblock::Component::Input.new :grammar => {:value => '<grammar root="foo"><rule id="foo"/></grammar>'}, :mode => :dtmf
comp_command.request!
subject.execute_command comp_command
comp_command.response(0.1).should == ProtocolError.new.setup(:item_not_found, "Could not find a call with ID #{call_id}", call_id)
@@ -655,11 +640,11 @@
end
before do
translator.register_call other_call
command.request!
- subject.wrapped_object.should_receive(:execute_agi_command).and_return code: 200
+ subject.should_receive(:execute_agi_command).and_return code: 200
subject.execute_command command
end
it 'retrieves and sets success on the correct Join' do
subject.process_ami_event ami_event
@@ -858,10 +843,19 @@
it 'sends the AMI event to the connection as a PB event' do
translator.should_receive(:handle_pb_event).with expected_pb_event
subject.process_ami_event ami_event
end
+ context "when the event doesn't pass the filter" do
+ before { Asterisk.event_filter = ->(event) { false } }
+ after { Asterisk.event_filter = nil }
+
+ it 'does not send the AMI event to the connection as a PB event' do
+ translator.should_receive(:handle_pb_event).never
+ subject.process_ami_event ami_event
+ end
+ end
end
describe '#execute_command' do
before do
command.request!
@@ -869,20 +863,20 @@
context 'with an accept command' do
let(:command) { Command::Accept.new }
it "should send an EXEC RINGING AGI command and set the command's response" do
- subject.wrapped_object.should_receive(:execute_agi_command).with('EXEC RINGING').and_return code: 200
+ subject.should_receive(:execute_agi_command).with('EXEC RINGING').and_return code: 200
subject.execute_command command
command.response(0.5).should be true
end
context "when the AMI commannd raises an error" do
let(:message) { 'Some error' }
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
- before { subject.wrapped_object.should_receive(:execute_agi_command).and_raise error }
+ before { subject.should_receive(:execute_agi_command).and_raise error }
it "should return an error with the message" do
subject.execute_command command
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
end
@@ -901,11 +895,11 @@
context 'with a reject command' do
let(:command) { Command::Reject.new }
it "with a :busy reason should send an EXEC Busy AGI command and set the command's response" do
command.reason = :busy
- subject.wrapped_object.should_receive(:execute_agi_command).with('EXEC Busy').and_return code: 200
+ subject.should_receive(:execute_agi_command).with('EXEC Busy').and_return code: 200
subject.execute_command command
command.response(0.5).should be true
end
it "with a :decline reason should send a Hangup AMI command (cause 21) and set the command's response" do
@@ -915,20 +909,20 @@
command.response(0.5).should be true
end
it "with an :error reason should send an EXEC Congestion AGI command and set the command's response" do
command.reason = :error
- subject.wrapped_object.should_receive(:execute_agi_command).with('EXEC Congestion').and_return code: 200
+ subject.should_receive(:execute_agi_command).with('EXEC Congestion').and_return code: 200
subject.execute_command command
command.response(0.5).should be true
end
context "when the AMI commannd raises an error" do
let(:message) { 'Some error' }
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
- before { subject.wrapped_object.should_receive(:execute_agi_command).and_raise error }
+ before { subject.should_receive(:execute_agi_command).and_raise error }
it "should return an error with the message" do
subject.execute_command command
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
end
@@ -946,26 +940,26 @@
context 'with an answer command' do
let(:command) { Command::Answer.new }
it "should send an ANSWER AGI command and set the command's response" do
- subject.wrapped_object.should_receive(:execute_agi_command).with('ANSWER').and_return code: 200
+ subject.should_receive(:execute_agi_command).with('ANSWER').and_return code: 200
subject.execute_command command
command.response(0.5).should be true
end
it "should be answered" do
- subject.wrapped_object.should_receive(:execute_agi_command)
+ subject.should_receive(:execute_agi_command)
subject.execute_command command
subject.should be_answered
end
context "when the AMI command raises an error" do
let(:message) { 'Some error' }
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
- before { subject.wrapped_object.should_receive(:execute_agi_command).and_raise error }
+ before { subject.should_receive(:execute_agi_command).and_raise error }
it "should return an error with the message" do
subject.execute_command command
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
end
@@ -1040,19 +1034,19 @@
end
before { translator.should_receive(:call_with_id).with(other_call_id).and_return(other_call) }
it "executes the proper dialplan Bridge application" do
- subject.wrapped_object.should_receive(:execute_agi_command).with('EXEC Bridge', "#{other_channel},F(#{REDIRECT_CONTEXT},#{REDIRECT_EXTENSION},#{REDIRECT_PRIORITY})").and_return code: 200
+ subject.should_receive(:execute_agi_command).with('EXEC Bridge', "#{other_channel},F(#{REDIRECT_CONTEXT},#{REDIRECT_EXTENSION},#{REDIRECT_PRIORITY})").and_return code: 200
subject.execute_command command
end
context "when the AMI command raises an error" do
let(:message) { 'Some error' }
let(:error) { RubyAMI::Error.new.tap { |e| e.message = message } }
- before { subject.wrapped_object.should_receive(:execute_agi_command).and_raise error }
+ before { subject.should_receive(:execute_agi_command).and_raise error }
it "should return an error with the message" do
subject.execute_command command
command.response(0.5).should be == ProtocolError.new.setup('error', message, subject.id)
end
@@ -1154,43 +1148,40 @@
context 'with an AGI command component' do
let :command do
Punchblock::Component::Asterisk::AGI::Command.new :name => 'Answer'
end
- let(:mock_action) { Translator::Asterisk::Component::Asterisk::AGICommand.new(command, subject) }
-
it 'should create an AGI command component actor and execute it asynchronously' do
- Component::Asterisk::AGICommand.should_receive(:new_link).once.with(command, subject).and_return mock_action
- mock_action.async.should_receive(:execute).once
+ mock_action = Translator::Asterisk::Component::Asterisk::AGICommand.new(command, subject)
+ Component::Asterisk::AGICommand.should_receive(:new).once.with(command, subject).and_return mock_action
+ mock_action.should_receive(:execute).once
subject.execute_command command
end
end
context 'with an Output component' do
let :command do
Punchblock::Component::Output.new
end
- let(:mock_action) { Translator::Asterisk::Component::Output.new(command, subject) }
-
it 'should create an Output component and execute it asynchronously' do
- Component::Output.should_receive(:new_link).once.with(command, subject).and_return mock_action
- mock_action.async.should_receive(:execute).once
+ mock_action = Translator::Asterisk::Component::Output.new(command, subject)
+ Component::Output.should_receive(:new).once.with(command, subject).and_return mock_action
+ mock_action.should_receive(:execute).once
subject.execute_command command
end
end
context 'with an Input component' do
let :command do
Punchblock::Component::Input.new
end
- let(:mock_action) { Translator::Asterisk::Component::Input.new(command, subject) }
-
it 'should create an Input component and execute it asynchronously' do
- Component::Input.should_receive(:new_link).once.with(command, subject).and_return mock_action
- mock_action.async.should_receive(:execute).once
+ mock_action = Translator::Asterisk::Component::Input.new(command, subject)
+ Component::Input.should_receive(:new).once.with(command, subject).and_return mock_action
+ mock_action.should_receive(:execute).once
subject.execute_command command
end
end
context 'with a Prompt component' do
@@ -1222,28 +1213,30 @@
})
end
let(:mock_action) { Translator::Asterisk::Component::MRCPPrompt.new(command, subject) }
+ before { mock_action}
+
context "when the recognizer is unimrcp and the renderer is unimrcp" do
let(:recognizer) { :unimrcp }
let(:renderer) { :unimrcp }
it 'should create an MRCPPrompt component and execute it asynchronously' do
- Component::MRCPPrompt.should_receive(:new_link).once.with(command, subject).and_return mock_action
- mock_action.async.should_receive(:execute).once
+ Component::MRCPPrompt.should_receive(:new).once.with(command, subject).and_return mock_action
+ mock_action.should_receive(:execute).once
subject.execute_command command
end
end
context "when the recognizer is unimrcp and the renderer is asterisk" do
let(:recognizer) { :unimrcp }
let(:renderer) { :asterisk }
it 'should create an MRCPPrompt component and execute it asynchronously' do
- Component::MRCPNativePrompt.should_receive(:new_link).once.with(command, subject).and_return mock_action
- mock_action.async.should_receive(:execute).once
+ Component::MRCPNativePrompt.should_receive(:new).once.with(command, subject).and_return mock_action
+ mock_action.should_receive(:execute).once
subject.execute_command command
end
end
context "when the recognizer is unimrcp and the renderer is something we can't compose with unimrcp" do
@@ -1259,27 +1252,26 @@
context "when the recognizer is something other than unimrcp" do
let(:recognizer) { :asterisk }
let(:renderer) { :unimrcp }
it 'should create a ComposedPrompt component and execute it asynchronously' do
- Component::ComposedPrompt.should_receive(:new_link).once.with(command, subject).and_return mock_action
- mock_action.async.should_receive(:execute).once
+ Component::ComposedPrompt.should_receive(:new).once.with(command, subject).and_return mock_action
+ mock_action.should_receive(:execute).once
subject.execute_command command
end
end
end
context 'with a Record component' do
let :command do
Punchblock::Component::Record.new
end
- let(:mock_action) { Translator::Asterisk::Component::Record.new(command, subject) }
-
it 'should create a Record component and execute it asynchronously' do
- Component::Record.should_receive(:new_link).once.with(command, subject).and_return mock_action
- mock_action.async.should_receive(:execute).once
+ mock_action = Translator::Asterisk::Component::Record.new(command, subject)
+ Component::Record.should_receive(:new).once.with(command, subject).and_return mock_action
+ mock_action.should_receive(:execute).once
subject.execute_command command
end
end
context 'with a component command' do
@@ -1325,41 +1317,21 @@
context "normally" do
it 'sends an error in response to the command' do
component = subject.component_with_id comp_id
- component.terminate
- sleep 0.1
- component.should_not be_alive
+ component.send_complete_event Punchblock::Component::Asterisk::AGI::Command::Complete.new
+
subject.component_with_id(comp_id).should be_nil
subsequent_command.request!
subject.execute_command subsequent_command
subsequent_command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id)
end
end
context "by crashing" do
- it 'sends an error in response to the command' do
- component = subject.component_with_id comp_id
-
- component.wrapped_object.define_singleton_method(:oops) do
- raise 'Woops, I died'
- end
-
- translator.should_receive(:handle_pb_event).once.with expected_event
-
- lambda { component.oops }.should raise_error(/Woops, I died/)
- sleep 0.1
- component.should_not be_alive
- subject.component_with_id(comp_id).should be_nil
-
- subsequent_command.request!
- subject.execute_command subsequent_command
- subsequent_command.response.should be == ProtocolError.new.setup(:item_not_found, "Could not find a component with ID #{comp_id} for call #{subject.id}", subject.id, comp_id)
- end
-
context "when we dispatch the command to it" do
it 'sends an error in response to the command' do
component = subject.component_with_id comp_id
component.should_receive(:execute_command).and_raise(Celluloid::DeadActorError)
@@ -1457,10 +1429,12 @@
"Command" => "EXEC ANSWER",
"Result" => "200%20result=123%20(timeout)%0A"
end
it 'should return the result' do
- fut = subject.future.execute_agi_command 'EXEC ANSWER'
+ fut = Celluloid::Future.new { subject.execute_agi_command 'EXEC ANSWER' }
+
+ sleep 0.25
subject.process_ami_event ami_event
fut.value.should == {code: 200, result: 123, data: 'timeout'}
end