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.
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,78 +1,78 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
3
+ require 'test_helper'
7
4
 
8
- class DiscoInfoTest < MiniTest::Unit::TestCase
9
- ALICE = Vines::User.new(:jid => 'alice@wonderland.lit/home')
10
-
11
- def setup
12
- @config = Vines::Config.new do
5
+ describe Vines::Stanza::Iq::DiscoInfo do
6
+ subject { Vines::Stanza::Iq::DiscoInfo.new(xml, stream) }
7
+ let(:stream) { MiniTest::Mock.new }
8
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/home') }
9
+ let(:config) do
10
+ Vines::Config.new do
13
11
  host 'wonderland.lit' do
14
12
  storage(:fs) { dir Dir.tmpdir }
15
13
  end
16
14
  end
17
- @stream = MiniTest::Mock.new
18
- @stream.expect(:user, ALICE)
19
- @stream.expect(:config, @config)
20
15
  end
21
16
 
22
- def test_private_storage_disabled
17
+ let(:xml) do
23
18
  query = %q{<query xmlns="http://jabber.org/protocol/disco#info"/>}
24
- node = node(%Q{<iq id="42" to="wonderland.lit" type="get">#{query}</iq>})
25
-
26
- expected = node(%Q{
27
- <iq from="wonderland.lit" id="42" to="#{ALICE.jid}" type="result">
28
- <query xmlns="http://jabber.org/protocol/disco#info">
29
- <identity category="server" type="im"/>
30
- <feature var="http://jabber.org/protocol/disco#info"/>
31
- <feature var="http://jabber.org/protocol/disco#items"/>
32
- <feature var="urn:xmpp:ping"/>
33
- <feature var="vcard-temp"/>
34
- <feature var="jabber:iq:version"/>
35
- </query>
36
- </iq>
37
- }.strip.gsub(/\n|\s{2,}/, ''))
38
-
39
- @config.vhost('wonderland.lit').private_storage false
40
- @stream.expect(:write, nil, [expected])
41
-
42
- stanza = Vines::Stanza::Iq::DiscoInfo.new(node, @stream)
43
- stanza.process
44
- assert @stream.verify
19
+ node(%Q{<iq id="42" to="wonderland.lit" type="get">#{query}</iq>})
45
20
  end
46
21
 
47
- def test_private_storage_enabled
48
- query = %q{<query xmlns="http://jabber.org/protocol/disco#info"/>}
49
- node = node(%Q{<iq id="42" to="wonderland.lit" type="get">#{query}</iq>})
50
-
51
- expected = node(%Q{
52
- <iq from="wonderland.lit" id="42" to="#{ALICE.jid}" type="result">
53
- <query xmlns="http://jabber.org/protocol/disco#info">
54
- <identity category="server" type="im"/>
55
- <feature var="http://jabber.org/protocol/disco#info"/>
56
- <feature var="http://jabber.org/protocol/disco#items"/>
57
- <feature var="urn:xmpp:ping"/>
58
- <feature var="vcard-temp"/>
59
- <feature var="jabber:iq:version"/>
60
- <feature var="jabber:iq:private"/>
61
- </query>
62
- </iq>
63
- }.strip.gsub(/\n|\s{2,}/, ''))
22
+ before do
23
+ class << stream
24
+ attr_accessor :config, :user
25
+ end
26
+ stream.config = config
27
+ stream.user = alice
28
+ end
64
29
 
65
- @config.vhost('wonderland.lit').private_storage true
66
- @stream.expect(:write, nil, [expected])
30
+ describe 'when private storage is disabled' do
31
+ let(:expected) do
32
+ node(%Q{
33
+ <iq from="wonderland.lit" id="42" to="#{alice.jid}" type="result">
34
+ <query xmlns="http://jabber.org/protocol/disco#info">
35
+ <identity category="server" type="im"/>
36
+ <feature var="http://jabber.org/protocol/disco#info"/>
37
+ <feature var="http://jabber.org/protocol/disco#items"/>
38
+ <feature var="urn:xmpp:ping"/>
39
+ <feature var="vcard-temp"/>
40
+ <feature var="jabber:iq:version"/>
41
+ </query>
42
+ </iq>
43
+ })
44
+ end
67
45
 
68
- stanza = Vines::Stanza::Iq::DiscoInfo.new(node, @stream)
69
- stanza.process
70
- assert @stream.verify
46
+ it 'returns info stanza without the private storage feature' do
47
+ config.vhost('wonderland.lit').private_storage false
48
+ stream.expect :write, nil, [expected]
49
+ subject.process
50
+ stream.verify
51
+ end
71
52
  end
72
53
 
73
- private
54
+ describe 'when private storage is enabled' do
55
+ let(:expected) do
56
+ node(%Q{
57
+ <iq from="wonderland.lit" id="42" to="#{alice.jid}" type="result">
58
+ <query xmlns="http://jabber.org/protocol/disco#info">
59
+ <identity category="server" type="im"/>
60
+ <feature var="http://jabber.org/protocol/disco#info"/>
61
+ <feature var="http://jabber.org/protocol/disco#items"/>
62
+ <feature var="urn:xmpp:ping"/>
63
+ <feature var="vcard-temp"/>
64
+ <feature var="jabber:iq:version"/>
65
+ <feature var="jabber:iq:private"/>
66
+ </query>
67
+ </iq>
68
+ })
69
+ end
74
70
 
75
- def node(xml)
76
- Nokogiri::XML(xml).root
71
+ it 'announces private storage feature in info stanza result' do
72
+ config.vhost('wonderland.lit').private_storage true
73
+ stream.expect :write, nil, [expected]
74
+ subject.process
75
+ stream.verify
76
+ end
77
77
  end
78
78
  end
@@ -1,47 +1,49 @@
1
1
  # encoding: UTF-8
2
2
 
3
- require 'tmpdir'
4
- require 'vines'
5
- require 'ext/nokogiri'
6
- require 'minitest/autorun'
7
-
8
- class DiscoItemsTest < MiniTest::Unit::TestCase
9
- def setup
10
- @stream = MiniTest::Mock.new
11
- end
12
-
13
- def test_component_items
14
- query = %q{<query xmlns="http://jabber.org/protocol/disco#items"/>}
15
- node = node(%Q{<iq id="42" to="wonderland.lit" type="get">#{query}</iq>})
16
-
17
- expected = node(%q{
18
- <iq from="wonderland.lit" id="42" to="alice@wonderland.lit/home" type="result">
19
- <query xmlns="http://jabber.org/protocol/disco#items">
20
- <item jid="cake.wonderland.lit"/>
21
- <item jid="tea.wonderland.lit"/>
22
- </query>
23
- </iq>
24
- }.strip.gsub(/\n|\s{2,}/, ''))
25
-
26
- config = Vines::Config.new do
3
+ require 'test_helper'
4
+
5
+ describe Vines::Stanza::Iq::DiscoItems do
6
+ subject { Vines::Stanza::Iq::DiscoItems.new(xml, stream) }
7
+ let(:stream) { MiniTest::Mock.new }
8
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/home') }
9
+ let(:config) do
10
+ Vines::Config.new do
27
11
  host 'wonderland.lit' do
28
12
  storage(:fs) { dir Dir.tmpdir }
29
13
  components 'tea' => 'secr3t', 'cake' => 'passw0rd'
30
14
  end
31
15
  end
16
+ end
32
17
 
33
- @stream.expect(:user, Vines::User.new(:jid => 'alice@wonderland.lit/home'))
34
- @stream.expect(:write, nil, [expected])
35
- @stream.expect(:config, config)
36
-
37
- stanza = Vines::Stanza::Iq::DiscoItems.new(node, @stream)
38
- stanza.process
39
- assert @stream.verify
18
+ before do
19
+ class << stream
20
+ attr_accessor :config, :user
21
+ end
22
+ stream.config = config
23
+ stream.user = alice
40
24
  end
41
25
 
42
- private
26
+ describe 'when querying server items' do
27
+ let(:xml) do
28
+ query = %q{<query xmlns="http://jabber.org/protocol/disco#items"/>}
29
+ node(%Q{<iq id="42" to="wonderland.lit" type="get">#{query}</iq>})
30
+ end
31
+
32
+ let(:result) do
33
+ node(%q{
34
+ <iq from="wonderland.lit" id="42" to="alice@wonderland.lit/home" type="result">
35
+ <query xmlns="http://jabber.org/protocol/disco#items">
36
+ <item jid="cake.wonderland.lit"/>
37
+ <item jid="tea.wonderland.lit"/>
38
+ </query>
39
+ </iq>
40
+ })
41
+ end
43
42
 
44
- def node(xml)
45
- Nokogiri::XML(xml).root
43
+ it 'includes component domains in output' do
44
+ stream.expect :write, nil, [result]
45
+ subject.process
46
+ stream.verify
47
+ end
46
48
  end
47
49
  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 PrivateStorageTest < 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::PrivateStorage do
6
+ subject { Vines::Stanza::Iq::PrivateStorage.new(xml, stream) }
7
+ let(:alice) { Vines::User.new(jid: 'alice@wonderland.lit/tea') }
8
+ let(:storage) { MiniTest::Mock.new }
9
+ let(:stream) { MiniTest::Mock.new }
10
+ let(:config) do
11
+ Vines::Config.new do
12
12
  host 'wonderland.lit' do
13
13
  storage(:fs) { dir Dir.tmpdir }
14
14
  private_storage true
@@ -16,174 +16,169 @@ class PrivateStorageTest < MiniTest::Unit::TestCase
16
16
  end
17
17
  end
18
18
 
19
- def test_feature_disabled_raises_error
20
- query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
21
- node = node(%Q{<iq id="42" type="get">#{query}</iq>})
22
-
23
- @config.vhost('wonderland.lit').private_storage false
24
- @stream.expect(:domain, 'wonderland.lit')
25
- @stream.expect(:config, @config)
26
-
27
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
28
- assert_raises(Vines::StanzaErrors::ServiceUnavailable) { stanza.process }
29
- assert @stream.verify
19
+ before do
20
+ class << stream
21
+ attr_accessor :config, :domain, :user
22
+ end
23
+ stream.config = config
24
+ stream.user = alice
25
+ stream.domain = 'wonderland.lit'
30
26
  end
31
27
 
32
- def test_get_another_user_fragment_raises_error
33
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
34
- query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
35
- node = node(%Q{<iq id="42" to="hatter@wonderland.lit" type="get">#{query}</iq>})
28
+ describe 'when private storage feature is disabled' do
29
+ let(:xml) do
30
+ query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
31
+ node(%Q{<iq id="42" type="get">#{query}</iq>})
32
+ end
36
33
 
37
- @stream.expect(:user, alice)
34
+ before do
35
+ config.vhost('wonderland.lit').private_storage false
36
+ end
38
37
 
39
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
40
- assert_raises(Vines::StanzaErrors::Forbidden) { stanza.process }
41
- assert @stream.verify
38
+ it 'raises a service-unavailable stanza error' do
39
+ -> { subject.process }.must_raise Vines::StanzaErrors::ServiceUnavailable
40
+ stream.verify
41
+ end
42
42
  end
43
43
 
44
- def test_get_with_zero_children_raises_error
45
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
46
- query = %q{<query xmlns="jabber:iq:private"></query>}
47
- node = node(%Q{<iq id="42" type="get">#{query}</iq>})
48
-
49
- @stream.expect(:domain, 'wonderland.lit')
50
- @stream.expect(:config, @config)
44
+ describe 'when retrieving a fragment for another user jid' do
45
+ let(:xml) do
46
+ query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
47
+ node(%Q{<iq id="42" to="hatter@wonderland.lit" type="get">#{query}</iq>})
48
+ end
51
49
 
52
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
53
- assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process }
54
- assert @stream.verify
50
+ it 'raises a forbidden stanza error' do
51
+ -> { subject.process }.must_raise Vines::StanzaErrors::Forbidden
52
+ stream.verify
53
+ end
55
54
  end
56
55
 
57
- def test_get_with_two_children_raises_error
58
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
59
- query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/><two xmlns="b"/></query>}
60
- node = node(%Q{<iq id="42" type="get">#{query}</iq>})
61
-
62
- @stream.expect(:domain, 'wonderland.lit')
63
- @stream.expect(:config, @config)
56
+ describe 'when get stanza contains zero child elements' do
57
+ let(:xml) do
58
+ query = %q{<query xmlns="jabber:iq:private"></query>}
59
+ node(%Q{<iq id="42" type="get">#{query}</iq>})
60
+ end
64
61
 
65
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
66
- assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process }
67
- assert @stream.verify
62
+ it 'raises a not-acceptable stanza error' do
63
+ -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable
64
+ stream.verify
65
+ end
68
66
  end
69
67
 
70
- def test_set_with_zero_children_raises_error
71
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
72
- query = %q{<query xmlns="jabber:iq:private"></query>}
73
- node = node(%Q{<iq id="42" type="set">#{query}</iq>})
74
-
75
- @stream.expect(:domain, 'wonderland.lit')
76
- @stream.expect(:config, @config)
68
+ describe 'when get stanza contains more than one child element' do
69
+ let(:xml) do
70
+ query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/><two xmlns="b"/></query>}
71
+ node(%Q{<iq id="42" type="get">#{query}</iq>})
72
+ end
77
73
 
78
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
79
- assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process }
80
- assert @stream.verify
74
+ it 'raises a not-acceptable stanza error' do
75
+ -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable
76
+ stream.verify
77
+ end
81
78
  end
82
79
 
83
- def test_get_without_namespace_raises_error
84
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
85
- query = %q{<query xmlns="jabber:iq:private"><one/></query>}
86
- node = node(%Q{<iq id="42" type="get">#{query}</iq>})
87
-
88
- @stream.expect(:domain, 'wonderland.lit')
89
- @stream.expect(:config, @config)
80
+ describe 'when get stanza is missing a namespace' do
81
+ let(:xml) do
82
+ query = %q{<query xmlns="jabber:iq:private"><one/></query>}
83
+ node = node(%Q{<iq id="42" type="get">#{query}</iq>})
84
+ end
90
85
 
91
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
92
- assert_raises(Vines::StanzaErrors::NotAcceptable) { stanza.process }
93
- assert @stream.verify
86
+ it 'raises a not-acceptable stanza error' do
87
+ -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable
88
+ stream.verify
89
+ end
94
90
  end
95
91
 
96
- def test_get_missing_fragment_raises_error
97
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
98
- query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
99
- node = node(%Q{<iq id="42" type="get">#{query}</iq>})
100
-
101
- storage = MiniTest::Mock.new
102
- storage.expect(:find_fragment, nil, [alice.jid, node.elements[0].elements[0]])
92
+ describe 'when get stanza is missing fragment' do
93
+ let(:xml) do
94
+ query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
95
+ node(%Q{<iq id="42" type="get">#{query}</iq>})
96
+ end
103
97
 
104
- @stream.expect(:domain, 'wonderland.lit')
105
- @stream.expect(:config, @config)
106
- @stream.expect(:storage, storage, ['wonderland.lit'])
107
- @stream.expect(:user, alice)
98
+ before do
99
+ storage.expect :find_fragment, nil, [alice.jid, xml.elements[0].elements[0]]
100
+ stream.expect :storage, storage, ['wonderland.lit']
101
+ end
108
102
 
109
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
110
- assert_raises(Vines::StanzaErrors::ItemNotFound) { stanza.process }
111
- assert @stream.verify
112
- assert storage.verify
103
+ it 'raises an item-not-found stanza error' do
104
+ -> { subject.process }.must_raise Vines::StanzaErrors::ItemNotFound
105
+ stream.verify
106
+ storage.verify
107
+ end
113
108
  end
114
109
 
115
- def test_get_finds_fragment_writes_to_stream
116
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
117
- query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
118
- node = node(%Q{<iq id="42" type="get">#{query}</iq>})
119
-
120
- data = %q{<one xmlns="a"><child>data</child></one>}
121
- query = %Q{<query xmlns="jabber:iq:private">#{data}</query>}
122
- expected = node(%Q{<iq from="#{alice.jid}" id="42" to="#{alice.jid}" type="result">#{query}</iq>})
110
+ describe 'when get finds fragment successfully' do
111
+ let(:xml) do
112
+ query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
113
+ node = node(%Q{<iq id="42" type="get">#{query}</iq>})
114
+ end
123
115
 
124
- storage = MiniTest::Mock.new
125
- storage.expect(:find_fragment, node(data), [alice.jid, node.elements[0].elements[0]])
116
+ before do
117
+ data = %q{<one xmlns="a"><child>data</child></one>}
118
+ query = %Q{<query xmlns="jabber:iq:private">#{data}</query>}
119
+ expected = node(%Q{<iq from="#{alice.jid}" id="42" to="#{alice.jid}" type="result">#{query}</iq>})
126
120
 
127
- @stream.expect(:domain, 'wonderland.lit')
128
- @stream.expect(:config, @config)
129
- @stream.expect(:storage, storage, ['wonderland.lit'])
130
- @stream.expect(:user, alice)
131
- @stream.expect(:write, nil, [expected])
121
+ storage.expect :find_fragment, node(data), [alice.jid, xml.elements[0].elements[0]]
122
+ stream.expect :storage, storage, ['wonderland.lit']
123
+ stream.expect :write, nil, [expected]
124
+ end
132
125
 
133
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
134
- stanza.process
135
- assert @stream.verify
136
- assert storage.verify
126
+ it 'writes a response to the stream' do
127
+ subject.process
128
+ stream.verify
129
+ storage.verify
130
+ end
137
131
  end
138
132
 
139
- def test_set_one_fragment_writes_result_to_stream
140
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
141
- query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
142
- node = node(%Q{<iq id="42" type="set">#{query}</iq>})
143
-
144
- storage = MiniTest::Mock.new
145
- storage.expect(:save_fragment, nil, [alice.jid, node.elements[0].elements[0]])
133
+ describe 'when saving a fragment' do
134
+ let(:result) { node(%Q{<iq from="#{alice.jid}" id="42" to="#{alice.jid}" type="result"/>}) }
146
135
 
147
- expected = node(%Q{<iq from="#{alice.jid}" id="42" to="#{alice.jid}" type="result"/>})
148
-
149
- @stream.expect(:domain, 'wonderland.lit')
150
- @stream.expect(:config, @config)
151
- @stream.expect(:storage, storage, ['wonderland.lit'])
152
- @stream.expect(:user, alice)
153
- @stream.expect(:write, nil, [expected])
154
-
155
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
156
- stanza.process
157
- assert @stream.verify
158
- assert storage.verify
159
- end
136
+ before do
137
+ storage.expect :save_fragment, nil, [alice.jid, xml.elements[0].elements[0]]
138
+ stream.expect :storage, storage, ['wonderland.lit']
139
+ stream.expect :write, nil, [result]
140
+ end
160
141
 
161
- def test_set_two_fragments_writes_result_to_stream
162
- alice = Vines::User.new(:jid => 'alice@wonderland.lit/tea')
163
- query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/><two xmlns="a"/></query>}
164
- node = node(%Q{<iq id="42" type="set">#{query}</iq>})
142
+ describe 'and stanza contains zero child elements' do
143
+ let(:xml) do
144
+ query = %q{<query xmlns="jabber:iq:private"></query>}
145
+ node(%Q{<iq id="42" type="set">#{query}</iq>})
146
+ end
165
147
 
166
- storage = MiniTest::Mock.new
167
- storage.expect(:save_fragment, nil, [alice.jid, node.elements[0].elements[0]])
168
- storage.expect(:save_fragment, nil, [alice.jid, node.elements[0].elements[1]])
148
+ it 'raises a not-acceptable stanza error' do
149
+ -> { subject.process }.must_raise Vines::StanzaErrors::NotAcceptable
150
+ end
151
+ end
169
152
 
170
- expected = node(%Q{<iq from="#{alice.jid}" id="42" to="#{alice.jid}" type="result"/>})
153
+ describe 'and a single single fragment saves successfully' do
154
+ let(:xml) do
155
+ query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/></query>}
156
+ node(%Q{<iq id="42" type="set">#{query}</iq>})
157
+ end
171
158
 
172
- @stream.expect(:domain, 'wonderland.lit')
173
- @stream.expect(:config, @config)
174
- @stream.expect(:storage, storage, ['wonderland.lit'])
175
- @stream.expect(:user, alice)
176
- @stream.expect(:write, nil, [expected])
159
+ it 'writes a result to the stream' do
160
+ subject.process
161
+ stream.verify
162
+ storage.verify
163
+ end
164
+ end
177
165
 
178
- stanza = Vines::Stanza::Iq::PrivateStorage.new(node, @stream)
179
- stanza.process
180
- assert @stream.verify
181
- assert storage.verify
182
- end
166
+ describe 'and two fragments save successfully' do
167
+ let(:xml) do
168
+ query = %q{<query xmlns="jabber:iq:private"><one xmlns="a"/><two xmlns="a"/></query>}
169
+ node(%Q{<iq id="42" type="set">#{query}</iq>})
170
+ end
183
171
 
184
- private
172
+ before do
173
+ storage.expect :save_fragment, nil, [alice.jid, xml.elements[0].elements[1]]
174
+ stream.expect :storage, storage, ['wonderland.lit']
175
+ end
185
176
 
186
- def node(xml)
187
- Nokogiri::XML(xml).root
177
+ it 'writes a result to the stream' do
178
+ subject.process
179
+ stream.verify
180
+ storage.verify
181
+ end
182
+ end
188
183
  end
189
184
  end