blather 0.3.4 → 0.4.0

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 (110) hide show
  1. data/LICENSE +1 -1
  2. data/README.rdoc +41 -12
  3. data/examples/echo.rb +1 -1
  4. data/examples/execute.rb +0 -5
  5. data/examples/pubsub/cli.rb +64 -0
  6. data/examples/pubsub/ping_pong.rb +18 -0
  7. data/examples/rosterprint.rb +14 -0
  8. data/examples/xmpp4r/echo.rb +35 -0
  9. data/lib/blather.rb +35 -12
  10. data/lib/blather/client.rb +1 -1
  11. data/lib/blather/client/client.rb +19 -13
  12. data/lib/blather/client/dsl.rb +16 -0
  13. data/lib/blather/client/dsl/pubsub.rb +133 -0
  14. data/lib/blather/core_ext/active_support.rb +1 -117
  15. data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
  16. data/lib/blather/core_ext/nokogiri.rb +35 -0
  17. data/lib/blather/errors.rb +3 -20
  18. data/lib/blather/errors/sasl_error.rb +3 -1
  19. data/lib/blather/errors/stanza_error.rb +10 -17
  20. data/lib/blather/errors/stream_error.rb +11 -14
  21. data/lib/blather/jid.rb +1 -0
  22. data/lib/blather/roster.rb +9 -0
  23. data/lib/blather/roster_item.rb +6 -1
  24. data/lib/blather/stanza.rb +35 -18
  25. data/lib/blather/stanza/disco.rb +7 -1
  26. data/lib/blather/stanza/disco/disco_info.rb +45 -33
  27. data/lib/blather/stanza/disco/disco_items.rb +32 -21
  28. data/lib/blather/stanza/iq.rb +13 -8
  29. data/lib/blather/stanza/iq/query.rb +16 -8
  30. data/lib/blather/stanza/iq/roster.rb +33 -22
  31. data/lib/blather/stanza/message.rb +20 -31
  32. data/lib/blather/stanza/presence.rb +3 -5
  33. data/lib/blather/stanza/presence/status.rb +13 -21
  34. data/lib/blather/stanza/presence/subscription.rb +11 -16
  35. data/lib/blather/stanza/pubsub.rb +63 -0
  36. data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
  37. data/lib/blather/stanza/pubsub/create.rb +43 -0
  38. data/lib/blather/stanza/pubsub/errors.rb +9 -0
  39. data/lib/blather/stanza/pubsub/event.rb +77 -0
  40. data/lib/blather/stanza/pubsub/items.rb +63 -0
  41. data/lib/blather/stanza/pubsub/publish.rb +58 -0
  42. data/lib/blather/stanza/pubsub/retract.rb +53 -0
  43. data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
  44. data/lib/blather/stanza/pubsub/subscription.rb +66 -0
  45. data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
  46. data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
  47. data/lib/blather/stanza/pubsub_owner.rb +41 -0
  48. data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
  49. data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
  50. data/lib/blather/stream.rb +76 -168
  51. data/lib/blather/stream/client.rb +1 -2
  52. data/lib/blather/stream/component.rb +9 -5
  53. data/lib/blather/stream/features.rb +53 -0
  54. data/lib/blather/stream/features/resource.rb +63 -0
  55. data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
  56. data/lib/blather/stream/features/session.rb +44 -0
  57. data/lib/blather/stream/features/tls.rb +28 -0
  58. data/lib/blather/stream/parser.rb +70 -46
  59. data/lib/blather/xmpp_node.rb +113 -52
  60. data/spec/blather/client/client_spec.rb +44 -58
  61. data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
  62. data/spec/blather/client/dsl_spec.rb +19 -6
  63. data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
  64. data/spec/blather/errors/sasl_error_spec.rb +8 -8
  65. data/spec/blather/errors/stanza_error_spec.rb +25 -33
  66. data/spec/blather/errors/stream_error_spec.rb +21 -16
  67. data/spec/blather/errors_spec.rb +4 -11
  68. data/spec/blather/jid_spec.rb +31 -30
  69. data/spec/blather/roster_item_spec.rb +34 -23
  70. data/spec/blather/roster_spec.rb +27 -12
  71. data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
  72. data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
  73. data/spec/blather/stanza/iq/query_spec.rb +34 -11
  74. data/spec/blather/stanza/iq/roster_spec.rb +47 -30
  75. data/spec/blather/stanza/iq_spec.rb +19 -14
  76. data/spec/blather/stanza/message_spec.rb +30 -17
  77. data/spec/blather/stanza/presence/status_spec.rb +43 -20
  78. data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
  79. data/spec/blather/stanza/presence_spec.rb +34 -21
  80. data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
  81. data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
  82. data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
  83. data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
  84. data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
  85. data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
  86. data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
  87. data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
  88. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
  89. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
  90. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
  91. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
  92. data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
  93. data/spec/blather/stanza/pubsub_spec.rb +62 -0
  94. data/spec/blather/stanza_spec.rb +53 -38
  95. data/spec/blather/stream/client_spec.rb +231 -88
  96. data/spec/blather/stream/component_spec.rb +14 -5
  97. data/spec/blather/stream/parser_spec.rb +145 -0
  98. data/spec/blather/xmpp_node_spec.rb +192 -96
  99. data/spec/fixtures/pubsub.rb +311 -0
  100. data/spec/spec_helper.rb +5 -4
  101. metadata +54 -18
  102. data/Rakefile +0 -139
  103. data/ext/extconf.rb +0 -65
  104. data/ext/push_parser.c +0 -209
  105. data/lib/blather/core_ext/libxml.rb +0 -28
  106. data/lib/blather/stream/resource.rb +0 -48
  107. data/lib/blather/stream/session.rb +0 -36
  108. data/lib/blather/stream/stream_handler.rb +0 -39
  109. data/lib/blather/stream/tls.rb +0 -33
  110. data/spec/blather/core_ext/libxml_spec.rb +0 -58
