vines 0.4.5 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/Gemfile +3 -0
  2. data/README.md +48 -0
  3. data/Rakefile +6 -58
  4. data/bin/vines +12 -2
  5. data/conf/certs/ca-bundle.crt +568 -39
  6. data/conf/config.rb +9 -42
  7. data/lib/vines.rb +1 -8
  8. data/lib/vines/command/cert.rb +4 -4
  9. data/lib/vines/command/init.rb +3 -3
  10. data/lib/vines/config.rb +9 -0
  11. data/lib/vines/kit.rb +2 -7
  12. data/lib/vines/storage/local.rb +50 -17
  13. data/lib/vines/store.rb +6 -4
  14. data/lib/vines/stream.rb +1 -1
  15. data/lib/vines/stream/http/session.rb +0 -0
  16. data/lib/vines/stream/http/sessions.rb +0 -0
  17. data/lib/vines/stream/parser.rb +3 -2
  18. data/lib/vines/token_bucket.rb +19 -10
  19. data/lib/vines/version.rb +1 -1
  20. data/test/cluster/publisher_test.rb +45 -33
  21. data/test/cluster/sessions_test.rb +32 -39
  22. data/test/cluster/subscriber_test.rb +93 -78
  23. data/test/config/host_test.rb +2 -4
  24. data/test/config/pubsub_test.rb +132 -126
  25. data/test/config_test.rb +2 -4
  26. data/test/contact_test.rb +80 -66
  27. data/test/error_test.rb +54 -55
  28. data/test/jid_test.rb +1 -2
  29. data/test/kit_test.rb +22 -17
  30. data/test/router_test.rb +187 -146
  31. data/test/stanza/iq/disco_info_test.rb +59 -59
  32. data/test/stanza/iq/disco_items_test.rb +36 -34
  33. data/test/stanza/iq/private_storage_test.rb +138 -143
  34. data/test/stanza/iq/roster_test.rb +198 -175
  35. data/test/stanza/iq/session_test.rb +17 -18
  36. data/test/stanza/iq/vcard_test.rb +117 -116
  37. data/test/stanza/iq/version_test.rb +47 -46
  38. data/test/stanza/iq_test.rb +53 -49
  39. data/test/stanza/message_test.rb +92 -89
  40. data/test/stanza/presence/probe_test.rb +2 -5
  41. data/test/stanza/presence/subscribe_test.rb +67 -54
  42. data/test/stanza/pubsub/create_test.rb +86 -108
  43. data/test/stanza/pubsub/delete_test.rb +141 -114
  44. data/test/stanza/pubsub/publish_test.rb +256 -320
  45. data/test/stanza/pubsub/subscribe_test.rb +169 -150
  46. data/test/stanza/pubsub/unsubscribe_test.rb +111 -142
  47. data/test/stanza_test.rb +61 -54
  48. data/test/storage/ldap_test.rb +1 -2
  49. data/test/storage/local_test.rb +3 -5
  50. data/test/storage/null_test.rb +3 -4
  51. data/test/storage/storage_tests.rb +1 -3
  52. data/test/storage_test.rb +1 -2
  53. data/test/store_test.rb +1 -2
  54. data/test/stream/client/auth_test.rb +61 -63
  55. data/test/stream/client/ready_test.rb +7 -8
  56. data/test/stream/client/session_test.rb +19 -18
  57. data/test/stream/component/handshake_test.rb +40 -37
  58. data/test/stream/component/ready_test.rb +76 -61
  59. data/test/stream/component/start_test.rb +7 -8
  60. data/test/stream/http/auth_test.rb +3 -4
  61. data/test/stream/http/ready_test.rb +52 -60
  62. data/test/stream/http/request_test.rb +1 -3
  63. data/test/stream/http/sessions_test.rb +2 -3
  64. data/test/stream/http/start_test.rb +3 -4
  65. data/test/stream/parser_test.rb +3 -4
  66. data/test/stream/sasl_test.rb +105 -86
  67. data/test/stream/server/auth_test.rb +40 -36
  68. data/test/stream/server/outbound/auth_test.rb +3 -4
  69. data/test/stream/server/ready_test.rb +51 -51
  70. data/test/test_helper.rb +42 -0
  71. data/test/token_bucket_test.rb +38 -18
  72. data/test/user_test.rb +79 -49
  73. data/vines.gemspec +33 -0
  74. data/web/chat/javascripts/app.js +1 -1
  75. data/web/lib/coffeescripts/layout.coffee +1 -1
  76. data/web/lib/javascripts/base.js +10 -10
  77. data/web/lib/javascripts/jquery.js +4 -4
  78. metadata +31 -128
  79. data/README +0 -35
  80. data/lib/vines/storage/couchdb.rb +0 -129
  81. data/lib/vines/storage/mongodb.rb +0 -132
  82. data/lib/vines/storage/redis.rb +0 -127
  83. data/lib/vines/storage/sql.rb +0 -220
  84. data/test/rake_test_loader.rb +0 -17
  85. data/test/storage/couchdb_test.rb +0 -107
  86. data/test/storage/mock_mongo.rb +0 -40
  87. data/test/storage/mongodb_test.rb +0 -81
  88. data/test/storage/redis_test.rb +0 -51
  89. data/test/storage/sql_test.rb +0 -62
