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.
Files changed (115) hide show
  1. data/README +5 -9
  2. data/Rakefile +11 -9
  3. data/conf/config.rb +30 -4
  4. data/lib/vines/cluster/connection.rb +26 -0
  5. data/lib/vines/cluster/publisher.rb +55 -0
  6. data/lib/vines/cluster/pubsub.rb +92 -0
  7. data/lib/vines/cluster/sessions.rb +125 -0
  8. data/lib/vines/cluster/subscriber.rb +108 -0
  9. data/lib/vines/cluster.rb +246 -0
  10. data/lib/vines/command/init.rb +21 -24
  11. data/lib/vines/config/host.rb +48 -8
  12. data/lib/vines/config/port.rb +5 -0
  13. data/lib/vines/config/pubsub.rb +108 -0
  14. data/lib/vines/config.rb +74 -20
  15. data/lib/vines/jid.rb +14 -0
  16. data/lib/vines/router.rb +69 -55
  17. data/lib/vines/stanza/iq/disco_info.rb +22 -9
  18. data/lib/vines/stanza/iq/disco_items.rb +6 -3
  19. data/lib/vines/stanza/iq/ping.rb +1 -1
  20. data/lib/vines/stanza/iq/private_storage.rb +4 -8
  21. data/lib/vines/stanza/iq/roster.rb +6 -14
  22. data/lib/vines/stanza/iq/session.rb +2 -7
  23. data/lib/vines/stanza/iq/vcard.rb +4 -6
  24. data/lib/vines/stanza/iq/version.rb +1 -1
  25. data/lib/vines/stanza/iq.rb +8 -10
  26. data/lib/vines/stanza/presence/subscribe.rb +3 -11
  27. data/lib/vines/stanza/presence/subscribed.rb +16 -29
  28. data/lib/vines/stanza/presence/unsubscribe.rb +3 -15
  29. data/lib/vines/stanza/presence/unsubscribed.rb +3 -16
  30. data/lib/vines/stanza/presence.rb +30 -0
  31. data/lib/vines/stanza/pubsub/create.rb +39 -0
  32. data/lib/vines/stanza/pubsub/delete.rb +41 -0
  33. data/lib/vines/stanza/pubsub/publish.rb +66 -0
  34. data/lib/vines/stanza/pubsub/subscribe.rb +44 -0
  35. data/lib/vines/stanza/pubsub/unsubscribe.rb +30 -0
  36. data/lib/vines/stanza/pubsub.rb +22 -0
  37. data/lib/vines/stanza.rb +72 -22
  38. data/lib/vines/storage/couchdb.rb +46 -65
  39. data/lib/vines/storage/local.rb +20 -14
  40. data/lib/vines/storage/mongodb.rb +132 -0
  41. data/lib/vines/storage/null.rb +39 -0
  42. data/lib/vines/storage/redis.rb +61 -68
  43. data/lib/vines/storage/sql.rb +73 -69
  44. data/lib/vines/storage.rb +1 -1
  45. data/lib/vines/stream/client/bind.rb +2 -2
  46. data/lib/vines/stream/client/session.rb +71 -16
  47. data/lib/vines/stream/component/handshake.rb +1 -0
  48. data/lib/vines/stream/component/ready.rb +2 -2
  49. data/lib/vines/stream/http/session.rb +2 -0
  50. data/lib/vines/stream/http.rb +0 -6
  51. data/lib/vines/stream/server/final_restart.rb +1 -0
  52. data/lib/vines/stream/server/outbound/final_features.rb +1 -0
  53. data/lib/vines/stream/server/ready.rb +6 -2
  54. data/lib/vines/stream/server.rb +4 -3
  55. data/lib/vines/stream.rb +10 -6
  56. data/lib/vines/version.rb +1 -1
  57. data/lib/vines.rb +48 -22
  58. data/test/cluster/publisher_test.rb +45 -0
  59. data/test/cluster/sessions_test.rb +54 -0
  60. data/test/cluster/subscriber_test.rb +94 -0
  61. data/test/config/host_test.rb +100 -21
  62. data/test/config/pubsub_test.rb +181 -0
  63. data/test/config_test.rb +225 -43
  64. data/test/jid_test.rb +7 -0
  65. data/test/router_test.rb +181 -9
  66. data/test/stanza/iq/disco_info_test.rb +8 -6
  67. data/test/stanza/iq/disco_items_test.rb +3 -3
  68. data/test/stanza/iq/private_storage_test.rb +8 -19
  69. data/test/stanza/iq/roster_test.rb +1 -1
  70. data/test/stanza/iq/session_test.rb +3 -6
  71. data/test/stanza/iq/vcard_test.rb +6 -2
  72. data/test/stanza/iq/version_test.rb +3 -2
  73. data/test/stanza/iq_test.rb +5 -5
  74. data/test/stanza/message_test.rb +3 -2
  75. data/test/stanza/presence/probe_test.rb +2 -1
  76. data/test/stanza/pubsub/create_test.rb +138 -0
  77. data/test/stanza/pubsub/delete_test.rb +142 -0
  78. data/test/stanza/pubsub/publish_test.rb +373 -0
  79. data/test/stanza/pubsub/subscribe_test.rb +186 -0
  80. data/test/stanza/pubsub/unsubscribe_test.rb +179 -0
  81. data/test/stanza_test.rb +2 -1
  82. data/test/storage/local_test.rb +26 -25
  83. data/test/storage/mock_mongo.rb +40 -0
  84. data/test/storage/mock_redis.rb +98 -0
  85. data/test/storage/mongodb_test.rb +81 -0
  86. data/test/storage/null_test.rb +30 -0
  87. data/test/storage/redis_test.rb +3 -36
  88. data/test/stream/component/handshake_test.rb +4 -0
  89. data/test/stream/component/ready_test.rb +2 -1
  90. data/test/stream/server/ready_test.rb +7 -1
  91. data/web/404.html +5 -3
  92. data/web/chat/coffeescripts/chat.coffee +9 -5
  93. data/web/chat/javascripts/app.js +1 -1
  94. data/web/chat/javascripts/chat.js +14 -8
  95. data/web/chat/stylesheets/chat.css +4 -1
  96. data/web/lib/coffeescripts/button.coffee +9 -5
  97. data/web/lib/coffeescripts/filter.coffee +1 -1
  98. data/web/lib/coffeescripts/login.coffee +14 -1
  99. data/web/lib/coffeescripts/session.coffee +8 -11
  100. data/web/lib/images/dark-gray.png +0 -0
  101. data/web/lib/images/light-gray.png +0 -0
  102. data/web/lib/images/logo-large.png +0 -0
  103. data/web/lib/images/logo-small.png +0 -0
  104. data/web/lib/images/white.png +0 -0
  105. data/web/lib/javascripts/base.js +9 -8
  106. data/web/lib/javascripts/button.js +20 -12
  107. data/web/lib/javascripts/filter.js +1 -1
  108. data/web/lib/javascripts/icons.js +7 -1
  109. data/web/lib/javascripts/jquery.js +4 -4
  110. data/web/lib/javascripts/login.js +16 -2
  111. data/web/lib/javascripts/raphael.js +5 -7
  112. data/web/lib/javascripts/session.js +10 -14
  113. data/web/lib/stylesheets/base.css +7 -11
  114. data/web/lib/stylesheets/login.css +31 -27
  115. metadata +100 -34