@@ -1,28 +1,35 @@
1
1
  require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
2
2
 
3
- describe 'Blather::Stanza::Presence::Subscription' do
3
+ describe Blather::Stanza::Presence::Subscription do
4
4
  it 'registers itself' do
5
- XMPPNode.class_from_registration(:subscription, nil).must_equal Stanza::Presence::Subscription
5
+ Blather::XMPPNode.class_from_registration(:subscription, nil).must_equal Blather::Stanza::Presence::Subscription
6
+ end
7
+
8
+ [:subscribe, :subscribed, :unsubscribe, :unsubscribed].each do |type|
9
+ it "must be importable as #{type}" do
10
+ doc = parse_stanza "<presence type='#{type}'/>"
11
+ Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Presence::Subscription
12
+ end
6
13
  end
7
14
 
8
15
  it 'can set to on creation' do
9
- sub = Stanza::Presence::Subscription.new 'a@b'
16
+ sub = Blather::Stanza::Presence::Subscription.new 'a@b'
10
17
  sub.to.to_s.must_equal 'a@b'
11
18
  end
12
19
 
13
20
  it 'can set a type on creation' do
14
- sub = Stanza::Presence::Subscription.new nil, :subscribed
21
+ sub = Blather::Stanza::Presence::Subscription.new nil, :subscribed
15
22
  sub.type.must_equal :subscribed
16
23
  end
17
24
 
18
- it 'strips JIDs when setting #to' do
19
- sub = Stanza::Presence::Subscription.new 'a@b/c'
25
+ it 'strips Blather::JIDs when setting #to' do
26
+ sub = Blather::Stanza::Presence::Subscription.new 'a@b/c'
20
27
  sub.to.to_s.must_equal 'a@b'
21
28
  end
22
29
 
23
30
  it 'generates an approval using #approve!' do
24
- jid = JID.new 'a@b'
25
- sub = Stanza::Presence::Subscription.new
31
+ jid = Blather::JID.new 'a@b'
32
+ sub = Blather::Stanza::Presence::Subscription.new
26
33
  sub.from = jid
27
34
  sub.approve!
28
35
  sub.to.must_equal jid
@@ -30,8 +37,8 @@ describe 'Blather::Stanza::Presence::Subscription' do
30
37
  end
31
38
 
32
39
  it 'generates a refusal using #refuse!' do
