vines 0.3.2 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +5 -9
- data/Rakefile +11 -9
- data/conf/config.rb +30 -4
- data/lib/vines/cluster/connection.rb +26 -0
- data/lib/vines/cluster/publisher.rb +55 -0
- data/lib/vines/cluster/pubsub.rb +92 -0
- data/lib/vines/cluster/sessions.rb +125 -0
- data/lib/vines/cluster/subscriber.rb +108 -0
- data/lib/vines/cluster.rb +246 -0
- data/lib/vines/command/init.rb +21 -24
- data/lib/vines/config/host.rb +48 -8
- data/lib/vines/config/port.rb +5 -0
- data/lib/vines/config/pubsub.rb +108 -0
- data/lib/vines/config.rb +74 -20
- data/lib/vines/jid.rb +14 -0
- data/lib/vines/router.rb +69 -55
- data/lib/vines/stanza/iq/disco_info.rb +22 -9
- data/lib/vines/stanza/iq/disco_items.rb +6 -3
- data/lib/vines/stanza/iq/ping.rb +1 -1
- data/lib/vines/stanza/iq/private_storage.rb +4 -8
- data/lib/vines/stanza/iq/roster.rb +6 -14
- data/lib/vines/stanza/iq/session.rb +2 -7
- data/lib/vines/stanza/iq/vcard.rb +4 -6
- data/lib/vines/stanza/iq/version.rb +1 -1
- data/lib/vines/stanza/iq.rb +8 -10
- data/lib/vines/stanza/presence/subscribe.rb +3 -11
- data/lib/vines/stanza/presence/subscribed.rb +16 -29
- data/lib/vines/stanza/presence/unsubscribe.rb +3 -15
- data/lib/vines/stanza/presence/unsubscribed.rb +3 -16
- data/lib/vines/stanza/presence.rb +30 -0
- data/lib/vines/stanza/pubsub/create.rb +39 -0
- data/lib/vines/stanza/pubsub/delete.rb +41 -0
- data/lib/vines/stanza/pubsub/publish.rb +66 -0
- data/lib/vines/stanza/pubsub/subscribe.rb +44 -0
- data/lib/vines/stanza/pubsub/unsubscribe.rb +30 -0
- data/lib/vines/stanza/pubsub.rb +22 -0
- data/lib/vines/stanza.rb +72 -22
- data/lib/vines/storage/couchdb.rb +46 -65
- data/lib/vines/storage/local.rb +20 -14
- data/lib/vines/storage/mongodb.rb +132 -0
- data/lib/vines/storage/null.rb +39 -0
- data/lib/vines/storage/redis.rb +61 -68
- data/lib/vines/storage/sql.rb +73 -69
- data/lib/vines/storage.rb +1 -1
- data/lib/vines/stream/client/bind.rb +2 -2
- data/lib/vines/stream/client/session.rb +71 -16
- data/lib/vines/stream/component/handshake.rb +1 -0
- data/lib/vines/stream/component/ready.rb +2 -2
- data/lib/vines/stream/http/session.rb +2 -0
- data/lib/vines/stream/http.rb +0 -6
- data/lib/vines/stream/server/final_restart.rb +1 -0
- data/lib/vines/stream/server/outbound/final_features.rb +1 -0
- data/lib/vines/stream/server/ready.rb +6 -2
- data/lib/vines/stream/server.rb +4 -3
- data/lib/vines/stream.rb +10 -6
- data/lib/vines/version.rb +1 -1
- data/lib/vines.rb +48 -22
- data/test/cluster/publisher_test.rb +45 -0
- data/test/cluster/sessions_test.rb +54 -0
- data/test/cluster/subscriber_test.rb +94 -0
- data/test/config/host_test.rb +100 -21
- data/test/config/pubsub_test.rb +181 -0
- data/test/config_test.rb +225 -43
- data/test/jid_test.rb +7 -0
- data/test/router_test.rb +181 -9
- data/test/stanza/iq/disco_info_test.rb +8 -6
- data/test/stanza/iq/disco_items_test.rb +3 -3
- data/test/stanza/iq/private_storage_test.rb +8 -19
- data/test/stanza/iq/roster_test.rb +1 -1
- data/test/stanza/iq/session_test.rb +3 -6
- data/test/stanza/iq/vcard_test.rb +6 -2
- data/test/stanza/iq/version_test.rb +3 -2
- data/test/stanza/iq_test.rb +5 -5
- data/test/stanza/message_test.rb +3 -2
- data/test/stanza/presence/probe_test.rb +2 -1
- data/test/stanza/pubsub/create_test.rb +138 -0
- data/test/stanza/pubsub/delete_test.rb +142 -0
- data/test/stanza/pubsub/publish_test.rb +373 -0
- data/test/stanza/pubsub/subscribe_test.rb +186 -0
- data/test/stanza/pubsub/unsubscribe_test.rb +179 -0
- data/test/stanza_test.rb +2 -1
- data/test/storage/local_test.rb +26 -25
- data/test/storage/mock_mongo.rb +40 -0
- data/test/storage/mock_redis.rb +98 -0
- data/test/storage/mongodb_test.rb +81 -0
- data/test/storage/null_test.rb +30 -0
- data/test/storage/redis_test.rb +3 -36
- data/test/stream/component/handshake_test.rb +4 -0
- data/test/stream/component/ready_test.rb +2 -1
- data/test/stream/server/ready_test.rb +7 -1
- data/web/404.html +5 -3
- data/web/chat/coffeescripts/chat.coffee +9 -5
- data/web/chat/javascripts/app.js +1 -1
- data/web/chat/javascripts/chat.js +14 -8
- data/web/chat/stylesheets/chat.css +4 -1
- data/web/lib/coffeescripts/button.coffee +9 -5
- data/web/lib/coffeescripts/filter.coffee +1 -1
- data/web/lib/coffeescripts/login.coffee +14 -1
- data/web/lib/coffeescripts/session.coffee +8 -11
- data/web/lib/images/dark-gray.png +0 -0
- data/web/lib/images/light-gray.png +0 -0
- data/web/lib/images/logo-large.png +0 -0
- data/web/lib/images/logo-small.png +0 -0
- data/web/lib/images/white.png +0 -0
- data/web/lib/javascripts/base.js +9 -8
- data/web/lib/javascripts/button.js +20 -12
- data/web/lib/javascripts/filter.js +1 -1
- data/web/lib/javascripts/icons.js +7 -1
- data/web/lib/javascripts/jquery.js +4 -4
- data/web/lib/javascripts/login.js +16 -2
- data/web/lib/javascripts/raphael.js +5 -7
- data/web/lib/javascripts/session.js +10 -14
- data/web/lib/stylesheets/base.css +7 -11
- data/web/lib/stylesheets/login.css +31 -27
- metadata +100 -34
@@ -0,0 +1,138 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'vines'
|
5
|
+
require 'ext/nokogiri'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
|
8
|
+
class CreatePubSubTest < MiniTest::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@user = Vines::User.new(jid: 'alice@wonderland.lit/tea')
|
11
|
+
@config = Vines::Config.new do
|
12
|
+
host 'wonderland.lit' do
|
13
|
+
storage(:fs) { dir Dir.tmpdir }
|
14
|
+
pubsub 'games'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@stream = MiniTest::Mock.new
|
18
|
+
@stream.expect(:config, @config)
|
19
|
+
@stream.expect(:user, @user)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_missing_to_address_raises
|
23
|
+
node = node(%q{
|
24
|
+
<iq type='set' id='42'>
|
25
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
26
|
+
<create node='game_13'/>
|
27
|
+
</pubsub>
|
28
|
+
</iq>
|
29
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
30
|
+
|
31
|
+
@stream.expect(:domain, 'wonderland.lit')
|
32
|
+
|
33
|
+
stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
|
34
|
+
assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
|
35
|
+
assert @stream.verify
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_server_domain_to_address_raises
|
39
|
+
node = node(%q{
|
40
|
+
<iq type='set' to='wonderland.lit' id='42'>
|
41
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
42
|
+
<create node='game_13'/>
|
43
|
+
</pubsub>
|
44
|
+
</iq>
|
45
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
46
|
+
|
47
|
+
stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
|
48
|
+
assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
|
49
|
+
assert @stream.verify
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_non_pubsub_to_address_routes
|
53
|
+
node = node(%q{
|
54
|
+
<iq type='set' to='bogus.wonderland.lit' id='42'>
|
55
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
56
|
+
<create node='game_13'/>
|
57
|
+
</pubsub>
|
58
|
+
</iq>
|
59
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
60
|
+
|
61
|
+
router = MiniTest::Mock.new
|
62
|
+
router.expect(:route, nil, [node])
|
63
|
+
@stream.expect(:router, router)
|
64
|
+
|
65
|
+
stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
|
66
|
+
stanza.process
|
67
|
+
assert @stream.verify
|
68
|
+
assert router.verify
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_multiple_create_elements_raises
|
72
|
+
node = node(%q{
|
73
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
74
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
75
|
+
<create node='game_13'/>
|
76
|
+
<create node='game_14'/>
|
77
|
+
</pubsub>
|
78
|
+
</iq>
|
79
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
80
|
+
|
81
|
+
stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
|
82
|
+
assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
|
83
|
+
assert @stream.verify
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_create_duplicate_node_raises
|
87
|
+
node = node(%q{
|
88
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
89
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
90
|
+
<create node='game_13'/>
|
91
|
+
</pubsub>
|
92
|
+
</iq>
|
93
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
94
|
+
|
95
|
+
stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
|
96
|
+
def stanza.pubsub
|
97
|
+
pubsub = MiniTest::Mock.new
|
98
|
+
pubsub.expect(:node?, true, ['game_13'])
|
99
|
+
pubsub
|
100
|
+
end
|
101
|
+
assert_raises(Vines::StanzaErrors::Conflict) { stanza.process }
|
102
|
+
assert @stream.verify
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_good_stanza_processes
|
106
|
+
node = node(%q{
|
107
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
108
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
109
|
+
<create node='game_13'/>
|
110
|
+
</pubsub>
|
111
|
+
</iq>
|
112
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
113
|
+
|
114
|
+
def @stream.nodes; @nodes; end
|
115
|
+
def @stream.write(node)
|
116
|
+
@nodes ||= []
|
117
|
+
@nodes << node
|
118
|
+
end
|
119
|
+
|
120
|
+
stanza = Vines::Stanza::PubSub::Create.new(node, @stream)
|
121
|
+
stanza.process
|
122
|
+
|
123
|
+
assert @stream.verify
|
124
|
+
assert_equal 1, @stream.nodes.size
|
125
|
+
|
126
|
+
expected = %q{<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">}
|
127
|
+
expected << %q{<pubsub xmlns="http://jabber.org/protocol/pubsub"><create node="game_13"/></pubsub>}
|
128
|
+
expected << %q{</iq>}
|
129
|
+
expected = node(expected)
|
130
|
+
assert_equal expected, @stream.nodes[0]
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
def node(xml)
|
136
|
+
Nokogiri::XML(xml).root
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'vines'
|
5
|
+
require 'ext/nokogiri'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
|
8
|
+
class DeletePubSubTest < MiniTest::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@user = Vines::User.new(jid: 'alice@wonderland.lit/tea')
|
11
|
+
@config = Vines::Config.new do
|
12
|
+
host 'wonderland.lit' do
|
13
|
+
storage(:fs) { dir Dir.tmpdir }
|
14
|
+
pubsub 'games'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@stream = MiniTest::Mock.new
|
18
|
+
@stream.expect(:config, @config)
|
19
|
+
@stream.expect(:user, @user)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_missing_to_address_raises
|
23
|
+
node = node(%q{
|
24
|
+
<iq type='set' id='42'>
|
25
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
26
|
+
<delete node='game_13'/>
|
27
|
+
</pubsub>
|
28
|
+
</iq>
|
29
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
30
|
+
|
31
|
+
@stream.expect(:domain, 'wonderland.lit')
|
32
|
+
|
33
|
+
stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
|
34
|
+
assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
|
35
|
+
assert @stream.verify
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_server_domain_to_address_raises
|
39
|
+
node = node(%q{
|
40
|
+
<iq type='set' to='wonderland.lit' id='42'>
|
41
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
42
|
+
<delete node='game_13'/>
|
43
|
+
</pubsub>
|
44
|
+
</iq>
|
45
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
46
|
+
|
47
|
+
stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
|
48
|
+
assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
|
49
|
+
assert @stream.verify
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_non_pubsub_to_address_routes
|
53
|
+
node = node(%q{
|
54
|
+
<iq type='set' to='bogus.wonderland.lit' id='42'>
|
55
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
56
|
+
<delete node='game_13'/>
|
57
|
+
</pubsub>
|
58
|
+
</iq>
|
59
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
60
|
+
|
61
|
+
router = MiniTest::Mock.new
|
62
|
+
router.expect(:route, nil, [node])
|
63
|
+
@stream.expect(:router, router)
|
64
|
+
|
65
|
+
stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
|
66
|
+
stanza.process
|
67
|
+
assert @stream.verify
|
68
|
+
assert router.verify
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_multiple_delete_elements_raises
|
72
|
+
node = node(%q{
|
73
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
74
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
75
|
+
<delete node='game_13'/>
|
76
|
+
<delete node='game_14'/>
|
77
|
+
</pubsub>
|
78
|
+
</iq>
|
79
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
80
|
+
|
81
|
+
stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
|
82
|
+
assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
|
83
|
+
assert @stream.verify
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_delete_missing_node_raises
|
87
|
+
node = node(%q{
|
88
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
89
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
90
|
+
<delete node='game_13'/>
|
91
|
+
</pubsub>
|
92
|
+
</iq>
|
93
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
94
|
+
|
95
|
+
stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
|
96
|
+
assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
|
97
|
+
assert @stream.verify
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_good_stanza_processes
|
101
|
+
node = node(%q{
|
102
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
103
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
104
|
+
<delete node='game_13'/>
|
105
|
+
</pubsub>
|
106
|
+
</iq>
|
107
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
108
|
+
|
109
|
+
def @stream.nodes; @nodes; end
|
110
|
+
def @stream.write(node)
|
111
|
+
@nodes ||= []
|
112
|
+
@nodes << node
|
113
|
+
end
|
114
|
+
|
115
|
+
stanza = Vines::Stanza::PubSub::Delete.new(node, @stream)
|
116
|
+
def stanza.mock_pubsub; @mock_pubsub; end
|
117
|
+
def stanza.pubsub
|
118
|
+
unless @mock_pubsub
|
119
|
+
xml = %q{<message><event xmlns="http://jabber.org/protocol/pubsub#event"><delete node="game_13"/></event></message>}
|
120
|
+
@mock_pubsub = MiniTest::Mock.new
|
121
|
+
@mock_pubsub.expect(:node?, true, ['game_13'])
|
122
|
+
@mock_pubsub.expect(:publish, nil, ['game_13', Nokogiri::XML(xml).root])
|
123
|
+
@mock_pubsub.expect(:delete_node, nil, ['game_13'])
|
124
|
+
end
|
125
|
+
@mock_pubsub
|
126
|
+
end
|
127
|
+
stanza.process
|
128
|
+
|
129
|
+
assert @stream.verify
|
130
|
+
assert stanza.mock_pubsub.verify
|
131
|
+
assert_equal 1, @stream.nodes.size
|
132
|
+
|
133
|
+
expected = node(%q{<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result"/>})
|
134
|
+
assert_equal expected, @stream.nodes[0]
|
135
|
+
end
|
136
|
+
|
137
|
+
private
|
138
|
+
|
139
|
+
def node(xml)
|
140
|
+
Nokogiri::XML(xml).root
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,373 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'tmpdir'
|
4
|
+
require 'vines'
|
5
|
+
require 'ext/nokogiri'
|
6
|
+
require 'minitest/autorun'
|
7
|
+
|
8
|
+
class PublishPubSubTest < MiniTest::Unit::TestCase
|
9
|
+
def setup
|
10
|
+
@user = Vines::User.new(jid: 'alice@wonderland.lit/tea')
|
11
|
+
@config = Vines::Config.new do
|
12
|
+
host 'wonderland.lit' do
|
13
|
+
storage(:fs) { dir Dir.tmpdir }
|
14
|
+
pubsub 'games'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@stream = MiniTest::Mock.new
|
18
|
+
@stream.expect(:config, @config)
|
19
|
+
@stream.expect(:user, @user)
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_missing_to_address_raises
|
23
|
+
node = node(%q{
|
24
|
+
<iq type='set' id='42'>
|
25
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
26
|
+
<publish node='game_13'>
|
27
|
+
<item id='item_42'>
|
28
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
29
|
+
<title>Test</title>
|
30
|
+
<summary>This is a summary.</summary>
|
31
|
+
</entry>
|
32
|
+
</item>
|
33
|
+
</publish>
|
34
|
+
</pubsub>
|
35
|
+
</iq>
|
36
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
37
|
+
|
38
|
+
@stream.expect(:domain, 'wonderland.lit')
|
39
|
+
|
40
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
41
|
+
assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
|
42
|
+
assert @stream.verify
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_server_domain_to_address_raises
|
46
|
+
node = node(%q{
|
47
|
+
<iq type='set' to='wonderland.lit' id='42'>
|
48
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
49
|
+
<publish node='game_13'>
|
50
|
+
<item id='item_42'>
|
51
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
52
|
+
<title>Test</title>
|
53
|
+
<summary>This is a summary.</summary>
|
54
|
+
</entry>
|
55
|
+
</item>
|
56
|
+
</publish>
|
57
|
+
</pubsub>
|
58
|
+
</iq>
|
59
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
60
|
+
|
61
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
62
|
+
assert_raises(Vines::StanzaErrors::FeatureNotImplemented) { stanza.process }
|
63
|
+
assert @stream.verify
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_non_pubsub_to_address_routes
|
67
|
+
node = node(%q{
|
68
|
+
<iq type='set' to='bogus.wonderland.lit' id='42'>
|
69
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
70
|
+
<publish node='game_13'>
|
71
|
+
<item id='item_42'>
|
72
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
73
|
+
<title>Test</title>
|
74
|
+
<summary>This is a summary.</summary>
|
75
|
+
</entry>
|
76
|
+
</item>
|
77
|
+
</publish>
|
78
|
+
</pubsub>
|
79
|
+
</iq>
|
80
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
81
|
+
|
82
|
+
router = MiniTest::Mock.new
|
83
|
+
router.expect(:route, nil, [node])
|
84
|
+
@stream.expect(:router, router)
|
85
|
+
|
86
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
87
|
+
stanza.process
|
88
|
+
assert @stream.verify
|
89
|
+
assert router.verify
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_multiple_publish_elements_raises
|
93
|
+
node = node(%q{
|
94
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
95
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
96
|
+
<publish node='game_13'>
|
97
|
+
<item id='item_42'>
|
98
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
99
|
+
<title>Test</title>
|
100
|
+
<summary>This is a summary.</summary>
|
101
|
+
</entry>
|
102
|
+
</item>
|
103
|
+
</publish>
|
104
|
+
<publish node='game_13'>
|
105
|
+
<item id='item_42'>
|
106
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
107
|
+
<title>Test</title>
|
108
|
+
<summary>This is a summary.</summary>
|
109
|
+
</entry>
|
110
|
+
</item>
|
111
|
+
</publish>
|
112
|
+
</pubsub>
|
113
|
+
</iq>
|
114
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
115
|
+
|
116
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
117
|
+
assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
|
118
|
+
assert @stream.verify
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_multiple_item_elements_raises
|
122
|
+
node = node(%q{
|
123
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
124
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
125
|
+
<publish node='game_13'>
|
126
|
+
<item id='item_42'>
|
127
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
128
|
+
<title>Test</title>
|
129
|
+
<summary>This is a summary.</summary>
|
130
|
+
</entry>
|
131
|
+
</item>
|
132
|
+
<item id="item_43">bad</item>
|
133
|
+
</publish>
|
134
|
+
</pubsub>
|
135
|
+
</iq>
|
136
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
137
|
+
|
138
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
139
|
+
def stanza.mock_pubsub; @mock_pubsub; end
|
140
|
+
def stanza.pubsub
|
141
|
+
unless @mock_pubsub
|
142
|
+
@mock_pubsub = MiniTest::Mock.new
|
143
|
+
@mock_pubsub.expect(:node?, true, ['game_13'])
|
144
|
+
end
|
145
|
+
@mock_pubsub
|
146
|
+
end
|
147
|
+
assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
|
148
|
+
assert @stream.verify
|
149
|
+
assert stanza.mock_pubsub.verify
|
150
|
+
end
|
151
|
+
|
152
|
+
def test_multiple_payload_elements_raises
|
153
|
+
node = node(%q{
|
154
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
155
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
156
|
+
<publish node='game_13'>
|
157
|
+
<item id='item_42'>
|
158
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
159
|
+
<title>Test</title>
|
160
|
+
<summary>This is a summary.</summary>
|
161
|
+
</entry>
|
162
|
+
<entry>bad</entry>
|
163
|
+
</item>
|
164
|
+
</publish>
|
165
|
+
</pubsub>
|
166
|
+
</iq>
|
167
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
168
|
+
|
169
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
170
|
+
def stanza.mock_pubsub; @mock_pubsub; end
|
171
|
+
def stanza.pubsub
|
172
|
+
unless @mock_pubsub
|
173
|
+
@mock_pubsub = MiniTest::Mock.new
|
174
|
+
@mock_pubsub.expect(:node?, true, ['game_13'])
|
175
|
+
end
|
176
|
+
@mock_pubsub
|
177
|
+
end
|
178
|
+
assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
|
179
|
+
assert @stream.verify
|
180
|
+
assert stanza.mock_pubsub.verify
|
181
|
+
end
|
182
|
+
|
183
|
+
def test_no_payload_elements_raises
|
184
|
+
node = node(%q{
|
185
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
186
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
187
|
+
<publish node='game_13'>
|
188
|
+
<item id='item_42'>
|
189
|
+
</item>
|
190
|
+
</publish>
|
191
|
+
</pubsub>
|
192
|
+
</iq>
|
193
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
194
|
+
|
195
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
196
|
+
def stanza.mock_pubsub; @mock_pubsub; end
|
197
|
+
def stanza.pubsub
|
198
|
+
unless @mock_pubsub
|
199
|
+
@mock_pubsub = MiniTest::Mock.new
|
200
|
+
@mock_pubsub.expect(:node?, true, ['game_13'])
|
201
|
+
end
|
202
|
+
@mock_pubsub
|
203
|
+
end
|
204
|
+
|
205
|
+
assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
|
206
|
+
assert @stream.verify
|
207
|
+
assert stanza.mock_pubsub.verify
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_publish_to_missing_node_raises
|
211
|
+
node = node(%q{
|
212
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
213
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
214
|
+
<publish node='game_13'>
|
215
|
+
<item id='item_42'>
|
216
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
217
|
+
<title>Test</title>
|
218
|
+
<summary>This is a summary.</summary>
|
219
|
+
</entry>
|
220
|
+
</item>
|
221
|
+
</publish>
|
222
|
+
</pubsub>
|
223
|
+
</iq>
|
224
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
225
|
+
|
226
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
227
|
+
assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
|
228
|
+
assert @stream.verify
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_generate_item_id
|
232
|
+
node = node(%q{
|
233
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
234
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
235
|
+
<publish node='game_13'>
|
236
|
+
<item>
|
237
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
238
|
+
<title>Test</title>
|
239
|
+
<summary>This is a summary.</summary>
|
240
|
+
</entry>
|
241
|
+
</item>
|
242
|
+
</publish>
|
243
|
+
</pubsub>
|
244
|
+
</iq>
|
245
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
246
|
+
|
247
|
+
def @stream.nodes; @nodes; end
|
248
|
+
def @stream.write(node)
|
249
|
+
@nodes ||= []
|
250
|
+
@nodes << node
|
251
|
+
end
|
252
|
+
|
253
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
254
|
+
def stanza.mock_pubsub; @mock_pubsub; end
|
255
|
+
def stanza.pubsub
|
256
|
+
unless @mock_pubsub
|
257
|
+
@mock_pubsub = MiniTest::Mock.new
|
258
|
+
@mock_pubsub.expect(:node?, true, ['game_13'])
|
259
|
+
def @mock_pubsub.published; @published; end
|
260
|
+
def @mock_pubsub.publish(node, message)
|
261
|
+
@published ||= []
|
262
|
+
@published << [node, message]
|
263
|
+
end
|
264
|
+
end
|
265
|
+
@mock_pubsub
|
266
|
+
end
|
267
|
+
stanza.process
|
268
|
+
|
269
|
+
assert @stream.verify
|
270
|
+
assert stanza.mock_pubsub.verify
|
271
|
+
assert_equal 1, @stream.nodes.size
|
272
|
+
|
273
|
+
# test result stanza contains generated item id
|
274
|
+
expected = node(%q{
|
275
|
+
<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
|
276
|
+
<pubsub xmlns="http://jabber.org/protocol/pubsub">
|
277
|
+
<publish node="game_13">
|
278
|
+
<item/>
|
279
|
+
</publish>
|
280
|
+
</pubsub>
|
281
|
+
</iq>}.strip.gsub(/\n|\s{2,}/, ''))
|
282
|
+
# id is random
|
283
|
+
item = @stream.nodes[0].xpath('ns:pubsub/ns:publish/ns:item', 'ns' => 'http://jabber.org/protocol/pubsub').first
|
284
|
+
refute_nil item['id']
|
285
|
+
item.remove_attribute('id')
|
286
|
+
assert_equal expected, @stream.nodes[0]
|
287
|
+
|
288
|
+
# test published message has a generated item id
|
289
|
+
expected = node(%q{
|
290
|
+
<message>
|
291
|
+
<event xmlns="http://jabber.org/protocol/pubsub#event">
|
292
|
+
<items node="game_13">
|
293
|
+
<item publisher="alice@wonderland.lit/tea">
|
294
|
+
<entry xmlns="http://www.w3.org/2005/Atom">
|
295
|
+
<title>Test</title>
|
296
|
+
<summary>This is a summary.</summary>
|
297
|
+
</entry>
|
298
|
+
</item>
|
299
|
+
</items>
|
300
|
+
</event>
|
301
|
+
</message>
|
302
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
303
|
+
published_node, published_message = *stanza.mock_pubsub.published[0]
|
304
|
+
assert_equal 'game_13', published_node
|
305
|
+
# id is random
|
306
|
+
item = published_message.xpath('ns:event/ns:items/ns:item', 'ns' => 'http://jabber.org/protocol/pubsub#event').first
|
307
|
+
refute_nil item['id']
|
308
|
+
item.remove_attribute('id')
|
309
|
+
assert_equal expected, published_message
|
310
|
+
end
|
311
|
+
|
312
|
+
def test_good_stanza_processes
|
313
|
+
node = node(%q{
|
314
|
+
<iq type='set' to='games.wonderland.lit' id='42'>
|
315
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
316
|
+
<publish node='game_13'>
|
317
|
+
<item id='item_42'>
|
318
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
319
|
+
<title>Test</title>
|
320
|
+
<summary>This is a summary.</summary>
|
321
|
+
</entry>
|
322
|
+
</item>
|
323
|
+
</publish>
|
324
|
+
</pubsub>
|
325
|
+
</iq>
|
326
|
+
}.strip.gsub(/\n|\s{2,}/, ''))
|
327
|
+
|
328
|
+
def @stream.nodes; @nodes; end
|
329
|
+
def @stream.write(node)
|
330
|
+
@nodes ||= []
|
331
|
+
@nodes << node
|
332
|
+
end
|
333
|
+
|
334
|
+
stanza = Vines::Stanza::PubSub::Publish.new(node, @stream)
|
335
|
+
def stanza.mock_pubsub; @mock_pubsub; end
|
336
|
+
def stanza.pubsub
|
337
|
+
unless @mock_pubsub
|
338
|
+
xml = %q{
|
339
|
+
<message>
|
340
|
+
<event xmlns="http://jabber.org/protocol/pubsub#event">
|
341
|
+
<items node="game_13">
|
342
|
+
<item id="item_42" publisher="alice@wonderland.lit/tea">
|
343
|
+
<entry xmlns="http://www.w3.org/2005/Atom">
|
344
|
+
<title>Test</title>
|
345
|
+
<summary>This is a summary.</summary>
|
346
|
+
</entry>
|
347
|
+
</item>
|
348
|
+
</items>
|
349
|
+
</event>
|
350
|
+
</message>
|
351
|
+
}.strip.gsub(/\n|\s{2,}/, '')
|
352
|
+
@mock_pubsub = MiniTest::Mock.new
|
353
|
+
@mock_pubsub.expect(:node?, true, ['game_13'])
|
354
|
+
@mock_pubsub.expect(:publish, nil, ['game_13', Nokogiri::XML(xml).root])
|
355
|
+
end
|
356
|
+
@mock_pubsub
|
357
|
+
end
|
358
|
+
stanza.process
|
359
|
+
|
360
|
+
assert @stream.verify
|
361
|
+
assert stanza.mock_pubsub.verify
|
362
|
+
assert_equal 1, @stream.nodes.size
|
363
|
+
|
364
|
+
expected = node(%q{<iq from="games.wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result"/>})
|
365
|
+
assert_equal expected, @stream.nodes[0]
|
366
|
+
end
|
367
|
+
|
368
|
+
private
|
369
|
+
|
370
|
+
def node(xml)
|
371
|
+
Nokogiri::XML(xml).root
|
372
|
+
end
|
373
|
+
end
|