data/lib/vines.rb CHANGED
@@ -2,26 +2,34 @@
2
2
 
3
3
  module Vines
4
4
  NAMESPACES = {
5
- :stream => 'http://etherx.jabber.org/streams'.freeze,
6
- :client => 'jabber:client'.freeze,
7
- :server => 'jabber:server'.freeze,
8
- :component => 'jabber:component:accept'.freeze,
9
- :roster => 'jabber:iq:roster'.freeze,
10
- :non_sasl => 'jabber:iq:auth'.freeze,
11
- :storage => 'jabber:iq:private'.freeze,
12
- :version => 'jabber:iq:version'.freeze,
13
- :sasl => 'urn:ietf:params:xml:ns:xmpp-sasl'.freeze,
14
- :tls => 'urn:ietf:params:xml:ns:xmpp-tls'.freeze,
15
- :bind => 'urn:ietf:params:xml:ns:xmpp-bind'.freeze,
16
- :session => 'urn:ietf:params:xml:ns:xmpp-session'.freeze,
17
- :ping => 'urn:xmpp:ping'.freeze,
18
- :disco_items => 'http://jabber.org/protocol/disco#items'.freeze,
19
- :disco_info => 'http://jabber.org/protocol/disco#info'.freeze,
20
- :http_bind => 'http://jabber.org/protocol/httpbind'.freeze,
21
- :bosh => 'urn:xmpp:xbosh'.freeze,
22
- :vcard => 'vcard-temp'.freeze,
23
- :si => 'http://jabber.org/protocol/si'.freeze,
24
- :byte_streams => 'http://jabber.org/protocol/bytestreams'.freeze
5
+ :stream => 'http://etherx.jabber.org/streams'.freeze,
6
+ :client => 'jabber:client'.freeze,
7
+ :server => 'jabber:server'.freeze,
8
+ :component => 'jabber:component:accept'.freeze,
9
+ :roster => 'jabber:iq:roster'.freeze,
10
+ :non_sasl => 'jabber:iq:auth'.freeze,
11
+ :storage => 'jabber:iq:private'.freeze,
12
+ :version => 'jabber:iq:version'.freeze,
13
+ :sasl => 'urn:ietf:params:xml:ns:xmpp-sasl'.freeze,
14
+ :tls => 'urn:ietf:params:xml:ns:xmpp-tls'.freeze,
15
+ :bind => 'urn:ietf:params:xml:ns:xmpp-bind'.freeze,
16
+ :session => 'urn:ietf:params:xml:ns:xmpp-session'.freeze,
17
+ :ping => 'urn:xmpp:ping'.freeze,
18
+ :pubsub => 'http://jabber.org/protocol/pubsub'.freeze,
19
+ :pubsub_event => 'http://jabber.org/protocol/pubsub#event'.freeze,
20
+ :pubsub_create => 'http://jabber.org/protocol/pubsub#create-nodes'.freeze,
21
+ :pubsub_delete => 'http://jabber.org/protocol/pubsub#delete-nodes'.freeze,
22
+ :pubsub_instant => 'http://jabber.org/protocol/pubsub#instant-nodes'.freeze,
23
+ :pubsub_item_ids => 'http://jabber.org/protocol/pubsub#item-ids'.freeze,
24
+ :pubsub_publish => 'http://jabber.org/protocol/pubsub#publish'.freeze,
25
+ :pubsub_subscribe => 'http://jabber.org/protocol/pubsub#subscribe'.freeze,
26
+ :disco_items => 'http://jabber.org/protocol/disco#items'.freeze,
27
+ :disco_info => 'http://jabber.org/protocol/disco#info'.freeze,
28
+ :http_bind => 'http://jabber.org/protocol/httpbind'.freeze,
29
+ :bosh => 'urn:xmpp:xbosh'.freeze,
30
+ :vcard => 'vcard-temp'.freeze,
31
+ :si => 'http://jabber.org/protocol/si'.freeze,
32
+ :byte_streams => 'http://jabber.org/protocol/bytestreams'.freeze
25
33
  }.freeze
