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,206 +1,229 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'ext/nokogiri'
|
5
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
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
|
-
|
52
|
-
|
53
|
-
|
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
|
-
|
56
|
-
|
57
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
63
|
-
end
|
52
|
+
stream.expect :write, nil, [expected]
|
53
|
+
stream.expect :requested_roster!, nil
|
54
|
+
end
|
64
55
|
|
65
|
-
|
66
|
-
|
67
|
-
|
56
|
+
it 'sorts groups alphabetically' do
|
57
|
+
subject.process
|
58
|
+
stream.verify
|
59
|
+
end
|
60
|
+
end
|
68
61
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
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
|
75
|
-
|
76
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
<
|
83
|
-
|
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
|
86
|
-
|
87
|
-
|
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
|
-
|
91
|
-
|
92
|
-
|
93
|
-
<
|
94
|
-
<
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
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
|
-
|
105
|
-
|
106
|
-
|
107
|
-
<
|
108
|
-
<
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
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
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
</
|
146
|
-
</
|
147
|
-
|
148
|
-
|
149
|
-
stanza
|
150
|
-
|
151
|
-
|
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
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
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
|
-
|
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
|
-
|
204
|
-
|
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 '
|
4
|
-
require 'ext/nokogiri'
|
5
|
-
require 'minitest/autorun'
|
3
|
+
require 'test_helper'
|
6
4
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
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
|
-
|
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
|
-
|
24
|
-
|
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 '
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
24
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
33
|
+
before do
|
34
|
+
router.expect :route, nil, [xml]
|
35
|
+
stream.expect :router, router
|
36
|
+
end
|
29
37
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
it 'routes rather than handle locally' do
|
39
|
+
subject.process
|
40
|
+
stream.verify
|
41
|
+
router.verify
|
42
|
+
end
|
43
|
+
end
|
35
44
|
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
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
|
-
|
90
|
-
|
91
|
-
|
56
|
+
it 'sends vcard for authenticated jid' do
|
57
|
+
subject.process
|
58
|
+
stream.verify
|
59
|
+
storage.verify
|
60
|
+
end
|
61
|
+
end
|
92
62
|
|
93
|
-
|
94
|
-
|
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
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
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
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
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
|
-
|
108
|
-
|
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
|
-
|
112
|
-
|
85
|
+
before do
|
86
|
+
storage.expect :find_vcard, nil, [alice.jid.bare]
|
87
|
+
stream.expect :storage, storage, ['wonderland.lit']
|
88
|
+
end
|
113
89
|
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
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
|
143
|
-
|
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
|