agent_xmpp 0.1.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 (73) hide show
  1. data/.document +5 -0
  2. data/.gitignore +11 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +417 -0
  5. data/Rakefile +75 -0
  6. data/VERSION +1 -0
  7. data/agent_xmpp.gemspec +144 -0
  8. data/lib/agent_xmpp.rb +22 -0
  9. data/lib/agent_xmpp/admin.rb +113 -0
  10. data/lib/agent_xmpp/client.rb +7 -0
  11. data/lib/agent_xmpp/client/boot.rb +83 -0
  12. data/lib/agent_xmpp/client/client.rb +64 -0
  13. data/lib/agent_xmpp/client/connection.rb +108 -0
  14. data/lib/agent_xmpp/client/controller.rb +394 -0
  15. data/lib/agent_xmpp/client/message_delegate.rb +720 -0
  16. data/lib/agent_xmpp/client/message_pipe.rb +193 -0
  17. data/lib/agent_xmpp/client/response.rb +102 -0
  18. data/lib/agent_xmpp/config.rb +48 -0
  19. data/lib/agent_xmpp/main.rb +175 -0
  20. data/lib/agent_xmpp/models.rb +7 -0
  21. data/lib/agent_xmpp/models/contact.rb +85 -0
  22. data/lib/agent_xmpp/models/message.rb +152 -0
  23. data/lib/agent_xmpp/models/publication.rb +53 -0
  24. data/lib/agent_xmpp/models/roster.rb +107 -0
  25. data/lib/agent_xmpp/models/service.rb +91 -0
  26. data/lib/agent_xmpp/models/subscription.rb +61 -0
  27. data/lib/agent_xmpp/models/table_definitions.rb +107 -0
  28. data/lib/agent_xmpp/patches.rb +7 -0
  29. data/lib/agent_xmpp/patches/array.rb +32 -0
  30. data/lib/agent_xmpp/patches/float.rb +10 -0
  31. data/lib/agent_xmpp/patches/hash.rb +13 -0
  32. data/lib/agent_xmpp/patches/object.rb +15 -0
  33. data/lib/agent_xmpp/patches/rexml.rb +69 -0
  34. data/lib/agent_xmpp/patches/string.rb +15 -0
  35. data/lib/agent_xmpp/xmpp.rb +18 -0
  36. data/lib/agent_xmpp/xmpp/element.rb +158 -0
  37. data/lib/agent_xmpp/xmpp/entry.rb +36 -0
  38. data/lib/agent_xmpp/xmpp/error_response.rb +189 -0
  39. data/lib/agent_xmpp/xmpp/iq.rb +90 -0
  40. data/lib/agent_xmpp/xmpp/iq_command.rb +54 -0
  41. data/lib/agent_xmpp/xmpp/iq_disco.rb +206 -0
  42. data/lib/agent_xmpp/xmpp/iq_pubsub.rb +270 -0
  43. data/lib/agent_xmpp/xmpp/iq_roster.rb +183 -0
  44. data/lib/agent_xmpp/xmpp/iq_version.rb +89 -0
  45. data/lib/agent_xmpp/xmpp/jid.rb +150 -0
  46. data/lib/agent_xmpp/xmpp/message.rb +82 -0
  47. data/lib/agent_xmpp/xmpp/presence.rb +127 -0
  48. data/lib/agent_xmpp/xmpp/sasl.rb +241 -0
  49. data/lib/agent_xmpp/xmpp/stanza.rb +107 -0
  50. data/lib/agent_xmpp/xmpp/x_data.rb +357 -0
  51. data/test/app/app.rb +339 -0
  52. data/test/cases/test_application_message_processing.rb +65 -0
  53. data/test/cases/test_errors.rb +24 -0
  54. data/test/cases/test_presence_management.rb +139 -0
  55. data/test/cases/test_roster_management.rb +214 -0
  56. data/test/cases/test_service_discovery.rb +168 -0
  57. data/test/cases/test_session_management.rb +120 -0
  58. data/test/cases/test_version_discovery.rb +67 -0
  59. data/test/helpers/matchers.rb +23 -0
  60. data/test/helpers/mocks.rb +82 -0
  61. data/test/helpers/test_case_extensions.rb +45 -0
  62. data/test/helpers/test_client.rb +44 -0
  63. data/test/helpers/test_delegate.rb +60 -0
  64. data/test/helpers/test_helper.rb +91 -0
  65. data/test/messages/application_messages.rb +206 -0
  66. data/test/messages/error_messages.rb +35 -0
  67. data/test/messages/presence_messages.rb +66 -0
  68. data/test/messages/roster_messages.rb +126 -0
  69. data/test/messages/service_discovery_messages.rb +201 -0
  70. data/test/messages/session_messages.rb +158 -0
  71. data/test/messages/version_discovery_messages.rb +69 -0
  72. data/test/peer/peer.rb +21 -0
  73. metadata +187 -0
