vines 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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