33
- jid = JID.new 'a@b'
34
- sub = Stanza::Presence::Subscription.new
40
+ jid = Blather::JID.new 'a@b'
41
+ sub = Blather::Stanza::Presence::Subscription.new
35
42
  sub.from = jid
36
43
  sub.refuse!
37
44
  sub.to.must_equal jid
@@ -39,8 +46,8 @@ describe 'Blather::Stanza::Presence::Subscription' do
39
46
  end
40
47
 
41
48
  it 'generates an unsubscript using #unsubscribe!' do
42
- jid = JID.new 'a@b'
43
- sub = Stanza::Presence::Subscription.new
49
+ jid = Blather::JID.new 'a@b'
50
+ sub = Blather::Stanza::Presence::Subscription.new
44
51
  sub.from = jid
45
52
  sub.unsubscribe!
46
53
  sub.to.must_equal jid
@@ -48,8 +55,8 @@ describe 'Blather::Stanza::Presence::Subscription' do
48
55
  end
49
56
 
50
57
  it 'generates a cancellation using #cancel!' do
51
- jid = JID.new 'a@b'
52
- sub = Stanza::Presence::Subscription.new
58
+ jid = Blather::JID.new 'a@b'
59
+ sub = Blather::Stanza::Presence::Subscription.new
53
60
  sub.from = jid
54
61
  sub.cancel!
55
62
  sub.to.must_equal jid
@@ -57,8 +64,8 @@ describe 'Blather::Stanza::Presence::Subscription' do
57
64
  end
58
65
 
59
66
  it 'generates a request using #request!' do
60
- jid = JID.new 'a@b'
61
- sub = Stanza::Presence::Subscription.new
67
+ jid = Blather::JID.new 'a@b'
68
+ sub = Blather::Stanza::Presence::Subscription.new
62
69
  sub.from = jid
63
70
  sub.request!
64
71
  sub.to.must_equal jid
@@ -66,20 +73,33 @@ describe 'Blather::Stanza::Presence::Subscription' do
66
73
  end
67
74
 
68
75
  it 'has a #request? helper' do
69
- sub = Stanza::Presence::Subscription.new
76
+ sub = Blather::Stanza::Presence::Subscription.new
70
77
  sub.must_respond_to :request?
71
78
  sub.type = :subscribe
72
79
  sub.request?.must_equal true
73
80
  end
74
81
 
82
+ it "successfully routes chained actions" do
83
+ from = Blather::JID.new("foo@bar.com")
84
+ to = Blather::JID.new("baz@quux.com")
85
+ sub = Blather::Stanza::Presence::Subscription.new
86
+ sub.from = from
87
+ sub.to = to
88
+ sub.cancel!
89
+ sub.unsubscribe!
90
+ sub.type.must_equal :unsubscribe
91
+ sub.to.must_equal from
92
+ sub.from.must_equal to
93
+ end
94
+
75
95
  it "will inherit only another node's attributes" do
76
- inheritable = XMPPNode.new 'foo'
77
- inheritable.attributes[:bar] = 'baz'
96
+ inheritable = Blather::XMPPNode.new 'foo'
97
+ inheritable[:bar] = 'baz'
78
98
 
79
- sub = Stanza::Presence::Subscription.new
99
+ sub = Blather::Stanza::Presence::Subscription.new
80
100
  sub.must_respond_to :inherit
81
101
 
82
102
  sub.inherit inheritable
83
- sub.attributes[:bar].must_equal 'baz'
103
+ sub[:bar].must_equal 'baz'
84
104
  end
85
105
  end
@@ -1,53 +1,66 @@
1
1
  require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
2
2
 
3
- describe 'Blather::Stanza::Presence' do
3
+ describe Blather::Stanza::Presence do
4
4
  it 'registers itself' do
5
- XMPPNode.class_from_registration(:presence, nil).must_equal Stanza::Presence
5
+ Blather::XMPPNode.class_from_registration(:presence, nil).must_equal Blather::Stanza::Presence
6
6
  end
7
7
 