@@ -0,0 +1,214 @@
1
+ ##############################################################################################################
2
+ require 'test_helper'
3
+
4
+ ##############################################################################################################
5
+ class TestRosterManagement < Test::Unit::TestCase
6
+
7
+ #.........................................................................................................
8
+ def setup
9
+ @troy = AgentXmpp::Xmpp::Jid.new('troy@nowhere.com')
10
+ @dev = AgentXmpp::Xmpp::Jid.new('dev@nowhere.com')
11
+ end
12
+
13
+ #.........................................................................................................
14
+ def test_receive_roster_item(client)
15
+ delegate = client.new_delegate
16
+ delegate.on_roster_item_method.should_not be_called
17
+ delegate.on_all_roster_items_method.should_not be_called
18
+ yield client
19
+ delegate.on_roster_item_method.should be_called
20
+ delegate.on_all_roster_items_method.should be_called
21
+ end
22
+
23
+ ####------------------------------------------------------------------------------------------------------
24
+ #.........................................................................................................
25
+ should "query server for roster on succesful session start and activate configured roster items which match those returned in query result" do
26
+
27
+ config = {'jid' => 'test@nowhere.com', 'roster' =>[@dev.bare.to_s, @troy.bare.to_s], 'password' => 'nopass'}
28
+ client = TestClient.new(config)
29
+ test_init_roster(client)
30
+
31
+ end
32
+
33
+ #.........................................................................................................
34
+ should "query server for roster on succesful session start and send a subscription request to configured roster items not returned by query result" do
35
+
36
+ #### client configured with two contacts in roster. 'troy@nowhere.com' will not be returned by roster initial query
37
+ config = {'jid' => 'test@nowhere.com', 'roster' =>[@dev.bare.to_s, @troy.bare.to_s], 'password' => 'nopass'}
38
+ client = TestClient.new(config)
39
+ test_send_roster_request(client)
40
+ delegate = client.new_delegate
41
+
42
+ #### receive roster request and verify that appropriate roster item is activated and add roster message is sent for 'troy@nowhere.com'
43
+ test_receive_roster_item(client) do |client|
44
+ AgentXmpp::Roster.find_all{|r| r[:status].should be(:inactive)}
45
+ client.receiving(RosterMessages.recv_iq_result_query_roster(client, [@dev.bare.to_s])).should \
46
+ respond_with(RosterMessages.send_iq_set_query_roster(client, @troy.bare.to_s))
47
+ AgentXmpp::Contact.find_by_jid(@dev)[:status].should be(:both)
48
+ AgentXmpp::Contact.find_by_jid(@troy)[:status].should be(:inactive)
49
+ end
50
+
51
+ ### receive roster add ackgnowledgement and send subscription request
52
+ delegate = client.new_delegate
53
+ delegate.on_acknowledge_add_roster_item_method.should_not be_called
54
+ client.receiving(RosterMessages.recv_iq_result_query_roster_ack(client)).should \
55
+ respond_with(PresenceMessages.send_presence_subscribe(client, @troy.bare.to_s))
56
+ delegate.on_acknowledge_add_roster_item_method.should be_called
57
+
58
+ #### receive roster update with subscribe=none for newly added contact
59
+ test_receive_roster_item(client) do |client|
60
+ client.receiving(RosterMessages.recv_iq_set_query_roster_none(client, @troy.bare.to_s)).should not_respond
61
+ AgentXmpp::Contact.find_by_jid(@troy)[:status].should be(:added)
62
+ end
63
+
64
+ #### receive roster update with subscription=none and ask=subscribe indicating pending susbscription request for newly added contact
65
+ test_receive_roster_item(client) do |client|
66
+ client.receiving(RosterMessages.recv_iq_set_query_roster_none_subscribe(client, @troy.bare.to_s)).should not_respond
67
+ AgentXmpp::Contact.find_by_jid(@troy)[:status].should be(:ask)
68
+ end
69
+
70
+ #### receive roster update with subscription=to indicating that the contact's presence updates will be received
71
+ #### (i.e. the contact accepted the invite)
72
+ test_receive_roster_item(client) do |client|
73
+ client.receiving(RosterMessages.recv_iq_set_query_roster_to(client, @troy.bare.to_s)).should not_respond
74
+ AgentXmpp::Contact.find_by_jid(@troy)[:status].should be(:to)
75
+ end
76
+
77
+ #### receive subscribe request from contact and accept
78
+ delegate = client.new_delegate
79
+ delegate.on_presence_subscribe_method.should_not be_called
80
+ client.receiving(PresenceMessages.recv_presence_subscribe(client, @troy.bare.to_s)).should \
81
+ respond_with(PresenceMessages.send_presence_subscribed(client, @troy.bare.to_s))
82
+ delegate.on_presence_subscribe_method.should be_called
83
+
84
+ #### receive roster update with subscription=both indicating that the contact's presence updates will be received and contact
85
+ #### will treceive presence updates and activate contact roster item
86
+ test_receive_roster_item(client) do |client|
87
+ client.receiving(RosterMessages.recv_iq_set_query_roster_both(client, @troy.bare.to_s)).should not_respond
88
+ AgentXmpp::Contact.find_by_jid(@troy)[:status].should be(:both)
89
+ end
90
+
91
+ end
92
+
93
+ #.........................................................................................................
94
+ should "query server for roster on succesful session start and send an unsubscribe request to roster items returned by query result that are not in the configuration roster" do
95
+
96
+ #### client configured with one contact in roster. 'troy@nowhere.com' will be returned by roster initial query
97
+ config = {'jid' => 'test@nowhere.com', 'roster' =>[@dev.bare.to_s], 'password' => 'nopass'}
98
+ client = TestClient.new(config)
99
+ test_send_roster_request(client)
100
+ delegate = client.new_delegate
101
+
102
+ #### receive roster request and verify that appropriate roster item is activated and remove roster message is sent for 'troy@nowhere.com'
103
+ test_receive_roster_item(client) do |client|
104
+ AgentXmpp::Roster.find_all{|r| r[:status].should be(:inactive)}
105
+ client.receiving(RosterMessages.recv_iq_result_query_roster(client, [@dev.bare.to_s, @troy.bare.to_s])).should \
106
+ respond_with(RosterMessages.send_iq_set_query_roster_remove(client, @troy.bare.to_s))
107
+ AgentXmpp::Contact.find_by_jid(@dev)[:status].should be(:both)
108
+ end
109
+
110
+ #### receive roster remove ackgnowledgement
111
+ delegate = client.new_delegate
112
+ delegate.on_acknowledge_remove_roster_item_method.should_not be_called
113
+ client.receiving(RosterMessages.recv_iq_result_query_roster_ack(client)).should not_respond
114
+ delegate.on_acknowledge_remove_roster_item_method.should be_called
115
+
116
+ #### recieve roster item remove
117
+ delegate.on_remove_roster_item_method.should_not be_called
118
+ delegate.on_all_roster_items_method.should_not be_called
119
+ client.receiving(RosterMessages.recv_iq_set_query_roster_remove(client, @troy.bare.to_s)).should not_respond
120
+ AgentXmpp::Contact.has_jid?(@troy).should be(false)
121
+ delegate.on_remove_roster_item_method.should be_called
122
+ delegate.on_all_roster_items_method.should be_called
123
+
124
+ end
125
+
126
+ #.........................................................................................................
127
+ should "remove roster item if a roster add message is received for a roster item not in the configuration roster" do
128
+
129
+ config = {'jid' => 'test@nowhere.com', 'roster' =>[@dev.bare.to_s], 'password' => 'nopass'}
130
+ client = TestClient.new(config)
131
+ test_init_roster(client)
132
+
133
+ #### receive roster request and verify that appropriate roster item is not configured and send remove roster message to 'troy@nowhere.com'
134
+ test_receive_roster_item(client) do |client|
135
+ AgentXmpp::Roster.find_all{|r| r[:status].should be(:inactive)}
136
+ client.receiving(RosterMessages.recv_iq_set_query_roster_none_subscribe(client, [@troy.bare.to_s])).should \
137
+ respond_with(RosterMessages.send_iq_set_query_roster_remove(client, @troy.bare.to_s))
138
+ AgentXmpp::Contact.has_jid?(@troy).should be(false)
139
+ end
140
+
141
+ #### receive roster remove ackgnowledgement
142
+ delegate = client.new_delegate
143
+ delegate.on_acknowledge_remove_roster_item_method.should_not be_called
144
+ client.receiving(RosterMessages.recv_iq_result_query_roster_ack(client)).should not_respond
145
+ delegate.on_acknowledge_remove_roster_item_method.should be_called
146
+
147
+ end
148
+
149
+ #.........................................................................................................
150
+ should "query server for roster on succesful session start and throw an exeception if there is an error retrieving roster" do
151
+
152
+ #### client configured with two contacts in roster
153
+ config = {'jid' => 'test@nowhere.com', 'roster' =>[@dev.bare.to_s], 'password' => 'nopass'}
154
+ client = TestClient.new(config)
155
+ test_send_roster_request(client)
156
+ delegate = client.new_delegate
157
+
158
+ #### receive roster request and verify that roster items are activated
159
+ lambda{client.receiving(RosterMessages.recv_error_query_roster_add(client))}.should raise_error(AgentXmpp::AgentXmppError)
160
+
161
+ end
162
+
163
+ #.........................................................................................................
164
+ should "not respond to errors received in response to a remove roster query" do
165
+
166
+ config = {'jid' => 'test@nowhere.com', 'roster' =>[@dev.bare.to_s], 'password' => 'nopass'}
167
+ client = TestClient.new(config)
168
+ test_init_roster(client)
169
+
170
+ #### receive roster request and verify that appropriate roster item is not configured and send remove roster message to 'troy@nowhere.com'
171
+ test_receive_roster_item(client) do |client|
172
+ AgentXmpp::Roster.find_all{|r| r[:status].should be(:inactive)}
173
+ client.receiving(RosterMessages.recv_iq_set_query_roster_none_subscribe(client, [@troy.bare.to_s])).should \
174
+ respond_with(RosterMessages.send_iq_set_query_roster_remove(client, @troy.bare.to_s))
175
+ AgentXmpp::Contact.has_jid?(@troy).should be(false)
176
+ end
177
+
178
+ #### receive roster remove ackgnowledgement
179
+ delegate = client.new_delegate
180
+ delegate.on_remove_roster_item_error_method.should_not be_called
181
+ client.receiving(RosterMessages.recv_error_query_roster_remove(client)).should not_respond
182
+ AgentXmpp::Contact.has_jid?(@troy).should be(false)
183
+ delegate.on_remove_roster_item_error_method.should be_called
184
+
185
+ end
186
+
187
+ #.........................................................................................................
188
+ should "not respond to errors received in response to an add roster query but should remove roster item from configured list" do
189
+
190
+ #### client configured with two contacts in roster. 'troy@nowhere.com' will not be returned by roster initial query
191
+ config = {'jid' => 'test@nowhere.com', 'roster' =>[@dev.bare.to_s, @troy.bare.to_s], 'password' => 'nopass'}
192
+ client = TestClient.new(config)
193
+ test_send_roster_request(client)
194
+ delegate = client.new_delegate
195
+
196
+ #### receive roster request and verify that appropriate roster item is activated and add roster message is sent for 'troy@nowhere.com'
197
+ test_receive_roster_item(client) do |client|
198
+ AgentXmpp::Roster.find_all{|r| r[:status].should be(:inactive)}
199
+ client.receiving(RosterMessages.recv_iq_result_query_roster(client, [@dev.bare.to_s])).should \
200
+ respond_with(RosterMessages.send_iq_set_query_roster(client, @troy.bare.to_s))
201
+ AgentXmpp::Contact.find_by_jid(@dev)[:status].should be(:both)
202
+ AgentXmpp::Contact.find_by_jid(@troy)[:status].should be(:inactive)
203
+ end
204
+
205
+ ### receive roster add ackgnowledgement and send subscription request
206
+ delegate = client.new_delegate
207
+ delegate.on_add_roster_item_error_method.should_not be_called
208
+ client.receiving(RosterMessages.recv_error_query_roster_remove(client)).should not_respond
209
+ delegate.on_add_roster_item_error_method.should be_called
210
+ AgentXmpp::Contact.has_jid?(@troy).should be(false)
211
+
212
+ end
213
+
214
+ end
@@ -0,0 +1,168 @@
1
+ ##############################################################################################################
2
+ require 'test_helper'
3
+
4
+ ##############################################################################################################
5
+ class TestServiceDiscovery < Test::Unit::TestCase
6
+
7
+ #.........................................................................................................
8
+ def setup
9
+ @client = TestClient.new()
10
+ test_init_roster(@client)
11
+ @delegate = @client.new_delegate
12
+ @server = AgentXmpp::Xmpp::Jid.new(@client.jid.domain)
13
+ @test = AgentXmpp::Xmpp::Jid.new('test@plan-b.ath.cx/home')
14
+ @noone = AgentXmpp::Xmpp::Jid.new('noone@plan-b.ath.cx/nowhere')
15
+ end
16
+
17
+ ####------------------------------------------------------------------------------------------------------
18
+ context "after sesson start a disco#info request addressed to the server should be generated" do
19
+
20
+ #.........................................................................................................
21
+ setup do
22
+ @delegate.on_discoinfo_result_method.should_not be_called
23
+ AgentXmpp::Service.has_disco_info?(@server).should be(false)
24
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_result_query_discoinfo(@client, @server.to_s)).should \
25
+ respond_with(ServiceDiscoveryMessages.send_iq_get_query_discoitems(@client, @server.to_s))
26
+ @delegate.on_discoinfo_result_method.should be_called
27
+ AgentXmpp::Service.has_disco_info?(@server).should be(true)
28
+ end
29
+
30
+ #.........................................................................................................
31
+ should "and the result update the server roster entry and generate a disco#info request if the result is not an error" do
32
+ end
33
+
34
+ #.........................................................................................................
35
+ should "update the server roster entry with result of server disco#items request if the result is not an error" do
36
+ @delegate.on_discoitems_result_method.should_not be_called
37
+ AgentXmpp::Service.has_disco_items?(@server).should be(false)
38
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_result_query_discoitems(@client, @server.to_s)).should not_respond
39
+ @delegate.on_discoitems_result_method.should be_called
40
+ AgentXmpp::Service.has_disco_items?(@server).should be(true)
41
+ end
42
+
43
+ #.........................................................................................................
44
+ should "not update the server roster entry with the disco#items result if the result is an error" do
45
+ @delegate.on_discoitems_result_method.should_not be_called
46
+ @delegate.on_discoitems_error_method.should_not be_called
47
+ AgentXmpp::Service.has_disco_items?(@server).should be(false)
48
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_error_query_discoitems(@client, @server.to_s)).should not_respond
49
+ @delegate.on_discoitems_result_method.should_not be_called
50
+ @delegate.on_discoitems_error_method.should be_called
51
+ AgentXmpp::Service.has_disco_items?(@server).should be(false)
52
+ end
53
+
54
+ end
55
+
56
+ ####------------------------------------------------------------------------------------------------------
57
+ context "after transition of contact to presence with type=available a disco#info request addressed to the contact should be genearated and the result" do
58
+
59
+ #.........................................................................................................
60
+ setup do
61
+ AgentXmpp::Xmpp::IdGenerator.set_gen_id([1,2])
62
+ @client.receiving(PresenceMessages.recv_presence_available(@client, @test.to_s))
63
+ @delegate.on_discoinfo_result_method.should_not be_called
64
+ AgentXmpp::Service.has_disco_info?(@test).should be(false)
65
+ AgentXmpp::Xmpp::IdGenerator.set_gen_id
66
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_result_query_discoinfo(@client, @test.to_s)).should \
67
+ respond_with(ServiceDiscoveryMessages.send_iq_get_query_discoitems(@client, @test.to_s))
68
+ @delegate.on_discoinfo_result_method.should be_called
69
+ AgentXmpp::Service.has_disco_info?(@test).should be(true)
70
+ end
71
+
72
+ #.........................................................................................................
73
+ should "update the contact roster entry and generate a disco#items request if the result is not an error" do
74
+ end
75
+
76
+ #.........................................................................................................
77
+ should "update the contact roster entry with result of contact disco#items request if the result is not an error" do
78
+ @delegate.on_discoitems_result_method.should_not be_called
79
+ AgentXmpp::Service.has_disco_items?(@test).should be(false)
80
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_result_query_discoitems(@client, @test.to_s)).should not_respond
81
+ @delegate.on_discoitems_result_method.should be_called
82
+ AgentXmpp::Service.has_disco_items?(@test).should be(true)
83
+ end
84
+
85
+ #.........................................................................................................
86
+ should "not update the contact roster entry with the disco#info result or geneate a disco#items request if the result is an error" do
87
+ @delegate.on_discoitems_result_method.should_not be_called
88
+ @delegate.on_discoitems_error_method.should_not be_called
89
+ AgentXmpp::Service.has_disco_items?(@test).should be(false)
90
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_error_query_discoitems(@client, @test.to_s)).should not_respond
91
+ @delegate.on_discoitems_result_method.should_not be_called
92
+ @delegate.on_discoitems_error_method.should be_called
93
+ AgentXmpp::Service.has_disco_items?(@test).should be(false)
94
+ end
95
+
96
+ end
97
+
98
+ #.........................................................................................................
99
+ should "not update the roster entry with the disco#info result or geneate a disco#items request if an error is received as a result of a disco#info request" do
100
+ @delegate.on_discoinfo_result_method.should_not be_called
101
+ @delegate.on_discoinfo_error_method.should_not be_called
102
+ AgentXmpp::Service.has_disco_info?(@server).should be(false)
103
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_error_query_discoinfo(@client, @server.to_s)).should not_respond
104
+ AgentXmpp::Service.has_disco_info?(@server).should be(false)
105
+ @delegate.on_discoinfo_result_method.should_not be_called
106
+ @delegate.on_discoinfo_error_method.should be_called
107
+ end
108
+
109
+ #.........................................................................................................
110
+ should "respond with features and identity when get disco#info is received without a specified node from a jid in the configuration roster" do
111
+ @delegate.on_discoinfo_get_method.should_not be_called
112
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_get_query_discoinfo(@client, @test.to_s)).should \
113
+ respond_with(ServiceDiscoveryMessages.send_iq_result_query_discoinfo(@client, @test.to_s))
114
+ @delegate.on_discoinfo_get_method.should be_called
115
+ end
116
+
117
+ #.........................................................................................................
118
+ should "respond with service-unavailable error when get disco#info is received for unsupported node" do
119
+ @delegate.on_discoinfo_get_method.should_not be_called
120
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_get_query_discoinfo_error(@client, @test.to_s)).should \
121
+ respond_with(ServiceDiscoveryMessages.send_iq_error_discoinfo_service_unavailable(@client, @test.to_s))
122
+ @delegate.on_discoinfo_get_method.should be_called
123
+ end
124
+
125
+ #.........................................................................................................
126
+ should "not respond if get disco#info is received from a jid not in the configuration roster" do
127
+ AgentXmpp::Contact.has_jid?(@noone).should be(false)
128
+ @delegate.on_discoinfo_get_method.should_not be_called
129
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_get_query_discoinfo(@client, @noone.to_s)).should not_respond
130
+ AgentXmpp::Contact.has_jid?(@noone).should be(false)
131
+ @delegate.on_discoinfo_get_method.should be_called
132
+ end
133
+
134
+ #.........................................................................................................
135
+ should "respond with empty result when get disco#items is received with no specified node from a jid in the configuration roster" do
136
+ @delegate.on_discoitems_get_method.should_not be_called
137
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_get_query_discoitems(@client, @test.to_s)).should \
138
+ respond_with(ServiceDiscoveryMessages.send_iq_result_query_discoitems(@client, @test.to_s))
139
+ @delegate.on_discoitems_get_method.should be_called
140
+ end
141
+
142
+ #.........................................................................................................
143
+ should "respond with command nodes when get disco#items is received for the node 'http://jabber.org/protocol/commands'" do
144
+ @delegate.on_discoitems_get_method.should_not be_called
145
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_get_query_discoitems_for_commands_node(@client, @test.to_s)).should \
146
+ respond_with(ServiceDiscoveryMessages.send_iq_result_query_discoitems_for_commands_node(@client, @test.to_s))
147
+ @delegate.on_discoitems_get_method.should be_called
148
+ end
149
+
150
+ #.........................................................................................................
151
+ should "respond with item-not-found error when get disco#items is received for unsupported node" do
152
+ @delegate.on_discoitems_get_method.should_not be_called
153
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_get_query_discoitems_error(@client, @test.to_s)).should \
154
+ respond_with(ServiceDiscoveryMessages.send_iq_error_discoitems_item_not_found(@client, @test.to_s))
155
+ @delegate.on_discoitems_get_method.should be_called
156
+ end
157
+
158
+ #.........................................................................................................
159
+ should "not respond if get disco#items is received from a jid not in the configuration roster" do
160
+ AgentXmpp::Contact.has_jid?(@noone).should be(false)
161
+ @delegate.on_discoitems_get_method.should_not be_called
162
+ @client.receiving(ServiceDiscoveryMessages.recv_iq_get_query_discoitems(@client, @noone.to_s)).should not_respond
163
+ AgentXmpp::Contact.has_jid?(@noone).should be(false)
164
+ @delegate.on_discoitems_get_method.should be_called
165
+ end
166
+
167
+ end
168
+
@@ -0,0 +1,120 @@
1
+ ##############################################################################################################
2
+ require 'test_helper'
3
+
4
+ ##############################################################################################################
5
+ class TestSessionManagement < Test::Unit::TestCase
6
+
7
+ #.........................................................................................................
8
+ def setup
9
+ @client = TestClient.new
10
+ AgentXmpp::Xmpp::IdGenerator.set_gen_id
11
+ @delegate = @client.new_delegate
12
+ end
13
+
14
+ #.........................................................................................................
15
+ should "authenticate with PLAIN SASL authentication when stream features includes PLAIN authentication" do
16
+
17
+ #### connect to server
18
+ @client.client.pipe.connection_completed.should \
19
+ respond_with(SessionMessages.send_supported_xml_version(@client), SessionMessages.send_stream(@client))
20
+
21
+ #### receive pre authentication stream feautues and mechanisms and authenticate
22
+ @delegate.on_authenticate_method.should_not be_called
23
+ @delegate.on_preauthenticate_features_method.should_not be_called
24
+ @client.receiving(SessionMessages.recv_preauthentication_stream_features_with_plain_SASL(@client)).should \
25
+ respond_with(SessionMessages.send_auth_plain(@client))
26
+ @client.receiving(SessionMessages.recv_auth_success(@client)).should respond_with(SessionMessages.send_stream(@client))
27
+ @delegate.on_preauthenticate_features_method.should be_called
28
+ @delegate.on_authenticate_method.should be_called
29
+
30
+ #### bind resource
31
+ @delegate.on_bind_method.should_not be_called
32
+ @delegate.on_postauthenticate_features_method.should_not be_called
33
+ @client.receiving(SessionMessages.recv_postauthentication_stream_features(@client)).should respond_with(SessionMessages.send_iq_set_bind(@client))
34
+ @client.receiving(SessionMessages.recv_iq_result_bind(@client)).should respond_with(SessionMessages.send_iq_set_session(@client))
35
+ @delegate.on_postauthenticate_features_method.should be_called
36
+ @delegate.on_bind_method.should be_called
37
+
38
+ #### start session and request roster
39
+ @delegate.on_start_session_method.should_not be_called
40
+ @client.receiving(SessionMessages.recv_iq_result_session(@client)).should \
41
+ respond_with(SessionMessages.send_presence_init(@client), RosterMessages.send_iq_get_query_roster(@client),
42
+ ServiceDiscoveryMessages.send_iq_get_query_discoinfo(@client, @client.jid.domain))
43
+ @delegate.on_start_session_method.should be_called
44
+
45
+ end
46
+
47
+ #.........................................................................................................
48
+ should "raise exception when stream features do not include PLAIN authentication" do
49
+
50
+ #### connect to server
51
+ @client.client.pipe.connection_completed
52
+
53
+ #### receive pre authentication stream feautues which do not include plain authentication
54
+ lambda{@client.receiving(SessionMessages.recv_preauthentication_stream_features_without_plain_SASL(@client))}.should \
55
+ raise_error(AgentXmpp::AgentXmppError)
56
+ end
57
+
58
+ #.........................................................................................................
59
+ should "raise exception when authentication fails" do
60
+
61
+ #### connect to server
62
+ @client.client.pipe.connection_completed
63
+
64
+ #### receive pre authentication stream feautues and mechanisms and authenticate
65
+ @client.receiving(SessionMessages.recv_preauthentication_stream_features_with_plain_SASL(@client)).should \
66
+ respond_with(SessionMessages.send_auth_plain(@client))
67
+ lambda{@client.receiving(SessionMessages.recv_auth_failure(@client))}.should raise_error(AgentXmpp::AgentXmppError)
68
+
69
+ end
70
+
71
+ #.........................................................................................................
72
+ should "raise exception when bind fails" do
73
+
74
+ #### connect to server
75
+ @client.client.pipe.connection_completed
76
+
77
+ #### receive pre authentication stream feautues and mechanisms and authenticate
78
+ @delegate.on_authenticate_method.should_not be_called
79
+ @delegate.on_preauthenticate_features_method.should_not be_called
80
+ @client.receiving(SessionMessages.recv_preauthentication_stream_features_with_plain_SASL(@client)).should \
81
+ respond_with(SessionMessages.send_auth_plain(@client))
82
+ @client.receiving(SessionMessages.recv_auth_success(@client)).should respond_with(SessionMessages.send_stream(@client))
83
+ @delegate.on_preauthenticate_features_method.should be_called
84
+ @delegate.on_authenticate_method.should be_called
85
+
86
+ #### bind resource and receive error
87
+ @client.receiving(SessionMessages.recv_postauthentication_stream_features(@client)).should respond_with(SessionMessages.send_iq_set_bind(@client))
88
+ lambda{@client.receiving(SessionMessages.recv_error_bind(@client))}.should raise_error(AgentXmpp::AgentXmppError)
89
+
90
+ end
91
+
92
+ #.........................................................................................................
93
+ should "raise exception when session start fails" do
94
+
95
+ #### connect to server
96
+ @client.client.pipe.connection_completed
97
+
98
+ #### receive pre authentication stream feautues and mechanisms and authenticate
99
+ @delegate.on_authenticate_method.should_not be_called
100
+ @delegate.on_preauthenticate_features_method.should_not be_called
101
+ @client.receiving(SessionMessages.recv_preauthentication_stream_features_with_plain_SASL(@client)).should \
102
+ respond_with(SessionMessages.send_auth_plain(@client))
103
+ @client.receiving(SessionMessages.recv_auth_success(@client)).should respond_with(SessionMessages.send_stream(@client))
104
+ @delegate.on_preauthenticate_features_method.should be_called
105
+ @delegate.on_authenticate_method.should be_called
106
+
107
+ #### bind resource
108
+ @delegate.on_postauthenticate_features_method.should_not be_called
109
+ @delegate.on_bind_method.should_not be_called
110
+ @client.receiving(SessionMessages.recv_postauthentication_stream_features(@client)).should respond_with(SessionMessages.send_iq_set_bind(@client))
111
+ @client.receiving(SessionMessages.recv_iq_result_bind(@client)).should respond_with(SessionMessages.send_iq_set_session(@client))
112
+ @delegate.on_postauthenticate_features_method.should be_called
113
+ @delegate.on_bind_method.should be_called
114
+
115
+ #### start session and request roster
116
+ lambda{@client.receiving(SessionMessages.recv_error_session(@client))}.should raise_error(AgentXmpp::AgentXmppError)
117
+
118
+ end
119
+
120
+ end