vines 0.4.5 → 0.4.6
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/Gemfile +3 -0
- data/README.md +48 -0
- data/Rakefile +6 -58
- data/bin/vines +12 -2
- data/conf/certs/ca-bundle.crt +568 -39
- data/conf/config.rb +9 -42
- data/lib/vines.rb +1 -8
- data/lib/vines/command/cert.rb +4 -4
- data/lib/vines/command/init.rb +3 -3
- data/lib/vines/config.rb +9 -0
- data/lib/vines/kit.rb +2 -7
- data/lib/vines/storage/local.rb +50 -17
- data/lib/vines/store.rb +6 -4
- data/lib/vines/stream.rb +1 -1
- data/lib/vines/stream/http/session.rb +0 -0
- data/lib/vines/stream/http/sessions.rb +0 -0
- data/lib/vines/stream/parser.rb +3 -2
- data/lib/vines/token_bucket.rb +19 -10
- data/lib/vines/version.rb +1 -1
- data/test/cluster/publisher_test.rb +45 -33
- data/test/cluster/sessions_test.rb +32 -39
- data/test/cluster/subscriber_test.rb +93 -78
- data/test/config/host_test.rb +2 -4
- data/test/config/pubsub_test.rb +132 -126
- data/test/config_test.rb +2 -4
- data/test/contact_test.rb +80 -66
- data/test/error_test.rb +54 -55
- data/test/jid_test.rb +1 -2
- data/test/kit_test.rb +22 -17
- data/test/router_test.rb +187 -146
- data/test/stanza/iq/disco_info_test.rb +59 -59
- data/test/stanza/iq/disco_items_test.rb +36 -34
- data/test/stanza/iq/private_storage_test.rb +138 -143
- data/test/stanza/iq/roster_test.rb +198 -175
- data/test/stanza/iq/session_test.rb +17 -18
- data/test/stanza/iq/vcard_test.rb +117 -116
- data/test/stanza/iq/version_test.rb +47 -46
- data/test/stanza/iq_test.rb +53 -49
- data/test/stanza/message_test.rb +92 -89
- data/test/stanza/presence/probe_test.rb +2 -5
- data/test/stanza/presence/subscribe_test.rb +67 -54
- data/test/stanza/pubsub/create_test.rb +86 -108
- data/test/stanza/pubsub/delete_test.rb +141 -114
- data/test/stanza/pubsub/publish_test.rb +256 -320
- data/test/stanza/pubsub/subscribe_test.rb +169 -150
- data/test/stanza/pubsub/unsubscribe_test.rb +111 -142
- data/test/stanza_test.rb +61 -54
- data/test/storage/ldap_test.rb +1 -2
- data/test/storage/local_test.rb +3 -5
- data/test/storage/null_test.rb +3 -4
- data/test/storage/storage_tests.rb +1 -3
- data/test/storage_test.rb +1 -2
- data/test/store_test.rb +1 -2
- data/test/stream/client/auth_test.rb +61 -63
- data/test/stream/client/ready_test.rb +7 -8
- data/test/stream/client/session_test.rb +19 -18
- data/test/stream/component/handshake_test.rb +40 -37
- data/test/stream/component/ready_test.rb +76 -61
- data/test/stream/component/start_test.rb +7 -8
- data/test/stream/http/auth_test.rb +3 -4
- data/test/stream/http/ready_test.rb +52 -60
- data/test/stream/http/request_test.rb +1 -3
- data/test/stream/http/sessions_test.rb +2 -3
- data/test/stream/http/start_test.rb +3 -4
- data/test/stream/parser_test.rb +3 -4
- data/test/stream/sasl_test.rb +105 -86
- data/test/stream/server/auth_test.rb +40 -36
- data/test/stream/server/outbound/auth_test.rb +3 -4
- data/test/stream/server/ready_test.rb +51 -51
- data/test/test_helper.rb +42 -0
- data/test/token_bucket_test.rb +38 -18
- data/test/user_test.rb +79 -49
- data/vines.gemspec +33 -0
- data/web/chat/javascripts/app.js +1 -1
- data/web/lib/coffeescripts/layout.coffee +1 -1
- data/web/lib/javascripts/base.js +10 -10
- data/web/lib/javascripts/jquery.js +4 -4
- metadata +31 -128
- data/README +0 -35
- data/lib/vines/storage/couchdb.rb +0 -129
- data/lib/vines/storage/mongodb.rb +0 -132
- data/lib/vines/storage/redis.rb +0 -127
- data/lib/vines/storage/sql.rb +0 -220
- data/test/rake_test_loader.rb +0 -17
- data/test/storage/couchdb_test.rb +0 -107
- data/test/storage/mock_mongo.rb +0 -40
- data/test/storage/mongodb_test.rb +0 -81
- data/test/storage/redis_test.rb +0 -51
- data/test/storage/sql_test.rb +0 -62
@@ -1,53 +1,46 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'ext/nokogiri'
|
3
|
+
require 'test_helper'
|
5
4
|
require 'storage/storage_tests'
|
6
5
|
require 'storage/mock_redis'
|
7
|
-
require 'minitest/autorun'
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
7
|
+
describe Vines::Cluster::Sessions do
|
8
|
+
subject { Vines::Cluster::Sessions.new(cluster) }
|
9
|
+
let(:connection) { MockRedis.new }
|
10
|
+
let(:cluster) { OpenStruct.new(id: 'abc', connection: connection) }
|
11
|
+
let(:jid1) { 'alice@wonderland.lit/tea' }
|
12
|
+
let(:jid2) { 'alice@wonderland.lit/cake' }
|
15
13
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
assert_equal session2.to_json, @connection.db["sessions:alice@wonderland.lit"]['cake']
|
30
|
-
assert_equal [jid1, jid2], @connection.db["cluster:nodes:abc"].to_a
|
31
|
-
assert @cluster.verify
|
14
|
+
describe 'when saving to the cluster' do
|
15
|
+
it 'writes to a redis hash' do
|
16
|
+
StorageTests::EMLoop.new do
|
17
|
+
subject.save(jid1, {available: true, interested: true})
|
18
|
+
subject.save(jid2, {available: false, interested: false})
|
19
|
+
EM.next_tick do
|
20
|
+
session1 = {node: 'abc', available: true, interested: true}
|
21
|
+
session2 = {node: 'abc', available: false, interested: false}
|
22
|
+
connection.db["sessions:alice@wonderland.lit"].size.must_equal 2
|
23
|
+
connection.db["sessions:alice@wonderland.lit"]['tea'].must_equal session1.to_json
|
24
|
+
connection.db["sessions:alice@wonderland.lit"]['cake'].must_equal session2.to_json
|
25
|
+
connection.db["cluster:nodes:abc"].to_a.must_equal [jid1, jid2]
|
26
|
+
end
|
32
27
|
end
|
33
28
|
end
|
34
29
|
end
|
35
30
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
@connection.db["cluster:nodes:abc"] = Set.new([jid1, jid2])
|
31
|
+
describe 'when deleting from the cluster' do
|
32
|
+
it 'removes from a redis hash' do
|
33
|
+
StorageTests::EMLoop.new do
|
34
|
+
connection.db["sessions:alice@wonderland.lit"] = {}
|
35
|
+
connection.db["sessions:alice@wonderland.lit"]['tea'] = {node: 'abc', available: true}.to_json
|
36
|
+
connection.db["sessions:alice@wonderland.lit"]['cake'] = {node: 'abc', available: true}.to_json
|
37
|
+
connection.db["cluster:nodes:abc"] = Set.new([jid1, jid2])
|
44
38
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
assert @cluster.verify
|
39
|
+
subject.delete(jid1)
|
40
|
+
EM.next_tick do
|
41
|
+
connection.db["sessions:alice@wonderland.lit"].size.must_equal 1
|
42
|
+
connection.db["cluster:nodes:abc"].to_a.must_equal [jid2]
|
43
|
+
end
|
51
44
|
end
|
52
45
|
end
|
53
46
|
end
|
@@ -1,94 +1,109 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'ext/nokogiri'
|
5
|
-
require 'minitest/autorun'
|
6
|
-
|
7
|
-
class ClusterSubscriberTest < MiniTest::Unit::TestCase
|
8
|
-
def setup
|
9
|
-
@connection = MiniTest::Mock.new
|
10
|
-
@cluster = MiniTest::Mock.new
|
11
|
-
@cluster.expect(:id, 'abc')
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_subscribe
|
15
|
-
@cluster.expect(:connect, @connection)
|
16
|
-
@connection.expect(:subscribe, nil, ['cluster:nodes:all'])
|
17
|
-
@connection.expect(:subscribe, nil, ['cluster:nodes:abc'])
|
18
|
-
@connection.expect(:on, nil, [:message])
|
19
|
-
subscriber = Vines::Cluster::Subscriber.new(@cluster)
|
20
|
-
subscriber.subscribe
|
21
|
-
assert @connection.verify
|
22
|
-
assert @cluster.verify
|
23
|
-
end
|
3
|
+
require 'test_helper'
|
24
4
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
5
|
+
describe Vines::Cluster::Subscriber do
|
6
|
+
subject { Vines::Cluster::Subscriber.new(cluster) }
|
7
|
+
let(:connection) { MiniTest::Mock.new }
|
8
|
+
let(:cluster) { MiniTest::Mock.new }
|
9
|
+
let(:now) { Time.now.to_i }
|
29
10
|
|
30
|
-
|
31
|
-
|
32
|
-
assert @connection.verify
|
33
|
-
assert @cluster.verify
|
11
|
+
before do
|
12
|
+
cluster.expect :id, 'abc'
|
34
13
|
end
|
35
14
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
15
|
+
describe '#subscribe' do
|
16
|
+
before do
|
17
|
+
cluster.expect :connect, connection
|
18
|
+
connection.expect :subscribe, nil, ['cluster:nodes:all']
|
19
|
+
connection.expect :subscribe, nil, ['cluster:nodes:abc']
|
20
|
+
connection.expect :on, nil, [:message]
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'subscribes to its own channel and the broadcast channel' do
|
24
|
+
subject.subscribe
|
25
|
+
connection.verify
|
26
|
+
cluster.verify
|
27
|
+
end
|
45
28
|
end
|
46
29
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
30
|
+
describe 'when receiving a heartbeat broadcast message' do
|
31
|
+
before do
|
32
|
+
cluster.expect :poke, nil, ['node-42', now]
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'pokes the session manager for the broadcasting node' do
|
36
|
+
msg = {from: 'node-42', type: 'heartbeat', time: now}.to_json
|
37
|
+
subject.send(:on_message, 'cluster:nodes:all', msg)
|
38
|
+
connection.verify
|
39
|
+
cluster.verify
|
40
|
+
end
|
56
41
|
end
|
57
42
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
assert stream.verify
|
70
|
-
assert @connection.verify
|
71
|
-
assert @cluster.verify
|
43
|
+
describe 'when receiving an initial online broadcast message' do
|
44
|
+
before do
|
45
|
+
cluster.expect :poke, nil, ['node-42', now]
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'pokes the session manager for the broadcasting node' do
|
49
|
+
msg = {from: 'node-42', type: 'online', time: now}.to_json
|
50
|
+
subject.send(:on_message, 'cluster:nodes:all', msg)
|
51
|
+
connection.verify
|
52
|
+
cluster.verify
|
53
|
+
end
|
72
54
|
end
|
73
55
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
56
|
+
describe 'when receiving an offline broadcast message' do
|
57
|
+
before do
|
58
|
+
cluster.expect :delete_sessions, nil, ['node-42']
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'deletes the sessions for the broadcasting node' do
|
62
|
+
msg = {from: 'node-42', type: 'offline', time: now}.to_json
|
63
|
+
subject.send(:on_message, 'cluster:nodes:all', msg)
|
64
|
+
connection.verify
|
65
|
+
cluster.verify
|
66
|
+
end
|
67
|
+
end
|
83
68
|
|
84
|
-
|
85
|
-
|
69
|
+
describe 'when receiving a stanza routed to my node' do
|
70
|
+
let(:stream) { MiniTest::Mock.new }
|
71
|
+
let(:stanza) { "<message to='alice@wonderland.lit/tea'>hello</message>" }
|
72
|
+
let(:xml) { Nokogiri::XML(stanza).root }
|
73
|
+
|
74
|
+
before do
|
75
|
+
stream.expect :write, nil, [xml]
|
76
|
+
cluster.expect :connected_resources, [stream], ['alice@wonderland.lit/tea']
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'writes the stanza to the connected user streams' do
|
80
|
+
msg = {from: 'node-42', type: 'stanza', stanza: stanza}.to_json
|
81
|
+
subject.send(:on_message, 'cluster:nodes:abc', msg)
|
82
|
+
stream.verify
|
83
|
+
connection.verify
|
84
|
+
cluster.verify
|
85
|
+
end
|
86
|
+
end
|
86
87
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
88
|
+
describe 'when receiving a user update message to my node' do
|
89
|
+
let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
|
90
|
+
let(:storage) { MiniTest::Mock.new }
|
91
|
+
let(:stream) { MiniTest::Mock.new }
|
92
|
+
|
93
|
+
before do
|
94
|
+
storage.expect :find_user, alice, [alice.jid.bare]
|
95
|
+
stream.expect :user, alice
|
96
|
+
cluster.expect :storage, storage, ['wonderland.lit']
|
97
|
+
cluster.expect :connected_resources, [stream], [alice.jid.bare]
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'reloads the user from storage and updates their connected streams' do
|
101
|
+
msg = {from: 'node-42', type: 'user', jid: alice.jid.to_s}.to_json
|
102
|
+
subject.send(:on_message, 'cluster:nodes:abc', msg)
|
103
|
+
storage.verify
|
104
|
+
stream.verify
|
105
|
+
connection.verify
|
106
|
+
cluster.verify
|
107
|
+
end
|
93
108
|
end
|
94
109
|
end
|
data/test/config/host_test.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'vines'
|
5
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
6
4
|
|
7
|
-
|
5
|
+
describe Vines::Config::Host do
|
8
6
|
def test_missing_storage
|
9
7
|
assert_raises(RuntimeError) do
|
10
8
|
Vines::Config.new do
|
data/test/config/pubsub_test.rb
CHANGED
@@ -1,181 +1,187 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'vines'
|
5
|
-
require 'ext/nokogiri'
|
6
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
7
4
|
|
8
|
-
|
9
|
-
|
5
|
+
describe Vines::Config::PubSub do
|
6
|
+
subject { config.pubsub('topics.wonderland.lit') }
|
7
|
+
let(:alice) { Vines::JID.new('alice@wonderland.lit') }
|
8
|
+
let(:romeo) { Vines::JID.new('romeo@verona.lit') }
|
9
|
+
let(:config) do
|
10
10
|
@config = Vines::Config.new do
|
11
11
|
host 'wonderland.lit' do
|
12
12
|
storage(:fs) { dir Dir.tmpdir }
|
13
13
|
pubsub 'topics'
|
14
14
|
end
|
15
15
|
end
|
16
|
-
@pubsub = @config.pubsub('topics.wonderland.lit')
|
17
16
|
end
|
18
17
|
|
19
|
-
|
18
|
+
it 'adds and deletes a topic node' do
|
20
19
|
topic = 'rhode_island_is_neither_a_road_nor_an_island'
|
21
|
-
refute
|
22
|
-
|
23
|
-
assert
|
24
|
-
|
25
|
-
refute
|
20
|
+
refute subject.node?(topic)
|
21
|
+
subject.add_node(topic)
|
22
|
+
assert subject.node?(topic)
|
23
|
+
subject.delete_node(topic)
|
24
|
+
refute subject.node?(topic)
|
26
25
|
end
|
27
26
|
|
28
|
-
|
27
|
+
it 'ignores deleting a missing topic node' do
|
29
28
|
topic = 'kittens_vs_puppies'
|
30
|
-
refute
|
31
|
-
|
32
|
-
refute
|
29
|
+
refute subject.node?(topic)
|
30
|
+
subject.delete_node(topic)
|
31
|
+
refute subject.node?(topic)
|
33
32
|
end
|
34
33
|
|
35
|
-
|
34
|
+
it 'subscribes a jid to a node' do
|
36
35
|
topic = 'with_jid'
|
37
36
|
jid = Vines::JID.new('alice@wonderland.lit')
|
38
|
-
|
39
|
-
|
40
|
-
assert
|
41
|
-
assert
|
37
|
+
subject.add_node(topic)
|
38
|
+
subject.subscribe(topic, jid)
|
39
|
+
assert subject.subscribed?(topic, jid.to_s)
|
40
|
+
assert subject.subscribed?(topic, jid)
|
42
41
|
end
|
43
42
|
|
44
|
-
|
43
|
+
it 'does not allow remote jids to subscribe to a node by default' do
|
45
44
|
topic = 'remote_jids_failed'
|
46
45
|
jid = 'romeo@verona.lit'
|
47
|
-
|
48
|
-
|
49
|
-
refute
|
46
|
+
subject.add_node(topic)
|
47
|
+
subject.subscribe(topic, jid)
|
48
|
+
refute subject.subscribed?(topic, jid)
|
50
49
|
end
|
51
50
|
|
52
|
-
|
51
|
+
it 'allows remote jid subscriptions when cross domain messages are enabled' do
|
53
52
|
topic = 'remote_jids_allowed'
|
54
53
|
jid = 'romeo@verona.lit'
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
assert
|
54
|
+
config.vhost('wonderland.lit').cross_domain_messages true
|
55
|
+
subject.add_node(topic)
|
56
|
+
subject.subscribe(topic, jid)
|
57
|
+
assert subject.subscribed?(topic, jid)
|
59
58
|
end
|
60
59
|
|
61
|
-
|
60
|
+
it 'ignores subscribing to a missing node' do
|
62
61
|
topic = 'bogus'
|
63
62
|
jid = 'alice@wonderland.lit'
|
64
|
-
refute
|
65
|
-
|
66
|
-
refute
|
67
|
-
refute
|
63
|
+
refute subject.node?(topic)
|
64
|
+
subject.subscribe(topic, jid)
|
65
|
+
refute subject.node?(topic)
|
66
|
+
refute subject.subscribed?(topic, jid)
|
68
67
|
end
|
69
68
|
|
70
|
-
|
69
|
+
it 'deletes the node after unsubscribing' do
|
71
70
|
topic = 'delete_me'
|
72
71
|
jid = 'alice@wonderland.lit/tea'
|
73
|
-
|
74
|
-
|
75
|
-
assert
|
76
|
-
|
77
|
-
refute
|
78
|
-
refute
|
72
|
+
subject.add_node(topic)
|
73
|
+
subject.subscribe(topic, jid)
|
74
|
+
assert subject.subscribed?(topic, jid)
|
75
|
+
subject.unsubscribe(topic, jid)
|
76
|
+
refute subject.subscribed?(topic, jid)
|
77
|
+
refute subject.node?(topic)
|
79
78
|
end
|
80
79
|
|
81
|
-
|
80
|
+
it 'unsubscribes a jid from all topics' do
|
82
81
|
topic = 'pirates_vs_ninjas'
|
83
82
|
topic2 = 'pirates_vs_ninjas_2'
|
84
83
|
jid = 'alice@wonderland.lit'
|
85
84
|
jid2 = 'hatter@wonderland.lit'
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
assert
|
93
|
-
assert
|
94
|
-
assert
|
95
|
-
|
96
|
-
|
97
|
-
refute
|
98
|
-
refute
|
99
|
-
refute
|
100
|
-
assert
|
85
|
+
subject.add_node(topic)
|
86
|
+
subject.add_node(topic2)
|
87
|
+
|
88
|
+
subject.subscribe(topic, jid)
|
89
|
+
subject.subscribe(topic, jid2)
|
90
|
+
subject.subscribe(topic2, jid)
|
91
|
+
assert subject.subscribed?(topic, jid)
|
92
|
+
assert subject.subscribed?(topic, jid2)
|
93
|
+
assert subject.subscribed?(topic2, jid)
|
94
|
+
|
95
|
+
subject.unsubscribe_all(jid)
|
96
|
+
refute subject.node?(topic2)
|
97
|
+
refute subject.subscribed?(topic, jid)
|
98
|
+
refute subject.subscribed?(topic2, jid)
|
99
|
+
assert subject.subscribed?(topic, jid2)
|
101
100
|
end
|
102
101
|
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
102
|
+
describe 'when publishing a message to a topic node' do
|
103
|
+
let(:xml) do
|
104
|
+
node(%q{
|
105
|
+
<iq type='set' to='topics.wonderland.lit'>
|
106
|
+
<pubsub xmlns='http://jabber.org/protocol/pubsub'>
|
107
|
+
<publish node='pirates_vs_ninjas'>
|
108
|
+
<item id='item_42'>
|
109
|
+
<entry xmlns='http://www.w3.org/2005/Atom'>
|
110
|
+
<title>Test</title>
|
111
|
+
<summary>This is a summary.</summary>
|
112
|
+
</entry>
|
113
|
+
</item>
|
114
|
+
</publish>
|
115
|
+
</pubsub>
|
116
|
+
</iq>})
|
117
|
+
end
|
118
|
+
|
119
|
+
let(:recipient) do
|
120
|
+
recipient = MiniTest::Mock.new
|
121
|
+
recipient.expect :user, Vines::User.new(jid: alice)
|
122
|
+
class << recipient
|
123
|
+
attr_accessor :nodes
|
124
|
+
def write(node)
|
114
125
|
@nodes ||= []
|
115
126
|
@nodes << node
|
116
127
|
end
|
117
128
|
end
|
118
|
-
|
129
|
+
recipient
|
119
130
|
end
|
120
131
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
assert recipient.verify
|
150
|
-
|
151
|
-
# id is random
|
152
|
-
refute_nil recipient.nodes[0]['id']
|
153
|
-
refute_nil @config.router.nodes[0]['id']
|
154
|
-
recipient.nodes[0].remove_attribute('id')
|
155
|
-
@config.router.nodes[0].remove_attribute('id')
|
156
|
-
|
157
|
-
expected['to'] = 'alice@wonderland.lit'
|
158
|
-
expected['from'] = 'topics.wonderland.lit'
|
159
|
-
assert_equal expected, recipient.nodes[0]
|
160
|
-
|
161
|
-
expected['to'] = 'romeo@verona.lit'
|
162
|
-
assert_equal expected, @config.router.nodes[0]
|
163
|
-
end
|
132
|
+
before do
|
133
|
+
router = MiniTest::Mock.new
|
134
|
+
router.expect :connected_resources, [recipient], [alice, 'topics.wonderland.lit']
|
135
|
+
class << router
|
136
|
+
attr_accessor :nodes
|
137
|
+
def route(node)
|
138
|
+
@nodes ||= []
|
139
|
+
@nodes << node
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
class << config
|
144
|
+
attr_accessor :router
|
145
|
+
end
|
146
|
+
config.router = router
|
147
|
+
config.vhost('wonderland.lit').cross_domain_messages true
|
148
|
+
|
149
|
+
subject.add_node(topic)
|
150
|
+
subject.subscribe(topic, alice)
|
151
|
+
subject.subscribe(topic, romeo)
|
152
|
+
end
|
153
|
+
|
154
|
+
let(:topic) { 'pirates_vs_ninjas' }
|
155
|
+
|
156
|
+
it 'writes the message to local connected resource streams' do
|
157
|
+
expected = xml.clone
|
158
|
+
expected['to'] = 'alice@wonderland.lit'
|
159
|
+
expected['from'] = 'topics.wonderland.lit'
|
164
160
|
|
165
|
-
|
161
|
+
subject.publish(topic, xml)
|
162
|
+
config.router.verify
|
163
|
+
recipient.verify
|
166
164
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
@nodes ||= []
|
173
|
-
@nodes << node
|
165
|
+
# id is random
|
166
|
+
received = recipient.nodes.first
|
167
|
+
received['id'].wont_be_nil
|
168
|
+
received.remove_attribute('id')
|
169
|
+
received.must_equal expected
|
174
170
|
end
|
175
|
-
recipient
|
176
|
-
end
|
177
171
|
|
178
|
-
|
179
|
-
|
172
|
+
it 'routes the message to remote jids' do
|
173
|
+
expected = xml.clone
|
174
|
+
expected['to'] = 'romeo@verona.lit'
|
175
|
+
expected['from'] = 'topics.wonderland.lit'
|
176
|
+
|
177
|
+
subject.publish(topic, xml)
|
178
|
+
config.router.verify
|
179
|
+
|
180
|
+
# id is random
|
181
|
+
routed = config.router.nodes.first
|
182
|
+
routed['id'].wont_be_nil
|
183
|
+
routed.remove_attribute('id')
|
184
|
+
routed.must_equal expected
|
185
|
+
end
|
180
186
|
end
|
181
187
|
end
|