8
- it 'ensures type is one of Stanza::Presence::VALID_TYPES' do
9
- presence = Stanza::Presence.new
8
+ it 'must be importable' do
9
+ doc = parse_stanza '<presence type="probe"/>'
10
+ Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Presence
11
+ end
12
+
13
+ it 'ensures type is one of Blather::Stanza::Presence::VALID_TYPES' do
14
+ presence = Blather::Stanza::Presence.new
10
15
  lambda { presence.type = :invalid_type_name }.must_raise(Blather::ArgumentError)
11
16
 
12
- Stanza::Presence::VALID_TYPES.each do |valid_type|
17
+ Blather::Stanza::Presence::VALID_TYPES.each do |valid_type|
13
18
  presence.type = valid_type
14
19
  presence.type.must_equal valid_type
15
20
  end
16
21
  end
17
22
 
18
- Stanza::Presence::VALID_TYPES.each do |valid_type|
23
+ Blather::Stanza::Presence::VALID_TYPES.each do |valid_type|
19
24
  it "provides a helper (#{valid_type}?) for type #{valid_type}" do
20
- Stanza::Presence.new.must_respond_to :"#{valid_type}?"
25
+ Blather::Stanza::Presence.new.must_respond_to :"#{valid_type}?"
26
+ end
27
+
28
+ it "returns true on call to (#{valid_type}?) if type == #{valid_type}" do
29
+ method = "#{valid_type}?".to_sym
30
+ pres = Blather::Stanza::Presence.new
31
+ pres.type = valid_type
32
+ pres.must_respond_to method
33
+ pres.__send__(method).must_equal true
21
34
  end
22
35
  end
23
36
 
24
37
  it 'creates a Status object when importing a node with type == nil' do
25
- s = Stanza::Presence.import(XMPPNode.new)
26
- s.must_be_kind_of Stanza::Presence::Status
38
+ s = Blather::Stanza::Presence.import(Blather::XMPPNode.new)
39
+ s.must_be_kind_of Blather::Stanza::Presence::Status
27
40
  s.state.must_equal :available
28
41
  end
29
42
 
30
43
  it 'creates a Status object when importing a node with type == "unavailable"' do
31
- n = XMPPNode.new
32
- n.attributes[:type] = :unavailable
33
- s = Stanza::Presence.import(n)
34
- s.must_be_kind_of Stanza::Presence::Status
44
+ n = Blather::XMPPNode.new
45
+ n[:type] = :unavailable
46
+ s = Blather::Stanza::Presence.import(n)
47
+ s.must_be_kind_of Blather::Stanza::Presence::Status
35
48
  s.state.must_equal :unavailable
36
49
  end
37
50
 
38
51
  it 'creates a Subscription object when importing a node with type == "subscribe"' do
39
- n = XMPPNode.new
40
- n.attributes[:type] = :subscribe
41
- s = Stanza::Presence.import(n)
42
- s.must_be_kind_of Stanza::Presence::Subscription
52
+ n = Blather::XMPPNode.new
53
+ n[:type] = :subscribe
54
+ s = Blather::Stanza::Presence.import(n)
55
+ s.must_be_kind_of Blather::Stanza::Presence::Subscription
43
56
  s.type.must_equal :subscribe
44
57
  end
45
58
 
46
59
  it 'creates a Presence object when importing a node with type equal to something unkown' do
47
- n = XMPPNode.new
48
- n.attributes[:type] = :foo
49
- s = Stanza::Presence.import(n)
50
- s.must_be_kind_of Stanza::Presence
60
+ n = Blather::XMPPNode.new
61
+ n[:type] = :foo
62
+ s = Blather::Stanza::Presence.import(n)
63
+ s.must_be_kind_of Blather::Stanza::Presence
51
64
  s.type.must_equal :foo
52
65
  end
53
66
  end
