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.
- data/.document +5 -0
- data/.gitignore +11 -0
- data/LICENSE +20 -0
- data/README.rdoc +417 -0
- data/Rakefile +75 -0
- data/VERSION +1 -0
- data/agent_xmpp.gemspec +144 -0
- data/lib/agent_xmpp.rb +22 -0
- data/lib/agent_xmpp/admin.rb +113 -0
- data/lib/agent_xmpp/client.rb +7 -0
- data/lib/agent_xmpp/client/boot.rb +83 -0
- data/lib/agent_xmpp/client/client.rb +64 -0
- data/lib/agent_xmpp/client/connection.rb +108 -0
- data/lib/agent_xmpp/client/controller.rb +394 -0
- data/lib/agent_xmpp/client/message_delegate.rb +720 -0
- data/lib/agent_xmpp/client/message_pipe.rb +193 -0
- data/lib/agent_xmpp/client/response.rb +102 -0
- data/lib/agent_xmpp/config.rb +48 -0
- data/lib/agent_xmpp/main.rb +175 -0
- data/lib/agent_xmpp/models.rb +7 -0
- data/lib/agent_xmpp/models/contact.rb +85 -0
- data/lib/agent_xmpp/models/message.rb +152 -0
- data/lib/agent_xmpp/models/publication.rb +53 -0
- data/lib/agent_xmpp/models/roster.rb +107 -0
- data/lib/agent_xmpp/models/service.rb +91 -0
- data/lib/agent_xmpp/models/subscription.rb +61 -0
- data/lib/agent_xmpp/models/table_definitions.rb +107 -0
- data/lib/agent_xmpp/patches.rb +7 -0
- data/lib/agent_xmpp/patches/array.rb +32 -0
- data/lib/agent_xmpp/patches/float.rb +10 -0
- data/lib/agent_xmpp/patches/hash.rb +13 -0
- data/lib/agent_xmpp/patches/object.rb +15 -0
- data/lib/agent_xmpp/patches/rexml.rb +69 -0
- data/lib/agent_xmpp/patches/string.rb +15 -0
- data/lib/agent_xmpp/xmpp.rb +18 -0
- data/lib/agent_xmpp/xmpp/element.rb +158 -0
- data/lib/agent_xmpp/xmpp/entry.rb +36 -0
- data/lib/agent_xmpp/xmpp/error_response.rb +189 -0
- data/lib/agent_xmpp/xmpp/iq.rb +90 -0
- data/lib/agent_xmpp/xmpp/iq_command.rb +54 -0
- data/lib/agent_xmpp/xmpp/iq_disco.rb +206 -0
- data/lib/agent_xmpp/xmpp/iq_pubsub.rb +270 -0
- data/lib/agent_xmpp/xmpp/iq_roster.rb +183 -0
- data/lib/agent_xmpp/xmpp/iq_version.rb +89 -0
- data/lib/agent_xmpp/xmpp/jid.rb +150 -0
- data/lib/agent_xmpp/xmpp/message.rb +82 -0
- data/lib/agent_xmpp/xmpp/presence.rb +127 -0
- data/lib/agent_xmpp/xmpp/sasl.rb +241 -0
- data/lib/agent_xmpp/xmpp/stanza.rb +107 -0
- data/lib/agent_xmpp/xmpp/x_data.rb +357 -0
- data/test/app/app.rb +339 -0
- data/test/cases/test_application_message_processing.rb +65 -0
- data/test/cases/test_errors.rb +24 -0
- data/test/cases/test_presence_management.rb +139 -0
- data/test/cases/test_roster_management.rb +214 -0
- data/test/cases/test_service_discovery.rb +168 -0
- data/test/cases/test_session_management.rb +120 -0
- data/test/cases/test_version_discovery.rb +67 -0
- data/test/helpers/matchers.rb +23 -0
- data/test/helpers/mocks.rb +82 -0
- data/test/helpers/test_case_extensions.rb +45 -0
- data/test/helpers/test_client.rb +44 -0
- data/test/helpers/test_delegate.rb +60 -0
- data/test/helpers/test_helper.rb +91 -0
- data/test/messages/application_messages.rb +206 -0
- data/test/messages/error_messages.rb +35 -0
- data/test/messages/presence_messages.rb +66 -0
- data/test/messages/roster_messages.rb +126 -0
- data/test/messages/service_discovery_messages.rb +201 -0
- data/test/messages/session_messages.rb +158 -0
- data/test/messages/version_discovery_messages.rb +69 -0
- data/test/peer/peer.rb +21 -0
- metadata +187 -0
data/test/app/app.rb
ADDED
@@ -0,0 +1,339 @@
|
|
1
|
+
##########################################################################################################
|
2
|
+
require 'rubygems'
|
3
|
+
require "#{File.dirname(__FILE__)}/../../lib/agent_xmpp"
|
4
|
+
|
5
|
+
##########################################################################################################
|
6
|
+
# before filters
|
7
|
+
#.........................................................................................................
|
8
|
+
# only online contacts can send command messages
|
9
|
+
before :command => :all do
|
10
|
+
jid = params[:from]
|
11
|
+
AgentXmpp::Roster.find_by_jid(jid) or AgentXmpp.is_account_jid?(jid)
|
12
|
+
end
|
13
|
+
|
14
|
+
##########################################################################################################
|
15
|
+
# callbacks
|
16
|
+
#.........................................................................................................
|
17
|
+
before_start do
|
18
|
+
AgentXmpp.logger.level = Logger::DEBUG
|
19
|
+
File.delete("#{AgentXmpp.app_path}/in_memory.db") if File.exists?("#{AgentXmpp.app_path}/in_memory.db")
|
20
|
+
AgentXmpp.logger.info "before_start"
|
21
|
+
end
|
22
|
+
|
23
|
+
#.........................................................................................................
|
24
|
+
after_connected do |connection|
|
25
|
+
AgentXmpp.logger.info "after_connected"
|
26
|
+
end
|
27
|
+
|
28
|
+
#.........................................................................................................
|
29
|
+
restarting_client do |connection|
|
30
|
+
AgentXmpp.logger.info "restarting_client"
|
31
|
+
end
|
32
|
+
|
33
|
+
#.........................................................................................................
|
34
|
+
discovered_pubsub_node do |service, node|
|
35
|
+
AgentXmpp.logger.info "discovered_pubsub_node: #{service}, #{node}"
|
36
|
+
if node.eql?(AgentXmpp.user_pubsub_root+'/time')
|
37
|
+
AgentXmpp.logger.info "LAUNCHING TIME PUBLISH TASK"
|
38
|
+
EventMachine::PeriodicTimer.new(600) do
|
39
|
+
publish_time(Time.now.to_s)
|
40
|
+
AgentXmpp.logger.info "FIRING EVENT TIME: #{Time.now.to_s}"
|
41
|
+
end
|
42
|
+
elsif node.eql?(AgentXmpp.user_pubsub_root+'/gibberish')
|
43
|
+
AgentXmpp.logger.info "LAUNCHING GIBBERISH PUBLISH TASK"
|
44
|
+
EventMachine::PeriodicTimer.new(10) do
|
45
|
+
letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ',' ',' ',' ',' ',' ',' ']
|
46
|
+
publish_gibberish((0..300).inject(''){|j,i| j+=letters[((letters.length*rand).truncate)]}.gsub(/\s+/,' '))
|
47
|
+
AgentXmpp.logger.info "FIRING EVENT GIBBERISH: #{Time.now.to_s}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
#.........................................................................................................
|
53
|
+
discovered_command_nodes do |jid, nodes|
|
54
|
+
AgentXmpp.logger.info "discovered_command_nodes"
|
55
|
+
nodes.each do |n|
|
56
|
+
AgentXmpp.logger.info "COMMAND NODE: #{jid}, #{n}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
#.........................................................................................................
|
61
|
+
received_presence do |from, status|
|
62
|
+
AgentXmpp.logger.info "received_presence: #{from}, #{status}"
|
63
|
+
end
|
64
|
+
|
65
|
+
##########################################################################################################
|
66
|
+
# command processing: response payloads
|
67
|
+
#.........................................................................................................
|
68
|
+
command 'data/scalar' do
|
69
|
+
AgentXmpp.logger.info "ACTION: scalar"
|
70
|
+
'scalar'
|
71
|
+
end
|
72
|
+
|
73
|
+
#.........................................................................................................
|
74
|
+
command 'data/hash' do
|
75
|
+
AgentXmpp.logger.info "ACTION: hash"
|
76
|
+
{:xyz => 'wuv', :attr1 => 'val1', :attr2 => 'val2', :test1 => 'ans1'}
|
77
|
+
end
|
78
|
+
|
79
|
+
#.........................................................................................................
|
80
|
+
command 'data/scalar_array' do
|
81
|
+
AgentXmpp.logger.info "ACTION: array"
|
82
|
+
['val1', 'val2','val3', 'val4']
|
83
|
+
end
|
84
|
+
|
85
|
+
#.........................................................................................................
|
86
|
+
command 'data/hash_array' do
|
87
|
+
AgentXmpp.logger.info "ACTION: hash_array"
|
88
|
+
{:attr1 => ['val11', 'val11'], :attr2 => 'val12'}
|
89
|
+
end
|
90
|
+
|
91
|
+
#.........................................................................................................
|
92
|
+
command 'data/array_hash' do
|
93
|
+
AgentXmpp.logger.info "ACTION: array_hash"
|
94
|
+
[{:attr1 => 'val11', :attr2 => 'val12'},
|
95
|
+
{:attr1 => 'val21', :attr2 => 'val22'},
|
96
|
+
{:attr1 => 'val31', :attr2 => 'val32'}]
|
97
|
+
end
|
98
|
+
|
99
|
+
#.........................................................................................................
|
100
|
+
command 'data/array_hash_array' do
|
101
|
+
AgentXmpp.logger.info "ACTION: hash_array"
|
102
|
+
[{:attr1 => ['val11', 'val11'], :attr2 => 'val12'},
|
103
|
+
{:attr1 => ['val21', 'val21'], :attr2 => 'val22'},
|
104
|
+
{:attr1 => ['val31', 'val31'], :attr2 => 'val32'}]
|
105
|
+
end
|
106
|
+
|
107
|
+
##########################################################################################################
|
108
|
+
# command processing: data forms
|
109
|
+
#.........................................................................................................
|
110
|
+
command 'form/text_single' do
|
111
|
+
AgentXmpp.logger.info "ACTION: text_single"
|
112
|
+
on(:execute) do |form|
|
113
|
+
form.add_title('Your Name')
|
114
|
+
form.add_instructions('Use the keyboard to enter your name below.')
|
115
|
+
form.add_text_single('name', 'enter your name')
|
116
|
+
form.add_fixed('State of residence')
|
117
|
+
form.add_text_single('state')
|
118
|
+
end
|
119
|
+
on(:submit) do
|
120
|
+
params[:data]
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
#.........................................................................................................
|
125
|
+
command 'form/text_private' do
|
126
|
+
AgentXmpp.logger.info "ACTION: text_multi"
|
127
|
+
on(:execute) do |form|
|
128
|
+
form.add_title('Enter a Secret')
|
129
|
+
form.add_instructions('Use the keyboard to enter your secret below.')
|
130
|
+
form.add_text_private('secret', 'The Secret')
|
131
|
+
form.add_fixed('Renter your secret')
|
132
|
+
form.add_text_private('another_secret')
|
133
|
+
end
|
134
|
+
on(:submit) do
|
135
|
+
params[:data]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
#.........................................................................................................
|
140
|
+
command 'form/jid_single' do
|
141
|
+
AgentXmpp.logger.info "ACTION: text_single"
|
142
|
+
on(:execute) do |form|
|
143
|
+
form.add_title('The JID')
|
144
|
+
form.add_instructions('Use the keyboard to enter a JID below.')
|
145
|
+
form.add_jid_single('jid', 'A JID')
|
146
|
+
form.add_fixed("Another JID")
|
147
|
+
form.add_jid_single('another_jid')
|
148
|
+
end
|
149
|
+
on(:submit) do
|
150
|
+
params[:data]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
#.........................................................................................................
|
155
|
+
command 'form/text_multi' do
|
156
|
+
AgentXmpp.logger.info "ACTION: text_multi"
|
157
|
+
on(:execute) do |form|
|
158
|
+
form.add_title('Tell a Story')
|
159
|
+
form.add_instructions('Use the keyboard to enter your story below.')
|
160
|
+
form.add_text_multi('story', 'Your Story')
|
161
|
+
form.add_fixed("A haiku is required")
|
162
|
+
form.add_text_multi('haiku')
|
163
|
+
end
|
164
|
+
on(:submit) do
|
165
|
+
params[:data]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
#.........................................................................................................
|
170
|
+
command 'form/list_single' do
|
171
|
+
AgentXmpp.logger.info "ACTION: list_single"
|
172
|
+
on(:execute) do |form|
|
173
|
+
form.add_title('Fruits')
|
174
|
+
form.add_instructions('Select a fruit from the list.')
|
175
|
+
form.add_list_single('fruits', [:apple, :orange, :lemon, :lime, :kiwi_fruit], 'available fruits')
|
176
|
+
form.add_fixed('Choose a car')
|
177
|
+
form.add_list_single('car', [:audi_s4, :bmw_m3, :subaru_wrx_ti, :mitsubishi_evo])
|
178
|
+
end
|
179
|
+
on(:submit) do
|
180
|
+
params[:data]
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
#.........................................................................................................
|
185
|
+
command 'form/boolean', :defer => true do
|
186
|
+
AgentXmpp.logger.info "ACTION: boolean"
|
187
|
+
on(:execute) do |form|
|
188
|
+
form.add_title('Hyper Drive Configuration')
|
189
|
+
form.add_instructions('Choose the hyperdrive configuration which best suits your needs')
|
190
|
+
form.add_boolean('answer', 'On or Off please')
|
191
|
+
form.add_boolean('flux_capcitors', 'Enable flux capacitors for superluminal transport')
|
192
|
+
form.add_fixed('Enable SQUIDs for enhanced quantum decoherence')
|
193
|
+
form.add_boolean('squids')
|
194
|
+
end
|
195
|
+
on(:submit) do
|
196
|
+
params[:data]
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
#.........................................................................................................
|
201
|
+
command 'form/long_form' do
|
202
|
+
AgentXmpp.logger.info "ACTION: long_form"
|
203
|
+
on(:execute) do |form|
|
204
|
+
form.add_title('The Long Form')
|
205
|
+
form.add_instructions('Make the correct choices and provide the required information.')
|
206
|
+
form.add_fixed("Your name is required.")
|
207
|
+
form.add_text_single('first_name', 'First Name')
|
208
|
+
form.add_text_single('last_name', 'Last Name')
|
209
|
+
form.add_fixed("Your address is required.")
|
210
|
+
form.add_text_single('street', 'Street')
|
211
|
+
form.add_text_single('city', 'City')
|
212
|
+
form.add_text_single('state', 'State')
|
213
|
+
form.add_text_single('zip', 'Zip Code')
|
214
|
+
form.add_fixed("Enter two friends.")
|
215
|
+
form.add_jid_single('contact_1', 'contact JID')
|
216
|
+
form.add_jid_single('contact_2', 'contact JID')
|
217
|
+
form.add_fixed("Your password is required.")
|
218
|
+
form.add_text_private('password', 'Password')
|
219
|
+
form.add_text_private('renter_password', 'Renter Password')
|
220
|
+
form.add_fixed("Choose your food.")
|
221
|
+
form.add_list_single('fruits', [:apple, :orange, :lemon, :lime, :kiwi_fruit], 'Select a Fruit')
|
222
|
+
form.add_list_single('nuts', [:peanut, :almond, :cashew, :pecan, :walnut], 'Select a Nut')
|
223
|
+
form.add_list_single('vegetables', [:broccoli, :carrot, :corn, :tomato, :onion], 'Select a Vegtable')
|
224
|
+
form.add_fixed("Answer the questions.")
|
225
|
+
form.add_boolean('yes_or_no', 'Yes or No please?')
|
226
|
+
form.add_boolean('flux_capcitors', 'Enable flux capacitors for superluminal transport')
|
227
|
+
form.add_fixed("A story of at least 250 characters is required")
|
228
|
+
form.add_text_multi('story', 'Your Story')
|
229
|
+
end
|
230
|
+
on(:submit) do
|
231
|
+
params[:data]
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
#.........................................................................................................
|
236
|
+
command 'form/another_long_form' do
|
237
|
+
AgentXmpp.logger.info "ACTION: another_long_form"
|
238
|
+
on(:execute) do |form|
|
239
|
+
form.add_title('The Other Long Form')
|
240
|
+
form.add_instructions('Make the correct choices and provide the required information')
|
241
|
+
form.add_fixed("Your nickname is required.")
|
242
|
+
form.add_text_single('nickname', 'Nickname')
|
243
|
+
form.add_fixed
|
244
|
+
form.add_text_single('street', 'Street')
|
245
|
+
form.add_text_single('city', 'City')
|
246
|
+
form.add_text_single('state', 'State')
|
247
|
+
form.add_text_single('zip', 'Zip Code')
|
248
|
+
form.add_fixed("Your password is required.")
|
249
|
+
form.add_text_private('password', 'Password')
|
250
|
+
form.add_text_private('renter_password', 'Renter Password')
|
251
|
+
form.add_fixed("A haiku is required")
|
252
|
+
form.add_text_multi('haiku')
|
253
|
+
form.add_fixed("A limerick is required")
|
254
|
+
form.add_text_multi('limericck')
|
255
|
+
form.add_fixed("A story of at least 250 characters is required.")
|
256
|
+
form.add_text_multi('story', 'Your Story')
|
257
|
+
end
|
258
|
+
on(:submit) do
|
259
|
+
params[:data]
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
#.........................................................................................................
|
264
|
+
command 'form/no_title' do
|
265
|
+
AgentXmpp.logger.info "ACTION: no_title"
|
266
|
+
on(:execute) do |form|
|
267
|
+
form.add_instructions('Choose On or Off')
|
268
|
+
form.add_boolean('answer', 'On or Off please')
|
269
|
+
end
|
270
|
+
on(:submit) do
|
271
|
+
params[:data]
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
#.........................................................................................................
|
276
|
+
command 'form/no_instructions' do
|
277
|
+
AgentXmpp.logger.info "ACTION: no_instructions"
|
278
|
+
on(:execute) do |form|
|
279
|
+
form.add_title('Yes or No')
|
280
|
+
form.add_boolean('answer', 'Yes or No please')
|
281
|
+
end
|
282
|
+
on(:submit) do
|
283
|
+
params[:data]
|
284
|
+
end
|
285
|
+
end
|
286
|
+
|
287
|
+
#.........................................................................................................
|
288
|
+
command 'form/text_view_with_jids' do
|
289
|
+
AgentXmpp.logger.info "ACTION: text_view_with_jids"
|
290
|
+
on(:execute) do |form|
|
291
|
+
form.add_title('Account Information')
|
292
|
+
form.add_instructions('Enter and Account below and provide a description')
|
293
|
+
form.add_jid_single('jid', 'account JID')
|
294
|
+
form.add_text_multi('description', 'Description of Account')
|
295
|
+
end
|
296
|
+
on(:submit) do
|
297
|
+
params[:data]
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
#.........................................................................................................
|
302
|
+
command 'form/multiple_steps' do
|
303
|
+
AgentXmpp.logger.info "ACTION: multiple_steps"
|
304
|
+
on(:execute) do |form|
|
305
|
+
form.add_title('Account Features')
|
306
|
+
form.add_instructions('Enter and Account')
|
307
|
+
form.add_jid_single('jid', 'account JID')
|
308
|
+
end
|
309
|
+
on(:submit) do |form|
|
310
|
+
form.add_title("Account '#{params[:data]['jid']}'")
|
311
|
+
form.add_instructions('Enable/Disbale features')
|
312
|
+
form.add_boolean('idle_logout', 'On or Off please')
|
313
|
+
form.add_boolean('electrocution', 'Electrocute on login failure?')
|
314
|
+
form.add_text_multi('mod', 'Message of the day')
|
315
|
+
form.add_text_multi('warn', 'Warning message')
|
316
|
+
end
|
317
|
+
on(:submit) do
|
318
|
+
params_list.inject({}){|r,p| r.merge(p[:data])}
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
|
323
|
+
##########################################################################################################
|
324
|
+
# chat messages
|
325
|
+
#.........................................................................................................
|
326
|
+
chat do
|
327
|
+
AgentXmpp.logger.info "CHAT MESSAGE: #{params[:from]}, #{params[:body]}"
|
328
|
+
params[:body].nil? ? 'what?' : params[:body].reverse
|
329
|
+
end
|
330
|
+
|
331
|
+
##########################################################################################################
|
332
|
+
# pubsub events
|
333
|
+
#.........................................................................................................
|
334
|
+
|
335
|
+
#.........................................................................................................
|
336
|
+
# event 'troy@test.local', 'junk' do
|
337
|
+
# AgentXmpp.logger.info "EVENT: troy@test.local/junk"
|
338
|
+
# send_chat(:to=>params[:from], :body=>'got '+params[:data])
|
339
|
+
# end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
##############################################################################################################
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
##############################################################################################################
|
5
|
+
class TestApplicationMessageProcessing < Test::Unit::TestCase
|
6
|
+
|
7
|
+
#.........................................................................................................
|
8
|
+
def setup
|
9
|
+
@config = {'jid' => 'test@nowhere.com', 'roster' =>['dev@nowhere.com'], 'password' => 'nopass'}
|
10
|
+
@client = TestClient.new(@config)
|
11
|
+
AgentXmpp::Xmpp::IdGenerator.set_gen_id
|
12
|
+
test_init_roster(@client)
|
13
|
+
@delegate = @client.new_delegate
|
14
|
+
end
|
15
|
+
|
16
|
+
#.........................................................................................................
|
17
|
+
should "respond to a received message with agent version information if no chat route is specified" do
|
18
|
+
@client.receiving(ApplicationMessages.recv_message_chat(@client, 'dev@nowhere.com')).should \
|
19
|
+
respond_with(ApplicationMessages.send_message_chat(@client, 'dev@nowhere.com'))
|
20
|
+
end
|
21
|
+
|
22
|
+
#.........................................................................................................
|
23
|
+
should "respond to requests with scalars in jabber:x:data format" do
|
24
|
+
@client.receiving(ApplicationMessages.recv_iq_set_command_execute(@client, 'scalar', 'dev@nowhere.com')).should \
|
25
|
+
respond_with(ApplicationMessages.send_iq_result_command_x_data_scalar(@client, 'dev@nowhere.com'))
|
26
|
+
end
|
27
|
+
|
28
|
+
#.........................................................................................................
|
29
|
+
should "respond to requests with arrays of scalars in jabber:x:data format" do
|
30
|
+
@client.receiving(ApplicationMessages.recv_iq_set_command_execute(@client, 'scalar_array', 'dev@nowhere.com')).should \
|
31
|
+
respond_with(ApplicationMessages.send_iq_result_command_x_data_scalar_array(@client, 'dev@nowhere.com'))
|
32
|
+
end
|
33
|
+
|
34
|
+
#.........................................................................................................
|
35
|
+
should "respond to requests with hashes in jabber:x:data format" do
|
36
|
+
@client.receiving(ApplicationMessages.recv_iq_set_command_execute(@client, 'hash', 'dev@nowhere.com')).should \
|
37
|
+
respond_with(ApplicationMessages.send_iq_result_command_x_data_hash(@client, 'dev@nowhere.com'))
|
38
|
+
end
|
39
|
+
|
40
|
+
#.........................................................................................................
|
41
|
+
should "respond to requests with arrays of hashes in jabber:x:data format" do
|
42
|
+
@client.receiving(ApplicationMessages.recv_iq_set_command_execute(@client, 'array_hash', 'dev@nowhere.com')).should \
|
43
|
+
respond_with(ApplicationMessages.send_iq_result_command_x_data_array_hash(@client, 'dev@nowhere.com'))
|
44
|
+
end
|
45
|
+
|
46
|
+
#.........................................................................................................
|
47
|
+
should "respond to requests with hashes of arrays in jabber:x:data format" do
|
48
|
+
@client.receiving(ApplicationMessages.recv_iq_set_command_execute(@client, 'hash_array', 'dev@nowhere.com')).should \
|
49
|
+
respond_with(ApplicationMessages.send_iq_result_command_x_data_hash_array(@client, 'dev@nowhere.com'))
|
50
|
+
end
|
51
|
+
|
52
|
+
#.........................................................................................................
|
53
|
+
should "respond to requests with arrays of hashes of arrays in jabber:x:data format" do
|
54
|
+
@client.receiving(ApplicationMessages.recv_iq_set_command_execute(@client, 'array_hash_array', 'dev@nowhere.com')).should \
|
55
|
+
respond_with(ApplicationMessages.send_iq_result_command_x_data_array_hash_array(@client, 'dev@nowhere.com'))
|
56
|
+
end
|
57
|
+
|
58
|
+
#.........................................................................................................
|
59
|
+
should "return error if command node does not map to a route" do
|
60
|
+
@client.receiving(ApplicationMessages.recv_iq_set_command_execute(@client, 'no_route', 'dev@nowhere.com')).should \
|
61
|
+
respond_with(ApplicationMessages.send_error_command_routing(@client, 'no_route', 'dev@nowhere.com'))
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
##############################################################################################################
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
##############################################################################################################
|
5
|
+
class TestErrors < Test::Unit::TestCase
|
6
|
+
|
7
|
+
#.........................................................................................................
|
8
|
+
def setup
|
9
|
+
@client = TestClient.new()
|
10
|
+
test_init_roster(@client)
|
11
|
+
@delegate = @client.new_delegate
|
12
|
+
@test = AgentXmpp::Xmpp::Jid.new('test@plan-b.ath.cx/home')
|
13
|
+
end
|
14
|
+
|
15
|
+
#.........................................................................................................
|
16
|
+
should "respond with feature-not-implemented when unsupported messages are received" do
|
17
|
+
@delegate.on_unsupported_message_method.should_not be_called
|
18
|
+
@client.receiving(ErrorMessages.recv_iq_error(@client, @test.to_s)).should \
|
19
|
+
respond_with(ErrorMessages.send_iq_error(@client, @test.to_s))
|
20
|
+
@delegate.on_unsupported_message_method.should be_called
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
@@ -0,0 +1,139 @@
|
|
1
|
+
##############################################################################################################
|
2
|
+
require 'test_helper'
|
3
|
+
|
4
|
+
##############################################################################################################
|
5
|
+
class TestPresenceManagement < Test::Unit::TestCase
|
6
|
+
|
7
|
+
#.........................................................................................................
|
8
|
+
def setup
|
9
|
+
@config = {'jid' => 'test@nowhere.com', 'roster' =>['dev@nowhere.com', 'troy@nowhere.com'], 'password' => 'nopass'}
|
10
|
+
@client = TestClient.new(@config)
|
11
|
+
test_init_roster(@client)
|
12
|
+
@delegate = @client.new_delegate
|
13
|
+
@home = AgentXmpp::Xmpp::Jid.new('troy@nowhere.com/home')
|
14
|
+
@work = AgentXmpp::Xmpp::Jid.new('troy@nowhere.com/work')
|
15
|
+
@noone = AgentXmpp::Xmpp::Jid.new('noone@nowhere.com/here')
|
16
|
+
end
|
17
|
+
|
18
|
+
####------------------------------------------------------------------------------------------------------
|
19
|
+
context "on receipt of first presence message from jid in configured roster" do
|
20
|
+
|
21
|
+
#.........................................................................................................
|
22
|
+
setup do
|
23
|
+
AgentXmpp::Xmpp::IdGenerator.set_gen_id([1,2])
|
24
|
+
RosterItemModel.find_all_by_contact_jid(@home).should be_empty
|
25
|
+
@delegate.on_presence_method.should_not be_called
|
26
|
+
@client.receiving(PresenceMessages.recv_presence_available(@client, @home.to_s)).should \
|
27
|
+
respond_with(VersionDiscoveryMessages.send_iq_get_query_version(@client, @home.to_s), \
|
28
|
+
ServiceDiscoveryMessages.send_iq_get_query_discoinfo(@client, @home.to_s))
|
29
|
+
@delegate.on_presence_method.should be_called
|
30
|
+
AgentXmpp::Roster.find_by_jid(@home).should_not be_nil
|
31
|
+
end
|
32
|
+
|
33
|
+
#.........................................................................................................
|
34
|
+
should "create presence status entry in roster for resource and send client version request to jid" do
|
35
|
+
end
|
36
|
+
|
37
|
+
#.........................................................................................................
|
38
|
+
should "update roster item resource presence status to unavailble on receiving unavailable presence" do
|
39
|
+
@delegate = @client.new_delegate
|
40
|
+
@delegate.on_presence_unavailable_method.should_not be_called
|
41
|
+
AgentXmpp::Roster.find_by_jid(@home).type.should be_nil # nil presence type=available
|
42
|
+
@client.receiving(PresenceMessages.recv_presence_unavailable(@client, @home.to_s)).should not_respond
|
43
|
+
@delegate.on_presence_unavailable_method.should be_called
|
44
|
+
AgentXmpp::Roster.find_by_jid(@home).type.should be(:unavailable)
|
45
|
+
end
|
46
|
+
|
47
|
+
#.........................................................................................................
|
48
|
+
should "update existing roster item resource presence status from unavailble to availble on receiving available presence" do
|
49
|
+
@delegate = @client.new_delegate
|
50
|
+
@client.receiving(PresenceMessages.recv_presence_unavailable(@client, @home.to_s)).should not_respond
|
51
|
+
AgentXmpp::Xmpp::IdGenerator.set_gen_id([1,2])
|
52
|
+
AgentXmpp::Roster.find_by_jid(@home).type.should be(:unavailable)
|
53
|
+
@delegate.on_presence_method.should_not be_called
|
54
|
+
@client.receiving(PresenceMessages.recv_presence_available(@client, @home.to_s)).should \
|
55
|
+
respond_with(VersionDiscoveryMessages.send_iq_get_query_version(@client, @home.to_s), \
|
56
|
+
ServiceDiscoveryMessages.send_iq_get_query_discoinfo(@client, @home.to_s))
|
57
|
+
@delegate.on_presence_method.should be_called
|
58
|
+
AgentXmpp::Roster.find_by_jid(@home).type.should be_nil # nil presence type=available
|
59
|
+
end
|
60
|
+
|
61
|
+
#.........................................................................................................
|
62
|
+
should "maintain multiple presence status entries for multiple resources for a roster item" do
|
63
|
+
@delegate = @client.new_delegate
|
64
|
+
AgentXmpp::Xmpp::IdGenerator.set_gen_id([1,2])
|
65
|
+
@delegate.on_presence_method.should_not be_called
|
66
|
+
AgentXmpp::Roster.find_by_jid(@work).should be_nil
|
67
|
+
@client.receiving(PresenceMessages.recv_presence_available(@client, @work.to_s)).should \
|
68
|
+
respond_with(VersionDiscoveryMessages.send_iq_get_query_version(@client, @work.to_s), \
|
69
|
+
ServiceDiscoveryMessages.send_iq_get_query_discoinfo(@client, @work.to_s))
|
70
|
+
@delegate.on_presence_method.should be_called
|
71
|
+
AgentXmpp::Roster.find_by_jid(@work).should_not be_nil
|
72
|
+
AgentXmpp::Roster.find_by_jid(@home).should_not be_nil
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
#.........................................................................................................
|
78
|
+
should "create presence status for resource on receipt of self presence" do
|
79
|
+
RosterItemModel.find_all_by_contact_jid(@client.client.jid).should be_empty
|
80
|
+
@delegate.on_presence_method.should_not be_called
|
81
|
+
@client.receiving(PresenceMessages.recv_presence_self(@client)).should not_respond
|
82
|
+
@delegate.on_presence_method.should be_called
|
83
|
+
AgentXmpp::Roster.find_by_jid(@client.client.jid).should_not be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
#.........................................................................................................
|
87
|
+
should "ignore presence messages from jids not in configured roster" do
|
88
|
+
AgentXmpp::Contact.has_jid?(@noone).should be(false)
|
89
|
+
@delegate.on_presence_method.should_not be_called
|
90
|
+
@client.receiving(PresenceMessages.recv_presence_available(@client, @noone.to_s)).should not_respond
|
91
|
+
@delegate.on_presence_method.should be_called
|
92
|
+
AgentXmpp::Contact.has_jid?(@noone).should be(false)
|
93
|
+
end
|
94
|
+
|
95
|
+
#.........................................................................................................
|
96
|
+
should "accept subscription requests from jids which are in the configured roster" do
|
97
|
+
AgentXmpp::Contact.has_jid?(@home).should be(true)
|
98
|
+
@delegate.on_presence_subscribe_method.should_not be_called
|
99
|
+
@delegate.on_presence_subscribed_method.should_not be_called
|
100
|
+
@client.receiving(PresenceMessages.recv_presence_subscribe(@client, @home.bare.to_s)).should \
|
101
|
+
respond_with(PresenceMessages.send_presence_subscribed(@client, @home.bare.to_s))
|
102
|
+
@client.receiving(PresenceMessages.recv_presence_subscribed(@client, @home.bare.to_s)).should not_respond
|
103
|
+
@delegate.on_presence_subscribe_method.should be_called
|
104
|
+
@delegate.on_presence_subscribed_method.should be_called
|
105
|
+
AgentXmpp::Contact.has_jid?(@home).should be(true)
|
106
|
+
end
|
107
|
+
|
108
|
+
#.........................................................................................................
|
109
|
+
should "remove roster item with jid from configured roster when an unsubscribe resquest is recieved" do
|
110
|
+
AgentXmpp::Contact.has_jid?(@home).should be(true)
|
111
|
+
@delegate.on_presence_unsubscribed_method.should_not be_called
|
112
|
+
@client.receiving(PresenceMessages.recv_presence_unsubscribed(@client, @home.bare.to_s)).should \
|
113
|
+
respond_with(RosterMessages.send_iq_set_query_roster_remove(@client, @home.bare.to_s))
|
114
|
+
@client.receiving(RosterMessages.recv_iq_result_query_roster_ack(@client)).should not_respond
|
115
|
+
@delegate.on_presence_unsubscribed_method.should be_called
|
116
|
+
AgentXmpp::Contact.has_jid?(@home).should be(false)
|
117
|
+
end
|
118
|
+
|
119
|
+
#.........................................................................................................
|
120
|
+
should "do nothing when an unsubscribe resquest is recieved from a jid not in the configured roster" do
|
121
|
+
AgentXmpp::Contact.has_jid?(@noone).should be(false)
|
122
|
+
@delegate.on_presence_unsubscribed_method.should_not be_called
|
123
|
+
@client.receiving(PresenceMessages.recv_presence_unsubscribed(@client, @noone.bare.to_s)).should not_respond
|
124
|
+
@delegate.on_presence_unsubscribed_method.should be_called
|
125
|
+
AgentXmpp::Contact.has_jid?(@noone).should be(false)
|
126
|
+
end
|
127
|
+
|
128
|
+
#.........................................................................................................
|
129
|
+
should "decline subscription requests from jids which are not in the configured roster" do
|
130
|
+
AgentXmpp::Contact.has_jid?(@noone).should be(false)
|
131
|
+
@delegate.on_presence_subscribe_method.should_not be_called
|
132
|
+
@client.receiving(PresenceMessages.recv_presence_subscribe(@client, @noone.bare.to_s)).should \
|
133
|
+
respond_with(PresenceMessages.send_presence_unsubscribed(@client, @noone.bare.to_s))
|
134
|
+
@delegate.on_presence_subscribe_method.should be_called
|
135
|
+
AgentXmpp::Contact.has_jid?(@noone).should be(false)
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|