shingara-blather 0.4.8
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/LICENSE +22 -0
- data/README.md +162 -0
- data/examples/echo.rb +18 -0
- data/examples/execute.rb +16 -0
- data/examples/ping_pong.rb +37 -0
- data/examples/print_hierarchy.rb +76 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/stream_only.rb +27 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/lib/blather/client/client.rb +310 -0
- data/lib/blather/client/dsl/pubsub.rb +170 -0
- data/lib/blather/client/dsl.rb +264 -0
- data/lib/blather/client.rb +87 -0
- data/lib/blather/core_ext/nokogiri.rb +40 -0
- data/lib/blather/errors/sasl_error.rb +43 -0
- data/lib/blather/errors/stanza_error.rb +107 -0
- data/lib/blather/errors/stream_error.rb +82 -0
- data/lib/blather/errors.rb +69 -0
- data/lib/blather/jid.rb +142 -0
- data/lib/blather/roster.rb +111 -0
- data/lib/blather/roster_item.rb +122 -0
- data/lib/blather/stanza/disco/disco_info.rb +176 -0
- data/lib/blather/stanza/disco/disco_items.rb +132 -0
- data/lib/blather/stanza/disco.rb +25 -0
- data/lib/blather/stanza/iq/query.rb +53 -0
- data/lib/blather/stanza/iq/roster.rb +179 -0
- data/lib/blather/stanza/iq.rb +138 -0
- data/lib/blather/stanza/message.rb +332 -0
- data/lib/blather/stanza/presence/status.rb +212 -0
- data/lib/blather/stanza/presence/subscription.rb +101 -0
- data/lib/blather/stanza/presence.rb +163 -0
- data/lib/blather/stanza/pubsub/affiliations.rb +79 -0
- data/lib/blather/stanza/pubsub/create.rb +65 -0
- data/lib/blather/stanza/pubsub/errors.rb +18 -0
- data/lib/blather/stanza/pubsub/event.rb +123 -0
- data/lib/blather/stanza/pubsub/items.rb +103 -0
- data/lib/blather/stanza/pubsub/publish.rb +103 -0
- data/lib/blather/stanza/pubsub/retract.rb +92 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +68 -0
- data/lib/blather/stanza/pubsub/subscription.rb +134 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +81 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +68 -0
- data/lib/blather/stanza/pubsub.rb +129 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +52 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +52 -0
- data/lib/blather/stanza/pubsub_owner.rb +51 -0
- data/lib/blather/stanza.rb +149 -0
- data/lib/blather/stream/client.rb +31 -0
- data/lib/blather/stream/component.rb +38 -0
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/features/sasl.rb +187 -0
- data/lib/blather/stream/features/session.rb +44 -0
- data/lib/blather/stream/features/tls.rb +28 -0
- data/lib/blather/stream/features.rb +53 -0
- data/lib/blather/stream/parser.rb +102 -0
- data/lib/blather/stream.rb +231 -0
- data/lib/blather/xmpp_node.rb +218 -0
- data/lib/blather.rb +78 -0
- data/spec/blather/client/client_spec.rb +559 -0
- data/spec/blather/client/dsl/pubsub_spec.rb +462 -0
- data/spec/blather/client/dsl_spec.rb +143 -0
- data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
- data/spec/blather/errors/sasl_error_spec.rb +33 -0
- data/spec/blather/errors/stanza_error_spec.rb +129 -0
- data/spec/blather/errors/stream_error_spec.rb +108 -0
- data/spec/blather/errors_spec.rb +33 -0
- data/spec/blather/jid_spec.rb +87 -0
- data/spec/blather/roster_item_spec.rb +96 -0
- data/spec/blather/roster_spec.rb +103 -0
- data/spec/blather/stanza/discos/disco_info_spec.rb +226 -0
- data/spec/blather/stanza/discos/disco_items_spec.rb +148 -0
- data/spec/blather/stanza/iq/query_spec.rb +64 -0
- data/spec/blather/stanza/iq/roster_spec.rb +140 -0
- data/spec/blather/stanza/iq_spec.rb +45 -0
- data/spec/blather/stanza/message_spec.rb +132 -0
- data/spec/blather/stanza/presence/status_spec.rb +132 -0
- data/spec/blather/stanza/presence/subscription_spec.rb +105 -0
- data/spec/blather/stanza/presence_spec.rb +66 -0
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
- data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
- data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
- data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
- data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
- data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
- data/spec/blather/stanza/pubsub_spec.rb +67 -0
- data/spec/blather/stanza_spec.rb +116 -0
- data/spec/blather/stream/client_spec.rb +1011 -0
- data/spec/blather/stream/component_spec.rb +95 -0
- data/spec/blather/stream/parser_spec.rb +145 -0
- data/spec/blather/xmpp_node_spec.rb +231 -0
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +43 -0
- metadata +249 -0
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
describe Blather::Stanza::Message do
|
|
4
|
+
it 'registers itself' do
|
|
5
|
+
Blather::XMPPNode.class_from_registration(:message, nil).must_equal Blather::Stanza::Message
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'must be importable' do
|
|
9
|
+
doc = parse_stanza <<-XML
|
|
10
|
+
<message
|
|
11
|
+
to='romeo@example.net'
|
|
12
|
+
from='juliet@example.com/balcony'
|
|
13
|
+
type='chat'
|
|
14
|
+
xml:lang='en'>
|
|
15
|
+
<body>Wherefore art thou, Romeo?</body>
|
|
16
|
+
</message>
|
|
17
|
+
XML
|
|
18
|
+
Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Message
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'provides "attr_accessor" for body' do
|
|
22
|
+
s = Blather::Stanza::Message.new
|
|
23
|
+
s.body.must_be_nil
|
|
24
|
+
s.find('body').must_be_empty
|
|
25
|
+
|
|
26
|
+
s.body = 'test message'
|
|
27
|
+
s.body.wont_be_nil
|
|
28
|
+
s.find('body').wont_be_empty
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'provides "attr_accessor" for subject' do
|
|
32
|
+
s = Blather::Stanza::Message.new
|
|
33
|
+
s.subject.must_be_nil
|
|
34
|
+
s.find('subject').must_be_empty
|
|
35
|
+
|
|
36
|
+
s.subject = 'test subject'
|
|
37
|
+
s.subject.wont_be_nil
|
|
38
|
+
s.find('subject').wont_be_empty
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'provides "attr_accessor" for thread' do
|
|
42
|
+
s = Blather::Stanza::Message.new
|
|
43
|
+
s.thread.must_be_nil
|
|
44
|
+
s.find('thread').must_be_empty
|
|
45
|
+
|
|
46
|
+
s.thread = 1234
|
|
47
|
+
s.thread.wont_be_nil
|
|
48
|
+
s.find('thread').wont_be_empty
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'can set a parent attribute for thread' do
|
|
52
|
+
s = Blather::Stanza::Message.new
|
|
53
|
+
s.thread.must_be_nil
|
|
54
|
+
s.find('thread').must_be_empty
|
|
55
|
+
|
|
56
|
+
s.thread = {4321 => 1234}
|
|
57
|
+
s.thread.must_equal '1234'
|
|
58
|
+
s.parent_thread.must_equal '4321'
|
|
59
|
+
s.find('thread[@parent="4321"]').wont_be_empty
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'ensures type is one of Blather::Stanza::Message::VALID_TYPES' do
|
|
63
|
+
lambda { Blather::Stanza::Message.new nil, nil, :invalid_type_name }.must_raise(Blather::ArgumentError)
|
|
64
|
+
|
|
65
|
+
Blather::Stanza::Message::VALID_TYPES.each do |valid_type|
|
|
66
|
+
msg = Blather::Stanza::Message.new nil, nil, valid_type
|
|
67
|
+
msg.type.must_equal valid_type
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
Blather::Stanza::Message::VALID_TYPES.each do |valid_type|
|
|
72
|
+
it "provides a helper (#{valid_type}?) for type #{valid_type}" do
|
|
73
|
+
Blather::Stanza::Message.new.must_respond_to :"#{valid_type}?"
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'ensures an html node exists when asked for xhtml_node' do
|
|
78
|
+
search_args = [
|
|
79
|
+
'/message/html_ns:html',
|
|
80
|
+
{:html_ns => Blather::Stanza::Message::HTML_NS}
|
|
81
|
+
]
|
|
82
|
+
msg = Blather::Stanza::Message.new
|
|
83
|
+
msg.find_first(*search_args).must_be_nil
|
|
84
|
+
|
|
85
|
+
msg.xhtml_node
|
|
86
|
+
msg.find_first(*search_args).wont_be_nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
it 'ensures a body node exists when asked for xhtml_node' do
|
|
90
|
+
search_args = [
|
|
91
|
+
'/message/html_ns:html/body_ns:body',
|
|
92
|
+
{:html_ns => Blather::Stanza::Message::HTML_NS,
|
|
93
|
+
:body_ns => Blather::Stanza::Message::HTML_BODY_NS}
|
|
94
|
+
]
|
|
95
|
+
msg = Blather::Stanza::Message.new
|
|
96
|
+
msg.find_first(*search_args).must_be_nil
|
|
97
|
+
|
|
98
|
+
msg.xhtml_node
|
|
99
|
+
msg.find_first(*search_args).wont_be_nil
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
it 'returns an existing node when asked for xhtml_node' do
|
|
103
|
+
msg = Blather::Stanza::Message.new
|
|
104
|
+
msg << (h = Blather::XMPPNode.new('html', msg.document))
|
|
105
|
+
h.namespace = Blather::Stanza::Message::HTML_NS
|
|
106
|
+
h << (b = Blather::XMPPNode.new('body', msg.document))
|
|
107
|
+
b.namespace = Blather::Stanza::Message::HTML_BODY_NS
|
|
108
|
+
|
|
109
|
+
msg.xhtml_node.must_equal(b)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
it 'has an xhtml setter' do
|
|
113
|
+
msg = Blather::Stanza::Message.new
|
|
114
|
+
xhtml = "<some>xhtml</some>"
|
|
115
|
+
msg.xhtml = xhtml
|
|
116
|
+
msg.xhtml_node.content.strip.must_equal(xhtml)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
it 'sets valid xhtml even if the input is not valid' do
|
|
120
|
+
msg = Blather::Stanza::Message.new
|
|
121
|
+
xhtml = "<some>xhtml"
|
|
122
|
+
msg.xhtml = xhtml
|
|
123
|
+
msg.xhtml_node.content.strip.must_equal("<some>xhtml</some>")
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
it 'has an xhtml getter' do
|
|
127
|
+
msg = Blather::Stanza::Message.new
|
|
128
|
+
xhtml = "<some>xhtml</some>"
|
|
129
|
+
msg.xhtml = xhtml
|
|
130
|
+
msg.xhtml.must_equal(xhtml)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
describe Blather::Stanza::Presence::Status do
|
|
4
|
+
it 'registers itself' do
|
|
5
|
+
Blather::XMPPNode.class_from_registration(:status, nil).must_equal Blather::Stanza::Presence::Status
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it 'must be importable as unavailable' do
|
|
9
|
+
doc = parse_stanza '<presence type="unavailable"/>'
|
|
10
|
+
Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Presence::Status
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it 'must be importable as nil' do
|
|
14
|
+
doc = parse_stanza '<presence/>'
|
|
15
|
+
Blather::XMPPNode.import(doc.root).must_be_instance_of Blather::Stanza::Presence::Status
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'can set state on creation' do
|
|
19
|
+
status = Blather::Stanza::Presence::Status.new :away
|
|
20
|
+
status.state.must_equal :away
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'can set a message on creation' do
|
|
24
|
+
status = Blather::Stanza::Presence::Status.new nil, 'Say hello!'
|
|
25
|
+
status.message.must_equal 'Say hello!'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'ensures type is nil or :unavailable' do
|
|
29
|
+
status = Blather::Stanza::Presence::Status.new
|
|
30
|
+
lambda { status.type = :invalid_type_name }.must_raise(Blather::ArgumentError)
|
|
31
|
+
|
|
32
|
+
[nil, :unavailable].each do |valid_type|
|
|
33
|
+
status.type = valid_type
|
|
34
|
+
status.type.must_equal valid_type
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'ensures state is one of Presence::Status::VALID_STATES' do
|
|
39
|
+
status = Blather::Stanza::Presence::Status.new
|
|
40
|
+
lambda { status.state = :invalid_type_name }.must_raise(Blather::ArgumentError)
|
|
41
|
+
|
|
42
|
+
Blather::Stanza::Presence::Status::VALID_STATES.each do |valid_state|
|
|
43
|
+
status.state = valid_state
|
|
44
|
+
status.state.must_equal valid_state
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'returns :available if state is nil' do
|
|
49
|
+
Blather::Stanza::Presence::Status.new.state.must_equal :available
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'returns :available if <show/> is blank' do
|
|
53
|
+
status = Blather::XMPPNode.import(parse_stanza(<<-NODE).root)
|
|
54
|
+
<presence><show/><presence/>
|
|
55
|
+
NODE
|
|
56
|
+
status.state.must_equal :available
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'returns :unavailable if type is :unavailable' do
|
|
60
|
+
status = Blather::Stanza::Presence::Status.new
|
|
61
|
+
status.type = :unavailable
|
|
62
|
+
status.state.must_equal :unavailable
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'ensures priority is not greater than 127' do
|
|
66
|
+
lambda { Blather::Stanza::Presence::Status.new.priority = 128 }.must_raise(Blather::ArgumentError)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'ensures priority is not less than -128' do
|
|
70
|
+
lambda { Blather::Stanza::Presence::Status.new.priority = -129 }.must_raise(Blather::ArgumentError)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it 'has "attr_accessor" for priority' do
|
|
74
|
+
status = Blather::Stanza::Presence::Status.new
|
|
75
|
+
status.priority.must_equal 0
|
|
76
|
+
|
|
77
|
+
status.priority = 10
|
|
78
|
+
status.children.detect { |n| n.element_name == 'priority' }.wont_be_nil
|
|
79
|
+
status.priority.must_equal 10
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it 'has "attr_accessor" for message' do
|
|
83
|
+
status = Blather::Stanza::Presence::Status.new
|
|
84
|
+
status.message.must_be_nil
|
|
85
|
+
|
|
86
|
+
status.message = 'new message'
|
|
87
|
+
status.children.detect { |n| n.element_name == 'status' }.wont_be_nil
|
|
88
|
+
status.message.must_equal 'new message'
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'must be comparable by priority' do
|
|
92
|
+
jid = Blather::JID.new 'a@b/c'
|
|
93
|
+
|
|
94
|
+
status1 = Blather::Stanza::Presence::Status.new
|
|
95
|
+
status1.from = jid
|
|
96
|
+
|
|
97
|
+
status2 = Blather::Stanza::Presence::Status.new
|
|
98
|
+
status2.from = jid
|
|
99
|
+
|
|
100
|
+
status1.priority = 1
|
|
101
|
+
status2.priority = -1
|
|
102
|
+
(status1 <=> status2).must_equal 1
|
|
103
|
+
(status2 <=> status1).must_equal -1
|
|
104
|
+
|
|
105
|
+
status2.priority = 1
|
|
106
|
+
(status1 <=> status2).must_equal 0
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
it 'raises an argument error if compared to a status with a different Blather::JID' do
|
|
110
|
+
status1 = Blather::Stanza::Presence::Status.new
|
|
111
|
+
status1.from = 'a@b/c'
|
|
112
|
+
|
|
113
|
+
status2 = Blather::Stanza::Presence::Status.new
|
|
114
|
+
status2.from = 'd@e/f'
|
|
115
|
+
|
|
116
|
+
lambda { status1 <=> status2 }.must_raise(Blather::ArgumentError)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
([:available] + Blather::Stanza::Presence::Status::VALID_STATES).each do |valid_state|
|
|
120
|
+
it "provides a helper (#{valid_state}?) for state #{valid_state}" do
|
|
121
|
+
Blather::Stanza::Presence::Status.new.must_respond_to :"#{valid_state}?"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "returns true on call to (#{valid_state}?) if state == #{valid_state}" do
|
|
125
|
+
method = "#{valid_state}?".to_sym
|
|
126
|
+
stat = Blather::Stanza::Presence::Status.new
|
|
127
|
+
stat.state = valid_state
|
|
128
|
+
stat.must_respond_to method
|
|
129
|
+
stat.__send__(method).must_equal true
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
describe Blather::Stanza::Presence::Subscription do
|
|
4
|
+
it 'registers itself' do
|
|
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
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'can set to on creation' do
|
|
16
|
+
sub = Blather::Stanza::Presence::Subscription.new 'a@b'
|
|
17
|
+
sub.to.to_s.must_equal 'a@b'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'can set a type on creation' do
|
|
21
|
+
sub = Blather::Stanza::Presence::Subscription.new nil, :subscribed
|
|
22
|
+
sub.type.must_equal :subscribed
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'strips Blather::JIDs when setting #to' do
|
|
26
|
+
sub = Blather::Stanza::Presence::Subscription.new 'a@b/c'
|
|
27
|
+
sub.to.to_s.must_equal 'a@b'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'generates an approval using #approve!' do
|
|
31
|
+
jid = Blather::JID.new 'a@b'
|
|
32
|
+
sub = Blather::Stanza::Presence::Subscription.new
|
|
33
|
+
sub.from = jid
|
|
34
|
+
sub.approve!
|
|
35
|
+
sub.to.must_equal jid
|
|
36
|
+
sub.type.must_equal :subscribed
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'generates a refusal using #refuse!' do
|
|
40
|
+
jid = Blather::JID.new 'a@b'
|
|
41
|
+
sub = Blather::Stanza::Presence::Subscription.new
|
|
42
|
+
sub.from = jid
|
|
43
|
+
sub.refuse!
|
|
44
|
+
sub.to.must_equal jid
|
|
45
|
+
sub.type.must_equal :unsubscribed
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'generates an unsubscript using #unsubscribe!' do
|
|
49
|
+
jid = Blather::JID.new 'a@b'
|
|
50
|
+
sub = Blather::Stanza::Presence::Subscription.new
|
|
51
|
+
sub.from = jid
|
|
52
|
+
sub.unsubscribe!
|
|
53
|
+
sub.to.must_equal jid
|
|
54
|
+
sub.type.must_equal :unsubscribe
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
it 'generates a cancellation using #cancel!' do
|
|
58
|
+
jid = Blather::JID.new 'a@b'
|
|
59
|
+
sub = Blather::Stanza::Presence::Subscription.new
|
|
60
|
+
sub.from = jid
|
|
61
|
+
sub.cancel!
|
|
62
|
+
sub.to.must_equal jid
|
|
63
|
+
sub.type.must_equal :unsubscribed
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
it 'generates a request using #request!' do
|
|
67
|
+
jid = Blather::JID.new 'a@b'
|
|
68
|
+
sub = Blather::Stanza::Presence::Subscription.new
|
|
69
|
+
sub.from = jid
|
|
70
|
+
sub.request!
|
|
71
|
+
sub.to.must_equal jid
|
|
72
|
+
sub.type.must_equal :subscribe
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
it 'has a #request? helper' do
|
|
76
|
+
sub = Blather::Stanza::Presence::Subscription.new
|
|
77
|
+
sub.must_respond_to :request?
|
|
78
|
+
sub.type = :subscribe
|
|
79
|
+
sub.request?.must_equal true
|
|
80
|
+
end
|
|
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
|
+
|
|
95
|
+
it "will inherit only another node's attributes" do
|
|
96
|
+
inheritable = Blather::XMPPNode.new 'foo'
|
|
97
|
+
inheritable[:bar] = 'baz'
|
|
98
|
+
|
|
99
|
+
sub = Blather::Stanza::Presence::Subscription.new
|
|
100
|
+
sub.must_respond_to :inherit
|
|
101
|
+
|
|
102
|
+
sub.inherit inheritable
|
|
103
|
+
sub[:bar].must_equal 'baz'
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[.. .. spec_helper])
|
|
2
|
+
|
|
3
|
+
describe Blather::Stanza::Presence do
|
|
4
|
+
it 'registers itself' do
|
|
5
|
+
Blather::XMPPNode.class_from_registration(:presence, nil).must_equal Blather::Stanza::Presence
|
|
6
|
+
end
|
|
7
|
+
|
|
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
|
|
15
|
+
lambda { presence.type = :invalid_type_name }.must_raise(Blather::ArgumentError)
|
|
16
|
+
|
|
17
|
+
Blather::Stanza::Presence::VALID_TYPES.each do |valid_type|
|
|
18
|
+
presence.type = valid_type
|
|
19
|
+
presence.type.must_equal valid_type
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
Blather::Stanza::Presence::VALID_TYPES.each do |valid_type|
|
|
24
|
+
it "provides a helper (#{valid_type}?) for type #{valid_type}" do
|
|
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
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'creates a Status object when importing a node with type == nil' do
|
|
38
|
+
s = Blather::Stanza::Presence.import(Blather::XMPPNode.new)
|
|
39
|
+
s.must_be_kind_of Blather::Stanza::Presence::Status
|
|
40
|
+
s.state.must_equal :available
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it 'creates a Status object when importing a node with type == "unavailable"' do
|
|
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
|
|
48
|
+
s.state.must_equal :unavailable
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it 'creates a Subscription object when importing a node with type == "subscribe"' do
|
|
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
|
|
56
|
+
s.type.must_equal :subscribe
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it 'creates a Presence object when importing a node with type equal to something unkown' do
|
|
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
|
|
64
|
+
s.type.must_equal :foo
|
|
65
|
+
end
|
|
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
|