From c995e329d324c62cc0b1a2e614a588dff13e638b Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 12 Sep 2012 14:13:01 -0600 Subject: [PATCH 01/28] Bump Ruby version to 1.9.3. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 56143a6..a96cfe0 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Login with your favorite chat program (iChat, Adium, Pidgin, etc.) to start chat ## Dependencies -Vines requires Ruby 1.9.2 or better. Instructions for installing the +Vines requires Ruby 1.9.3 or better. Instructions for installing the needed OS packages, as well as Ruby itself, are available at http://www.getvines.org/ruby. From 0341e36f2a0c54bcc49a01fd03ed6891eb1c42e0 Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 12 Sep 2012 14:33:15 -0600 Subject: [PATCH 02/28] Convert to specs. --- test/stanza/iq/version_test.rb | 93 +++++++++++++++++----------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/test/stanza/iq/version_test.rb b/test/stanza/iq/version_test.rb index 8cbe776..1016e65 100644 --- a/test/stanza/iq/version_test.rb +++ b/test/stanza/iq/version_test.rb @@ -1,63 +1,64 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class VersionTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - @config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stanza::Iq::Version do + subject { Vines::Stanza::Iq::Version.new(xml, stream) } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } + let(:stream) { MiniTest::Mock.new } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } end end end - def test_to_address_routes - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - node = node(%q{}) - - router = MiniTest::Mock.new - router.expect(:route, nil, [node]) - - @stream.expect(:config, @config) - @stream.expect(:user, alice) - @stream.expect(:router, router) - - stanza = Vines::Stanza::Iq::Version.new(node, @stream) - stanza.process - assert @stream.verify - assert router.verify + before do + class << stream + attr_accessor :config, :user + end + stream.config = config + stream.user = alice end - def test_version_get_returns_result - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - node = node(%q{}) - - @stream.expect(:config, @config) - @stream.expect(:user, alice) - @stream.expect(:domain, 'wonderland.lit') - - expected = node(%Q{ - - - Vines - #{Vines::VERSION} - - }.strip.gsub(/\n|\s{2,}/, '')) + describe 'when not addressed to the server' do + let(:router) { MiniTest::Mock.new } + let(:xml) { node(%q{}) } - @stream.expect(:write, nil, [expected]) + before do + router.expect :route, nil, [xml] + stream.expect :router, router + end - stanza = Vines::Stanza::Iq::Version.new(node, @stream) - stanza.process - assert @stream.verify + it 'routes the stanza to the recipient jid' do + subject.process + stream.verify + router.verify + end end - private + describe 'when missing a to address' do + let(:xml) { node(%q{}) } + let(:expected) do + node(%Q{ + + + Vines + #{Vines::VERSION} + + }) + end + + before do + stream.expect :domain, 'wonderland.lit' + stream.expect :domain, 'wonderland.lit' + stream.expect :write, nil, [expected] + end - def node(xml) - Nokogiri::XML(xml).root + it 'returns a version result when missing a to jid' do + subject.process + stream.verify + end end end From 7d886e40d39010c9715aabed1e49ebe380a29a53 Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 12 Sep 2012 15:34:37 -0600 Subject: [PATCH 03/28] Convert to specs. --- test/stanza/iq/private_storage_test.rb | 281 ++++++++++++------------- 1 file changed, 138 insertions(+), 143 deletions(-) diff --git a/test/stanza/iq/private_storage_test.rb b/test/stanza/iq/private_storage_test.rb index db743ae..cda1422 100644 --- a/test/stanza/iq/private_storage_test.rb +++ b/test/stanza/iq/private_storage_test.rb @@ -1,14 +1,14 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class PrivateStorageTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - @config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stanza::Iq::PrivateStorage do + subject { Vines::Stanza::Iq::PrivateStorage.new(xml, stream) } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } + let(:storage) { MiniTest::Mock.new } + let(:stream) { MiniTest::Mock.new } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } private_storage true @@ -16,174 +16,169 @@ def setup end end - def test_feature_disabled_raises_error - query = %q{} - node = node(%Q{#{query}}) - - @config.vhost('wonderland.lit').private_storage false - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) - - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - assert_raises(Vines::StanzaErrors::ServiceUnavailable) { stanza.process } - assert @stream.verify + before do + class << stream + attr_accessor :config, :domain, :user + end + stream.config = config + stream.user = alice + stream.domain = 'wonderland.lit' end - def test_get_another_user_fragment_raises_error - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) + describe 'when private storage feature is disabled' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - @stream.expect(:user, alice) + before do + config.vhost('wonderland.lit').private_storage false + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process } - assert @stream.verify + it 'raises a service-unavailable stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::ServiceUnavailable + stream.verify + end end - def test_get_with_zero_children_raises_error - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) - - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) + describe 'when retrieving a fragment for another user jid' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process } - assert @stream.verify + it 'raises a forbidden stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden + stream.verify + end end - def test_get_with_two_children_raises_error - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) - - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) + describe 'when get stanza contains zero child elements' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process } - assert @stream.verify + it 'raises a not-acceptable stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable + stream.verify + end end - def test_set_with_zero_children_raises_error - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) - - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) + describe 'when get stanza contains more than one child element' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process } - assert @stream.verify + it 'raises a not-acceptable stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable + stream.verify + end end - def test_get_without_namespace_raises_error - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) - - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) + describe 'when get stanza is missing a namespace' do + let(:xml) do + query = %q{} + node = node(%Q{#{query}}) + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process } - assert @stream.verify + it 'raises a not-acceptable stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable + stream.verify + end end - def test_get_missing_fragment_raises_error - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) - - storage = MiniTest::Mock.new - storage.expect(:find_fragment, nil, [alice.jid, node.elements[0].elements[0]]) + describe 'when get stanza is missing fragment' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) - @stream.expect(:storage, storage, ['wonderland.lit']) - @stream.expect(:user, alice) + before do + storage.expect :find_fragment, nil, [alice.jid, xml.elements[0].elements[0]] + stream.expect :storage, storage, ['wonderland.lit'] + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process } - assert @stream.verify - assert storage.verify + it 'raises an item-not-found stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound + stream.verify + storage.verify + end end - def test_get_finds_fragment_writes_to_stream - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) - - data = %q{data} - query = %Q{#{data}} - expected = node(%Q{#{query}}) + describe 'when get finds fragment successfully' do + let(:xml) do + query = %q{} + node = node(%Q{#{query}}) + end - storage = MiniTest::Mock.new - storage.expect(:find_fragment, node(data), [alice.jid, node.elements[0].elements[0]]) + before do + data = %q{data} + query = %Q{#{data}} + expected = node(%Q{#{query}}) - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) - @stream.expect(:storage, storage, ['wonderland.lit']) - @stream.expect(:user, alice) - @stream.expect(:write, nil, [expected]) + storage.expect :find_fragment, node(data), [alice.jid, xml.elements[0].elements[0]] + stream.expect :storage, storage, ['wonderland.lit'] + stream.expect :write, nil, [expected] + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - stanza.process - assert @stream.verify - assert storage.verify + it 'writes a response to the stream' do + subject.process + stream.verify + storage.verify + end end - def test_set_one_fragment_writes_result_to_stream - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) - - storage = MiniTest::Mock.new - storage.expect(:save_fragment, nil, [alice.jid, node.elements[0].elements[0]]) + describe 'when saving a fragment' do + let(:result) { node(%Q{}) } - expected = node(%Q{}) - - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) - @stream.expect(:storage, storage, ['wonderland.lit']) - @stream.expect(:user, alice) - @stream.expect(:write, nil, [expected]) - - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - stanza.process - assert @stream.verify - assert storage.verify - end + before do + storage.expect :save_fragment, nil, [alice.jid, xml.elements[0].elements[0]] + stream.expect :storage, storage, ['wonderland.lit'] + stream.expect :write, nil, [result] + end - def test_set_two_fragments_writes_result_to_stream - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - query = %q{} - node = node(%Q{#{query}}) + describe 'and stanza contains zero child elements' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - storage = MiniTest::Mock.new - storage.expect(:save_fragment, nil, [alice.jid, node.elements[0].elements[0]]) - storage.expect(:save_fragment, nil, [alice.jid, node.elements[0].elements[1]]) + it 'raises a not-acceptable stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable + end + end - expected = node(%Q{}) + describe 'and a single single fragment saves successfully' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:config, @config) - @stream.expect(:storage, storage, ['wonderland.lit']) - @stream.expect(:user, alice) - @stream.expect(:write, nil, [expected]) + it 'writes a result to the stream' do + subject.process + stream.verify + storage.verify + end + end - stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream) - stanza.process - assert @stream.verify - assert storage.verify - end + describe 'and two fragments save successfully' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end - private + before do + storage.expect :save_fragment, nil, [alice.jid, xml.elements[0].elements[1]] + stream.expect :storage, storage, ['wonderland.lit'] + end - def node(xml) - Nokogiri::XML(xml).root + it 'writes a result to the stream' do + subject.process + stream.verify + storage.verify + end + end end end From 9cbf83c87757cc85b94ca5eac94a7b7cbf04faee Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 12 Sep 2012 15:36:02 -0600 Subject: [PATCH 04/28] Spacing changes. --- test/stanza/iq/private_storage_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/stanza/iq/private_storage_test.rb b/test/stanza/iq/private_storage_test.rb index cda1422..7029c88 100644 --- a/test/stanza/iq/private_storage_test.rb +++ b/test/stanza/iq/private_storage_test.rb @@ -4,7 +4,7 @@ describe Vines::Stanza::Iq::PrivateStorage do subject { Vines::Stanza::Iq::PrivateStorage.new(xml, stream) } - let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } let(:storage) { MiniTest::Mock.new } let(:stream) { MiniTest::Mock.new } let(:config) do From bc9026a7262fd2be36e07ed1ca09afa70667e671 Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 12 Sep 2012 17:54:04 -0600 Subject: [PATCH 05/28] Convert to specs. --- test/stanza/pubsub/subscribe_test.rb | 319 ++++++++++++++------------- 1 file changed, 169 insertions(+), 150 deletions(-) diff --git a/test/stanza/pubsub/subscribe_test.rb b/test/stanza/pubsub/subscribe_test.rb index 3d627a8..2a97238 100644 --- a/test/stanza/pubsub/subscribe_test.rb +++ b/test/stanza/pubsub/subscribe_test.rb @@ -1,186 +1,205 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class SubscribePubSubTest < MiniTest::Unit::TestCase - def setup - @user = Vines::User.new(jid: 'alice@wonderland.lit/tea') - @config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stanza::PubSub::Subscribe do + subject { Vines::Stanza::PubSub::Subscribe.new(xml, stream) } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } + let(:stream) { MiniTest::Mock.new } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } pubsub 'games' end end - @stream = MiniTest::Mock.new - @stream.expect(:config, @config) - @stream.expect(:user, @user) end - def test_missing_to_address_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) + before do + class << stream + attr_accessor :config, :domain, :nodes, :user + def write(node) + @nodes ||= [] + @nodes << node + end + end + stream.config = config + stream.user = alice + stream.domain = 'wonderland.lit' + end - @stream.expect(:domain, 'wonderland.lit') + describe 'when missing a to address' do + let(:xml) do + node(%q{ + + + + + + }) + end - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process } - assert @stream.verify + it 'raises a feature-not-implemented stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented + stream.verify + end end - def test_server_domain_to_address_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process } - assert @stream.verify - end + describe 'when addressed to a bare server domain' do + let(:xml) do + node(%q{ + + + + + + }) + end - def test_non_pubsub_to_address_routes - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) + it 'raises a feature-not-implemented stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented + stream.verify + end + end - router = MiniTest::Mock.new - router.expect(:route, nil, [node]) + describe 'when addressed to a non-pubsub address' do + let(:router) { MiniTest::Mock.new } + let(:xml) do + node(%q{ + + + + + + }) + end - @stream.expect(:router, router) + it 'routes rather than handle locally' do + router.expect :route, nil, [xml] + stream.expect :router, router - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - stanza.process - assert @stream.verify - assert router.verify + subject.process + stream.verify + router.verify + end end - def test_multiple_subscribe_elements_raises - node = node(%q{ - - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } - assert @stream.verify + describe 'when stanza contains multiple subscribe elements' do + let(:xml) do + node(%q{ + + + + + + + }) + end + + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + stream.verify + end end - def test_subscribe_missing_node_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process } - assert @stream.verify + describe 'when stanza is missing a subscribe element' do + let(:xml) do + node(%q{ + + + + + + }) + end + + it 'raises an item-not-found stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound + stream.verify + end end - def test_subscribe_twice_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - def stanza.mock_pubsub; @mock_pubsub; end - def stanza.pubsub - unless @mock_pubsub - @mock_pubsub = MiniTest::Mock.new - @mock_pubsub.expect(:node?, true, ['game_13']) - @mock_pubsub.expect(:subscribed?, true, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')]) + describe 'when attempting to subscribe to a node twice' do + let(:pubsub) { MiniTest::Mock.new } + let(:xml) do + node(%q{ + + + + + + }) + end + + before do + pubsub.expect :node?, true, ['game_13'] + pubsub.expect :subscribed?, true, ['game_13', alice.jid] + end + + it 'raises a policy-violation stanza error' do + subject.stub :pubsub, pubsub do + -> { subject.process }.must_raise Vines::StanzaErrors::PolicyViolation end - @mock_pubsub + stream.verify + pubsub.verify end - assert_raises(Vines::StanzaErrors::PolicyViolation) { stanza.process } - assert @stream.verify - assert stanza.mock_pubsub.verify end - def test_subscribe_illegal_jid_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } - assert @stream.verify + describe 'when subscribing with an illegal jid' do + let(:xml) do + node(%q{ + + + + + + }) + end + + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + stream.verify + end end - def test_good_stanza_processes - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - def @stream.nodes; @nodes; end - def @stream.write(node) - @nodes ||= [] - @nodes << node - end - - stanza = Vines::Stanza::PubSub::Subscribe.new(node, @stream) - def stanza.mock_pubsub; @mock_pubsub; end - def stanza.pubsub - unless @mock_pubsub - @mock_pubsub = MiniTest::Mock.new - @mock_pubsub.expect(:node?, true, ['game_13']) - @mock_pubsub.expect(:subscribed?, false, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')]) - @mock_pubsub.expect(:subscribe, nil, ['game_13', Vines::JID.new('alice@wonderland.lit/tea')]) - end - @mock_pubsub + describe 'when subscribing with a valid stanza' do + let(:xml) do + node(%q{ + + + + + + }) end - stanza.process - assert @stream.verify - assert stanza.mock_pubsub.verify - assert_equal 1, @stream.nodes.size + let(:expected) do + node(%q{ + + + + + + }) + end - expected = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - assert_equal expected, @stream.nodes[0] - end + let(:pubsub) { MiniTest::Mock.new } - private + before do + pubsub.expect :node?, true, ['game_13'] + pubsub.expect :subscribed?, false, ['game_13', alice.jid] + pubsub.expect :subscribe, nil, ['game_13', alice.jid] + end + + it 'writes a result stanza to the stream' do + subject.stub :pubsub, pubsub do + subject.process + end - def node(xml) - Nokogiri::XML(xml).root + stream.verify + pubsub.verify + stream.nodes.size.must_equal 1 + stream.nodes.first.must_equal expected + end end end From 6518f3d581c699b825b22b503e9a00d59c08b527 Mon Sep 17 00:00:00 2001 From: David Graham Date: Thu, 13 Sep 2012 04:01:46 -0600 Subject: [PATCH 06/28] Convert to specs. --- test/stanza/pubsub/delete_test.rb | 255 +++++++++++++++++------------- 1 file changed, 141 insertions(+), 114 deletions(-) diff --git a/test/stanza/pubsub/delete_test.rb b/test/stanza/pubsub/delete_test.rb index d23f30d..2ec2894 100644 --- a/test/stanza/pubsub/delete_test.rb +++ b/test/stanza/pubsub/delete_test.rb @@ -1,142 +1,169 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class DeletePubSubTest < MiniTest::Unit::TestCase - def setup - @user = Vines::User.new(jid: 'alice@wonderland.lit/tea') - @config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stanza::PubSub::Delete do + subject { Vines::Stanza::PubSub::Delete.new(xml, stream) } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } + let(:stream) { MiniTest::Mock.new } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } pubsub 'games' end end - @stream = MiniTest::Mock.new - @stream.expect(:config, @config) - @stream.expect(:user, @user) end - def test_missing_to_address_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) + before do + class << stream + attr_accessor :config, :domain, :nodes, :user + def write(node) + @nodes ||= [] + @nodes << node + end + end + stream.config = config + stream.domain = 'wonderland.lit' + stream.user = alice + end - @stream.expect(:domain, 'wonderland.lit') + describe 'when missing a to address' do + let(:xml) do + node(%q{ + + + + + + }) + end - stanza = Vines::Stanza::PubSub::Delete.new(node, @stream) - assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process } - assert @stream.verify + it 'raises a feature-not-implemented stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented + stream.verify + end end - def test_server_domain_to_address_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Delete.new(node, @stream) - assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process } - assert @stream.verify + describe 'when addressed to a bare server domain jid' do + let(:xml) do + node(%q{ + + + + + + }) + end + + it 'raises a feature-not-implemented stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented + stream.verify + end end - def test_non_pubsub_to_address_routes - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - router = MiniTest::Mock.new - router.expect(:route, nil, [node]) - @stream.expect(:router, router) - - stanza = Vines::Stanza::PubSub::Delete.new(node, @stream) - stanza.process - assert @stream.verify - assert router.verify + describe 'when addressed to a non-pubsub address' do + let(:router) { MiniTest::Mock.new } + let(:xml) do + node(%q{ + + + + + + }) + end + + before do + router.expect :route, nil, [xml] + stream.expect :router, router + end + + it 'routes rather than handle locally' do + subject.process + stream.verify + router.verify + end end - def test_multiple_delete_elements_raises - node = node(%q{ - - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Delete.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } - assert @stream.verify + describe 'when stanza contains multiple delete elements' do + let(:xml) do + node(%q{ + + + + + + + }) + end + + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + stream.verify + end end - def test_delete_missing_node_raises - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::PubSub::Delete.new(node, @stream) - assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process } - assert @stream.verify + describe 'when deleting a missing node' do + let(:xml) do + node(%q{ + + + + + + }) + end + + it 'raises an item-not-found stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound + stream.verify + end end - def test_good_stanza_processes - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - def @stream.nodes; @nodes; end - def @stream.write(node) - @nodes ||= [] - @nodes << node - end - - stanza = Vines::Stanza::PubSub::Delete.new(node, @stream) - def stanza.mock_pubsub; @mock_pubsub; end - def stanza.pubsub - unless @mock_pubsub - xml = %q{} - @mock_pubsub = MiniTest::Mock.new - @mock_pubsub.expect(:node?, true, ['game_13']) - @mock_pubsub.expect(:publish, nil, ['game_13', Nokogiri::XML(xml).root]) - @mock_pubsub.expect(:delete_node, nil, ['game_13']) - end - @mock_pubsub + describe 'when valid stanza is received' do + let(:pubsub) { MiniTest::Mock.new } + let(:xml) do + node(%q{ + + + + + + }) end - stanza.process - assert @stream.verify - assert stanza.mock_pubsub.verify - assert_equal 1, @stream.nodes.size + let(:result) { node(%Q{}) } - expected = node(%q{}) - assert_equal expected, @stream.nodes[0] - end + let(:broadcast) do + node(%q{ + + + + + }) + end - private + before do + pubsub.expect :node?, true, ['game_13'] + pubsub.expect :publish, nil, ['game_13', broadcast] + pubsub.expect :delete_node, nil, ['game_13'] + end - def node(xml) - Nokogiri::XML(xml).root + it 'broadcasts the delete to subscribers' do + subject.stub :pubsub, pubsub do + subject.process + end + stream.verify + pubsub.verify + end + + it 'sends a result stanza to sender' do + subject.stub :pubsub, pubsub do + subject.process + end + stream.nodes.size.must_equal 1 + stream.nodes.first.must_equal result + end end end From af620e898664502c51d234633882f80146f6e959 Mon Sep 17 00:00:00 2001 From: David Graham Date: Thu, 13 Sep 2012 04:24:53 -0600 Subject: [PATCH 07/28] Convert to specs. --- test/stream/component/ready_test.rb | 137 +++++++++++++++------------- 1 file changed, 76 insertions(+), 61 deletions(-) diff --git a/test/stream/component/ready_test.rb b/test/stream/component/ready_test.rb index 75cb91a..59d0ddb 100644 --- a/test/stream/component/ready_test.rb +++ b/test/stream/component/ready_test.rb @@ -1,88 +1,103 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class ComponentReadyTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - @state = Vines::Stream::Component::Ready.new(@stream, nil) - @config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stream::Component::Ready do + subject { Vines::Stream::Component::Ready.new(stream, nil) } + let(:alice) { Vines::User.new(jid: 'alice@tea.wonderland.lit') } + let(:hatter) { Vines::User.new(jid: 'hatter@wonderland.lit') } + let(:stream) { MiniTest::Mock.new } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } end end end - def test_missing_to_and_from_addresses - node = node('') - assert_raises(Vines::StreamErrors::ImproperAddressing) { @state.node(node) } - assert @stream.verify + before do + class << stream + attr_accessor :config + end + stream.config = config end - def test_missing_from_address - node = node(%q{}) - assert_raises(Vines::StreamErrors::ImproperAddressing) { @state.node(node) } - assert @stream.verify + describe 'when missing to and from addresses' do + it 'raises an improper-addressing stream error' do + node = node('') + -> { subject.node(node) }.must_raise Vines::StreamErrors::ImproperAddressing + stream.verify + end end - def test_missing_to_address - node = node(%q{}) - assert_raises(Vines::StreamErrors::ImproperAddressing) { @state.node(node) } - assert @stream.verify + describe 'when missing from address' do + it 'raises an improper-addressing stream error' do + node = node(%q{}) + -> { subject.node(node) }.must_raise Vines::StreamErrors::ImproperAddressing + stream.verify + end end - def test_invalid_from_address - @stream.expect(:remote_domain, 'tea.wonderland.lit') - node = node(%q{}) - assert_raises(Vines::StreamErrors::InvalidFrom) { @state.node(node) } - assert @stream.verify + describe 'when missing to address' do + it 'raises an improper-addressing stream error' do + node = node(%q{}) + -> { subject.node(node) }.must_raise Vines::StreamErrors::ImproperAddressing + stream.verify + end end - def test_unsupported_stanza_type - node = node('') - assert_raises(Vines::StreamErrors::UnsupportedStanzaType) { @state.node(node) } - assert @stream.verify + describe 'when from address domain does not match component domain' do + it 'raises and invalid-from stream error' do + stream.expect :remote_domain, 'tea.wonderland.lit' + node = node(%q{}) + -> { subject.node(node) }.must_raise Vines::StreamErrors::InvalidFrom + stream.verify + end end - def test_remote_message_routes - node = node(%q{}) - @stream.expect(:remote_domain, 'tea.wonderland.lit') - @stream.expect(:config, @config) - @stream.expect(:user=, nil, [Vines::User.new(:jid => 'alice@tea.wonderland.lit')]) - - @router = MiniTest::Mock.new - @router.expect(:route, nil, [node]) - @stream.expect(:router, @router) - - @state.node(node) - assert @stream.verify - assert @router.verify + describe 'when unrecognized element is received' do + it 'raises an unsupported-stanza-type stream error' do + node = node('') + -> { subject.node(node) }.must_raise Vines::StreamErrors::UnsupportedStanzaType + stream.verify + end end - def test_local_message_processes - node = node(%q{}) - @stream.expect(:remote_domain, 'tea.wonderland.lit') - @stream.expect(:config, @config) - @stream.expect(:user=, nil, [Vines::User.new(:jid => 'alice@tea.wonderland.lit')]) - @stream.expect(:user, Vines::User.new(:jid => 'alice@tea.wonderland.lit')) + describe 'when addressed to a remote jid' do + let(:router) { MiniTest::Mock.new } + let(:xml) { node(%q{}) } - @recipient = MiniTest::Mock.new - @recipient.expect(:user, Vines::User.new(:jid => 'hatter@wonderland.lit')) - @recipient.expect(:write, nil, [node]) - - @stream.expect(:connected_resources, [@recipient], [Vines::JID.new('hatter@wonderland.lit')]) + before do + router.expect :route, nil, [xml] + stream.expect :remote_domain, 'tea.wonderland.lit' + stream.expect :user=, nil, [alice] + stream.expect :router, router + end - @state.node(node) - assert @stream.verify - assert @recipient.verify + it 'routes rather than handle locally' do + subject.node(xml) + stream.verify + router.verify + end end - private + describe 'when addressed to a local jid' do + let(:recipient) { MiniTest::Mock.new } + let(:xml) { node(%q{}) } + + before do + recipient.expect :user, hatter + recipient.expect :write, nil, [xml] + stream.expect :remote_domain, 'tea.wonderland.lit' + stream.expect :user=, nil, [alice] + stream.expect :user, alice + stream.expect :connected_resources, [recipient], [hatter.jid] + end - def node(xml) - Nokogiri::XML(xml).root + it 'sends the message to the connected stream' do + subject.node(xml) + stream.verify + recipient.verify + end end end From 22a920580a3fae851201ca47429e4d6b0ac9263d Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 14 Sep 2012 08:35:31 +0400 Subject: [PATCH 08/28] Use OpenStruct instead of MiniTest::Mock. --- test/cluster/sessions_test.rb | 71 ++++++++++++++++------------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/test/cluster/sessions_test.rb b/test/cluster/sessions_test.rb index 0e56460..f1f5116 100644 --- a/test/cluster/sessions_test.rb +++ b/test/cluster/sessions_test.rb @@ -1,53 +1,46 @@ # encoding: UTF-8 -require 'vines' -require 'ext/nokogiri' +require 'test_helper' require 'storage/storage_tests' require 'storage/mock_redis' -require 'minitest/autorun' -class ClusterSessionsTest < MiniTest::Unit::TestCase - def setup - @connection = MockRedis.new - @cluster = MiniTest::Mock.new - @cluster.expect(:connection, @connection) - end +describe Vines::Cluster::Sessions do + subject { Vines::Cluster::Sessions.new(cluster) } + let(:connection) { MockRedis.new } + let(:cluster) { OpenStruct.new(id: 'abc', connection: connection) } + let(:jid1) { 'alice@wonderland.lit/tea' } + let(:jid2) { 'alice@wonderland.lit/cake' } - def test_save - StorageTests::EMLoop.new do - @cluster.expect(:id, 'abc') - jid1 = 'alice@wonderland.lit/tea' - jid2 = 'alice@wonderland.lit/cake' - sessions = Vines::Cluster::Sessions.new(@cluster) - sessions.save(jid1, {available: true, interested: true}) - sessions.save(jid2, {available: false, interested: false}) - EM.next_tick do - session1 = {node: 'abc', available: true, interested: true} - session2 = {node: 'abc', available: false, interested: false} - assert_equal 2, @connection.db["sessions:alice@wonderland.lit"].size - assert_equal session1.to_json, @connection.db["sessions:alice@wonderland.lit"]['tea'] - assert_equal session2.to_json, @connection.db["sessions:alice@wonderland.lit"]['cake'] - assert_equal [jid1, jid2], @connection.db["cluster:nodes:abc"].to_a - assert @cluster.verify + describe 'when saving to the cluster' do + it 'writes to a redis hash' do + StorageTests::EMLoop.new do + subject.save(jid1, {available: true, interested: true}) + subject.save(jid2, {available: false, interested: false}) + EM.next_tick do + session1 = {node: 'abc', available: true, interested: true} + session2 = {node: 'abc', available: false, interested: false} + connection.db["sessions:alice@wonderland.lit"].size.must_equal 2 + connection.db["sessions:alice@wonderland.lit"]['tea'].must_equal session1.to_json + connection.db["sessions:alice@wonderland.lit"]['cake'].must_equal session2.to_json + connection.db["cluster:nodes:abc"].to_a.must_equal [jid1, jid2] + end end end end - def test_delete - StorageTests::EMLoop.new do - jid1 = 'alice@wonderland.lit/tea' - jid2 = 'alice@wonderland.lit/cake' - @connection.db["sessions:alice@wonderland.lit"] = {} - @connection.db["sessions:alice@wonderland.lit"]['tea'] = {node: 'abc', available: true}.to_json - @connection.db["sessions:alice@wonderland.lit"]['cake'] = {node: 'abc', available: true}.to_json - @connection.db["cluster:nodes:abc"] = Set.new([jid1, jid2]) + describe 'when deleting from the cluster' do + it 'removes from a redis hash' do + StorageTests::EMLoop.new do + connection.db["sessions:alice@wonderland.lit"] = {} + connection.db["sessions:alice@wonderland.lit"]['tea'] = {node: 'abc', available: true}.to_json + connection.db["sessions:alice@wonderland.lit"]['cake'] = {node: 'abc', available: true}.to_json + connection.db["cluster:nodes:abc"] = Set.new([jid1, jid2]) - sessions = Vines::Cluster::Sessions.new(@cluster) - sessions.delete(jid1) - EM.next_tick do - assert_equal 1, @connection.db["sessions:alice@wonderland.lit"].size - assert_equal [jid2], @connection.db["cluster:nodes:abc"].to_a - assert @cluster.verify + subject.delete(jid1) + EM.next_tick do + connection.db["sessions:alice@wonderland.lit"].size.must_equal 1 + connection.db["cluster:nodes:abc"].to_a.must_equal [jid2] + end end end end From 182a8392412fcc5caefd3a1b14fcbc01d41572a9 Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 14 Sep 2012 22:37:05 +0400 Subject: [PATCH 09/28] Fix mock errors for MiniTest 3. --- test/stream/http/ready_test.rb | 112 +++++++++++++++------------------ 1 file changed, 52 insertions(+), 60 deletions(-) diff --git a/test/stream/http/ready_test.rb b/test/stream/http/ready_test.rb index 3279126..50c0614 100644 --- a/test/stream/http/ready_test.rb +++ b/test/stream/http/ready_test.rb @@ -1,94 +1,86 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::Stream::Http::Ready do - before do - @stream = MiniTest::Mock.new - @state = Vines::Stream::Http::Ready.new(@stream, nil) + subject { Vines::Stream::Http::Ready.new(stream, nil) } + let(:stream) { MiniTest::Mock.new } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit') } + let(:hatter) { Vines::User.new(jid: 'hatter@wonderland.lit') } + let(:config) do + Vines::Config.new do + host 'wonderland.lit' do + storage(:fs) { dir Dir.tmpdir } + end + end end it "raises when body element is missing" do node = node('') - @stream.expect(:valid_session?, true, [nil]) - -> { @state.node(node) }.must_raise Vines::StreamErrors::NotAuthorized + stream.expect :valid_session?, true, [nil] + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized end it "raises when namespace is missing" do node = node('') - @stream.expect(:valid_session?, true, ['12']) - assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) } - -> { @state.node(node) }.must_raise Vines::StreamErrors::NotAuthorized + stream.expect :valid_session?, true, ['12'] + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized end it "raises when rid attribute is missing" do node = node('') - @stream.expect(:valid_session?, true, ['12']) - -> { @state.node(node) }.must_raise Vines::StreamErrors::NotAuthorized + stream.expect :valid_session?, true, ['12'] + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized end it "raises when session id is invalid" do - @stream.expect(:valid_session?, false, ['12']) + stream.expect :valid_session?, false, ['12'] node = node('') - -> { @state.node(node) }.must_raise Vines::StreamErrors::NotAuthorized - assert @stream.verify + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized + stream.verify end it "processes when body element is empty" do node = node('') - @stream.expect(:valid_session?, true, ['12']) - @stream.expect(:parse_body, [], [node]) - @state.node(node) - assert @stream.verify + stream.expect :valid_session?, true, ['12'] + stream.expect :parse_body, [], [node] + subject.node(node) + stream.verify end - it "processes all stanzas in one body element" do - alice = Vines::User.new(jid: 'alice@wonderland.lit') - hatter = Vines::User.new(jid: 'hatter@wonderland.lit') - - config = Vines::Config.new do - host 'wonderland.lit' do - storage(:fs) { dir Dir.tmpdir } - end + describe 'when receiving multiple stanzas in one body element' do + let(:recipient) { MiniTest::Mock.new } + let(:bogus) { node('raises stanza error') } + let(:ok) { node('but processes this message') } + let(:xml) { node(%Q{#{bogus}#{ok}}) } + let(:raises) { Vines::Stanza.from_node(bogus, stream) } + let(:processes) { Vines::Stanza.from_node(ok, stream) } + + before do + recipient.expect :user, hatter + recipient.expect :write, nil, [Vines::Stanza::Message] + + stream.expect :valid_session?, true, ['12'] + stream.expect :parse_body, [raises, processes], [xml] + stream.expect :error, nil, [Vines::StanzaErrors::BadRequest] + stream.expect :config, config + stream.expect :user, alice + stream.expect :connected_resources, [recipient], [hatter.jid] end - bogus = node('raises stanza error') - ok = node('but processes this message') - node = node(%Q{#{bogus}#{ok}}) - - raises = Vines::Stanza.from_node(bogus, @stream) - processes = Vines::Stanza.from_node(ok, @stream) - - recipient = MiniTest::Mock.new - recipient.expect(:user, hatter) - recipient.expect(:write, nil, [Vines::Stanza::Message]) - - @stream.expect(:valid_session?, true, ['12']) - @stream.expect(:parse_body, [raises, processes], [node]) - @stream.expect(:error, nil, [Vines::StanzaErrors::BadRequest]) - @stream.expect(:config, config) - @stream.expect(:user, alice) - @stream.expect(:connected_resources, [recipient], [hatter.jid]) - - @state.node(node) - assert @stream.verify - assert recipient.verify + it 'processes all stanzas' do + subject.node(xml) + stream.verify + recipient.verify + end end it "terminates the session" do node = node('') - @stream.expect(:valid_session?, true, ['12']) - @stream.expect(:parse_body, [], [node]) - @stream.expect(:terminate, nil) - @state.node(node) - assert @stream.verify - end - - private - - def node(xml) - Nokogiri::XML(xml).root + stream.expect :valid_session?, true, ['12'] + stream.expect :parse_body, [], [node] + stream.expect :terminate, nil + subject.node(node) + stream.verify end end From def86de5735168b3adb6dcaa68d48412c507b175 Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 14 Sep 2012 22:49:55 +0400 Subject: [PATCH 10/28] Fix mock errors for MiniTest 3. --- test/stanza/iq/disco_info_test.rb | 118 +++++++++++++++--------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/test/stanza/iq/disco_info_test.rb b/test/stanza/iq/disco_info_test.rb index 52eb3b8..ca1a4b8 100644 --- a/test/stanza/iq/disco_info_test.rb +++ b/test/stanza/iq/disco_info_test.rb @@ -1,78 +1,78 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' -class DiscoInfoTest < MiniTest::Unit::TestCase - ALICE = Vines::User.new(:jid => 'alice@wonderland.lit/home') - - def setup - @config = Vines::Config.new do +describe Vines::Stanza::Iq::DiscoInfo do + subject { Vines::Stanza::Iq::DiscoInfo.new(xml, stream) } + let(:stream) { MiniTest::Mock.new } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/home') } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } end end - @stream = MiniTest::Mock.new - @stream.expect(:user, ALICE) - @stream.expect(:config, @config) end - def test_private_storage_disabled + let(:xml) do query = %q{} - node = node(%Q{#{query}}) - - expected = node(%Q{ - - - - - - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - @config.vhost('wonderland.lit').private_storage false - @stream.expect(:write, nil, [expected]) - - stanza = Vines::Stanza::Iq::DiscoInfo.new(node, @stream) - stanza.process - assert @stream.verify + node(%Q{#{query}}) end - def test_private_storage_enabled - query = %q{} - node = node(%Q{#{query}}) - - expected = node(%Q{ - - - - - - - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) + before do + class << stream + attr_accessor :config, :user + end + stream.config = config + stream.user = alice + end - @config.vhost('wonderland.lit').private_storage true - @stream.expect(:write, nil, [expected]) + describe 'when private storage is disabled' do + let(:expected) do + node(%Q{ + + + + + + + + + + + }) + end - stanza = Vines::Stanza::Iq::DiscoInfo.new(node, @stream) - stanza.process - assert @stream.verify + it 'returns info stanza without the private storage feature' do + config.vhost('wonderland.lit').private_storage false + stream.expect :write, nil, [expected] + subject.process + stream.verify + end end - private + describe 'when private storage is enabled' do + let(:expected) do + node(%Q{ + + + + + + + + + + + + }) + end - def node(xml) - Nokogiri::XML(xml).root + it 'announces private storage feature in info stanza result' do + config.vhost('wonderland.lit').private_storage true + stream.expect :write, nil, [expected] + subject.process + stream.verify + end end end From bfc778794550ddf61cc9e4c52436995556c09661 Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 14 Sep 2012 23:53:11 +0400 Subject: [PATCH 11/28] Convert to specs. --- test/stanza/iq/roster_test.rb | 374 ++++++++++++++++++---------------- 1 file changed, 199 insertions(+), 175 deletions(-) diff --git a/test/stanza/iq/roster_test.rb b/test/stanza/iq/roster_test.rb index 3cddb29..a274de3 100644 --- a/test/stanza/iq/roster_test.rb +++ b/test/stanza/iq/roster_test.rb @@ -1,206 +1,230 @@ # encoding: UTF-8 -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' -class RosterTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - end +describe Vines::Stanza::Iq::Roster do + subject { Vines::Stanza::Iq::Roster.new(xml, stream) } + let(:stream) { MiniTest::Mock.new } +# FIXME try without resource + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } - def test_roster_get_with_empty_roster - alice = Vines::User.new(:jid => 'alice@wonderland.lit') - expected = node(%q{}) - @stream.expect(:write, nil, [expected]) - @stream.expect(:requested_roster!, nil) - @stream.expect(:user, alice) - - node = node(%q{}) - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - stanza.process - assert @stream.verify + before do + class << stream + attr_accessor :domain, :user + end + stream.user = alice + stream.domain = 'wonderland.lit' end - def test_roster_get_with_non_empty_roster - alice = Vines::User.new(:jid => 'alice@wonderland.lit') - alice.roster << Vines::Contact.new(:jid => 'hatter@wonderland.lit') - alice.roster << Vines::Contact.new(:jid => 'cat@wonderland.lit', :groups => ['Friends', 'Cats']) - - expected = node(%q{ - - - - Cats - Friends - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - @stream.expect(:write, nil, [expected]) - @stream.expect(:requested_roster!, nil) - @stream.expect(:user, alice) - - node = node(%q{}) - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - stanza.process - assert @stream.verify + describe 'when retrieving an empty roster' do + let(:xml) { node(%q{}) } + let(:expected) { node(%q{}) } + + before do + stream.expect :write, nil, [expected] + stream.expect :requested_roster!, nil + end + + it 'returns an empty stanza' do + subject.process + stream.verify + end end - def test_roster_get_with_invalid_to_address - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - @stream.expect(:user, alice) + describe 'when retrieving a non-empty roster' do + let(:xml) { node(%q{}) } + let(:expected) do + node(%q{ + + + + Cats + Friends + + + + }) + end - node = node(%q{ - - - }.strip.gsub(/\n|\s{2,}/, '')) + before do + alice.roster << Vines::Contact.new(jid: 'hatter@wonderland.lit') + alice.roster << Vines::Contact.new(jid: 'cat@wonderland.lit', :groups => ['Friends', 'Cats']) - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process } - assert @stream.verify - end + stream.expect :write, nil, [expected] + stream.expect :requested_roster!, nil + end - def test_roster_set_with_invalid_to_address - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - @stream.expect(:user, alice) + it 'sorts groups alphabetically' do + subject.process + stream.verify + end + end - node = node(%q{ - - - }.strip.gsub(/\n|\s{2,}/, '')) + describe 'when requesting a roster for another user' do + let(:xml) do + node(%q{ + + + }) + end - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process } - assert @stream.verify + it 'raises a forbidden stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden + stream.verify + end end - def test_roster_set_with_no_items - node = node(%q{ - - - }.strip.gsub(/\n|\s{2,}/, '')) + describe 'when saving a roster for another user' do + let(:xml) do + node(%q{ + + + }) + end - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } - assert @stream.verify + it 'raises a forbidden stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden + stream.verify + end end - def test_roster_set_with_two_items - node = node(%q{ - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } - assert @stream.verify + describe 'when saving a roster with no items' do + let(:xml) do + node(%q{ + + + }) + end + + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + stream.verify + end end - def test_roster_set_missing_jid - node = node(%q{ - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } - assert @stream.verify + describe 'when updating a roster with more than one item' do + let(:xml) do + node(%q{ + + + + + + }) + end + + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + stream.verify + end end - def test_roster_set_with_duplicate_groups - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - @stream.expect(:user, alice) - - node = node(%q{ - - - - Friends - Friends - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } - assert @stream.verify + describe 'when adding a roster item without a jid attribute' do + let(:xml) do + node(%q{ + + + + + }) + end + + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + stream.verify + end end - def test_roster_set_with_empty_group - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - @stream.expect(:user, alice) - - node = node(%q{ - - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process } - assert @stream.verify + describe 'when adding a roster item with duplicate groups' do + let(:xml) do + node(%q{ + + + + Friends + Friends + + + }) + end + + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + stream.verify + end end - def test_roster_set_sends_results - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - storage = MiniTest::Mock.new - storage.expect(:save_user, nil, [alice]) - - recipient = MiniTest::Mock.new - recipient.expect(:user, alice) - def recipient.nodes; @nodes; end - def recipient.write(node) - @nodes ||= [] - @nodes << node - end - - @stream.expect(:user, alice) - @stream.expect(:interested_resources, [recipient], [alice.jid]) - @stream.expect(:update_user_streams, nil, [alice]) - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:storage, storage, ['wonderland.lit']) - expected = node(%Q{}) - @stream.expect(:write, nil, [expected]) - - node = node(%q{ - - - - Friends - - - }.strip.gsub(/\n|\s{2,}/, '')) - - stanza = Vines::Stanza::Iq::Roster.new(node, @stream) - stanza.process - assert @stream.verify - assert storage.verify - - expected = node(%q{ - - - - Friends - - - }.strip.gsub(/\n|\s{2,}/, '')) - recipient.nodes[0].remove_attribute('id') # id is random - assert_equal expected, recipient.nodes[0] + describe 'when adding a roster item with an empty group name' do + let(:xml) do + node(%q{ + + + + + + + }) + end + + it 'raises a not-acceptable stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable + stream.verify + end end - private + describe 'when saving a roster successfully' do + let(:xml) do + node(%q{ + + + + Friends + + + }) + end + + let(:expected) do + node(%q{ + + + + Friends + + + }) + end + + let(:storage) { MiniTest::Mock.new } + let(:recipient) { MiniTest::Mock.new } + let(:result) { node(%Q{}) } + + before do + storage.expect :save_user, nil, [alice] + + recipient.expect :user, alice + def recipient.nodes; @nodes; end + def recipient.write(node) + @nodes ||= [] + @nodes << node + end - def node(xml) - Nokogiri::XML(xml).root + stream.expect :interested_resources, [recipient], [alice.jid] + stream.expect :update_user_streams, nil, [alice] + stream.expect :storage, storage, ['wonderland.lit'] + stream.expect :write, nil, [result] + end + + it 'sends a result to the sender' do + subject.process + stream.verify + storage.verify + end + + it 'sends the new roster item to the interested streams' do + subject.process + recipient.nodes.first.remove_attribute('id') # id is random + recipient.nodes.first.must_equal expected + end end end From aa5df0592d505ef50bd4f69efd0b36e912abb609 Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 14 Sep 2012 23:57:49 +0400 Subject: [PATCH 12/28] Remove fixme. --- test/stanza/iq/roster_test.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/test/stanza/iq/roster_test.rb b/test/stanza/iq/roster_test.rb index a274de3..16d6ae3 100644 --- a/test/stanza/iq/roster_test.rb +++ b/test/stanza/iq/roster_test.rb @@ -5,7 +5,6 @@ describe Vines::Stanza::Iq::Roster do subject { Vines::Stanza::Iq::Roster.new(xml, stream) } let(:stream) { MiniTest::Mock.new } -# FIXME try without resource let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } before do From b8e49944facd0abb2204e424cc82f0c744754396 Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 15 Sep 2012 00:09:07 +0400 Subject: [PATCH 13/28] Update eventmachine to 1.0.0. --- vines.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vines.gemspec b/vines.gemspec index 500d725..7e6a993 100644 --- a/vines.gemspec +++ b/vines.gemspec @@ -20,7 +20,7 @@ Gem::Specification.new do |s| s.add_dependency 'bcrypt-ruby', '~> 3.0.1' s.add_dependency 'em-http-request', '~> 1.0.3' s.add_dependency 'em-hiredis', '~> 0.1.1' - s.add_dependency 'eventmachine', '>= 1.0.0.beta.4' + s.add_dependency 'eventmachine', '~> 1.0.0' s.add_dependency 'http_parser.rb', '~> 0.5.3' s.add_dependency 'mongo', '~> 1.5.2' s.add_dependency 'bson_ext', '~> 1.5.2' From 8880a3b894d5c1014c27f7f5772bf1b6b9d10601 Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 15 Sep 2012 00:10:24 +0400 Subject: [PATCH 14/28] Update nokogiri to 1.5.5. --- vines.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vines.gemspec b/vines.gemspec index 7e6a993..573ba3a 100644 --- a/vines.gemspec +++ b/vines.gemspec @@ -25,7 +25,7 @@ Gem::Specification.new do |s| s.add_dependency 'mongo', '~> 1.5.2' s.add_dependency 'bson_ext', '~> 1.5.2' s.add_dependency 'net-ldap', '~> 0.3.1' - s.add_dependency 'nokogiri', '~> 1.4.7' + s.add_dependency 'nokogiri', '~> 1.5.5' s.add_development_dependency 'minitest', '~> 2.11.2' s.add_development_dependency 'coffee-script', '~> 2.2.0' From 6f15cca70146cdbf6870189a554c3385b1a012dc Mon Sep 17 00:00:00 2001 From: David Graham Date: Sat, 15 Sep 2012 00:11:29 +0400 Subject: [PATCH 15/28] Update minitest to 3.4.0. --- vines.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vines.gemspec b/vines.gemspec index 573ba3a..fd21f6d 100644 --- a/vines.gemspec +++ b/vines.gemspec @@ -27,7 +27,7 @@ Gem::Specification.new do |s| s.add_dependency 'net-ldap', '~> 0.3.1' s.add_dependency 'nokogiri', '~> 1.5.5' - s.add_development_dependency 'minitest', '~> 2.11.2' + s.add_development_dependency 'minitest', '~> 3.4.0' s.add_development_dependency 'coffee-script', '~> 2.2.0' s.add_development_dependency 'coffee-script-source', '~> 1.3.3' s.add_development_dependency 'uglifier', '~> 1.3.0' From df6fd70e003c672b09fa4f94fc9a56b6aed4e995 Mon Sep 17 00:00:00 2001 From: David Graham Date: Mon, 17 Sep 2012 07:31:49 +0400 Subject: [PATCH 16/28] Fixes for MiniTest 3.4. --- test/stream/server/auth_test.rb | 76 +++++++++++++++++---------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/test/stream/server/auth_test.rb b/test/stream/server/auth_test.rb index aaebe79..d762a2d 100644 --- a/test/stream/server/auth_test.rb +++ b/test/stream/server/auth_test.rb @@ -1,57 +1,61 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::Stream::Server::Auth do # disable logging for tests Class.new.extend(Vines::Log).log.level = Logger::FATAL + subject { Vines::Stream::Server::Auth.new(stream) } + let(:stream) { MiniTest::Mock.new } + before do - @stream = MiniTest::Mock.new - @state = Vines::Stream::Server::Auth.new(@stream) + class << stream + attr_accessor :remote_domain + end + stream.remote_domain = 'wonderland.lit' end - describe 'external auth' do - it 'passes with empty authzid' do - @stream.expect(:remote_domain, 'wonderland.lit') - @stream.expect(:cert_domain_matches?, true, ['wonderland.lit']) - @stream.expect(:write, nil, ['']) - @stream.expect(:advance, nil, [Vines::Stream::Server::FinalRestart]) - @stream.expect(:reset, nil) - @stream.expect(:authentication_mechanisms, ['EXTERNAL']) - node = node(%Q{=}) - @state.node(node) - assert @stream.verify + describe 'when given a valid authzid' do + before do + stream.expect :cert_domain_matches?, true, ['wonderland.lit'] + stream.expect :write, nil, [''] + stream.expect :advance, nil, [Vines::Stream::Server::FinalRestart] + stream.expect :reset, nil + stream.expect :authentication_mechanisms, ['EXTERNAL'] + end + + it 'passes external auth with empty authzid' do + node = external('=') + subject.node(node) + stream.verify end - it 'passes when authzid matches from domain' do - @stream.expect(:remote_domain, 'wonderland.lit') - @stream.expect(:cert_domain_matches?, true, ['wonderland.lit']) - @stream.expect(:write, nil, ['']) - @stream.expect(:advance, nil, [Vines::Stream::Server::FinalRestart]) - @stream.expect(:reset, nil) - @stream.expect(:authentication_mechanisms, ['EXTERNAL']) - node = node(%Q{#{Base64.strict_encode64('wonderland.lit')}}) - @state.node(node) - assert @stream.verify + it 'passes external auth with authzid matching from domain' do + node = external(Base64.strict_encode64('wonderland.lit')) + subject.node(node) + stream.verify + end + end + + describe 'when given an invalid authzid' do + before do + stream.expect :write, nil, [''] + stream.expect :close_connection_after_writing, nil + stream.expect :error, nil, [Vines::SaslErrors::InvalidAuthzid] + stream.expect :authentication_mechanisms, ['EXTERNAL'] end - it 'fails when authzid does not match from domain' do - @stream.expect(:remote_domain, 'wonderland.lit') - @stream.expect(:write, nil, ['']) - @stream.expect(:close_connection_after_writing, nil) - @stream.expect(:error, nil, [Vines::SaslErrors::InvalidAuthzid]) - @stream.expect(:authentication_mechanisms, ['EXTERNAL']) - node = node(%Q{#{Base64.strict_encode64('verona.lit')}}) - @state.node(node) - assert @stream.verify + it 'fails external auth with mismatched from domain' do + node = external(Base64.strict_encode64('verona.lit')) + subject.node(node) + stream.verify end end private - def node(xml) - Nokogiri::XML(xml).root + def external(authzid) + node(%Q{#{authzid}}) end end From 668862b762240cc727e8e7fc7820c8db70d4b731 Mon Sep 17 00:00:00 2001 From: David Graham Date: Mon, 17 Sep 2012 08:07:02 +0400 Subject: [PATCH 17/28] Fixes for MiniTest 3.4. --- test/stream/client/auth_test.rb | 124 ++++++++++++++++---------------- 1 file changed, 61 insertions(+), 63 deletions(-) diff --git a/test/stream/client/auth_test.rb b/test/stream/client/auth_test.rb index 3e63b52..1cb0f41 100644 --- a/test/stream/client/auth_test.rb +++ b/test/stream/client/auth_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::Stream::Client::Auth do # disable logging for tests @@ -27,113 +26,112 @@ def save_user(user) end end - before do - @stream = MiniTest::Mock.new - @state = Vines::Stream::Client::Auth.new(@stream) - end + subject { Vines::Stream::Client::Auth.new(stream) } + let(:stream) { MiniTest::Mock.new } describe 'error handling' do it 'rejects invalid element' do node = node('') - assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) } + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized end it 'rejects invalid element in sasl namespace' do node = node(%Q{}) - assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) } + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized end it 'rejects auth elements missing sasl namespace' do node = node('') - assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) } + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized end it 'rejects auth element with invalid namespace' do node = node('') - assert_raises(Vines::StreamErrors::NotAuthorized) { @state.node(node) } + -> { subject.node(node) }.must_raise Vines::StreamErrors::NotAuthorized end it 'rejects valid auth element missing mechanism' do - @stream.expect(:error, nil, [Vines::SaslErrors::InvalidMechanism]) - @stream.expect(:authentication_mechanisms, ['PLAIN']) + stream.expect :error, nil, [Vines::SaslErrors::InvalidMechanism] + stream.expect :authentication_mechanisms, ['PLAIN'] node = node(%Q{tokens}) - @state.node(node) - assert @stream.verify + subject.node(node) + stream.verify end it 'rejects valid auth element with invalid mechanism' do - @stream.expect(:error, nil, [Vines::SaslErrors::InvalidMechanism]) - @stream.expect(:authentication_mechanisms, ['PLAIN']) + stream.expect :error, nil, [Vines::SaslErrors::InvalidMechanism] + stream.expect :authentication_mechanisms, ['PLAIN'] node = node(%Q{tokens}) - @state.node(node) - assert @stream.verify + subject.node(node) + stream.verify end end describe 'plain auth' do it 'rejects valid mechanism missing base64 text' do - @stream.expect(:error, nil, [Vines::SaslErrors::MalformedRequest]) - node = node(%Q{}) - @state.node(node) - assert @stream.verify + stream.expect :error, nil, [Vines::SaslErrors::MalformedRequest] + node = plain('') + subject.node(node) + stream.verify end it 'rejects invalid base64 text' do - @stream.expect(:error, nil, [Vines::SaslErrors::IncorrectEncoding]) - @stream.expect(:authentication_mechanisms, ['PLAIN']) - node = node(%Q{tokens}) - @state.node(node) - assert @stream.verify + stream.expect :error, nil, [Vines::SaslErrors::IncorrectEncoding] + stream.expect :authentication_mechanisms, ['PLAIN'] + node = plain('tokens') + subject.node(node) + stream.verify end it 'rejects invalid password' do - @stream.expect(:storage, MockStorage.new) - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:error, nil, [Vines::SaslErrors::NotAuthorized]) - @stream.expect(:authentication_mechanisms, ['PLAIN']) - node = node(%Q{#{Base64.strict_encode64("\x00alice\x00bogus")}}) - @state.node(node) - assert @stream.verify + stream.expect :storage, MockStorage.new + stream.expect :domain, 'wonderland.lit' + stream.expect :error, nil, [Vines::SaslErrors::NotAuthorized] + stream.expect :authentication_mechanisms, ['PLAIN'] + node = plain(Base64.strict_encode64("\x00alice\x00bogus")) + subject.node(node) + stream.verify end it 'passes with valid password' do user = Vines::User.new(jid: 'alice@wonderland.lit') - @stream.expect(:reset, nil) - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:storage, MockStorage.new) - @stream.expect(:user=, nil, [user]) - @stream.expect(:write, nil, [%Q{}]) - @stream.expect(:advance, nil, [Vines::Stream::Client::BindRestart]) - @stream.expect(:authentication_mechanisms, ['PLAIN']) - node = node(%Q{#{Base64.strict_encode64("\x00alice\x00secr3t")}}) - @state.node(node) - assert @stream.verify + stream.expect :reset, nil + stream.expect :domain, 'wonderland.lit' + stream.expect :storage, MockStorage.new + stream.expect :user=, nil, [user] + stream.expect :write, nil, [%Q{}] + stream.expect :advance, nil, [Vines::Stream::Client::BindRestart] + stream.expect :authentication_mechanisms, ['PLAIN'] + node = plain(Base64.strict_encode64("\x00alice\x00secr3t")) + subject.node(node) + stream.verify end it 'raises policy-violation after max auth attempts is reached' do - @stream.expect(:domain, 'wonderland.lit') - @stream.expect(:authentication_mechanisms, ['PLAIN']) - @stream.expect(:storage, MockStorage.new) - node = proc do - node(%Q{#{Base64.strict_encode64("\x00alice\x00bogus")}}) - end - - @stream.expect(:error, nil, [Vines::SaslErrors::NotAuthorized]) - @state.node(node.call) - assert @stream.verify - - @state.node(node.call) - assert @stream.verify - - @stream.expect(:error, nil, [Vines::StreamErrors::PolicyViolation]) - @state.node(node.call) - assert @stream.verify + stream.expect :domain, 'wonderland.lit' + stream.expect :storage, MockStorage.new + node = -> { plain(Base64.strict_encode64("\x00alice\x00bogus")) } + + stream.expect :authentication_mechanisms, ['PLAIN'] + stream.expect :error, nil, [Vines::SaslErrors::NotAuthorized] + subject.node(node.call) + stream.verify + + stream.expect :authentication_mechanisms, ['PLAIN'] + stream.expect :error, nil, [Vines::SaslErrors::NotAuthorized] + subject.node(node.call) + stream.verify + + stream.expect :authentication_mechanisms, ['PLAIN'] + stream.expect :error, nil, [Vines::StreamErrors::PolicyViolation] + subject.node(node.call) + stream.verify end end private - def node(xml) - Nokogiri::XML(xml).root + def plain(authzid) + node(%Q{#{authzid}}) end end From bbfe797aa88328ea307805003272d38a999e7fd9 Mon Sep 17 00:00:00 2001 From: David Graham Date: Mon, 17 Sep 2012 08:15:01 +0400 Subject: [PATCH 18/28] Convert to specs. --- test/stanza/iq/disco_items_test.rb | 70 +++++++++++++++--------------- 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/test/stanza/iq/disco_items_test.rb b/test/stanza/iq/disco_items_test.rb index 41f89d6..baaa52f 100644 --- a/test/stanza/iq/disco_items_test.rb +++ b/test/stanza/iq/disco_items_test.rb @@ -1,47 +1,49 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class DiscoItemsTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - end - - def test_component_items - query = %q{} - node = node(%Q{#{query}}) - - expected = node(%q{ - - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stanza::Iq::DiscoItems do + subject { Vines::Stanza::Iq::DiscoItems.new(xml, stream) } + let(:stream) { MiniTest::Mock.new } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/home') } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } components 'tea' => 'secr3t', 'cake' => 'passw0rd' end end + end - @stream.expect(:user, Vines::User.new(:jid => 'alice@wonderland.lit/home')) - @stream.expect(:write, nil, [expected]) - @stream.expect(:config, config) - - stanza = Vines::Stanza::Iq::DiscoItems.new(node, @stream) - stanza.process - assert @stream.verify + before do + class << stream + attr_accessor :config, :user + end + stream.config = config + stream.user = alice end - private + describe 'when querying server items' do + let(:xml) do + query = %q{} + node(%Q{#{query}}) + end + + let(:result) do + node(%q{ + + + + + + + }) + end - def node(xml) - Nokogiri::XML(xml).root + it 'includes component domains in output' do + stream.expect :write, nil, [result] + subject.process + stream.verify + end end end From f78d0d5c5c1c299be931bd6bdfed339fd4d8f120 Mon Sep 17 00:00:00 2001 From: David Graham Date: Mon, 17 Sep 2012 13:52:22 +0400 Subject: [PATCH 19/28] Convert to specs. --- test/stanza/message_test.rb | 181 ++++++++++++++++++------------------ 1 file changed, 92 insertions(+), 89 deletions(-) diff --git a/test/stanza/message_test.rb b/test/stanza/message_test.rb index 54b5476..4fc9630 100644 --- a/test/stanza/message_test.rb +++ b/test/stanza/message_test.rb @@ -1,123 +1,126 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class MessageTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - @config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stanza::Message do + subject { Vines::Stanza::Message.new(xml, stream) } + let(:stream) { MiniTest::Mock.new } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } + let(:romeo) { Vines::User.new(jid: 'romeo@verona.lit/balcony') } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } end end end - def test_bad_type_returns_error - node = node('hello!') - stanza = Vines::Stanza::Message.new(node, @stream) - assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process } + before do + class << stream + attr_accessor :config, :user + end + stream.user = alice + stream.config = config end - def test_missing_to_address_is_sent_to_sender - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - node = node('hello!') - - recipient = MiniTest::Mock.new - recipient.expect(:user, alice) - recipient.expect(:write, nil, [node]) - - @stream.expect(:user, alice) - @stream.expect(:connected_resources, [recipient], [alice.jid.bare]) + describe 'when message type attribute is invalid' do + let(:xml) { node('hello!') } - stanza = Vines::Stanza::Message.new(node, @stream) - stanza.process - assert @stream.verify - assert recipient.verify + it 'raises a bad-request stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest + end end - def test_message_to_non_user_is_ignored - bogus = Vines::JID.new('bogus@wonderland.lit/cake') - node = node(%Q{hello!}) - - storage = MiniTest::Mock.new - storage.expect(:find_user, nil, [bogus]) + describe 'when the to address is missing' do + let(:xml) { node('hello!') } + let(:recipient) { MiniTest::Mock.new } - @stream.expect(:config, @config) - @stream.expect(:storage, storage, [bogus.domain]) - @stream.expect(:connected_resources, [], [bogus]) + before do + recipient.expect :user, alice + recipient.expect :write, nil, [xml] + stream.expect :connected_resources, [recipient], [alice.jid.bare] + end - stanza = Vines::Stanza::Message.new(node, @stream) - stanza.process - assert @stream.verify - assert storage.verify + it 'sends the message to the senders connected streams' do + subject.process + stream.verify + recipient.verify + end end - def test_message_to_offline_user_returns_error - hatter = Vines::User.new(:jid => 'hatter@wonderland.lit/cake') - node = node(%Q{hello!}) - - storage = MiniTest::Mock.new - storage.expect(:find_user, hatter, [hatter.jid]) + describe 'when addressed to a non-user' do + let(:bogus) { Vines::JID.new('bogus@wonderland.lit/cake') } + let(:xml) { node(%Q{hello!}) } + let(:storage) { MiniTest::Mock.new } - @stream.expect(:config, @config) - @stream.expect(:storage, storage, [hatter.jid.domain]) - @stream.expect(:connected_resources, [], [hatter.jid]) + before do + storage.expect :find_user, nil, [bogus] + stream.expect :storage, storage, [bogus.domain] + stream.expect :connected_resources, [], [bogus] + end - stanza = Vines::Stanza::Message.new(node, @stream) - assert_raises(Vines::StanzaErrors::ServiceUnavailable) { stanza.process } - assert @stream.verify - assert storage.verify + it 'ignores the stanza' do + subject.process + stream.verify + storage.verify + end end - def test_message_to_local_user_in_different_domain_is_delivered - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - romeo = Vines::User.new(:jid => 'romeo@verona.lit/balcony') - node = node(%Q{hello!}) - expected = node(%Q{hello!}) - - recipient = MiniTest::Mock.new - recipient.expect(:user, romeo) - recipient.expect(:write, nil, [expected]) + describe 'when addressed to an offline user' do + let(:hatter) { Vines::User.new(jid: 'hatter@wonderland.lit/cake') } + let(:xml) { node(%Q{hello!}) } + let(:storage) { MiniTest::Mock.new } - @config.host 'verona.lit' do - storage(:fs) { dir Dir.tmpdir } + before do + storage.expect :find_user, hatter, [hatter.jid] + stream.expect :storage, storage, [hatter.jid.domain] + stream.expect :connected_resources, [], [hatter.jid] end - @stream.expect(:config, @config) - @stream.expect(:user, alice) - @stream.expect(:connected_resources, [recipient], [romeo.jid]) - - stanza = Vines::Stanza::Message.new(node, @stream) - stanza.process - assert @stream.verify - assert recipient.verify + it 'raises a service-unavailable stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::ServiceUnavailable + stream.verify + storage.verify + end end - def test_message_to_remote_user_is_routed - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - romeo = Vines::User.new(:jid => 'romeo@verona.lit/balcony') - node = node(%Q{hello!}) - expected = node(%Q{hello!}) + describe 'when address to a local user in a different domain' do + let(:xml) { node(%Q{hello!}) } + let(:expected) { node(%Q{hello!}) } + let(:recipient) { MiniTest::Mock.new } + + before do + recipient.expect :user, romeo + recipient.expect :write, nil, [expected] - router = MiniTest::Mock.new - @stream.expect(:config, @config) - router.expect(:route, nil, [expected]) + config.host 'verona.lit' do + storage(:fs) { dir Dir.tmpdir } + end - @stream.expect(:router, router) - @stream.expect(:user, alice) + stream.expect :connected_resources, [recipient], [romeo.jid] + end - stanza = Vines::Stanza::Message.new(node, @stream) - stanza.process - assert @stream.verify - assert router.verify + it 'delivers the stanza to the user' do + subject.process + stream.verify + recipient.verify + end end - private + describe 'when addressed to a remote user' do + let(:xml) { node(%Q{hello!}) } + let(:expected) { node(%Q{hello!}) } + let(:router) { MiniTest::Mock.new } - def node(xml) - Nokogiri::XML(xml).root + before do + router.expect :route, nil, [expected] + stream.expect :router, router + end + + it 'routes rather than handle locally' do + subject.process + stream.verify + router.verify + end end end From 722c9bf91803095a93ceaeabf0d0803cc9f55e40 Mon Sep 17 00:00:00 2001 From: David Graham Date: Mon, 17 Sep 2012 14:02:11 +0400 Subject: [PATCH 20/28] Use OpenStruct to avoid MiniTest::Mock errors. --- test/stream/client/session_test.rb | 37 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/test/stream/client/session_test.rb b/test/stream/client/session_test.rb index 42d29ae..04e8bef 100644 --- a/test/stream/client/session_test.rb +++ b/test/stream/client/session_test.rb @@ -1,26 +1,27 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' -class ClientSessionTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - @stream.expect(:config, nil) - end - - def test_equality - one = Vines::Stream::Client::Session.new(@stream) - two = Vines::Stream::Client::Session.new(@stream) +describe Vines::Stream::Client::Session do + subject { Vines::Stream::Client::Session.new(stream) } + let(:another) { Vines::Stream::Client::Session.new(stream) } + let(:stream) { OpenStruct.new(config: nil) } - assert_nil one <=> 42 + describe 'session equality checks' do + it 'uses class in equality check' do + (subject <=> 42).must_be_nil + end - assert one == one - assert one.eql?(one) - assert one.hash == one.hash + it 'is equal to itself' do + assert subject == subject + assert subject.eql?(subject) + assert subject.hash == subject.hash + end - refute one == two - refute one.eql?(two) - refute one.hash == two.hash + it 'is not equal to another session' do + refute subject == another + refute subject.eql?(another) + refute subject.hash == another.hash + end end end From 81ef90efdd07c81c770a722b7b23fc42c2c2ca67 Mon Sep 17 00:00:00 2001 From: David Graham Date: Mon, 17 Sep 2012 14:12:32 +0400 Subject: [PATCH 21/28] Convert to specs. --- test/stanza/iq_test.rb | 102 +++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/test/stanza/iq_test.rb b/test/stanza/iq_test.rb index 2c734e3..df43920 100644 --- a/test/stanza/iq_test.rb +++ b/test/stanza/iq_test.rb @@ -1,66 +1,70 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' -class IqTest < MiniTest::Unit::TestCase - def setup - @stream = MiniTest::Mock.new - @config = Vines::Config.new do +describe Vines::Stanza::Iq do + subject { Vines::Stanza::Iq.new(xml, stream) } + let(:stream) { MiniTest::Mock.new } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } + let(:hatter) { Vines::User.new(jid: 'hatter@wonderland.lit/crumpets') } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } end end end - def test_allow_other_iq_to_route - alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea') - hatter = Vines::User.new(:jid => 'hatter@wonderland.lit/crumpets') - node = node(%q{ - - - - - - - - - - - - - - }.strip.gsub(/\n|\s{2,}/, '')) - - recipient = MiniTest::Mock.new - recipient.expect(:user, alice, []) - recipient.expect(:write, nil, [node]) + before do + class << stream + attr_accessor :config, :user + end + stream.user = hatter + stream.config = config + end - @stream.expect(:config, @config) - @stream.expect(:user, hatter) - @stream.expect(:connected_resources, [recipient], [alice.jid]) + describe 'when addressed to a user rather than the server itself' do + let(:recipient) { MiniTest::Mock.new } + let(:xml) do + node(%q{ + + + + + + + + + + + + + + }) + end - stanza = Vines::Stanza::Iq.new(node, @stream) - stanza.process - assert @stream.verify - assert recipient.verify - end + before do + recipient.expect :user, alice, [] + recipient.expect :write, nil, [xml] + stream.expect :connected_resources, [recipient], [alice.jid] + end - def test_feature_not_implemented - node = node('') - stanza = Vines::Stanza::Iq.new(node, @stream) - assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process } + it 'routes the stanza to the users connected resources' do + subject.process + stream.verify + recipient.verify + end end - private + describe 'when given no type or body elements' do + let(:xml) { node('') } - def node(xml) - Nokogiri::XML(xml).root + it 'raises a feature-not-implemented stanza error' do + -> { subject.process }.must_raise Vines::StanzaErrors::FeatureNotImplemented + end end end From f534edb7eae0ad4cfabe3fab2f7ea777e42191b9 Mon Sep 17 00:00:00 2001 From: David Graham Date: Mon, 17 Sep 2012 14:40:20 +0400 Subject: [PATCH 22/28] Convert to specs. --- test/stanza/presence/subscribe_test.rb | 121 ++++++++++++++----------- 1 file changed, 67 insertions(+), 54 deletions(-) diff --git a/test/stanza/presence/subscribe_test.rb b/test/stanza/presence/subscribe_test.rb index 704e8f0..48b9905 100644 --- a/test/stanza/presence/subscribe_test.rb +++ b/test/stanza/presence/subscribe_test.rb @@ -1,70 +1,83 @@ # encoding: UTF-8 -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' -class SubscribeTest < MiniTest::Unit::TestCase - def test_outbound_subscribe_to_local_jid_but_missing_contact - alice = Vines::JID.new('alice@wonderland.lit/tea') - hatter = Vines::JID.new('hatter@wonderland.lit') +describe Vines::Stanza::Presence::Subscribe do + subject { Vines::Stanza::Presence::Subscribe.new(xml, stream) } + let(:stream) { MiniTest::Mock.new } + let(:alice) { Vines::JID.new('alice@wonderland.lit/tea') } + let(:hatter) { Vines::JID.new('hatter@wonderland.lit') } + let(:contact) { Vines::Contact.new(jid: hatter) } - contact = Vines::Contact.new(:jid => hatter) + before do + class << stream + attr_accessor :user, :nodes + def write(node) + @nodes ||= [] + @nodes << node + end + end + end - user = MiniTest::Mock.new - user.expect(:jid, alice) - user.expect(:request_subscription, nil, [hatter]) - user.expect(:contact, contact, [hatter]) + describe 'outbound subscription to a local jid, but missing contact' do + let(:xml) { node(%q{}) } + let(:user) { MiniTest::Mock.new } + let(:storage) { MiniTest::Mock.new } + let(:recipient) { MiniTest::Mock.new } - storage = MiniTest::Mock.new - storage.expect(:save_user, nil, [user]) - storage.expect(:find_user, nil, [hatter]) + before do + class << user + attr_accessor :jid + end + user.jid = alice + user.expect :request_subscription, nil, [hatter] + user.expect :contact, contact, [hatter] - recipient = MiniTest::Mock.new - recipient.expect(:user, user) - def recipient.nodes; @nodes; end - def recipient.write(node) - @nodes ||= [] - @nodes << node - end + storage.expect :save_user, nil, [user] + storage.expect :find_user, nil, [hatter] - stream = MiniTest::Mock.new - stream.expect(:domain, 'wonderland.lit') - stream.expect(:storage, storage, ['wonderland.lit']) - stream.expect(:user, user) - stream.expect(:interested_resources, [recipient], [alice]) - stream.expect(:update_user_streams, nil, [user]) - def stream.nodes; @nodes; end - def stream.write(node) - @nodes ||= [] - @nodes << node - end + recipient.expect :user, user + class << recipient + attr_accessor :nodes + def write(node) + @nodes ||= [] + @nodes << node + end + end - node = node(%q{}) - stanza = Vines::Stanza::Presence::Subscribe.new(node, stream) - def stanza.route_iq; false; end - def stanza.inbound?; false; end - def stanza.local?; true; end + stream.user = user + stream.expect :domain, 'wonderland.lit' + stream.expect :storage, storage, ['wonderland.lit'] + stream.expect :storage, storage, ['wonderland.lit'] + stream.expect :interested_resources, [recipient], [alice] + stream.expect :update_user_streams, nil, [user] - stanza.process - assert stream.verify - assert user.verify - assert storage.verify - assert_equal 1, stream.nodes.size - assert_equal 1, recipient.nodes.size + class << subject + def route_iq; false; end + def inbound?; false; end + def local?; true; end + end + end - expected = node(%q{}) - assert_equal expected, stream.nodes[0] + it 'rejects the subscription with an unsubscribed response' do + subject.process + stream.verify + user.verify + storage.verify + stream.nodes.size.must_equal 1 - query = %q{} - expected = node(%Q{#{query}}) - recipient.nodes[0].remove_attribute('id') # id is random - assert_equal expected, recipient.nodes[0] - end + expected = node(%q{}) + stream.nodes.first.must_equal expected + end - private + it 'sends a roster set to the interested resources with subscription none' do + subject.process + recipient.nodes.size.must_equal 1 - def node(xml) - Nokogiri::XML(xml).root + query = %q{} + expected = node(%Q{#{query}}) + recipient.nodes.first.remove_attribute('id') # id is random + recipient.nodes.first.must_equal expected + end end end From 88b0479fb9358e4bc0edf59bf0ad2759927f5672 Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 19 Sep 2012 08:58:23 -0600 Subject: [PATCH 23/28] Use test_helper. --- test/config_test.rb | 4 +--- test/jid_test.rb | 3 +-- test/kit_test.rb | 3 +-- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/test/config_test.rb b/test/config_test.rb index 9908169..ca04110 100644 --- a/test/config_test.rb +++ b/test/config_test.rb @@ -1,8 +1,6 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'minitest/autorun' +require 'test_helper' class ConfigTest < MiniTest::Unit::TestCase def test_missing_host diff --git a/test/jid_test.rb b/test/jid_test.rb index a596848..479af44 100644 --- a/test/jid_test.rb +++ b/test/jid_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::JID do it 'handles empty input' do diff --git a/test/kit_test.rb b/test/kit_test.rb index fceba17..9c028e6 100644 --- a/test/kit_test.rb +++ b/test/kit_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class KitTest < MiniTest::Unit::TestCase def test_hmac From 07698e5927ddb5146e4554ec71c3fc48ffd00bf6 Mon Sep 17 00:00:00 2001 From: David Graham Date: Wed, 19 Sep 2012 08:58:35 -0600 Subject: [PATCH 24/28] Convert to specs. --- test/stanza_test.rb | 115 +++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 54 deletions(-) diff --git a/test/stanza_test.rb b/test/stanza_test.rb index 4296a3d..b004735 100644 --- a/test/stanza_test.rb +++ b/test/stanza_test.rb @@ -1,78 +1,85 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class StanzaTest < MiniTest::Unit::TestCase - def setup - @alice = Vines::JID.new('alice@wonderland.lit/tea') - @romeo = Vines::JID.new('romeo@verona.lit/balcony') - @stream = MiniTest::Mock.new - @config = Vines::Config.new do +require 'test_helper' + +describe Vines::Stanza do + subject { Vines::Stanza::Message.new(xml, stream) } + let(:alice) { Vines::JID.new('alice@wonderland.lit/tea') } + let(:romeo) { Vines::JID.new('romeo@verona.lit/balcony') } + let(:stream) { MiniTest::Mock.new } + let(:config) do + Vines::Config.new do host 'wonderland.lit' do storage(:fs) { dir Dir.tmpdir } end end end - def test_validate_missing_addresses - node = node(%Q{hello!}) - stanza = Vines::Stanza::Message.new(node, @stream) - assert_nil stanza.validate_to - assert_nil stanza.validate_from - assert @stream.verify - end + describe 'when stanza contains no addresses' do + let(:xml) { node(%Q{hello!}) } - def test_validate_valid_addresses - node = node(%Q{hello!}) - stanza = Vines::Stanza::Message.new(node, @stream) - assert_equal @romeo, stanza.validate_to - assert_equal @alice, stanza.validate_from - assert @stream.verify + it 'validates them as nil' do + subject.validate_to.must_be_nil + subject.validate_from.must_be_nil + stream.verify + end end - def test_validate_invalid_addresses - node = node(%Q{hello!}) - stanza = Vines::Stanza::Message.new(node, @stream) - assert_raises(Vines::StanzaErrors::JidMalformed) { stanza.validate_to } - assert_raises(Vines::StanzaErrors::JidMalformed) { stanza.validate_from } - assert @stream.verify + describe 'when stanza contains valid addresses' do + let(:xml) { node(%Q{hello!}) } + + it 'validates and returns JID objects' do + subject.validate_to.must_equal romeo + subject.validate_from.must_equal alice + stream.verify + end end - def test_non_routable_stanza_is_local - stanza = Vines::Stanza.new(node(''), @stream) - assert stanza.local? - assert @stream.verify + describe 'when stanza contains invalid addresses' do + let(:xml) { node(%Q{hello!}) } + + it 'raises a jid-malformed stanza error' do + -> { subject.validate_to }.must_raise Vines::StanzaErrors::JidMalformed + -> { subject.validate_from }.must_raise Vines::StanzaErrors::JidMalformed + stream.verify + end end - def test_stanza_missing_to_is_local - node = node(%Q{hello!}) - stanza = Vines::Stanza::Message.new(node, @stream) - assert stanza.local? - assert @stream.verify + describe 'when receiving a non-routable stanza type' do + let(:xml) { node('') } + + it 'handles locally rather than routing' do + subject.local?.must_equal true + stream.verify + end end - def test_stanza_with_local_jid_is_local - node = node(%Q{hello!}) - @stream.expect(:config, @config) - stanza = Vines::Stanza::Message.new(node, @stream) - assert stanza.local? - assert @stream.verify + describe 'when stanza is missing a to address' do + let(:xml) { node(%Q{hello!}) } + + it 'handles locally rather than routing' do + subject.local?.must_equal true + stream.verify + end end - def test_stanza_with_remote_jid_is_not_local - node = node(%Q{hello!}) - @stream.expect(:config, @config) - stanza = Vines::Stanza::Message.new(node, @stream) - refute stanza.local? - assert @stream.verify + describe 'when stanza is addressed to a local jid' do + let(:xml) { node(%Q{hello!}) } + + it 'handles locally rather than routing' do + stream.expect :config, config + subject.local?.must_equal true + stream.verify + end end - private + describe 'when stanza is addressed to a remote jid' do + let(:xml) { node(%Q{hello!}) } - def node(xml) - Nokogiri::XML(xml).root + it 'is not considered a local stanza' do + stream.expect :config, config + subject.local?.must_equal false + stream.verify + end end end From f669c86dab950bebd482c8a127c243d6ed09bf1f Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 21 Sep 2012 10:17:37 -0600 Subject: [PATCH 25/28] More specs. --- test/contact_test.rb | 146 ++++++++++++++++++++++++------------------- 1 file changed, 80 insertions(+), 66 deletions(-) diff --git a/test/contact_test.rb b/test/contact_test.rb index a22310c..91dc8ba 100644 --- a/test/contact_test.rb +++ b/test/contact_test.rb @@ -1,88 +1,102 @@ # encoding: UTF-8 -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' - -class ContactTest < MiniTest::Unit::TestCase - def test_equality - alice = Vines::Contact.new(:jid => 'alice@wonderland.lit') - alice2 = Vines::Contact.new(:jid => 'alice@wonderland.lit') - hatter = Vines::Contact.new(:jid => 'hatter@wonderland.lit') - - assert_nil alice <=> 42 - - assert alice == alice2 - assert alice.eql?(alice2) - assert alice.hash == alice2.hash - - refute alice == hatter - refute alice.eql?(hatter) - refute alice.hash == hatter.hash +require 'test_helper' + +describe Vines::Contact do + subject do + Vines::Contact.new( + jid: 'alice@wonderland.lit', + name: "Alice", + groups: %w[Friends Buddies], + subscription: 'from') end - def test_initialize_missing_jid_raises - assert_raises(ArgumentError) { Vines::Contact.new } - assert_raises(ArgumentError) { Vines::Contact.new(:jid => '') } - end + describe 'contact equality checks' do + let(:alice) { Vines::Contact.new(jid: 'alice@wonderland.lit') } + let(:hatter) { Vines::Contact.new(jid: 'hatter@wonderland.lit') } - def test_initialize_domain_only_jid_does_not_raise - contact = Vines::Contact.new(:jid => 'tea.wonderland.lit') - assert_equal 'tea.wonderland.lit', contact.jid.to_s - end + it 'uses class in equality check' do + (subject <=> 42).must_be_nil + end - def test_to_roster_xml_sorts_groups - contact = Vines::Contact.new( - :jid => 'a@wonderland.lit', - :name => "Contact 1", - :groups => %w[B A]) + it 'is equal to itself' do + assert subject == subject + assert subject.eql?(subject) + assert subject.hash == subject.hash + end - expected = %q{ - - A - B - - }.strip.gsub(/\n/, '').gsub(/\s{2,}/, '') + it 'is equal to another contact with the same jid' do + assert subject == alice + assert subject.eql?(alice) + assert subject.hash == alice.hash + end - assert_equal expected, contact.to_roster_xml.to_xml(:indent => 0).gsub(/\n/, '') + it 'is not equal to a different jid' do + refute subject == hatter + refute subject.eql?(hatter) + refute subject.hash == hatter.hash + end end - def test_send_roster_push - contact = Vines::Contact.new( - :jid => 'alice@wonderland.lit', - :name => "Alice", - :groups => %w[Friends Buddies], - :subscription => 'from') - - recipient = MiniTest::Mock.new - recipient.expect(:user, Vines::User.new(:jid => 'hatter@wonderland.lit')) - def recipient.nodes; @nodes; end - def recipient.write(node) - @nodes ||= [] - @nodes << node + describe 'initialize' do + it 'raises when not given a jid' do + -> { Vines::Contact.new }.must_raise ArgumentError + -> { Vines::Contact.new(jid: '') }.must_raise ArgumentError end - contact.send_roster_push(recipient) - assert recipient.verify - assert_equal 1, recipient.nodes.size + it 'accepts a domain-only jid' do + contact = Vines::Contact.new(jid: 'tea.wonderland.lit') + contact.jid.to_s.must_equal 'tea.wonderland.lit' + end + end - expected = node(%q{ - - + describe '#to_roster_xml' do + let(:expected) do + node(%q{ Buddies Friends - - - }.strip.gsub(/\n/, '').gsub(/\s{2,}/, '')) - recipient.nodes[0].remove_attribute('id') # id is random - assert_equal expected, recipient.nodes[0] + }) + end + + it 'sorts group names' do + subject.to_roster_xml.must_equal expected + end end - private + describe '#send_roster_push' do + let(:recipient) { MiniTest::Mock.new } + let(:expected) do + node(%q{ + + + + Buddies + Friends + + + + }) + end - def node(xml) - Nokogiri::XML(xml).root + before do + recipient.expect :user, Vines::User.new(jid: 'hatter@wonderland.lit') + class << recipient + attr_accessor :nodes + def write(node) + @nodes ||= [] + @nodes << node + end + end + end + + it '' do + subject.send_roster_push(recipient) + recipient.verify + recipient.nodes.size.must_equal 1 + recipient.nodes.first.remove_attribute('id') # id is random + recipient.nodes.first.must_equal expected + end end end From cc3511a3932afbd6e921cff6ff0a93b229b21d3e Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 21 Sep 2012 10:25:53 -0600 Subject: [PATCH 26/28] Convert to specs. --- test/error_test.rb | 109 ++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 55 deletions(-) diff --git a/test/error_test.rb b/test/error_test.rb index f70dc47..0238e4d 100644 --- a/test/error_test.rb +++ b/test/error_test.rb @@ -1,59 +1,58 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' - -class ErrorTest < MiniTest::Unit::TestCase - def test_sasl_error_without_text - expected = %q{} - assert_equal expected, Vines::SaslErrors::TemporaryAuthFailure.new.to_xml - end - - def test_sasl_error_with_text - text = %q{busted} - expected = %q{%s} % text - assert_equal expected, Vines::SaslErrors::TemporaryAuthFailure.new('busted').to_xml - end - - def test_stream_error_without_text - expected = %q{} - assert_equal expected, Vines::StreamErrors::InternalServerError.new.to_xml - end - - def test_stream_error_with_text - text = %q{busted} - expected = %q{%s} % text - assert_equal expected, Vines::StreamErrors::InternalServerError.new('busted').to_xml - end - - def test_stanza_error_with_bad_type - node = node('') - assert_raises(RuntimeError) { Vines::StanzaErrors::BadRequest.new(node, 'bogus') } - end - - def test_stanza_error_with_bad_stanza - node = node('') - assert_raises(RuntimeError) { Vines::StanzaErrors::BadRequest.new(node, 'modify') } - end - - def test_stanza_error_without_text - error = %q{} - expected = %q{%s} % error - node = node(%Q{}) - assert_equal expected, Vines::StanzaErrors::BadRequest.new(node, 'modify').to_xml - end - - def test_stanza_error_with_text - text = %q{busted} - error = %q{%s} % text - expected = %q{%s} % error - node = node(%Q{}) - assert_equal expected, Vines::StanzaErrors::BadRequest.new(node, 'modify', 'busted').to_xml - end - - private - - def node(xml) - Nokogiri::XML(xml).root +require 'test_helper' + +describe Vines::XmppError do + describe Vines::SaslErrors do + it 'does not require a text element' do + expected = %q{} + Vines::SaslErrors::TemporaryAuthFailure.new.to_xml.must_equal expected + end + + it 'includes a text element when message is given' do + text = %q{busted} + expected = %q{%s} % text + Vines::SaslErrors::TemporaryAuthFailure.new('busted').to_xml.must_equal expected + end + end + + describe Vines::StreamErrors do + it 'does not require a text element' do + expected = %q{} + Vines::StreamErrors::InternalServerError.new.to_xml.must_equal expected + end + + it 'includes a text element when message is given' do + text = %q{busted} + expected = %q{%s} % text + Vines::StreamErrors::InternalServerError.new('busted').to_xml.must_equal expected + end + end + + describe Vines::StanzaErrors do + it 'raises when given a bad type' do + node = node('') + -> { Vines::StanzaErrors::BadRequest.new(node, 'bogus') }.must_raise RuntimeError + end + + it 'raises when given a bad stanza' do + node = node('') + -> { Vines::StanzaErrors::BadRequest.new(node, 'modify') }.must_raise RuntimeError + end + + it 'does not require a text element' do + error = %q{} + expected = %q{%s} % error + node = node(%Q{}) + Vines::StanzaErrors::BadRequest.new(node, 'modify').to_xml.must_equal expected + end + + it 'includes a text element when message is given' do + text = %q{busted} + error = %q{%s} % text + expected = %q{%s} % error + node = node(%Q{}) + Vines::StanzaErrors::BadRequest.new(node, 'modify', 'busted').to_xml.must_equal expected + end end end From 165983d1f2206eab49752948dadcf818ddb05a81 Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 21 Sep 2012 10:34:40 -0600 Subject: [PATCH 27/28] Require test_helper. --- test/cluster/publisher_test.rb | 3 +-- test/cluster/subscriber_test.rb | 4 +--- test/config/host_test.rb | 4 +--- test/config/pubsub_test.rb | 5 +---- test/stanza/iq/session_test.rb | 4 +--- test/stanza/presence/probe_test.rb | 5 +---- test/storage/couchdb_test.rb | 3 +-- test/storage/ldap_test.rb | 3 +-- test/storage/local_test.rb | 4 +--- test/storage/mongodb_test.rb | 3 +-- test/storage/null_test.rb | 3 +-- test/storage/redis_test.rb | 3 +-- test/storage/sql_test.rb | 3 +-- test/storage/storage_tests.rb | 4 +--- test/storage_test.rb | 3 +-- test/store_test.rb | 3 +-- test/stream/client/ready_test.rb | 3 +-- test/stream/component/handshake_test.rb | 3 +-- test/stream/component/start_test.rb | 3 +-- test/stream/http/auth_test.rb | 3 +-- test/stream/http/request_test.rb | 4 +--- test/stream/http/sessions_test.rb | 3 +-- test/stream/http/start_test.rb | 3 +-- test/stream/parser_test.rb | 3 +-- test/stream/server/outbound/auth_test.rb | 3 +-- test/stream/server/ready_test.rb | 3 +-- test/token_bucket_test.rb | 3 +-- test/user_test.rb | 3 +-- 28 files changed, 28 insertions(+), 66 deletions(-) diff --git a/test/cluster/publisher_test.rb b/test/cluster/publisher_test.rb index 2559651..88915bc 100644 --- a/test/cluster/publisher_test.rb +++ b/test/cluster/publisher_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class ClusterPublisherTest < MiniTest::Unit::TestCase def setup diff --git a/test/cluster/subscriber_test.rb b/test/cluster/subscriber_test.rb index 3569baa..de65601 100644 --- a/test/cluster/subscriber_test.rb +++ b/test/cluster/subscriber_test.rb @@ -1,8 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' class ClusterSubscriberTest < MiniTest::Unit::TestCase def setup diff --git a/test/config/host_test.rb b/test/config/host_test.rb index bf428bc..da7b0a9 100644 --- a/test/config/host_test.rb +++ b/test/config/host_test.rb @@ -1,8 +1,6 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'minitest/autorun' +require 'test_helper' class HostTest < MiniTest::Unit::TestCase def test_missing_storage diff --git a/test/config/pubsub_test.rb b/test/config/pubsub_test.rb index b91a731..adb99b6 100644 --- a/test/config/pubsub_test.rb +++ b/test/config/pubsub_test.rb @@ -1,9 +1,6 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' class ConfigPubSubTest < MiniTest::Unit::TestCase def setup diff --git a/test/stanza/iq/session_test.rb b/test/stanza/iq/session_test.rb index 5fdd138..6eabf71 100644 --- a/test/stanza/iq/session_test.rb +++ b/test/stanza/iq/session_test.rb @@ -1,8 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' class SessionTest < MiniTest::Unit::TestCase def test_session diff --git a/test/stanza/presence/probe_test.rb b/test/stanza/presence/probe_test.rb index e5debe7..693f837 100644 --- a/test/stanza/presence/probe_test.rb +++ b/test/stanza/presence/probe_test.rb @@ -1,9 +1,6 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' class ProbeTest < MiniTest::Unit::TestCase def setup diff --git a/test/storage/couchdb_test.rb b/test/storage/couchdb_test.rb index e367a52..056cb1c 100644 --- a/test/storage/couchdb_test.rb +++ b/test/storage/couchdb_test.rb @@ -1,8 +1,7 @@ # encoding: UTF-8 require 'storage_tests' -require 'vines' -require 'minitest/autorun' +require 'test_helper' class CouchDBTest < MiniTest::Unit::TestCase include StorageTests diff --git a/test/storage/ldap_test.rb b/test/storage/ldap_test.rb index 8e756ad..4035a5f 100644 --- a/test/storage/ldap_test.rb +++ b/test/storage/ldap_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::Storage::Ldap do ALICE_DN = 'uid=alice@wondlerand.lit,ou=People,dc=wonderland,dc=lit' diff --git a/test/storage/local_test.rb b/test/storage/local_test.rb index 60fc37c..d345c59 100644 --- a/test/storage/local_test.rb +++ b/test/storage/local_test.rb @@ -1,9 +1,7 @@ # encoding: UTF-8 require 'storage_tests' -require 'tmpdir' -require 'vines' -require 'minitest/autorun' +require 'test_helper' class LocalTest < MiniTest::Unit::TestCase include StorageTests diff --git a/test/storage/mongodb_test.rb b/test/storage/mongodb_test.rb index 84c6cca..f0cefb5 100644 --- a/test/storage/mongodb_test.rb +++ b/test/storage/mongodb_test.rb @@ -2,8 +2,7 @@ require 'mock_mongo' require 'storage_tests' -require 'vines' -require 'minitest/autorun' +require 'test_helper' class MongoDBTest < MiniTest::Unit::TestCase include StorageTests diff --git a/test/storage/null_test.rb b/test/storage/null_test.rb index 5af7a94..b052fdf 100644 --- a/test/storage/null_test.rb +++ b/test/storage/null_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class NullStorageTest < MiniTest::Unit::TestCase def setup diff --git a/test/storage/redis_test.rb b/test/storage/redis_test.rb index 523ccac..2a4d869 100644 --- a/test/storage/redis_test.rb +++ b/test/storage/redis_test.rb @@ -2,8 +2,7 @@ require 'mock_redis' require 'storage_tests' -require 'vines' -require 'minitest/autorun' +require 'test_helper' class RedisTest < MiniTest::Unit::TestCase include StorageTests diff --git a/test/storage/sql_test.rb b/test/storage/sql_test.rb index 0e16513..4132d72 100644 --- a/test/storage/sql_test.rb +++ b/test/storage/sql_test.rb @@ -1,8 +1,7 @@ # encoding: UTF-8 require 'storage_tests' -require 'vines' -require 'minitest/autorun' +require 'test_helper' class SqlTest < MiniTest::Unit::TestCase include StorageTests diff --git a/test/storage/storage_tests.rb b/test/storage/storage_tests.rb index dcb2690..7403a7b 100644 --- a/test/storage/storage_tests.rb +++ b/test/storage/storage_tests.rb @@ -1,8 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'ext/nokogiri' -require 'minitest/autorun' +require 'test_helper' # Mixin methods for storage implementation test classes. The behavioral # tests are the same regardless of implementation so share those methods diff --git a/test/storage_test.rb b/test/storage_test.rb index fcc8433..5ba017b 100644 --- a/test/storage_test.rb +++ b/test/storage_test.rb @@ -1,8 +1,7 @@ # encoding: UTF-8 require 'storage_tests' -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::Storage do ALICE = 'alice@wonderland.lit'.freeze diff --git a/test/store_test.rb b/test/store_test.rb index 1fbb752..f70d7ab 100644 --- a/test/store_test.rb +++ b/test/store_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::Store do before do diff --git a/test/stream/client/ready_test.rb b/test/stream/client/ready_test.rb index f4a2e7f..353489a 100644 --- a/test/stream/client/ready_test.rb +++ b/test/stream/client/ready_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class ClientReadyTest < MiniTest::Unit::TestCase STANZAS = [] diff --git a/test/stream/component/handshake_test.rb b/test/stream/component/handshake_test.rb index 3509161..07fd313 100644 --- a/test/stream/component/handshake_test.rb +++ b/test/stream/component/handshake_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class HandshakeTest < MiniTest::Unit::TestCase def setup diff --git a/test/stream/component/start_test.rb b/test/stream/component/start_test.rb index 6fb4ca8..0e505e3 100644 --- a/test/stream/component/start_test.rb +++ b/test/stream/component/start_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class ComponentStartTest < MiniTest::Unit::TestCase def setup diff --git a/test/stream/http/auth_test.rb b/test/stream/http/auth_test.rb index 3fc71e7..3dc7a49 100644 --- a/test/stream/http/auth_test.rb +++ b/test/stream/http/auth_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class HttpAuthTest < MiniTest::Unit::TestCase def setup diff --git a/test/stream/http/request_test.rb b/test/stream/http/request_test.rb index ec7d90d..2903d4b 100644 --- a/test/stream/http/request_test.rb +++ b/test/stream/http/request_test.rb @@ -1,8 +1,6 @@ # encoding: UTF-8 -require 'tmpdir' -require 'vines' -require 'minitest/autorun' +require 'test_helper' describe Vines::Stream::Http::Request do PASSWORD = File.expand_path('../passwords') diff --git a/test/stream/http/sessions_test.rb b/test/stream/http/sessions_test.rb index d64f5ed..483d722 100644 --- a/test/stream/http/sessions_test.rb +++ b/test/stream/http/sessions_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class SessionsTest < MiniTest::Unit::TestCase class MockSessions < Vines::Stream::Http::Sessions diff --git a/test/stream/http/start_test.rb b/test/stream/http/start_test.rb index 3392fa8..84b19c2 100644 --- a/test/stream/http/start_test.rb +++ b/test/stream/http/start_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class HttpStartTest < MiniTest::Unit::TestCase def setup diff --git a/test/stream/parser_test.rb b/test/stream/parser_test.rb index aa88ef1..2fa1826 100644 --- a/test/stream/parser_test.rb +++ b/test/stream/parser_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class ParserTest < MiniTest::Unit::TestCase STREAM_START = ''.freeze diff --git a/test/stream/server/outbound/auth_test.rb b/test/stream/server/outbound/auth_test.rb index 3d4d491..360e482 100644 --- a/test/stream/server/outbound/auth_test.rb +++ b/test/stream/server/outbound/auth_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class OutboundAuthTest < MiniTest::Unit::TestCase def setup diff --git a/test/stream/server/ready_test.rb b/test/stream/server/ready_test.rb index c1f7e19..1d9d2b5 100644 --- a/test/stream/server/ready_test.rb +++ b/test/stream/server/ready_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class ServerReadyTest < MiniTest::Unit::TestCase STANZAS = [] diff --git a/test/token_bucket_test.rb b/test/token_bucket_test.rb index 0eea6c9..d6631d9 100644 --- a/test/token_bucket_test.rb +++ b/test/token_bucket_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class TokenBucketTest < MiniTest::Unit::TestCase def test_init diff --git a/test/user_test.rb b/test/user_test.rb index 7f1a020..80aceda 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -1,7 +1,6 @@ # encoding: UTF-8 -require 'vines' -require 'minitest/autorun' +require 'test_helper' class UserTest < MiniTest::Unit::TestCase def test_equality From 2de02ad4f035044107be738621929ff498fba931 Mon Sep 17 00:00:00 2001 From: David Graham Date: Fri, 21 Sep 2012 10:42:42 -0600 Subject: [PATCH 28/28] Convert to specs. --- test/stanza/iq/session_test.rb | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/test/stanza/iq/session_test.rb b/test/stanza/iq/session_test.rb index 6eabf71..785f22a 100644 --- a/test/stanza/iq/session_test.rb +++ b/test/stanza/iq/session_test.rb @@ -2,23 +2,24 @@ require 'test_helper' -class SessionTest < MiniTest::Unit::TestCase - def test_session - stream = MiniTest::Mock.new - stream.expect(:domain, 'wonderland.lit') - stream.expect(:user, Vines::User.new(jid: 'alice@wonderland.lit/tea')) - expected = node(%q{}) - stream.expect(:write, nil, [expected]) +describe Vines::Stanza::Iq::Session do + subject { Vines::Stanza::Iq::Session.new(xml, stream) } + let(:stream) { MiniTest::Mock.new } + let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') } - node = node(%q{}) - stanza = Vines::Stanza::Iq::Session.new(node, stream) - stanza.process - assert stream.verify - end + describe 'when session initiation is requested' do + let(:xml) { node(%q{}) } + let(:result) { node(%q{}) } - private + before do + stream.expect :domain, 'wonderland.lit' + stream.expect :user, alice + stream.expect :write, nil, [result] + end - def node(xml) - Nokogiri::XML(xml).root + it 'just returns a result to satisy older clients' do + subject.process + stream.verify + end end end