26
34
 
27
35
  module Log
@@ -47,21 +55,23 @@ module Vines
47
55
  end
48
56
 
49
57
  %w[
50
- resolv-replace
51
58
  active_record
52
59
  base64
53
60
  bcrypt
54
61
  digest/sha1
55
62
  em-http
56
- em-redis
63
+ em-hiredis
57
64
  eventmachine
58
65
  fiber
59
66
  fileutils
60
67
  http/parser
61
68
  logger
69
+ mongo
62
70
  net/ldap
63
71
  nokogiri
64
72
  openssl
73
+ resolv
74
+ set
65
75
  socket
66
76
  uri
67
77
  yaml
@@ -92,17 +102,26 @@ end
92
102
  vines/stanza/presence/unavailable
93
103
  vines/stanza/presence/unsubscribe
94
104
  vines/stanza/presence/unsubscribed
105
+ vines/stanza/pubsub
106
+ vines/stanza/pubsub/create
107
+ vines/stanza/pubsub/delete
108
+ vines/stanza/pubsub/publish
109
+ vines/stanza/pubsub/subscribe
110
+ vines/stanza/pubsub/unsubscribe
95
111
 
96
112
  vines/storage
97
113
  vines/storage/couchdb
98
114
  vines/storage/ldap
99
115
  vines/storage/local
116
+ vines/storage/mongodb
117
+ vines/storage/null
100
118
  vines/storage/redis
101
119
  vines/storage/sql
102
120
 
103
121
  vines/config
104
122
  vines/config/host
105
123
  vines/config/port
124
+ vines/config/pubsub
106
125
 
107
126
  vines/store
108
127
  vines/contact
@@ -115,6 +134,13 @@ end
115
134
  vines/version
116
135
  vines/xmpp_server
117
136
 
137
+ vines/cluster
138
+ vines/cluster/connection
139
+ vines/cluster/publisher
140
+ vines/cluster/pubsub
141
+ vines/cluster/sessions
142
+ vines/cluster/subscriber
143
+
118
144
  vines/stream
119
145
  vines/stream/state
120
146
  vines/stream/parser
@@ -0,0 +1,45 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'vines'
4
+ require 'minitest/autorun'
5
+
6
+ class ClusterPublisherTest < MiniTest::Unit::TestCase
7
+ def setup
8
+ @connection = MiniTest::Mock.new
9
+ @cluster = MiniTest::Mock.new
10
+ @cluster.expect(:id, 'abc')
11
+ @cluster.expect(:connection, @connection)
12
+ end
13
+
14
+ def test_broadcast
15
+ msg = {from: 'abc', type: 'online', time: Time.now.to_i}.to_json
16
+ @connection.expect(:publish, nil, ["cluster:nodes:all", msg])
17
+
18
+ publisher = Vines::Cluster::Publisher.new(@cluster)
19
+ publisher.broadcast(:online)
20
+ assert @connection.verify
21
+ assert @cluster.verify
22
+ end
23
+
24
+ def test_route
25
+ stanza = "<message>hello</message>"
26
+ msg = {from: 'abc', type: 'stanza', stanza: stanza}.to_json
27
+ @connection.expect(:publish, nil, ["cluster:nodes:node-42", msg])
28
+
29
+ publisher = Vines::Cluster::Publisher.new(@cluster)
30
+ publisher.route(stanza, "node-42")
31
+ assert @connection.verify
32
+ assert @cluster.verify
33
+ end
34
+
35
+ def test_update_user
36
+ jid = Vines::JID.new('alice@wonderland.lit')
37
+ msg = {from: 'abc', type: 'user', jid: jid.to_s}.to_json
38
+ @connection.expect(:publish, nil, ["cluster:nodes:node-42", msg])
39
+
40
+ publisher = Vines::Cluster::Publisher.new(@cluster)
41
+ publisher.update_user(jid, "node-42")
42
+ assert @connection.verify
43
+ assert @cluster.verify
44
+ end
45
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'vines'
4
+ require 'ext/nokogiri'
5
+ require 'storage/storage_tests'
6
+ require 'storage/mock_redis'
7
+ require 'minitest/autorun'
8
+
9
+ class ClusterSessionsTest < MiniTest::Unit::TestCase
10
+ def setup
11
+ @connection = MockRedis.new
12
+ @cluster = MiniTest::Mock.new
13
+ @cluster.expect(:connection, @connection)
14
+ end
15
+
16
+ def test_save
17
+ StorageTests::EMLoop.new do
18
+ @cluster.expect(:id, 'abc')
19
+ jid1 = 'alice@wonderland.lit/tea'
20
+ jid2 = 'alice@wonderland.lit/cake'
21
+ sessions = Vines::Cluster::Sessions.new(@cluster)
22
+ sessions.save(jid1, {available: true, interested: true})
23
+ sessions.save(jid2, {available: false, interested: false})
24
+ EM.next_tick do
25
+ session1 = {node: 'abc', available: true, interested: true}
26
+ session2 = {node: 'abc', available: false, interested: false}
27
+ assert_equal 2, @connection.db["sessions:alice@wonderland.lit"].size
28
+ assert_equal session1.to_json, @connection.db["sessions:alice@wonderland.lit"]['tea']
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
32
+ end
33
+ end
34
+ end
35
+
36
+ def test_delete
37
+ StorageTests::EMLoop.new do
38
+ jid1 = 'alice@wonderland.lit/tea'
39
+ jid2 = 'alice@wonderland.lit/cake'
40
+ @connection.db["sessions:alice@wonderland.lit"] = {}
41
+ @connection.db["sessions:alice@wonderland.lit"]['tea'] = {node: 'abc', available: true}.to_json
42
+ @connection.db["sessions:alice@wonderland.lit"]['cake'] = {node: 'abc', available: true}.to_json
43
+ @connection.db["cluster:nodes:abc"] = Set.new([jid1, jid2])
44
+
45
+ sessions = Vines::Cluster::Sessions.new(@cluster)
46
+ sessions.delete(jid1)
47
+ EM.next_tick do
48
+ assert_equal 1, @connection.db["sessions:alice@wonderland.lit"].size
49
+ assert_equal [jid2], @connection.db["cluster:nodes:abc"].to_a
50
+ assert @cluster.verify
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,94 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'vines'
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
24
+
25
+ def test_heartbeat
26
+ now = Time.now.to_i
27
+ msg = {from: 'node-42', type: 'heartbeat', time: now}.to_json
28
+ @cluster.expect(:poke, nil, ['node-42', now])
29
+
30
+ subscriber = Vines::Cluster::Subscriber.new(@cluster)
31
+ subscriber.send(:on_message, 'cluster:nodes:all', msg)
32
+ assert @connection.verify
33
+ assert @cluster.verify
34
+ end
35
+
36
+ def test_online
37
+ now = Time.now.to_i
38
+ msg = {from: 'node-42', type: 'online', time: now}.to_json
39
+ @cluster.expect(:poke, nil, ['node-42', now])
40
+
41
+ subscriber = Vines::Cluster::Subscriber.new(@cluster)
42
+ subscriber.send(:on_message, 'cluster:nodes:all', msg)
43
+ assert @connection.verify
44
+ assert @cluster.verify
45
+ end
46
+
47
+ def test_offline
48
+ now = Time.now.to_i
49
+ msg = {from: 'node-42', type: 'offline', time: now}.to_json
50
+ @cluster.expect(:delete_sessions, nil, ['node-42'])
51
+
52
+ subscriber = Vines::Cluster::Subscriber.new(@cluster)
53
+ subscriber.send(:on_message, 'cluster:nodes:all', msg)
54
+ assert @connection.verify
55
+ assert @cluster.verify
56
+ end
57
+
58
+ def test_route_stanza
59
+ stanza = "<message to='alice@wonderland.lit/tea'>hello</message>"
60
+ node = Nokogiri::XML(stanza).root rescue nil
61
+ msg = {from: 'node-42', type: 'stanza', stanza: stanza}.to_json
62
+
63
+ stream = MiniTest::Mock.new
64
+ stream.expect(:write, nil, [node])
65
+ @cluster.expect(:connected_resources, [stream], ['alice@wonderland.lit/tea'])
66
+
67
+ subscriber = Vines::Cluster::Subscriber.new(@cluster)
68
+ subscriber.send(:on_message, 'cluster:nodes:abc', msg)
69
+ assert stream.verify
70
+ assert @connection.verify
71
+ assert @cluster.verify
72
+ end
73
+
74
+ def test_update_user
75
+ alice = Vines::User.new(jid: 'alice@wonderland.lit/tea')
76
+ msg = {from: 'node-42', type: 'user', jid: alice.jid.to_s}.to_json
77
+
78
+ storage = MiniTest::Mock.new
79
+ storage.expect(:find_user, alice, [alice.jid.bare])
80
+
81
+ stream = MiniTest::Mock.new
82
+ stream.expect(:user, alice)
83
+
84
+ @cluster.expect(:storage, storage, ['wonderland.lit'])
85
+ @cluster.expect(:connected_resources, [stream], [alice.jid.bare])
86
+
87
+ subscriber = Vines::Cluster::Subscriber.new(@cluster)
88
+ subscriber.send(:on_message, 'cluster:nodes:abc', msg)
89
+ assert storage.verify
90
+ assert stream.verify
91
+ assert @connection.verify
92
+ assert @cluster.verify
93
+ end
94
+ end
@@ -1,5 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
+ require 'tmpdir'
3
4
  require 'vines'
4
5
  require 'minitest/autorun'
5
6
 
@@ -30,8 +31,8 @@ class HostTest < MiniTest::Unit::TestCase
30
31
  assert_raises(RuntimeError) do
31
32
  Vines::Config.new do
32
33
  host 'wonderland.lit' do
33
- storage('fs') { dir '.' }
34
- storage('fs') { dir '.' }
34
+ storage('fs') { dir Dir.tmpdir }
35
+ storage('fs') { dir Dir.tmpdir }
35
36
  end
36
37
  end
37
38
  end
@@ -41,7 +42,7 @@ class HostTest < MiniTest::Unit::TestCase
41
42
  config = Vines::Config.new do
42
43
  host 'wonderland.lit' do
43
44
  storage 'fs' do
44
- dir '.'
45
+ dir Dir.tmpdir
45
46
  end
46
47
  end
47
48
  end
@@ -51,7 +52,7 @@ class HostTest < MiniTest::Unit::TestCase
51
52
  def test_ldap_added_to_storage
52
53
  config = Vines::Config.new do
53
54
  host 'wonderland.lit' do
54
- storage(:fs) { dir '.' }
55
+ storage(:fs) { dir Dir.tmpdir }
55
56
  # added after storage
56
57
  ldap 'ldap.wonderland.lit', 1636 do
57
58
  tls true
@@ -76,7 +77,7 @@ class HostTest < MiniTest::Unit::TestCase
76
77
  name_attr 'cn'
77
78
  end
78
79
  # added before storage
79
- storage(:fs) { dir '.' }
80
+ storage(:fs) { dir Dir.tmpdir }
80
81
  end
81
82
  end
82
83
  %w[wonderland.lit verona.lit].each do |domain|
@@ -89,7 +90,7 @@ class HostTest < MiniTest::Unit::TestCase
89
90
  assert_raises(RuntimeError) do
90
91
  Vines::Config.new do
91
92
  host 'wonderland.lit' do
92
- storage(:fs) { dir '.' }
93
+ storage(:fs) { dir Dir.tmpdir }
93
94
  components '' => 'secr3t'
94
95
  end
95
96
  end
@@ -100,7 +101,7 @@ class HostTest < MiniTest::Unit::TestCase
100
101
  assert_raises(RuntimeError) do
101
102
  Vines::Config.new do
102
103
  host 'wonderland.lit' do
103
- storage(:fs) { dir '.' }
104
+ storage(:fs) { dir Dir.tmpdir }
104
105
  components nil => 'secr3t'
105
106
  end
106
107
  end
@@ -111,7 +112,7 @@ class HostTest < MiniTest::Unit::TestCase
111
112
  assert_raises(RuntimeError) do
112
113
  Vines::Config.new do
113
114
  host 'wonderland.lit' do
114
- storage(:fs) { dir '.' }
115
+ storage(:fs) { dir Dir.tmpdir }
115
116
  components 'tea' => ''
116
117
  end
117
118
  end
@@ -122,7 +123,7 @@ class HostTest < MiniTest::Unit::TestCase
122
123
  assert_raises(RuntimeError) do
123
124
  Vines::Config.new do
124
125
  host 'wonderland.lit' do
125
- storage(:fs) { dir '.' }
126
+ storage(:fs) { dir Dir.tmpdir }
126
127
  components 'tea' => nil
127
128
  end
128
129
  end
@@ -133,7 +134,7 @@ class HostTest < MiniTest::Unit::TestCase
133
134
  assert_raises(RuntimeError) do
134
135
  Vines::Config.new do
135
136
  host 'wonderland.lit' do
136
- storage(:fs) { dir '.' }
137
+ storage(:fs) { dir Dir.tmpdir }
137
138
  components 'tea' => 'one'
138
139
  components 'TEA' => 'two'
139
140
  end
@@ -145,7 +146,7 @@ class HostTest < MiniTest::Unit::TestCase
145
146
  assert_raises(RuntimeError) do
146
147
  Vines::Config.new do
147
148
  host 'wonderland.lit' do
148
- storage(:fs) { dir '.' }
149
+ storage(:fs) { dir Dir.tmpdir }
149
150
  components 'tea' => 'one', 'TEA' => 'two'
150
151
  end
151
152
  end
@@ -156,7 +157,7 @@ class HostTest < MiniTest::Unit::TestCase
156
157
  assert_raises(RuntimeError) do
157
158
  Vines::Config.new do
158
159
  host 'wonderland.lit' do
159
- storage(:fs) { dir '.' }
160
+ storage(:fs) { dir Dir.tmpdir }
160
161
  components 'tea' => 'one'
161
162
  components :TEA => 'two'
162
163
  end
@@ -168,7 +169,7 @@ class HostTest < MiniTest::Unit::TestCase
168
169
  assert_raises(ArgumentError) do
169
170
  Vines::Config.new do
170
171
  host 'wonderland.lit ' do
171
- storage(:fs) { dir '.' }
172
+ storage(:fs) { dir Dir.tmpdir }
172
173
  end
173
174
  end
174
175
  end
@@ -178,7 +179,7 @@ class HostTest < MiniTest::Unit::TestCase
178
179
  assert_raises(RuntimeError) do
179
180
  Vines::Config.new do
180
181
  host 'alice@wonderland.lit' do
181
- storage(:fs) { dir '.' }
182
+ storage(:fs) { dir Dir.tmpdir }
182
183
  end
183
184
  end
184
185
  end
@@ -188,7 +189,7 @@ class HostTest < MiniTest::Unit::TestCase
188
189
  assert_raises(ArgumentError) do
189
190
  Vines::Config.new do
190
191
  host 'wonderland.lit' do
191
- storage(:fs) { dir '.' }
192
+ storage(:fs) { dir Dir.tmpdir }
192
193
  components 'exam ple' => 'one'
193
194
  end
194
195
  end
@@ -199,7 +200,7 @@ class HostTest < MiniTest::Unit::TestCase
199
200
  assert_raises(RuntimeError) do
200
201
  Vines::Config.new do
201
202
  host 'wonderland.lit' do
202
- storage(:fs) { dir '.' }
203
+ storage(:fs) { dir Dir.tmpdir }
203
204
  components 'alice@example' => 'one'
204
205
  end
205
206
  end
@@ -210,7 +211,7 @@ class HostTest < MiniTest::Unit::TestCase
210
211
  assert_raises(RuntimeError) do
211
212
  Vines::Config.new do
212
213
  host 'wonderland.lit' do
213
- storage(:fs) { dir '.' }
214
+ storage(:fs) { dir Dir.tmpdir }
214
215
  components 'exam.ple' => 'one'
215
216
  end
216
217
  end
@@ -220,7 +221,7 @@ class HostTest < MiniTest::Unit::TestCase
220
221
  def test_case_insensitive_component_name
221
222
  config = Vines::Config.new do
222
223
  host 'WONDERLAND.LIT' do
223
- storage(:fs) { dir '.' }
224
+ storage(:fs) { dir Dir.tmpdir }
224
225
  components 'TEA' => 'secr3t', CAKE: 'Passw0rd'
225
226
  end
226
227
  end
@@ -234,7 +235,7 @@ class HostTest < MiniTest::Unit::TestCase
234
235
  def test_component?
235
236
  config = Vines::Config.new do
236
237
  host 'wonderland.lit' do
237
- storage(:fs) { dir '.' }
238
+ storage(:fs) { dir Dir.tmpdir }
238
239
  components 'tea' => 'secr3t', cake: 'passw0rd'
239
240
  end
240
241
  end
@@ -244,6 +245,7 @@ class HostTest < MiniTest::Unit::TestCase
244
245
  refute host.component?('tea')
245
246
  refute host.component?(:cake)
246
247
  assert host.component?('tea.wonderland.lit')
248
+ assert host.component?(Vines::JID.new('tea.wonderland.lit'))
247
249
  assert host.component?('cake.wonderland.lit')
248
250
  assert_nil host.password(nil)
249
251
  assert_nil host.password('bogus')
@@ -256,6 +258,7 @@ class HostTest < MiniTest::Unit::TestCase
256
258
  refute config.component?('tea')
257
259
  refute config.component?('bogus')
258
260
  assert config.component?('tea.wonderland.lit')
261
+ assert config.component?(Vines::JID.new('tea.wonderland.lit'))
259
262
  assert config.component?('cake.wonderland.lit')
260
263
  assert config.component?('tea.wonderland.lit', 'cake.wonderland.lit')
261
264
  refute config.component?('tea.wonderland.lit', 'bogus.wonderland.lit')
@@ -266,10 +269,83 @@ class HostTest < MiniTest::Unit::TestCase
266
269
  assert_equal 'passw0rd', config.component_password('cake.wonderland.lit')
267
270
  end
268
271
 
272
+ def test_invalid_pubsub_domain_raises
273
+ assert_raises(ArgumentError) do
274
+ Vines::Config.new do
275
+ host 'wonderland.lit' do
276
+ storage(:fs) { dir Dir.tmpdir }
277
+ pubsub 'exam ple'
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ def test_invalid_jid_pubsub_domain_raises
284
+ assert_raises(RuntimeError) do
285
+ Vines::Config.new do
286
+ host 'wonderland.lit' do
287
+ storage(:fs) { dir Dir.tmpdir }
288
+ pubsub 'alice@example'
289
+ end
290
+ end
291
+ end
292
+ end
293
+
294
+ def test_multi_subdomain_pubsub_raises
295
+ assert_raises(RuntimeError) do
296
+ Vines::Config.new do
297
+ host 'wonderland.lit' do
298
+ storage(:fs) { dir Dir.tmpdir }
299
+ pubsub 'exam.ple'
300
+ end
301
+ end
302
+ end
303
+ end
304
+
305
+ def test_case_insensitive_pubsub_name
306
+ config = Vines::Config.new do
307
+ host 'WONDERLAND.LIT' do
308
+ storage(:fs) { dir Dir.tmpdir }
309
+ pubsub 'TEA', :CAKE
310
+ end
311
+ end
312
+ host = config.vhosts['wonderland.lit']
313
+ refute_nil host
314
+ assert_equal 2, host.pubsubs.size
315
+ refute_nil host.pubsubs['tea.wonderland.lit']
316
+ refute_nil host.pubsubs['cake.wonderland.lit']
317
+ end
318
+
319
+ def test_pubsub?
320
+ config = Vines::Config.new do
321
+ host 'wonderland.lit' do
322
+ storage(:fs) { dir Dir.tmpdir }
323
+ pubsub 'tea', :cake
324
+ end
325
+ end
326
+ host = config.vhosts['wonderland.lit']
327
+ refute_nil host
328
+ refute host.pubsub?(nil)
329
+ refute host.pubsub?('tea')
330
+ refute host.pubsub?(:cake)
331
+ assert host.pubsub?('tea.wonderland.lit')
332
+ assert host.pubsub?(Vines::JID.new('tea.wonderland.lit'))
333
+ assert host.pubsub?('cake.wonderland.lit')
334
+ assert_equal ['tea.wonderland.lit', 'cake.wonderland.lit'], host.pubsubs.keys
335
+
336
+ refute config.pubsub?(nil)
337
+ refute config.pubsub?('tea')
338
+ refute config.pubsub?('bogus')
339
+ assert config.pubsub?('tea.wonderland.lit')
340
+ assert config.pubsub?(Vines::JID.new('tea.wonderland.lit'))
341
+ assert config.pubsub?('cake.wonderland.lit')
342
+ refute config.pubsub?('alice@cake.wonderland.lit')
343
+ end
344
+
269
345
  def test_default_private_storage_is_off
270
346
  config = Vines::Config.new do
271
347
  host 'wonderland.lit' do
272
- storage(:fs) { dir '.' }
348
+ storage(:fs) { dir Dir.tmpdir }
273
349
  end
274
350
  end
275
351
  host = config.vhosts['wonderland.lit']
@@ -281,12 +357,15 @@ class HostTest < MiniTest::Unit::TestCase
281
357
  config = Vines::Config.new do
282
358
  host 'wonderland.lit' do
283
359
  private_storage true
284
- storage(:fs) { dir '.' }
360
+ storage(:fs) { dir Dir.tmpdir }
285
361
  end
286
362
  end
287
363
  host = config.vhosts['wonderland.lit']
288
364
  refute_nil host
289
365
  assert host.private_storage?
290
366
  assert config.private_storage?('wonderland.lit')
367
+ assert config.private_storage?(Vines::JID.new('wonderland.lit'))
368
+ refute config.private_storage?(Vines::JID.new('alice@wonderland.lit'))
369
+ refute config.private_storage?(nil)
291
370
  end
292
371
  end