@@ -1,206 +1,229 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'vines'
4
- require 'ext/nokogiri'
5
- require 'minitest/autorun'
3
+ require 'test_helper'
6
4
 
7
- class RosterTest < MiniTest::Unit::TestCase
8
- def setup
9
- @stream = MiniTest::Mock.new
10
- end
5
+ describe Vines::Stanza::Iq::Roster do
6
+ subject { Vines::Stanza::Iq::Roster.new(xml, stream) }
7
+ let(:stream) { MiniTest::Mock.new }
8
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
11
9
 
12
- def test_roster_get_with_empty_roster
13
- alice = Vines::User.new(:jid => 'alice@wonderland.lit')
14
- expected = node(%q{<iq id="42" type="result"><query xmlns="jabber:iq:roster"/></iq>})
15
- @stream.expect(:write, nil, [expected])
16
- @stream.expect(:requested_roster!, nil)
17
- @stream.expect(:user, alice)
18
-
19
- node = node(%q{<iq id="42" type="get"><query xmlns='jabber:iq:roster'/></iq>})
20
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
21
- stanza.process
22
- assert @stream.verify
10
+ before do
11
+ class << stream
12
+ attr_accessor :domain, :user
13
+ end
14
+ stream.user = alice
15
+ stream.domain = 'wonderland.lit'
23
16
  end
24
17
 