@@ -0,0 +1,57 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
2
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. fixtures pubsub])
3
+
4
+ def control_affiliations
5
+ { :owner => ['node1', 'node2'],
6
+ :publisher => ['node3'],
7
+ :outcast => ['node4'],
8
+ :member => ['node5'],
9
+ :none => ['node6'] }
10
+ end
11
+
12
+ describe Blather::Stanza::PubSub::Affiliations do
13
+ it 'registers itself' do
14
+ Blather::XMPPNode.class_from_registration(:affiliations, Blather::Stanza::PubSub.registered_ns).must_equal Blather::Stanza::PubSub::Affiliations
15
+ end
16
+
17
+ it 'can be imported' do
18
+ Blather::XMPPNode.import(parse_stanza(affiliations_xml).root).must_be_instance_of Blather::Stanza::PubSub::Affiliations
19
+ end
20
+
21
+ it 'ensures an affiliations node is present on create' do
22
+ affiliations = Blather::Stanza::PubSub::Affiliations.new
23
+ affiliations.find_first('//ns:affiliations', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_nil
24
+ end
25
+
26
+ it 'ensures an affiliations node exists when calling #affiliations' do
27
+ affiliations = Blather::Stanza::PubSub::Affiliations.new
28
+ affiliations.pubsub.remove_children :affiliations
29
+ affiliations.find_first('//ns:affiliations', :ns => Blather::Stanza::PubSub.registered_ns).must_be_nil
30
+
31
+ affiliations.affiliations.wont_be_nil
32
+ affiliations.find_first('//ns:affiliations', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_nil
33
+ end
34
+
35
+ it 'defaults to a get node' do
36
+ Blather::Stanza::PubSub::Affiliations.new.type.must_equal :get
37
+ end
38
+
39
+ it 'sets the host if requested' do
40
+ aff = Blather::Stanza::PubSub::Affiliations.new :get, 'pubsub.jabber.local'
41
+ aff.to.must_equal Blather::JID.new('pubsub.jabber.local')
42
+ end
43
+
44
+ it 'can import an affiliates result node' do
45
+ node = parse_stanza(affiliations_xml).root
46
+
47
+ affiliations = Blather::Stanza::PubSub::Affiliations.new.inherit node
48
+ affiliations.size.must_equal 5
49
+ affiliations.list.must_equal control_affiliations
50
+ end
51
+
52
+ it 'will iterate over each affiliation' do
53
+ Blather::XMPPNode.import(parse_stanza(affiliations_xml).root).each do |type, nodes|
54
+ nodes.must_equal control_affiliations[type]
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,56 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
2
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. fixtures pubsub])
3
+
4
+ describe Blather::Stanza::PubSub::Create do
5
+ it 'registers itself' do
6
+ Blather::XMPPNode.class_from_registration(:create, 'http://jabber.org/protocol/pubsub').must_equal Blather::Stanza::PubSub::Create
7
+ end
8
+
9
+ it 'can be imported' do
10
+ Blather::XMPPNode.import(parse_stanza(<<-NODE).root).must_be_instance_of Blather::Stanza::PubSub::Create
11
+ <iq type='set'
12
+ from='hamlet@denmark.lit/elsinore'
13
+ to='pubsub.shakespeare.lit'
14
+ id='create1'>
15
+ <pubsub xmlns='http://jabber.org/protocol/pubsub'>
16
+ <create node='princely_musings'/>
17
+ <configure/>
18
+ </pubsub>
19
+ </iq>
20
+ NODE
21
+ end
22
+
23
+ it 'ensures a create node is present on create' do
24
+ create = Blather::Stanza::PubSub::Create.new
25
+ create.find('//ns:pubsub/ns:create', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
26
+ end
27
+
28
+ it 'ensures a configure node is present on create' do
29
+ create = Blather::Stanza::PubSub::Create.new
30
+ create.find('//ns:pubsub/ns:configure', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
31
+ end
32
+
33
+ it 'ensures a create node exists when calling #create_node' do
34
+ create = Blather::Stanza::PubSub::Create.new
35
+ create.pubsub.remove_children :create
36
+ create.find('//ns:pubsub/ns:create', :ns => Blather::Stanza::PubSub.registered_ns).must_be_empty
37
+
38
+ create.create_node.wont_be_nil
39
+ create.find('//ns:pubsub/ns:create', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
40
+ end
41
+
42
+ it 'defaults to a set node' do
43
+ create = Blather::Stanza::PubSub::Create.new
44
+ create.type.must_equal :set
45
+ end
46
+
47
+ it 'sets the host if requested' do
48
+ create = Blather::Stanza::PubSub::Create.new :set, 'pubsub.jabber.local'
49
+ create.to.must_equal Blather::JID.new('pubsub.jabber.local')
50
+ end
51
+
52
+ it 'sets the node' do
53
+ create = Blather::Stanza::PubSub::Create.new :set, 'host', 'node-name'
54
+ create.node.must_equal 'node-name'
55
+ end
56
+ end
@@ -0,0 +1,84 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
2
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. fixtures pubsub])
3
+
4
+ describe Blather::Stanza::PubSub::Event do
5
+ it 'registers itself' do
6
+ Blather::XMPPNode.class_from_registration(:event, 'http://jabber.org/protocol/pubsub#event').must_equal Blather::Stanza::PubSub::Event
7
+ end
8
+
9
+ it 'is importable' do
10
+ Blather::XMPPNode.import(parse_stanza(event_notification_xml).root).must_be_instance_of Blather::Stanza::PubSub::Event
11
+ end
12
+
13
+ it 'ensures a query node is present on create' do
14
+ evt = Blather::Stanza::PubSub::Event.new
15
+ evt.find('ns:event', :ns => Blather::Stanza::PubSub::Event.registered_ns).wont_be_empty
16
+ end
17
+
18
+ it 'ensures an event node exists when calling #event_node' do
19
+ evt = Blather::Stanza::PubSub::Event.new
20
+ evt.remove_children :event
21
+ evt.find('*[local-name()="event"]').must_be_empty
22
+
23
+ evt.event_node.wont_be_nil
24
+ evt.find('ns:event', :ns => Blather::Stanza::PubSub::Event.registered_ns).wont_be_empty
25
+ end
26
+
27
+ it 'ensures an items node exists when calling #items_node' do
28
+ evt = Blather::Stanza::PubSub::Event.new
29
+ evt.remove_children :items
30
+ evt.find('*[local-name()="items"]').must_be_empty
31
+
32
+ evt.items_node.wont_be_nil
33
+ evt.find('ns:event/ns:items', :ns => Blather::Stanza::PubSub::Event.registered_ns).wont_be_empty
34
+ end
35
+
36
+ it 'knows the associated node name' do
37
+ evt = Blather::XMPPNode.import(parse_stanza(event_with_payload_xml).root)
38
+ evt.node.must_equal 'princely_musings'
39
+ end
40
+
41
+ it 'ensures newly inherited items are PubSubItem objects' do
42
+ evt = Blather::XMPPNode.import(parse_stanza(event_with_payload_xml).root)
43
+ evt.items?.must_equal true
44
+ evt.retractions?.must_equal false
45
+ evt.items.map { |i| i.class }.uniq.must_equal [Blather::Stanza::PubSub::PubSubItem]
46
+ end
47
+
48
+ it 'will iterate over each item' do
49
+ evt = Blather::XMPPNode.import(parse_stanza(event_with_payload_xml).root)
50
+ evt.items.each { |i| i.class.must_equal Blather::Stanza::PubSub::PubSubItem }
51
+ end
52
+
53
+ it 'handles receiving subscription ids' do
54
+ evt = Blather::XMPPNode.import(parse_stanza(event_subids_xml).root)
55
+ evt.subscription_ids.must_equal ['123-abc', '004-yyy']
56
+ end
57
+
58
+ it 'can have a list of retractions' do
59
+ evt = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
60
+ <message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
61
+ <event xmlns='http://jabber.org/protocol/pubsub#event'>
62
+ <items node='princely_musings'>
63
+ <retract id='ae890ac52d0df67ed7cfdf51b644e901'/>
64
+ </items>
65
+ </event>
66
+ </message>
67
+ NODE
68
+ evt.retractions?.must_equal true
69
+ evt.items?.must_equal false
70
+ evt.retractions.must_equal %w[ae890ac52d0df67ed7cfdf51b644e901]
71
+ end
72
+
73
+ it 'can be a purge' do
74
+ evt = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
75
+ <message from='pubsub.shakespeare.lit' to='francisco@denmark.lit' id='foo'>
76
+ <event xmlns='http://jabber.org/protocol/pubsub#event'>
77
+ <purge node='princely_musings'/>
78
+ </event>
79
+ </message>
80
+ NODE
81
+ evt.purge?.wont_be_nil
82
+ evt.node.must_equal 'princely_musings'
83
+ end
84
+ end
@@ -0,0 +1,79 @@
1
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
2
+ require File.join(File.dirname(__FILE__), *%w[.. .. .. fixtures pubsub])
3
+
4
+ describe Blather::Stanza::PubSub::Items do
5
+ it 'registers itself' do
6
+ Blather::XMPPNode.class_from_registration(:items, 'http://jabber.org/protocol/pubsub').must_equal Blather::Stanza::PubSub::Items
7
+ end
8
+
9
+ it 'can be imported' do
10
+ Blather::XMPPNode.import(parse_stanza(items_all_nodes_xml).root).must_be_instance_of Blather::Stanza::PubSub::Items
11
+ end
12
+
13
+ it 'ensures an items node is present on create' do
14
+ items = Blather::Stanza::PubSub::Items.new
15
+ items.find('//ns:pubsub/ns:items', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
16
+ end
17
+
18
+ it 'ensures an items node exists when calling #items' do
19
+ items = Blather::Stanza::PubSub::Items.new
20
+ items.pubsub.remove_children :items
21
+ items.find('//ns:pubsub/ns:items', :ns => Blather::Stanza::PubSub.registered_ns).must_be_empty
22
+
23
+ items.items.wont_be_nil
24
+ items.find('//ns:pubsub/ns:items', :ns => Blather::Stanza::PubSub.registered_ns).wont_be_empty
25
+ end
26
+
27
+ it 'defaults to a get node' do
28
+ aff = Blather::Stanza::PubSub::Items.new
29
+ aff.type.must_equal :get
30
+ end
31
+
32
+ it 'ensures newly inherited items are PubSubItem objects' do
33
+ items = Blather::XMPPNode.import(parse_stanza(items_all_nodes_xml).root)
34
+ items.map { |i| i.class }.uniq.must_equal [Blather::Stanza::PubSub::PubSubItem]
35
+ end
36
+
37
+ it 'will iterate over each item' do
38
+ n = parse_stanza items_all_nodes_xml
39
+ items = Blather::Stanza::PubSub::Items.new.inherit n.root
40
+ count = 0
41
+ items.each { |i| i.must_be_instance_of Blather::Stanza::PubSub::PubSubItem; count += 1 }
42
+ count.must_equal 4
43
+ end
44
+
45
+ it 'can create an items request node to request all items' do
46
+ host = 'pubsub.jabber.local'
47
+ node = 'princely_musings'
48
+
49
+ items = Blather::Stanza::PubSub::Items.request host, node
50
+ items.find("//ns:items[@node=\"#{node}\"]", :ns => Blather::Stanza::PubSub.registered_ns).size.must_equal 1
51
+ items.to.must_equal Blather::JID.new(host)
52
+ items.node.must_equal node
53
+ end
54
+
55
+ it 'can create an items request node to request some items' do
56
+ host = 'pubsub.jabber.local'
57
+ node = 'princely_musings'
58
+ items = %w[item1 item2]
59
+
60
+ items_xpath = items.map { |i| "@id=\"#{i}\"" } * ' or '
61
+
62
+ items = Blather::Stanza::PubSub::Items.request host, node, items
63
+ items.find("//ns:items[@node=\"#{node}\"]/ns:item[#{items_xpath}]", :ns => Blather::Stanza::PubSub.registered_ns).size.must_equal 2
64
+ items.to.must_equal Blather::JID.new(host)
65
+ items.node.must_equal node
66
+ end
67
+
68
+ it 'can create an items request node to request "max_number" of items' do
69
+ host = 'pubsub.jabber.local'
70
+ node = 'princely_musings'
71
+ max = 3
72
+
73
+ items = Blather::Stanza::PubSub::Items.request host, node, nil, max
74
+ items.find("//ns:pubsub/ns:items[@node=\"#{node}\" and @max_items=\"#{max}\"]", :ns => Blather::Stanza::PubSub.registered_ns).size.must_equal 1
75
+ items.to.must_equal Blather::JID.new(host)
76
+ items.node.must_equal node
77
+ items.max_items.must_equal max
78
+ end
79
+ end