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,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