25
- def test_roster_get_with_non_empty_roster
26
- alice = Vines::User.new(:jid => 'alice@wonderland.lit')
27
- alice.roster << Vines::Contact.new(:jid => 'hatter@wonderland.lit')
28
- alice.roster << Vines::Contact.new(:jid => 'cat@wonderland.lit', :groups => ['Friends', 'Cats'])
29
-
30
- expected = node(%q{
31
- <iq id="42" type="result">
32
- <query xmlns="jabber:iq:roster">
33
- <item jid="cat@wonderland.lit" subscription="none">
34
- <group>Cats</group>
35
- <group>Friends</group>
36
- </item>
37
- <item jid="hatter@wonderland.lit" subscription="none"/>
38
- </query>
39
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
40
-
41
- @stream.expect(:write, nil, [expected])
42
- @stream.expect(:requested_roster!, nil)
43
- @stream.expect(:user, alice)
44
-
45
- node = node(%q{<iq id="42" type="get"><query xmlns='jabber:iq:roster'/></iq>})
46
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
47
- stanza.process
48
- assert @stream.verify
18
+ describe 'when retrieving an empty roster' do
19
+ let(:xml) { node(%q{<iq id="42" type="get"><query xmlns='jabber:iq:roster'/></iq>}) }
20
+ let(:expected) { node(%q{<iq id="42" type="result"><query xmlns="jabber:iq:roster"/></iq>}) }
21
+
22
+ before do
23
+ stream.expect :write, nil, [expected]
24
+ stream.expect :requested_roster!, nil
25
+ end
26
+
27
+ it 'returns an empty stanza' do
28
+ subject.process
29
+ stream.verify
30
+ end
49
31
  end
50
32
 
51
- def test_roster_get_with_invalid_to_address
52
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
53
- @stream.expect(:user, alice)
33
+ describe 'when retrieving a non-empty roster' do
34
+ let(:xml) { node(%q{<iq id="42" type="get"><query xmlns='jabber:iq:roster'/></iq>}) }
35
+ let(:expected) do
36
+ node(%q{
37
+ <iq id="42" type="result">
38
+ <query xmlns="jabber:iq:roster">
39
+ <item jid="cat@wonderland.lit" subscription="none">
40
+ <group>Cats</group>
41
+ <group>Friends</group>
42
+ </item>
43
+ <item jid="hatter@wonderland.lit" subscription="none"/>
44
+ </query>
45
+ </iq>})
46
+ end
54
47
 
55
- node = node(%q{
56
- <iq id="42" type="get" to="romeo@verona.lit">
57
- <query xmlns="jabber:iq:roster"/>
58
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
48
+ before do
49
+ alice.roster << Vines::Contact.new(jid: 'hatter@wonderland.lit')
50
+ alice.roster << Vines::Contact.new(jid: 'cat@wonderland.lit', :groups => ['Friends', 'Cats'])
59
51
 
60
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
61
- assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process }
62
- assert @stream.verify
63
- end
52
+ stream.expect :write, nil, [expected]
53
+ stream.expect :requested_roster!, nil
54
+ end
64
55
 
65
- def test_roster_set_with_invalid_to_address
66
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
67
- @stream.expect(:user, alice)
56
+ it 'sorts groups alphabetically' do
57
+ subject.process
58
+ stream.verify
59
+ end
60
+ end
68
61
 
69
- node = node(%q{
70
- <iq id="42" type="set" to="romeo@verona.lit">
71
- <query xmlns="jabber:iq:roster"/>
72
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
62
+ describe 'when requesting a roster for another user' do
63
+ let(:xml) do
64
+ node(%q{
65
+ <iq id="42" type="get" to="romeo@verona.lit">
66
+ <query xmlns="jabber:iq:roster"/>
67
+ </iq>})
68
+ end
73
69
 
74
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
75
- assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process }
76
- assert @stream.verify
70
+ it 'raises a forbidden stanza error' do
71
+ -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden
72
+ stream.verify
73
+ end
77
74
  end
78
75
 
79
- def test_roster_set_with_no_items
80
- node = node(%q{
81
- <iq id="42" type="set">
82
- <query xmlns="jabber:iq:roster"/>
83
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
76
+ describe 'when saving a roster for another user' do
77
+ let(:xml) do
78
+ node(%q{
79
+ <iq id="42" type="set" to="romeo@verona.lit">
80
+ <query xmlns="jabber:iq:roster"/>
81
+ </iq>})
82
+ end
84
83
 
85
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
86
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
87
- assert @stream.verify
84
+ it 'raises a forbidden stanza error' do
85
+ -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden
86
+ stream.verify
87
+ end
88
88
  end
89
89
 
90
- def test_roster_set_with_two_items
91
- node = node(%q{
92
- <iq id="42" type="set">
93
- <query xmlns="jabber:iq:roster">
94
- <item jid="hatter@wonderland.lit"/>
95
- <item jid="cat@wonderland.lit"/>
96
- </query>
97
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
98
-
99
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
100
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
101
- assert @stream.verify
90
+ describe 'when saving a roster with no items' do
91
+ let(:xml) do
92
+ node(%q{
93
+ <iq id="42" type="set">
94
+ <query xmlns="jabber:iq:roster"/>
95
+ </iq>})
96
+ end
97
+
98
+ it 'raises a bad-request stanza error' do
99
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
100
+ stream.verify
101
+ end
102
102
  end
103
103
 
104
- def test_roster_set_missing_jid
105
- node = node(%q{
106
- <iq id="42" type="set">
107
- <query xmlns="jabber:iq:roster">
108
- <item name="Mad Hatter"/>
109
- </query>
110
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
111
-
112
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
113
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
114
- assert @stream.verify
104
+ describe 'when updating a roster with more than one item' do
105
+ let(:xml) do
106
+ node(%q{
107
+ <iq id="42" type="set">
108
+ <query xmlns="jabber:iq:roster">
109
+ <item jid="hatter@wonderland.lit"/>
110
+ <item jid="cat@wonderland.lit"/>
111
+ </query>
112
+ </iq>})
113
+ end
114
+
115
+ it 'raises a bad-request stanza error' do
116
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
117
+ stream.verify
118
+ end
115
119
  end
116
120
 
117
- def test_roster_set_with_duplicate_groups
118
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
119
- @stream.expect(:user, alice)
120
-
121
- node = node(%q{
122
- <iq id="42" type="set">
123
- <query xmlns="jabber:iq:roster">
124
- <item jid="hatter@wonderland.lit" name="Mad Hatter">
125
- <group>Friends</group>
126
- <group>Friends</group>
127
- </item>
128
- </query>
129
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
130
-
131
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
132
- assert_raises(Vines::StanzaErrors::BadRequest) { stanza.process }
133
- assert @stream.verify
121
+ describe 'when adding a roster item without a jid attribute' do
122
+ let(:xml) do
123
+ node(%q{
124
+ <iq id="42" type="set">
125
+ <query xmlns="jabber:iq:roster">
126
+ <item name="Mad Hatter"/>
127
+ </query>
128
+ </iq>})
129
+ end
130
+
131
+ it 'raises a bad-request stanza error' do
132
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
133
+ stream.verify
134
+ end
134
135
  end
135
136
 
136
- def test_roster_set_with_empty_group
137
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
138
- @stream.expect(:user, alice)
139
-
140
- node = node(%q{
141
- <iq id="42" type="set">
142
- <query xmlns="jabber:iq:roster">
143
- <item jid="hatter@wonderland.lit" name="Mad Hatter">
144
- <group></group>
145
- </item>
146
- </query>
147
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
148
-
149
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
150
- assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process }
151
- assert @stream.verify
137
+ describe 'when adding a roster item with duplicate groups' do
138
+ let(:xml) do
139
+ node(%q{
140
+ <iq id="42" type="set">
141
+ <query xmlns="jabber:iq:roster">
142
+ <item jid="hatter@wonderland.lit" name="Mad Hatter">
143
+ <group>Friends</group>
144
+ <group>Friends</group>
145
+ </item>
146
+ </query>
147
+ </iq>})
148
+ end
149
+
150
+ it 'raises a bad-request stanza error' do
151
+ -> { subject.process }.must_raise Vines::StanzaErrors::BadRequest
152
+ stream.verify
153
+ end
152
154
  end
153
155
 
154
- def test_roster_set_sends_results
155
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
156
- storage = MiniTest::Mock.new
157
- storage.expect(:save_user, nil, [alice])
158
-
159
- recipient = MiniTest::Mock.new
160
- recipient.expect(:user, alice)
161
- def recipient.nodes; @nodes; end
162
- def recipient.write(node)
163
- @nodes ||= []
164
- @nodes << node
165
- end
166
-
167
- @stream.expect(:user, alice)
168
- @stream.expect(:interested_resources, [recipient], [alice.jid])
169
- @stream.expect(:update_user_streams, nil, [alice])
170
- @stream.expect(:domain, 'wonderland.lit')
171
- @stream.expect(:storage, storage, ['wonderland.lit'])
172
- expected = node(%Q{<iq id="42" to="#{alice.jid}" type="result"/>})
173
- @stream.expect(:write, nil, [expected])
174
-
175
- node = node(%q{
176
- <iq id="42" type="set">
177
- <query xmlns="jabber:iq:roster">
178
- <item jid="hatter@wonderland.lit" name="Mad Hatter">
179
- <group>Friends</group>
180
- </item>
181
- </query>
182
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
183
-
184
- stanza = Vines::Stanza::Iq::Roster.new(node, @stream)
185
- stanza.process
186
- assert @stream.verify
187
- assert storage.verify
188
-
189
- expected = node(%q{
190
- <iq to="alice@wonderland.lit/tea" type="set">
191
- <query xmlns="jabber:iq:roster">
192
- <item jid="hatter@wonderland.lit" name="Mad Hatter" subscription="none">
193
- <group>Friends</group>
194
- </item>
195
- </query>
196
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
197
- recipient.nodes[0].remove_attribute('id') # id is random
198
- assert_equal expected, recipient.nodes[0]
156
+ describe 'when adding a roster item with an empty group name' do
157
+ let(:xml) do
158
+ node(%q{
159
+ <iq id="42" type="set">
160
+ <query xmlns="jabber:iq:roster">
161
+ <item jid="hatter@wonderland.lit" name="Mad Hatter">
162
+ <group></group>
163
+ </item>
164
+ </query>
165
+ </iq>})
166
+ end
167
+
168
+ it 'raises a not-acceptable stanza error' do
169
+ -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable
170
+ stream.verify
171
+ end
199
172
  end
200
173
 
201
- private
174
+ describe 'when saving a roster successfully' do
175
+ let(:xml) do
176
+ node(%q{
177
+ <iq id="42" type="set">
178
+ <query xmlns="jabber:iq:roster">
179
+ <item jid="hatter@wonderland.lit" name="Mad Hatter">
180
+ <group>Friends</group>
181
+ </item>
182
+ </query>
183
+ </iq>})
184
+ end
185
+
186
+ let(:expected) do
187
+ node(%q{
188
+ <iq to="alice@wonderland.lit/tea" type="set">
189
+ <query xmlns="jabber:iq:roster">
190
+ <item jid="hatter@wonderland.lit" name="Mad Hatter" subscription="none">
191
+ <group>Friends</group>
192
+ </item>
193
+ </query>
194
+ </iq>})
195
+ end
196
+
197
+ let(:storage) { MiniTest::Mock.new }
198
+ let(:recipient) { MiniTest::Mock.new }
199
+ let(:result) { node(%Q{<iq id="42" to="#{alice.jid}" type="result"/>}) }
200
+
201
+ before do
202
+ storage.expect :save_user, nil, [alice]
203
+
204
+ recipient.expect :user, alice
205
+ def recipient.nodes; @nodes; end
206
+ def recipient.write(node)
207
+ @nodes ||= []
208
+ @nodes << node
209
+ end
202
210
 
203
- def node(xml)
204
- Nokogiri::XML(xml).root
211
+ stream.expect :interested_resources, [recipient], [alice.jid]
212
+ stream.expect :update_user_streams, nil, [alice]
213
+ stream.expect :storage, storage, ['wonderland.lit']
214
+ stream.expect :write, nil, [result]
215
+ end
216
+
217
+ it 'sends a result to the sender' do
218
+ subject.process
219
+ stream.verify
220
+ storage.verify
221
+ end
222
+
223
+ it 'sends the new roster item to the interested streams' do
224
+ subject.process
225
+ recipient.nodes.first.remove_attribute('id') # id is random
226
+ recipient.nodes.first.must_equal expected
227
+ end
205
228
  end
206
229
  end
@@ -1,26 +1,25 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'vines'
4
- require 'ext/nokogiri'
5
- require 'minitest/autorun'
3
+ require 'test_helper'
6
4
 
7
- class SessionTest < MiniTest::Unit::TestCase
8
- def test_session
9
- stream = MiniTest::Mock.new
10
- stream.expect(:domain, 'wonderland.lit')
11
- stream.expect(:user, Vines::User.new(jid: 'alice@wonderland.lit/tea'))
12
- expected = node(%q{<iq from="wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result"/>})
13
- stream.expect(:write, nil, [expected])
5
+ describe Vines::Stanza::Iq::Session do
6
+ subject { Vines::Stanza::Iq::Session.new(xml, stream) }
7
+ let(:stream) { MiniTest::Mock.new }
8
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
14
9
 
15
- node = node(%q{<iq id="42" type="set"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>})
16
- stanza = Vines::Stanza::Iq::Session.new(node, stream)
17
- stanza.process
18
- assert stream.verify
19
- end
10
+ describe 'when session initiation is requested' do
11
+ let(:xml) { node(%q{<iq id="42" type="set"><session xmlns="urn:ietf:params:xml:ns:xmpp-session"/></iq>}) }
12
+ let(:result) { node(%q{<iq from="wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result"/>}) }
20
13
 
21
- private
14
+ before do
15
+ stream.expect :domain, 'wonderland.lit'
16
+ stream.expect :user, alice
17
+ stream.expect :write, nil, [result]
18
+ end
22
19
 
23
- def node(xml)
24
- Nokogiri::XML(xml).root
20
+ it 'just returns a result to satisy older clients' do
21
+ subject.process
22
+ stream.verify
23
+ end
25
24
  end
26
25
  end
@@ -1,14 +1,14 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class VcardTest < MiniTest::Unit::TestCase
9
- def setup
10
- @stream = MiniTest::Mock.new
11
- @config = Vines::Config.new do
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stanza::Iq::Vcard do
6
+ subject { Vines::Stanza::Iq::Vcard.new(xml, stream) }
7
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
8
+ let(:stream) { MiniTest::Mock.new }
9
+ let(:storage) { MiniTest::Mock.new }
10
+ let(:config) do
11
+ Vines::Config.new do
12
12
  host 'wonderland.lit' do
13
13
  cross_domain_messages true
14
14
  storage(:fs) { dir Dir.tmpdir }
@@ -16,130 +16,131 @@ class VcardTest < MiniTest::Unit::TestCase
16
16
  end
17
17
  end
18
18
 
19
- def test_vcard_get_on_remote_jid_routes
20
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
21
- node = node(%q{<iq id="42" to="romeo@verona.lit" type="get"><vCard xmlns="vcard-temp"/></iq>})
19
+ before do
20
+ class << stream
21
+ attr_accessor :config, :domain, :user
22
+ end
23
+ stream.config = config
24
+ stream.domain = 'wonderland.lit'
25
+ stream.user = alice
26
+ end
22
27
 
23
- router = MiniTest::Mock.new
24
- router.expect(:route, nil, [node])
28
+ describe 'when getting vcard' do
29
+ describe 'and addressed to a remote jid' do
30
+ let(:xml) { get('romeo@verona.lit') }
31
+ let(:router) { MiniTest::Mock.new }
25
32
 
26
- @stream.expect(:config, @config)
27
- @stream.expect(:user, alice)
28
- @stream.expect(:router, router)
33
+ before do
34
+ router.expect :route, nil, [xml]
35
+ stream.expect :router, router
36
+ end
29
37
 
30
- stanza = Vines::Stanza::Iq::Vcard.new(node, @stream)
31
- stanza.process
32
- assert @stream.verify
33
- assert router.verify
34
- end
38
+ it 'routes rather than handle locally' do
39
+ subject.process
40
+ stream.verify
41
+ router.verify
42
+ end
43
+ end
35
44
 
36
- def test_vcard_get_missing_to_address
37
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
38
- node = node(%q{<iq id="42" type="get"><vCard xmlns="vcard-temp"/></iq>})
39
-
40
- card = node(%q{<vCard xmlns="vcard-temp"><FN>Alice in Wonderland</FN></vCard>})
41
-
42
- storage = MiniTest::Mock.new
43
- storage.expect(:find_vcard, card, [alice.jid.bare])
44
-
45
- @stream.expect(:config, @config)
46
- @stream.expect(:user, alice)
47
- @stream.expect(:domain, 'wonderland.lit')
48
- @stream.expect(:storage, storage, ['wonderland.lit'])
49
- expected = node(%q{
50
- <iq id="42" to="alice@wonderland.lit/tea" type="result">
51
- <vCard xmlns="vcard-temp">
52
- <FN>Alice in Wonderland</FN>
53
- </vCard>
54
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
55
- @stream.expect(:write, nil, [expected])
56
-
57
- stanza = Vines::Stanza::Iq::Vcard.new(node, @stream)
58
- stanza.process
59
- assert @stream.verify
60
- assert storage.verify
61
- end
45
+ describe 'and missing to address' do
46
+ let(:xml) { get('') }
47
+ let(:card) { vcard('Alice') }
48
+ let(:expected) { result(alice.jid, '', card) }
62
49
 
63
- def test_vcard_get_another_user_includes_from_address
64
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
65
- node = node(%q{<iq id="42" to="hatter@wonderland.lit" type="get"><vCard xmlns="vcard-temp"/></iq>})
66
-
67
- card = node(%q{<vCard xmlns="vcard-temp"><FN>Mad Hatter</FN></vCard>})
68
-
69
- storage = MiniTest::Mock.new
70
- storage.expect(:find_vcard, card, [Vines::JID.new('hatter@wonderland.lit')])
71
-
72
- @stream.expect(:config, @config)
73
- @stream.expect(:user, alice)
74
- @stream.expect(:storage, storage, ['wonderland.lit'])
75
- expected = node(%q{
76
- <iq from="hatter@wonderland.lit" id="42" to="alice@wonderland.lit/tea" type="result">
77
- <vCard xmlns="vcard-temp">
78
- <FN>Mad Hatter</FN>
79
- </vCard>
80
- </iq>}.strip.gsub(/\n|\s{2,}/, ''))
81
- @stream.expect(:write, nil, [expected])
82
-
83
- stanza = Vines::Stanza::Iq::Vcard.new(node, @stream)
84
- stanza.process
85
- assert @stream.verify
86
- assert storage.verify
87
- end
50
+ before do
51
+ storage.expect :find_vcard, card, [alice.jid.bare]
52
+ stream.expect :storage, storage, ['wonderland.lit']
53
+ stream.expect :write, nil, [expected]
54
+ end
88
55
 
89
- def test_missing_vcard_get_returns_item_not_found
90
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
91
- node = node(%q{<iq id="42" type="get"><vCard xmlns="vcard-temp"/></iq>})
56
+ it 'sends vcard for authenticated jid' do
57
+ subject.process
58
+ stream.verify
59
+ storage.verify
60
+ end
61
+ end
92
62
 
93
- storage = MiniTest::Mock.new
94
- storage.expect(:find_vcard, nil, [alice.jid.bare])
63
+ describe 'for another user' do
64
+ let(:xml) { get(hatter) }
65
+ let(:card) { vcard('Hatter') }
66
+ let(:hatter) { Vines::JID.new('hatter@wonderland.lit') }
67
+ let(:expected) { result(alice.jid, hatter, card) }
95
68
 
96
- @stream.expect(:config, @config)
97
- @stream.expect(:user, alice)
98
- @stream.expect(:domain, 'wonderland.lit')
99
- @stream.expect(:storage, storage, ['wonderland.lit'])
69
+ before do
70
+ storage.expect :find_vcard, card, [hatter]
71
+ stream.expect :storage, storage, ['wonderland.lit']
72
+ stream.expect :write, nil, [expected]
73
+ end
100
74
 
101
- stanza = Vines::Stanza::Iq::Vcard.new(node, @stream)
102
- assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
103
- assert @stream.verify
104
- assert storage.verify
105
- end
75
+ it 'succeeds and returns vcard with from address' do
76
+ subject.process
77
+ stream.verify
78
+ storage.verify
79
+ end
80
+ end
106
81
 
107
- def test_vcard_set_on_another_user_returns_forbidden
108
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
109
- node = node(%q{<iq id="42" to="hatter@wonderland.lit" type="set"><vCard xmlns="vcard-temp"><FN>Alice</FN></vCard></iq>})
82
+ describe 'for missing vcard' do
83
+ let(:xml) { get('') }
110
84
 
111
- @stream.expect(:config, @config)
112
- @stream.expect(:user, alice)
85
+ before do
86
+ storage.expect :find_vcard, nil, [alice.jid.bare]
87
+ stream.expect :storage, storage, ['wonderland.lit']
88
+ end
113
89
 
114
- stanza = Vines::Stanza::Iq::Vcard.new(node, @stream)
115
- assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process }
116
- assert @stream.verify
90
+ it 'returns an item-not-found stanza error' do
91
+ -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound
92
+ stream.verify
93
+ storage.verify
94
+ end
95
+ end
117
96
  end
118
97
 
119
- def test_vcard_set_returns_result
120
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
121
- node = node(%q{<iq id="42" type="set"><vCard xmlns="vcard-temp"><FN>Alice</FN></vCard></iq>})
122
- card = node(%q{<vCard xmlns="vcard-temp"><FN>Alice</FN></vCard>})
123
-
124
- storage = MiniTest::Mock.new
125
- storage.expect(:save_vcard, nil, [alice.jid, card])
126
-
127
- @stream.expect(:config, @config)
128
- @stream.expect(:user, alice)
129
- @stream.expect(:domain, 'wonderland.lit')
130
- @stream.expect(:storage, storage, ['wonderland.lit'])
131
- expected = node(%q{<iq id="42" to="alice@wonderland.lit/tea" type="result"/>})
132
- @stream.expect(:write, nil, [expected])
133
-
134
- stanza = Vines::Stanza::Iq::Vcard.new(node, @stream)
135
- stanza.process
136
- assert @stream.verify
137
- assert storage.verify
98
+ describe 'when setting vcard' do
99
+ describe 'and addressed to another user' do
100
+ let(:xml) { set('hatter@wonderland.lit') }
101
+
102
+ it 'raises a forbidden stanza error' do
103
+ -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden
104
+ stream.verify
105
+ end
106
+ end
107
+
108
+ describe 'and missing to address' do
109
+ let(:xml) { set('') }
110
+ let(:card) { vcard('Alice') }
111
+ let(:expected) { result(alice.jid) }
112
+
113
+ before do
114
+ storage.expect :save_vcard, nil, [alice.jid, card]
115
+ stream.expect :storage, storage, ['wonderland.lit']
116
+ stream.expect :write, nil, [expected]
117
+ end
118
+
119
+ it 'succeeds and returns an iq result' do
120
+ subject.process
121
+ stream.verify
122
+ storage.verify
123
+ end
124
+ end
138
125
  end
139
126
 
140
127
  private
141
128
 
142
- def node(xml)
143
- Nokogiri::XML(xml).root
129
+ def vcard(name)
130
+ node(%Q{<vCard xmlns="vcard-temp"><FN>#{name}</FN></vCard>})
131
+ end
132
+
133
+ def get(to)
134
+ card = '<vCard xmlns="vcard-temp"/>'
135
+ iq(id: 42, to: to, type: 'get', body: card)
136
+ end
137
+
138
+ def set(to)
139
+ card = '<vCard xmlns="vcard-temp"><FN>Alice</FN></vCard>'
140
+ iq(id: 42, to: to, type: 'set', body: card)
141
+ end
142
+
143
+ def result(to, from=nil, card=nil)
144
+ iq(from: from, id: 42, to: to, type: 'result', body: card)
144
145
  end
145
146
  end