require 'spec_helper'
module Punchblock
module Connection
describe XMPP do
let(:options) { { :root_domain => 'rayo.net' } }
let(:connection) { XMPP.new({:username => '1@app.rayo.net', :password => 1}.merge(options)) }
let(:mock_event_handler) { stub_everything 'Event Handler' }
before do
connection.event_handler = mock_event_handler
end
subject { connection }
describe "rayo domains" do
context "with no domains specified, and a JID of 1@app.rayo.net" do
let(:options) { { :username => '1@app.rayo.net' } }
its(:root_domain) { should == 'app.rayo.net' }
its(:calls_domain) { should == 'calls.app.rayo.net' }
its(:mixers_domain) { should == 'mixers.app.rayo.net' }
end
context "with only a rayo domain set" do
let(:options) { { :rayo_domain => 'rayo.org' } }
its(:root_domain) { should == 'rayo.org' }
its(:calls_domain) { should == 'calls.rayo.org' }
its(:mixers_domain) { should == 'mixers.rayo.org' }
end
context "with only a root domain set" do
let(:options) { { :root_domain => 'rayo.org' } }
its(:root_domain) { should == 'rayo.org' }
its(:calls_domain) { should == 'calls.rayo.org' }
its(:mixers_domain) { should == 'mixers.rayo.org' }
end
context "with a root domain and calls domain set" do
let(:options) { { :root_domain => 'rayo.org', :calls_domain => 'phone_calls.rayo.org' } }
its(:root_domain) { should == 'rayo.org' }
its(:calls_domain) { should == 'phone_calls.rayo.org' }
its(:mixers_domain) { should == 'mixers.rayo.org' }
end
context "with a root domain and mixers domain set" do
let(:options) { { :root_domain => 'rayo.org', :mixers_domain => 'conferences.rayo.org' } }
its(:root_domain) { should == 'rayo.org' }
its(:calls_domain) { should == 'calls.rayo.org' }
its(:mixers_domain) { should == 'conferences.rayo.org' }
end
end
it 'should require a username and password to be passed in the options' do
expect { XMPP.new :password => 1 }.to raise_error ArgumentError
expect { XMPP.new :username => 1 }.to raise_error ArgumentError
end
it 'should properly set the Blather logger' do
Punchblock.logger = :foo
XMPP.new :username => '1@call.rayo.net', :password => 1
Blather.logger.should be :foo
Punchblock.reset_logger
end
it "looking up original command by command ID" do
pending
offer = Event::Offer.new
offer.call_id = '9f00061'
offer.to = 'sip:whatever@127.0.0.1'
output = <<-MSG
MSG
Component::Output
output = RayoNode.import parse_stanza(output).root
connection.expects(:write_to_stream).once.returns true
iq = Blather::Stanza::Iq.new :set, '9f00061@call.rayo.net'
connection.expects(:create_iq).returns iq
write_thread = Thread.new do
connection.write offer.call_id, output
end
result = import_stanza <<-MSG
MSG
sleep 0.5 # Block so there's enough time for the write thread to get to the point where it's waiting on an IQ
connection.__send__ :handle_iq_result, result
write_thread.join
output.state_name.should == :executing
connection.original_component_from_id('fgh4590').should == output
example_complete = import_stanza <<-MSG
MSG
connection.__send__ :handle_presence, example_complete
output.complete_event(0.5).source.should == output
output.component_id.should == 'fgh4590'
end
it 'should send a "Chat" presence when ready' do
client = connection.send :client
client.expects(:write).once.with do |stanza|
stanza.to.should == 'rayo.net' &&
stanza.is_a?(Blather::Stanza::Presence::Status) &&
stanza.chat?
end
connection.ready!
end
it 'should send a "Do Not Disturb" presence when not_ready' do
client = connection.send :client
client.expects(:write).once.with do |stanza|
stanza.to.should == 'rayo.net' &&
stanza.is_a?(Blather::Stanza::Presence::Status) &&
stanza.dnd?
end
connection.not_ready!
end
describe '#handle_presence' do
let :offer_xml do
<<-MSG
MSG
end
let(:example_offer) { import_stanza offer_xml }
it { example_offer.should be_a Blather::Stanza::Presence }
let :complete_xml do
<<-MSG
MSG
end
let(:example_complete) { import_stanza complete_xml }
it { example_complete.should be_a Blather::Stanza::Presence }
describe "presence received" do
describe "from an offer" do
let(:handle_presence) { connection.__send__ :handle_presence, example_offer }
it 'should call the event handler with the event' do
mock_event_handler.expects(:call).once.with do |event|
event.should be_instance_of Event::Offer
event.call_id.should == '9f00061'
event.domain.should == 'call.rayo.net'
end
handle_presence
end
it "should populate the call map with the domain for the call ID" do
handle_presence
callmap = connection.instance_variable_get(:'@callmap')
callmap['9f00061'].should == 'call.rayo.net'
end
end
describe "from something that's not a real event" do
let :irrelevant_xml do
<<-MSG
MSG
end
let(:example_irrelevant_event) { import_stanza irrelevant_xml }
it 'should not handle the event' do
mock_event_handler.expects(:call).never
lambda { connection.__send__ :handle_presence, example_irrelevant_event }.should throw_symbol(:pass)
end
end
end
end
describe "#handle_error" do
let(:call_id) { "f6d437f4-1e18-457b-99f8-b5d853f50347" }
let(:component_id) { 'abc123' }
let :error_xml do
<<-MSG
Could not find call [id=f6d437f4-1e18-457b-99f8-b5d853f50347]
MSG
end
let(:example_error) { import_stanza error_xml }
let(:cmd) { Component::Output.new }
before(:all) do
cmd.request!
connection.__send__ :handle_error, example_error, cmd
end
subject { cmd.response }
its(:call_id) { should == call_id }
its(:component_id) { should == component_id }
its(:name) { should == :item_not_found }
its(:text) { should == 'Could not find call [id=f6d437f4-1e18-457b-99f8-b5d853f50347]' }
end
describe "#prep_command_for_execution" do
let(:stanza) { subject.prep_command_for_execution command }
context "with a dial command" do
let(:command) { Command::Dial.new }
let(:expected_jid) { 'rayo.net' }
it "should use the correct JID" do
stanza = subject.prep_command_for_execution command
stanza.to.should == expected_jid
end
end
context "with a call command" do
let(:command) { Command::Answer.new.tap { |a| a.call_id = 'abc123' } }
let(:expected_jid) { 'abc123@calls.rayo.net' }
it "should use the correct JID" do
stanza.to.should == expected_jid
end
end
context "with a call component" do
let(:command) { Component::Output.new :call_id => 'abc123' }
let(:expected_jid) { 'abc123@calls.rayo.net' }
it "should use the correct JID" do
stanza.to.should == expected_jid
end
end
context "with a call component command" do
let(:command) { Component::Stop.new :call_id => 'abc123', :component_id => 'foobar' }
let(:expected_jid) { 'abc123@calls.rayo.net/foobar' }
it "should use the correct JID" do
stanza.to.should == expected_jid
end
end
context "with a mixer component" do
let(:command) { Component::Output.new :mixer_name => 'abc123' }
let(:expected_jid) { 'abc123@mixers.rayo.net' }
it "should use the correct JID" do
stanza.to.should == expected_jid
end
end
context "with a mixer component command" do
let(:command) { Component::Stop.new :mixer_name => 'abc123', :component_id => 'foobar' }
let(:expected_jid) { 'abc123@mixers.rayo.net/foobar' }
it "should use the correct JID" do
stanza.to.should == expected_jid
end
end
end
end # describe XMPP
end # XMPP
end # Punchblock