tp-blather 0.8.2

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 (150) hide show
  1. data/.autotest +13 -0
  2. data/.gemtest +0 -0
  3. data/.gitignore +19 -0
  4. data/.rspec +3 -0
  5. data/.travis.yml +8 -0
  6. data/CHANGELOG.md +249 -0
  7. data/Gemfile +4 -0
  8. data/Guardfile +5 -0
  9. data/LICENSE +22 -0
  10. data/README.md +413 -0
  11. data/Rakefile +20 -0
  12. data/TODO.md +2 -0
  13. data/blather.gemspec +51 -0
  14. data/examples/certs/README +20 -0
  15. data/examples/certs/ca-bundle.crt +3987 -0
  16. data/examples/echo.rb +19 -0
  17. data/examples/execute.rb +17 -0
  18. data/examples/ping_pong.rb +38 -0
  19. data/examples/print_hierarchy.rb +77 -0
  20. data/examples/rosterprint.rb +15 -0
  21. data/examples/stream_only.rb +28 -0
  22. data/examples/trusted_echo.rb +21 -0
  23. data/examples/xmpp4r/echo.rb +36 -0
  24. data/lib/blather.rb +112 -0
  25. data/lib/blather/cert_store.rb +53 -0
  26. data/lib/blather/client.rb +95 -0
  27. data/lib/blather/client/client.rb +345 -0
  28. data/lib/blather/client/dsl.rb +320 -0
  29. data/lib/blather/client/dsl/pubsub.rb +174 -0
  30. data/lib/blather/core_ext/eventmachine.rb +125 -0
  31. data/lib/blather/core_ext/ipaddr.rb +20 -0
  32. data/lib/blather/errors.rb +69 -0
  33. data/lib/blather/errors/sasl_error.rb +44 -0
  34. data/lib/blather/errors/stanza_error.rb +110 -0
  35. data/lib/blather/errors/stream_error.rb +84 -0
  36. data/lib/blather/file_transfer.rb +107 -0
  37. data/lib/blather/file_transfer/ibb.rb +68 -0
  38. data/lib/blather/file_transfer/s5b.rb +114 -0
  39. data/lib/blather/jid.rb +141 -0
  40. data/lib/blather/roster.rb +118 -0
  41. data/lib/blather/roster_item.rb +146 -0
  42. data/lib/blather/stanza.rb +167 -0
  43. data/lib/blather/stanza/disco.rb +32 -0
  44. data/lib/blather/stanza/disco/capabilities.rb +161 -0
  45. data/lib/blather/stanza/disco/disco_info.rb +205 -0
  46. data/lib/blather/stanza/disco/disco_items.rb +134 -0
  47. data/lib/blather/stanza/iq.rb +144 -0
  48. data/lib/blather/stanza/iq/command.rb +339 -0
  49. data/lib/blather/stanza/iq/ibb.rb +86 -0
  50. data/lib/blather/stanza/iq/ping.rb +50 -0
  51. data/lib/blather/stanza/iq/query.rb +53 -0
  52. data/lib/blather/stanza/iq/roster.rb +185 -0
  53. data/lib/blather/stanza/iq/s5b.rb +208 -0
  54. data/lib/blather/stanza/iq/si.rb +415 -0
  55. data/lib/blather/stanza/iq/vcard.rb +149 -0
  56. data/lib/blather/stanza/message.rb +428 -0
  57. data/lib/blather/stanza/message/muc_user.rb +119 -0
  58. data/lib/blather/stanza/muc/muc_user_base.rb +54 -0
  59. data/lib/blather/stanza/presence.rb +172 -0
  60. data/lib/blather/stanza/presence/c.rb +100 -0
  61. data/lib/blather/stanza/presence/muc.rb +35 -0
  62. data/lib/blather/stanza/presence/muc_user.rb +147 -0
  63. data/lib/blather/stanza/presence/status.rb +218 -0
  64. data/lib/blather/stanza/presence/subscription.rb +100 -0
  65. data/lib/blather/stanza/pubsub.rb +119 -0
  66. data/lib/blather/stanza/pubsub/affiliations.rb +79 -0
  67. data/lib/blather/stanza/pubsub/create.rb +65 -0
  68. data/lib/blather/stanza/pubsub/errors.rb +18 -0
  69. data/lib/blather/stanza/pubsub/event.rb +139 -0
  70. data/lib/blather/stanza/pubsub/items.rb +103 -0
  71. data/lib/blather/stanza/pubsub/publish.rb +103 -0
  72. data/lib/blather/stanza/pubsub/retract.rb +92 -0
  73. data/lib/blather/stanza/pubsub/subscribe.rb +68 -0
  74. data/lib/blather/stanza/pubsub/subscription.rb +135 -0
  75. data/lib/blather/stanza/pubsub/subscriptions.rb +83 -0
  76. data/lib/blather/stanza/pubsub/unsubscribe.rb +84 -0
  77. data/lib/blather/stanza/pubsub_owner.rb +51 -0
  78. data/lib/blather/stanza/pubsub_owner/delete.rb +52 -0
  79. data/lib/blather/stanza/pubsub_owner/purge.rb +52 -0
  80. data/lib/blather/stanza/x.rb +416 -0
  81. data/lib/blather/stream.rb +266 -0
  82. data/lib/blather/stream/client.rb +32 -0
  83. data/lib/blather/stream/component.rb +39 -0
  84. data/lib/blather/stream/features.rb +70 -0
  85. data/lib/blather/stream/features/register.rb +38 -0
  86. data/lib/blather/stream/features/resource.rb +63 -0
  87. data/lib/blather/stream/features/sasl.rb +190 -0
  88. data/lib/blather/stream/features/session.rb +45 -0
  89. data/lib/blather/stream/features/tls.rb +29 -0
  90. data/lib/blather/stream/parser.rb +102 -0
  91. data/lib/blather/version.rb +3 -0
  92. data/lib/blather/xmpp_node.rb +94 -0
  93. data/spec/blather/client/client_spec.rb +687 -0
  94. data/spec/blather/client/dsl/pubsub_spec.rb +492 -0
  95. data/spec/blather/client/dsl_spec.rb +266 -0
  96. data/spec/blather/errors/sasl_error_spec.rb +33 -0
  97. data/spec/blather/errors/stanza_error_spec.rb +129 -0
  98. data/spec/blather/errors/stream_error_spec.rb +108 -0
  99. data/spec/blather/errors_spec.rb +33 -0
  100. data/spec/blather/file_transfer_spec.rb +135 -0
  101. data/spec/blather/jid_spec.rb +87 -0
  102. data/spec/blather/roster_item_spec.rb +134 -0
  103. data/spec/blather/roster_spec.rb +107 -0
  104. data/spec/blather/stanza/discos/disco_info_spec.rb +247 -0
  105. data/spec/blather/stanza/discos/disco_items_spec.rb +154 -0
  106. data/spec/blather/stanza/iq/command_spec.rb +206 -0
  107. data/spec/blather/stanza/iq/ibb_spec.rb +124 -0
  108. data/spec/blather/stanza/iq/ping_spec.rb +45 -0
  109. data/spec/blather/stanza/iq/query_spec.rb +64 -0
  110. data/spec/blather/stanza/iq/roster_spec.rb +139 -0
  111. data/spec/blather/stanza/iq/s5b_spec.rb +57 -0
  112. data/spec/blather/stanza/iq/si_spec.rb +98 -0
  113. data/spec/blather/stanza/iq/vcard_spec.rb +93 -0
  114. data/spec/blather/stanza/iq_spec.rb +61 -0
  115. data/spec/blather/stanza/message/muc_user_spec.rb +152 -0
  116. data/spec/blather/stanza/message_spec.rb +282 -0
  117. data/spec/blather/stanza/presence/c_spec.rb +56 -0
  118. data/spec/blather/stanza/presence/muc_spec.rb +37 -0
  119. data/spec/blather/stanza/presence/muc_user_spec.rb +83 -0
  120. data/spec/blather/stanza/presence/status_spec.rb +144 -0
  121. data/spec/blather/stanza/presence/subscription_spec.rb +102 -0
  122. data/spec/blather/stanza/presence_spec.rb +125 -0
  123. data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
  124. data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
  125. data/spec/blather/stanza/pubsub/event_spec.rb +98 -0
  126. data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
  127. data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
  128. data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
  129. data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
  130. data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
  131. data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
  132. data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +74 -0
  133. data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
  134. data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
  135. data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
  136. data/spec/blather/stanza/pubsub_spec.rb +68 -0
  137. data/spec/blather/stanza/x_spec.rb +231 -0
  138. data/spec/blather/stanza_spec.rb +134 -0
  139. data/spec/blather/stream/client_spec.rb +1090 -0
  140. data/spec/blather/stream/component_spec.rb +108 -0
  141. data/spec/blather/stream/parser_spec.rb +152 -0
  142. data/spec/blather/stream/ssl_spec.rb +32 -0
  143. data/spec/blather/xmpp_node_spec.rb +47 -0
  144. data/spec/blather_spec.rb +34 -0
  145. data/spec/fixtures/pubsub.rb +311 -0
  146. data/spec/spec_helper.rb +17 -0
  147. data/yard/templates/default/class/html/handlers.erb +18 -0
  148. data/yard/templates/default/class/setup.rb +10 -0
  149. data/yard/templates/default/class/text/handlers.erb +1 -0
  150. metadata +459 -0
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+
3
+ def c_xml
4
+ <<-XML
5
+ <presence from='bard@shakespeare.lit/globe'>
6
+ <c xmlns='http://jabber.org/protocol/caps'
7
+ hash='sha-1'
8
+ node='http://www.chatopus.com'
9
+ ver='zHyEOgxTrkpSdGcQKH8EFPLsriY='/>
10
+ </presence>
11
+ XML
12
+ end
13
+
14
+ describe 'Blather::Stanza::Presence::C' do
15
+ it 'registers itself' do
16
+ Blather::XMPPNode.class_from_registration(:c, 'http://jabber.org/protocol/caps' ).should == Blather::Stanza::Presence::C
17
+ end
18
+
19
+ it 'must be importable' do
20
+ c = Blather::XMPPNode.parse c_xml
21
+ c.should be_kind_of Blather::Stanza::Presence::C::InstanceMethods
22
+ c.hash.should == :'sha-1'
23
+ c.node.should == 'http://www.chatopus.com'
24
+ c.ver.should == 'zHyEOgxTrkpSdGcQKH8EFPLsriY='
25
+ end
26
+
27
+ it 'ensures hash is one of Blather::Stanza::Presence::C::VALID_HASH_TYPES' do
28
+ lambda { Blather::Stanza::Presence::C.new nil, nil, :invalid_type_name }.should raise_error(Blather::ArgumentError)
29
+
30
+ Blather::Stanza::Presence::C::VALID_HASH_TYPES.each do |valid_hash|
31
+ c = Blather::Stanza::Presence::C.new nil, nil, valid_hash
32
+ c.hash.should == valid_hash.to_sym
33
+ end
34
+ end
35
+
36
+ it 'can set a hash on creation' do
37
+ c = Blather::Stanza::Presence::C.new nil, nil, :md5
38
+ c.hash.should == :md5
39
+ end
40
+
41
+ it 'can set a node on creation' do
42
+ c = Blather::Stanza::Presence::C.new 'http://www.chatopus.com'
43
+ c.node.should == 'http://www.chatopus.com'
44
+ end
45
+
46
+ it 'can set a ver on creation' do
47
+ c = Blather::Stanza::Presence::C.new nil, 'zHyEOgxTrkpSdGcQKH8EFPLsriY='
48
+ c.ver.should == 'zHyEOgxTrkpSdGcQKH8EFPLsriY='
49
+ end
50
+
51
+ it 'is equal on import and creation' do
52
+ p = Blather::XMPPNode.parse c_xml
53
+ c = Blather::Stanza::Presence::C.new 'http://www.chatopus.com', 'zHyEOgxTrkpSdGcQKH8EFPLsriY=', 'sha-1'
54
+ p.should == c
55
+ end
56
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ def muc_xml
4
+ <<-XML
5
+ <presence from='hag66@shakespeare.lit/pda'
6
+ id='n13mt3l'
7
+ to='coven@chat.shakespeare.lit/thirdwitch'>
8
+ <x xmlns='http://jabber.org/protocol/muc'/>
9
+ </presence>
10
+ XML
11
+ end
12
+
13
+ describe 'Blather::Stanza::Presence::MUC' do
14
+ it 'registers itself' do
15
+ Blather::XMPPNode.class_from_registration(:x, 'http://jabber.org/protocol/muc' ).should == Blather::Stanza::Presence::MUC
16
+ end
17
+
18
+ it 'must be importable' do
19
+ c = Blather::XMPPNode.parse(muc_xml)
20
+ c.should be_kind_of Blather::Stanza::Presence::MUC::InstanceMethods
21
+ c.xpath('ns:x', :ns => Blather::Stanza::Presence::MUC.registered_ns).count.should == 1
22
+ end
23
+
24
+ it 'ensures a form node is present on create' do
25
+ c = Blather::Stanza::Presence::MUC.new
26
+ c.xpath('ns:x', :ns => Blather::Stanza::Presence::MUC.registered_ns).should_not be_empty
27
+ end
28
+
29
+ it 'ensures a form node exists when calling #muc' do
30
+ c = Blather::Stanza::Presence::MUC.new
31
+ c.remove_children :x
32
+ c.xpath('ns:x', :ns => Blather::Stanza::Presence::MUC.registered_ns).should be_empty
33
+
34
+ c.muc.should_not be_nil
35
+ c.xpath('ns:x', :ns => Blather::Stanza::Presence::MUC.registered_ns).should_not be_empty
36
+ end
37
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ def muc_user_xml
4
+ <<-XML
5
+ <presence from='hag66@shakespeare.lit/pda'
6
+ id='n13mt3l'
7
+ to='coven@chat.shakespeare.lit/thirdwitch'>
8
+ <x xmlns='http://jabber.org/protocol/muc#user'>
9
+ <item affiliation='none'
10
+ jid='hag66@shakespeare.lit/pda'
11
+ role='participant'/>
12
+ <status code='100'/>
13
+ <status code='110'/>
14
+ <password>foobar</password>
15
+ </x>
16
+ </presence>
17
+ XML
18
+ end
19
+
20
+ describe 'Blather::Stanza::Presence::MUCUser' do
21
+ it 'must be importable' do
22
+ muc_user = Blather::XMPPNode.parse(muc_user_xml)
23
+ muc_user.should be_kind_of Blather::Stanza::Presence::MUCUser::InstanceMethods
24
+ muc_user.affiliation.should == :none
25
+ muc_user.jid.should == 'hag66@shakespeare.lit/pda'
26
+ muc_user.role.should == :participant
27
+ muc_user.status_codes.should == [100, 110]
28
+ muc_user.password.should == 'foobar'
29
+ end
30
+
31
+ it 'ensures a form node is present on create' do
32
+ c = Blather::Stanza::Presence::MUCUser.new
33
+ c.xpath('ns:x', :ns => Blather::Stanza::Presence::MUCUser.registered_ns).should_not be_empty
34
+ end
35
+
36
+ it 'ensures a form node exists when calling #muc' do
37
+ c = Blather::Stanza::Presence::MUCUser.new
38
+ c.remove_children :x
39
+ c.xpath('ns:x', :ns => Blather::Stanza::Presence::MUCUser.registered_ns).should be_empty
40
+
41
+ c.muc_user.should_not be_nil
42
+ c.xpath('ns:x', :ns => Blather::Stanza::Presence::MUCUser.registered_ns).should_not be_empty
43
+ end
44
+
45
+ it "must be able to set the affiliation" do
46
+ muc_user = Blather::Stanza::Presence::MUCUser.new
47
+ muc_user.affiliation.should == nil
48
+ muc_user.affiliation = :none
49
+ muc_user.affiliation.should == :none
50
+ end
51
+
52
+ it "must be able to set the role" do
53
+ muc_user = Blather::Stanza::Presence::MUCUser.new
54
+ muc_user.role.should == nil
55
+ muc_user.role = :participant
56
+ muc_user.role.should == :participant
57
+ end
58
+
59
+ it "must be able to set the jid" do
60
+ muc_user = Blather::Stanza::Presence::MUCUser.new
61
+ muc_user.jid.should == nil
62
+ muc_user.jid = 'foo@bar.com'
63
+ muc_user.jid.should == 'foo@bar.com'
64
+ end
65
+
66
+ it "must be able to set the status codes" do
67
+ muc_user = Blather::Stanza::Presence::MUCUser.new
68
+ muc_user.status_codes.should == []
69
+ muc_user.status_codes = [100, 110]
70
+ muc_user.status_codes.should == [100, 110]
71
+ muc_user.status_codes = [500]
72
+ muc_user.status_codes.should == [500]
73
+ end
74
+
75
+ it "must be able to set the password" do
76
+ muc_user = Blather::Stanza::Presence::MUCUser.new
77
+ muc_user.password.should == nil
78
+ muc_user.password = 'barbaz'
79
+ muc_user.password.should == 'barbaz'
80
+ muc_user.password = 'hello_world'
81
+ muc_user.password.should == 'hello_world'
82
+ end
83
+ end
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+
3
+ describe Blather::Stanza::Presence::Status do
4
+ it 'registers itself' do
5
+ Blather::XMPPNode.class_from_registration(:status, nil).should == Blather::Stanza::Presence::Status
6
+ end
7
+
8
+ it 'must be importable as unavailable' do
9
+ Blather::XMPPNode.parse('<presence type="unavailable"/>').should be_kind_of Blather::Stanza::Presence::Status::InstanceMethods
10
+ end
11
+
12
+ it 'must be importable as nil' do
13
+ Blather::XMPPNode.parse('<presence/>').should be_kind_of Blather::Stanza::Presence::Status::InstanceMethods
14
+ end
15
+
16
+ it 'must be importable with show, status and priority children' do
17
+ n = Blather::XMPPNode.parse <<-XML
18
+ <presence from='bard@shakespeare.lit/globe'>
19
+ <show>chat</show>
20
+ <status>Talk to me!</status>
21
+ <priority>10</priority>
22
+ </presence>
23
+ XML
24
+ n.should be_kind_of Blather::Stanza::Presence::Status::InstanceMethods
25
+ n.state.should == :chat
26
+ n.message.should == 'Talk to me!'
27
+ n.priority.should == 10
28
+ end
29
+
30
+ it 'can set state on creation' do
31
+ status = Blather::Stanza::Presence::Status.new :away
32
+ status.state.should == :away
33
+ end
34
+
35
+ it 'can set a message on creation' do
36
+ status = Blather::Stanza::Presence::Status.new nil, 'Say hello!'
37
+ status.message.should == 'Say hello!'
38
+ end
39
+
40
+ it 'ensures type is nil or :unavailable' do
41
+ status = Blather::Stanza::Presence::Status.new
42
+ lambda { status.type = :invalid_type_name }.should raise_error(Blather::ArgumentError)
43
+
44
+ [nil, :unavailable].each do |valid_type|
45
+ status.type = valid_type
46
+ status.type.should == valid_type
47
+ end
48
+ end
49
+
50
+ it 'ensures state is one of Presence::Status::VALID_STATES' do
51
+ status = Blather::Stanza::Presence::Status.new
52
+ lambda { status.state = :invalid_type_name }.should raise_error(Blather::ArgumentError)
53
+
54
+ Blather::Stanza::Presence::Status::VALID_STATES.each do |valid_state|
55
+ status.state = valid_state
56
+ status.state.should == valid_state
57
+ end
58
+ end
59
+
60
+ it 'returns :available if state is nil' do
61
+ Blather::Stanza::Presence::Status.new.state.should == :available
62
+ end
63
+
64
+ it 'returns :available if <show/> is blank' do
65
+ status = Blather::XMPPNode.parse(<<-NODE)
66
+ <presence><show/></presence>
67
+ NODE
68
+ status.state.should == :available
69
+ end
70
+
71
+ it 'returns :unavailable if type is :unavailable' do
72
+ status = Blather::Stanza::Presence::Status.new
73
+ status.type = :unavailable
74
+ status.state.should == :unavailable
75
+ end
76
+
77
+ it 'ensures priority is not greater than 127' do
78
+ lambda { Blather::Stanza::Presence::Status.new.priority = 128 }.should raise_error(Blather::ArgumentError)
79
+ end
80
+
81
+ it 'ensures priority is not less than -128' do
82
+ lambda { Blather::Stanza::Presence::Status.new.priority = -129 }.should raise_error(Blather::ArgumentError)
83
+ end
84
+
85
+ it 'has "attr_accessor" for priority' do
86
+ status = Blather::Stanza::Presence::Status.new
87
+ status.priority.should == 0
88
+
89
+ status.priority = 10
90
+ status.children.detect { |n| n.element_name == 'priority' }.should_not be_nil
91
+ status.priority.should == 10
92
+ end
93
+
94
+ it 'has "attr_accessor" for message' do
95
+ status = Blather::Stanza::Presence::Status.new
96
+ status.message.should be_nil
97
+
98
+ status.message = 'new message'
99
+ status.children.detect { |n| n.element_name == 'status' }.should_not be_nil
100
+ status.message.should == 'new message'
101
+ end
102
+
103
+ it 'must be comparable by priority' do
104
+ jid = Blather::JID.new 'a@b/c'
105
+
106
+ status1 = Blather::Stanza::Presence::Status.new
107
+ status1.from = jid
108
+
109
+ status2 = Blather::Stanza::Presence::Status.new
110
+ status2.from = jid
111
+
112
+ status1.priority = 1
113
+ status2.priority = -1
114
+ (status1 <=> status2).should == 1
115
+ (status2 <=> status1).should == -1
116
+
117
+ status2.priority = 1
118
+ (status1 <=> status2).should == 0
119
+ end
120
+
121
+ it 'raises an argument error if compared to a status with a different Blather::JID' do
122
+ status1 = Blather::Stanza::Presence::Status.new
123
+ status1.from = 'a@b/c'
124
+
125
+ status2 = Blather::Stanza::Presence::Status.new
126
+ status2.from = 'd@e/f'
127
+
128
+ lambda { status1 <=> status2 }.should raise_error(Blather::ArgumentError)
129
+ end
130
+
131
+ ([:available] + Blather::Stanza::Presence::Status::VALID_STATES).each do |valid_state|
132
+ it "provides a helper (#{valid_state}?) for state #{valid_state}" do
133
+ Blather::Stanza::Presence::Status.new.should respond_to :"#{valid_state}?"
134
+ end
135
+
136
+ it "returns true on call to (#{valid_state}?) if state == #{valid_state}" do
137
+ method = "#{valid_state}?".to_sym
138
+ stat = Blather::Stanza::Presence::Status.new
139
+ stat.state = valid_state
140
+ stat.should respond_to method
141
+ stat.__send__(method).should == true
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,102 @@
1
+ require 'spec_helper'
2
+
3
+ describe Blather::Stanza::Presence::Subscription do
4
+ it 'registers itself' do
5
+ Blather::XMPPNode.class_from_registration(:subscription, nil).should == Blather::Stanza::Presence::Subscription
6
+ end
7
+
8
+ [:subscribe, :subscribed, :unsubscribe, :unsubscribed].each do |type|
9
+ it "must be importable as #{type}" do
10
+ Blather::XMPPNode.parse("<presence type='#{type}'/>").should be_kind_of Blather::Stanza::Presence::Subscription::InstanceMethods
11
+ end
12
+ end
13
+
14
+ it 'can set to on creation' do
15
+ sub = Blather::Stanza::Presence::Subscription.new 'a@b'
16
+ sub.to.to_s.should == 'a@b'
17
+ end
18
+
19
+ it 'can set a type on creation' do
20
+ sub = Blather::Stanza::Presence::Subscription.new nil, :subscribed
21
+ sub.type.should == :subscribed
22
+ end
23
+
24
+ it 'strips Blather::JIDs when setting #to' do
25
+ sub = Blather::Stanza::Presence::Subscription.new 'a@b/c'
26
+ sub.to.to_s.should == 'a@b'
27
+ end
28
+
29
+ it 'generates an approval using #approve!' do
30
+ sub = Blather::Stanza.import Nokogiri::XML('<presence from="a@b" type="subscribe"><status/></presence>').root
31
+ sub.approve!
32
+ sub.to.should == 'a@b'
33
+ sub.type.should == :subscribed
34
+ end
35
+
36
+ it 'generates a refusal using #refuse!' do
37
+ jid = Blather::JID.new 'a@b'
38
+ sub = Blather::Stanza::Presence::Subscription.new
39
+ sub.from = jid
40
+ sub.refuse!
41
+ sub.to.should == jid
42
+ sub.type.should == :unsubscribed
43
+ end
44
+
45
+ it 'generates an unsubscript using #unsubscribe!' do
46
+ jid = Blather::JID.new 'a@b'
47
+ sub = Blather::Stanza::Presence::Subscription.new
48
+ sub.from = jid
49
+ sub.unsubscribe!
50
+ sub.to.should == jid
51
+ sub.type.should == :unsubscribe
52
+ end
53
+
54
+ it 'generates a cancellation using #cancel!' do
55
+ jid = Blather::JID.new 'a@b'
56
+ sub = Blather::Stanza::Presence::Subscription.new
57
+ sub.from = jid
58
+ sub.cancel!
59
+ sub.to.should == jid
60
+ sub.type.should == :unsubscribed
61
+ end
62
+
63
+ it 'generates a request using #request!' do
64
+ jid = Blather::JID.new 'a@b'
65
+ sub = Blather::Stanza::Presence::Subscription.new
66
+ sub.from = jid
67
+ sub.request!
68
+ sub.to.should == jid
69
+ sub.type.should == :subscribe
70
+ end
71
+
72
+ it 'has a #request? helper' do
73
+ sub = Blather::Stanza::Presence::Subscription.new
74
+ sub.should respond_to :request?
75
+ sub.type = :subscribe
76
+ sub.request?.should == true
77
+ end
78
+
79
+ it "successfully routes chained actions" do
80
+ from = Blather::JID.new("foo@bar.com")
81
+ to = Blather::JID.new("baz@quux.com")
82
+ sub = Blather::Stanza::Presence::Subscription.new
83
+ sub.from = from
84
+ sub.to = to
85
+ sub.cancel!
86
+ sub.unsubscribe!
87
+ sub.type.should == :unsubscribe
88
+ sub.to.should == from
89
+ sub.from.should == to
90
+ end
91
+
92
+ it "will inherit only another node's attributes" do
93
+ inheritable = Blather::XMPPNode.new 'foo'
94
+ inheritable[:bar] = 'baz'
95
+
96
+ sub = Blather::Stanza::Presence::Subscription.new
97
+ sub.should respond_to :inherit
98
+
99
+ sub.inherit inheritable
100
+ sub[:bar].should == 'baz'
101
+ end
102
+ end
@@ -0,0 +1,125 @@
1
+ require 'spec_helper'
2
+
3
+ describe Blather::Stanza::Presence do
4
+ it 'registers itself' do
5
+ Blather::XMPPNode.class_from_registration(:presence, nil).should == Blather::Stanza::Presence
6
+ end
7
+
8
+ it 'must be importable' do
9
+ Blather::XMPPNode.parse('<presence type="probe"/>').should be_instance_of Blather::Stanza::Presence
10
+ end
11
+
12
+ it 'ensures type is one of Blather::Stanza::Presence::VALID_TYPES' do
13
+ presence = Blather::Stanza::Presence.new
14
+ lambda { presence.type = :invalid_type_name }.should raise_error(Blather::ArgumentError)
15
+
16
+ Blather::Stanza::Presence::VALID_TYPES.each do |valid_type|
17
+ presence.type = valid_type
18
+ presence.type.should == valid_type
19
+ end
20
+ end
21
+
22
+ Blather::Stanza::Presence::VALID_TYPES.each do |valid_type|
23
+ it "provides a helper (#{valid_type}?) for type #{valid_type}" do
24
+ Blather::Stanza::Presence.new.should respond_to :"#{valid_type}?"
25
+ end
26
+
27
+ it "returns true on call to (#{valid_type}?) if type == #{valid_type}" do
28
+ method = "#{valid_type}?".to_sym
29
+ pres = Blather::Stanza::Presence.new
30
+ pres.type = valid_type
31
+ pres.should respond_to method
32
+ pres.__send__(method).should == true
33
+ end
34
+ end
35
+
36
+ it 'creates a C object when importing a node with a c child' do
37
+ string = <<-XML
38
+ <presence from='bard@shakespeare.lit/globe'>
39
+ <c xmlns='http://jabber.org/protocol/caps'
40
+ hash='sha-1'
41
+ node='http://www.chatopus.com'
42
+ ver='zHyEOgxTrkpSdGcQKH8EFPLsriY='/>
43
+ </presence>
44
+ XML
45
+ s = Blather::Stanza::Presence.parse string
46
+ s.should be_kind_of Blather::Stanza::Presence::C::InstanceMethods
47
+ s.node.should == 'http://www.chatopus.com'
48
+ s.handler_hierarchy.should include(:c)
49
+ end
50
+
51
+ it 'creates a Status object when importing a node with type == nil' do
52
+ s = Blather::Stanza::Presence.parse('<presence/>')
53
+ s.should be_kind_of Blather::Stanza::Presence::Status::InstanceMethods
54
+ s.state.should == :available
55
+ s.handler_hierarchy.should include(Blather::Stanza::Presence::Status.registered_name.to_sym)
56
+ end
57
+
58
+ it 'creates a Status object when importing a node with type == "unavailable"' do
59
+ s = Blather::Stanza::Presence.parse('<presence type="unavailable"/>')
60
+ s.should be_kind_of Blather::Stanza::Presence::Status::InstanceMethods
61
+ s.state.should == :unavailable
62
+ s.handler_hierarchy.should include(Blather::Stanza::Presence::Status.registered_name.to_sym)
63
+ end
64
+
65
+ it 'creates a Subscription object when importing a node with type == "subscribe"' do
66
+ s = Blather::Stanza::Presence.parse('<presence type="subscribe"/>')
67
+ s.should be_kind_of Blather::Stanza::Presence::Subscription::InstanceMethods
68
+ s.type.should == :subscribe
69
+ s.handler_hierarchy.should include(Blather::Stanza::Presence::Subscription.registered_name.to_sym)
70
+ end
71
+
72
+ it 'creates a MUC object when importing a node with a form in the MUC namespace' do
73
+ string = <<-XML
74
+ <presence from='bard@shakespeare.lit/globe'>
75
+ <x xmlns='http://jabber.org/protocol/muc'/>
76
+ </presence>
77
+ XML
78
+ s = Blather::Stanza::Presence.parse string
79
+ s.should be_kind_of Blather::Stanza::Presence::MUC::InstanceMethods
80
+ end
81
+
82
+ it 'creates a MUCUser object when importing a node with a form in the MUC#user namespace' do
83
+ string = <<-XML
84
+ <presence from='bard@shakespeare.lit/globe'>
85
+ <x xmlns='http://jabber.org/protocol/muc#user'/>
86
+ </presence>
87
+ XML
88
+ s = Blather::Stanza::Presence.parse string
89
+ s.should be_kind_of Blather::Stanza::Presence::MUCUser::InstanceMethods
90
+ end
91
+
92
+ it 'creates a Presence object when importing a node with type equal to something unknown' do
93
+ string = "<presence from='bard@shakespeare.lit/globe' type='foo'/>"
94
+ s = Blather::Stanza::Presence.parse string
95
+ s.should be_kind_of Blather::Stanza::Presence
96
+ s.type.should == :foo
97
+ s.handler_hierarchy.should include(Blather::Stanza::Presence.registered_name.to_sym)
98
+ end
99
+
100
+ it 'behaves like a C, a Status, and a MUCUser when all types of children are present' do
101
+ string = <<-XML
102
+ <presence from='bard@shakespeare.lit/globe'>
103
+ <show>chat</show>
104
+ <c xmlns='http://jabber.org/protocol/caps'
105
+ hash='sha-1'
106
+ node='http://www.chatopus.com'
107
+ ver='zHyEOgxTrkpSdGcQKH8EFPLsriY='/>
108
+ <x xmlns='http://jabber.org/protocol/muc#user'>
109
+ <item affiliation='none'
110
+ jid='hag66@shakespeare.lit/pda'
111
+ role='participant'/>
112
+ <status code='100'/>
113
+ <status code='110'/>
114
+ <password>foobar</password>
115
+ </x>
116
+ </presence>
117
+ XML
118
+ s = Blather::Stanza::Presence.parse string
119
+ s.state.should == :chat
120
+ s.node.should == 'http://www.chatopus.com'
121
+ s.role.should == :participant
122
+ s.handler_hierarchy.should include(Blather::Stanza::Presence::C.registered_name.to_sym)
123
+ s.handler_hierarchy.should include(Blather::Stanza::Presence::Status.registered_name.to_sym)
124
+ end
125
+ end