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,67 @@
1
+ ##############################################################################################################
2
+ require 'test_helper'
3
+
4
+ ##############################################################################################################
5
+ class TestClientVersionDiscovery < Test::Unit::TestCase
6
+
7
+ #.........................................................................................................
8
+ def setup
9
+ @troy = AgentXmpp::Xmpp::Jid.new('troy@nowhere.com/home')
10
+ @noone = AgentXmpp::Xmpp::Jid.new('noone@nowhere.com/nothing')
11
+ @config = {'jid' => 'test@nowhere.com', 'roster' =>[@troy.bare.to_s], 'password' => 'nopass'}
12
+ @client = TestClient.new(@config)
13
+ test_init_roster(@client)
14
+ @delegate = @client.new_delegate
15
+ end
16
+
17
+ ####-------------------------------------------------------------------------------------------------------
18
+ context "on receiving a presence message of type=available from a jid in configured roster" do
19
+
20
+ #.........................................................................................................
21
+ setup do
22
+ AgentXmpp::Xmpp::IdGenerator.set_gen_id([1,2])
23
+ @delegate.on_version_get_method.should_not be_called
24
+ @delegate.on_version_result_method.should_not be_called
25
+ AgentXmpp::Roster.find_by_jid(@troy).should be_nil
26
+ @client.receiving(PresenceMessages.recv_presence_available(@client, @troy.to_s)).should \
27
+ respond_with(VersionDiscoveryMessages.send_iq_get_query_version(@client, @troy.to_s))
28
+ AgentXmpp::Roster.find_by_jid(@troy).should_not be_nil
29
+ end
30
+
31
+ #.........................................................................................................
32
+ should "send a client version request to that jid and do nothing if the result is an error" do
33
+ @client.receiving(VersionDiscoveryMessages.recv_iq_result_query_version(@client, @troy.to_s)).should not_respond
34
+ AgentXmpp::Roster.has_version?(@troy).should be(true)
35
+ @delegate.on_version_result_method.should be_called
36
+ end
37
+
38
+ #.........................................................................................................
39
+ should "respond to client version requests from that jid" do
40
+ @client.receiving(VersionDiscoveryMessages.recv_iq_result_query_version(@client, @troy.to_s)).should not_respond
41
+ AgentXmpp::Roster.has_version?(@troy).should be(true)
42
+ @delegate.on_version_result_method.should be_called
43
+ @client.receiving(VersionDiscoveryMessages.recv_iq_get_query_version(@client, @troy.to_s)).should \
44
+ respond_with(VersionDiscoveryMessages.send_iq_result_query_version(@client, @troy.to_s))
45
+ @delegate.on_version_get_method.should be_called
46
+ end
47
+
48
+ #.........................................................................................................
49
+ should "send a client version request to that jid and update roster with result version information" do
50
+ @delegate.on_version_error_method.should_not be_called
51
+ @client.receiving(VersionDiscoveryMessages.recv_iq_error_query_version(@client, @troy.to_s)).should not_respond
52
+ AgentXmpp::Roster.has_version?(@troy).should be(false)
53
+ @delegate.on_version_error_method.should be_called
54
+ end
55
+
56
+ end
57
+
58
+ #.........................................................................................................
59
+ should "not respond to client version requests from jids not in configured roster" do
60
+ @delegate.on_version_get_method.should_not be_called
61
+ AgentXmpp::Contact.has_jid?(@noone).should be(false)
62
+ @client.receiving(VersionDiscoveryMessages.recv_iq_get_query_version(@client, @noone.to_s)).should not_respond
63
+ @delegate.on_version_get_method.should be_called
64
+ end
65
+
66
+ end
67
+
@@ -0,0 +1,23 @@
1
+ ####------------------------------------------------------------------------------------------------------
2
+ def_matcher :respond_with do |receiver, matcher, args|
3
+ prepare_msg = lambda{|msg| msg.collect{|i| i.split(/\n+/).inject("") {|p, m| p + m.strip.gsub(/id='\d+'/, '').gsub(/\s+/, " ")}}}
4
+ given = prepare_msg[[receiver].flatten].join
5
+ expected = prepare_msg[args].join
6
+ matcher.positive_msg = "Expected response message of \"#{expected}\" but was given message \"#{given}\""
7
+ matcher.negative_msg = "Expected response message \"#{expected}\" to not match given message \"#{given}\""
8
+ given.include?(expected)
9
+ end
10
+
11
+ ####------------------------------------------------------------------------------------------------------
12
+ def_matcher :not_respond do |receiver, matcher, args|
13
+ matcher.positive_msg = "Expected no responce"
14
+ matcher.negative_msg = "Expected a response"
15
+ receiver.nil? || receiver.empty?
16
+ end
17
+
18
+ ####------------------------------------------------------------------------------------------------------
19
+ def_matcher :be_called do |receiver, matcher, args|
20
+ matcher.positive_msg = "Expected client delgate method '#{receiver.last}' to be called"
21
+ matcher.negative_msg = "Expected client delgate method '#{receiver.last}' to not be called"
22
+ receiver.first
23
+ end
@@ -0,0 +1,82 @@
1
+ ##############################################################################################################
2
+ module AgentXmpp
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class Connection
6
+
7
+ #.........................................................................................................
8
+ def self.new(*args)
9
+ allocate.instance_eval do
10
+ initialize(*args)
11
+ connection_completed
12
+ self
13
+ end
14
+ end
15
+
16
+ #.........................................................................................................
17
+ def send_data(data)
18
+ data
19
+ end
20
+
21
+ def connection_completed
22
+ pipe.connection_completed
23
+ end
24
+
25
+ #.........................................................................................................
26
+ def error?
27
+ false
28
+ end
29
+
30
+ #.........................................................................................................
31
+ def reset_parser
32
+ end
33
+
34
+ #### Connection
35
+ end
36
+
37
+ #####-------------------------------------------------------------------------------------------------------
38
+ class Client
39
+
40
+ #.........................................................................................................
41
+ def connect
42
+ @connection = AgentXmpp::Connection.new(self)
43
+ end
44
+
45
+ #.........................................................................................................
46
+ def reconnect
47
+ true
48
+ end
49
+
50
+ #### Client
51
+ end
52
+
53
+ #####-------------------------------------------------------------------------------------------------------
54
+ class Controller
55
+ def handle_request
56
+ request_callback(request).collect{|m| Send(Xmpp::Stanza::import(REXML::Document.new(m).root))}
57
+ end
58
+ end
59
+
60
+ #####-------------------------------------------------------------------------------------------------------
61
+ class Boot
62
+ def self.boot
63
+ end
64
+ end
65
+
66
+ #### AgentXmpp
67
+ end
68
+
69
+
70
+ ##############################################################################################################
71
+ module AgentXmpp
72
+ module Xmpp
73
+ class IdGenerator
74
+ @gen_id;
75
+ class << self
76
+ def set_gen_id(val=1); @gen_id = val; end
77
+ def gen_id; @gen_id; end;
78
+ def generate_id; @gen_id.kind_of?(Array) ? @gen_id.shift : @gen_id; end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,45 @@
1
+ #####-------------------------------------------------------------------------------------------------------
2
+ class Test::Unit::TestCase
3
+
4
+ #.........................................................................................................
5
+ def bind_resource(client)
6
+ AgentXmpp::Xmpp::IdGenerator.set_gen_id
7
+ client.receiving(SessionMessages.recv_preauthentication_stream_features_with_plain_SASL(client))
8
+ client.receiving(SessionMessages.recv_auth_success(client))
9
+ client.receiving(SessionMessages.recv_postauthentication_stream_features(client))
10
+ client.receiving(SessionMessages.recv_iq_result_bind(client))
11
+ end
12
+
13
+ #.........................................................................................................
14
+ def test_send_roster_request(client)
15
+
16
+ #### client configured with two contacts in roster
17
+ delegate = client.new_delegate
18
+ bind_resource(client)
19
+
20
+ #### session starts and roster is requested
21
+ delegate.on_start_session_method.should_not be_called
22
+ AgentXmpp::Xmpp::IdGenerator.set_gen_id([1,2])
23
+ client.receiving(SessionMessages.recv_iq_result_session(client)).should \
24
+ respond_with(SessionMessages.send_presence_init(client), RosterMessages.send_iq_get_query_roster(client), \
25
+ ServiceDiscoveryMessages.send_iq_get_query_discoinfo(client, client.jid.domain))
26
+ delegate.on_start_session_method.should be_called
27
+ AgentXmpp::Xmpp::IdGenerator.set_gen_id
28
+ end
29
+
30
+ #.........................................................................................................
31
+ def test_init_roster(client)
32
+
33
+ #### client configured with two contacts in roster
34
+ test_send_roster_request(client)
35
+ delegate = client.new_delegate
36
+
37
+ #### receive roster request and verify that roster items are activated
38
+ delegate.on_all_roster_items_method.should_not be_called
39
+ AgentXmpp::Roster.find_all{|r| r[:status].should be(:inactive)}
40
+ client.receiving(RosterMessages.recv_iq_result_query_roster(client, AgentXmpp.config['roster'])).should not_respond
41
+ AgentXmpp::Roster.find_all{|r| r[:status].should be(:both)}
42
+ delegate.on_all_roster_items_method.should be_called
43
+ end
44
+
45
+ end
@@ -0,0 +1,44 @@
1
+ ##############################################################################################################
2
+ class TestClient
3
+
4
+ #.........................................................................................................
5
+ attr_reader :client, :config, :jid
6
+
7
+ #.........................................................................................................
8
+ def initialize(config = nil)
9
+ @config = config || File.open('test/helpers/agent_xmpp.yml') {|yf| YAML::load(yf)}
10
+ @client = AgentXmpp::Client.new(@config)
11
+ @jid = @client.jid
12
+ @client.connect
13
+ end
14
+
15
+ #.........................................................................................................
16
+ def connection
17
+ @client.connection
18
+ end
19
+
20
+ #.........................................................................................................
21
+ def responder_list
22
+ @client.pipe.responder_list
23
+ end
24
+
25
+ #.........................................................................................................
26
+ def new_delegate
27
+ @client.remove_delegate(@delegate) unless @delegate.nil?
28
+ @delegate = TestDelegate.new
29
+ @client.add_delegate(@delegate)
30
+ @delegate
31
+ end
32
+
33
+ #.........................................................................................................
34
+ def receiving(msg)
35
+ prepared_msg = msg.split(/\n/).inject("") {|p, m| p + m.strip}
36
+ doc = REXML::Document.new(prepared_msg).root
37
+ doc = doc.elements.first if doc.name.eql?('stream')
38
+ if ['presence', 'message', 'iq'].include?(doc.name)
39
+ doc = AgentXmpp::Xmpp::Stanza::import(doc)
40
+ end
41
+ client.connection.receive(doc)
42
+ end
43
+
44
+ end
@@ -0,0 +1,60 @@
1
+ ##############################################################################################################
2
+ class TestDelegate
3
+
4
+ ####------------------------------------------------------------------------------------------------------
5
+ class << self
6
+
7
+ #.........................................................................................................
8
+ @@callback_methods = []
9
+
10
+ #.........................................................................................................
11
+ def delegate_callbacks(*args)
12
+ args.each do |meth|
13
+ @@callback_methods.push(meth)
14
+ class_eval <<-do_eval
15
+ def #{meth}(*args)
16
+ AgentXmpp.logger.info "TEST_DELEGATE #{meth.to_s.upcase}"
17
+ @#{meth}_method = true
18
+ nil
19
+ end
20
+ def #{meth}_method
21
+ [@#{meth}_method, "#{meth.to_s}"]
22
+ end
23
+ attr_writer :#{meth}_method
24
+ do_eval
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+ #---------------------------------------------------------------------------------------------------------
31
+ #### connection
32
+ delegate_callbacks :on_connect, :on_disconnect, :on_did_not_connect, :on_did_not_authenticate
33
+
34
+ #### authentication
35
+ delegate_callbacks :on_authenticate, :on_bind, :on_start_session, :on_preauthenticate_features,
36
+ :on_postauthenticate_features
37
+
38
+ #### presence
39
+ delegate_callbacks :on_presence, :on_presence_subscribe, :on_presence_unsubscribed, :on_presence_subscribed, :on_presence_unavailable
40
+
41
+ #### roster management
42
+ delegate_callbacks :on_roster_item, :on_all_roster_items, :on_acknowledge_add_roster_item,
43
+ :on_roster_result, :on_roster_set, :on_remove_roster_item, :on_acknowledge_remove_roster_item,
44
+ :on_remove_roster_item_error, :on_add_roster_item_error
45
+
46
+ #### service discovery management
47
+ delegate_callbacks :on_version_result, :on_version_get, :on_version_error, :on_discoinfo_result,
48
+ :on_discoinfo_get, :on_discoitems_get, :on_discoitems_result,
49
+ :on_discoinfo_error, :on_discoitems_error
50
+
51
+ #### errors
52
+ delegate_callbacks :on_unsupported_message
53
+
54
+ #---------------------------------------------------------------------------------------------------------
55
+ def initialize
56
+ @@callback_methods.each{|m| send("#{m.to_s}_method=".to_sym, false)}
57
+ end
58
+
59
+ #### TestDelegate
60
+ end
@@ -0,0 +1,91 @@
1
+ #####-------------------------------------------------------------------------------------------------------
2
+ require 'test/unit'
3
+ require 'rubygems'
4
+ begin
5
+ require 'shoulda'
6
+ rescue LoadError
7
+ abort "shoulda is not available. In order to run test, you must: sudo gem install thoughtbot-shoulda --source=http://gems.github.com"
8
+ end
9
+ begin
10
+ require 'matchy'
11
+ rescue LoadError
12
+ abort "matchy is not available. In order to run test, you must: sudo gem install mhennemeyer-matchy --source=http://gems.github.com"
13
+ end
14
+
15
+ #####-------------------------------------------------------------------------------------------------------
16
+ $:.unshift('lib')
17
+ require 'rubygems'
18
+ require 'agent_xmpp'
19
+
20
+ #####-------------------------------------------------------------------------------------------------------
21
+ require 'test_delegate'
22
+ require 'mocks'
23
+ require 'test_client'
24
+ require 'matchers'
25
+ require 'test_case_extensions'
26
+
27
+ #####-------------------------------------------------------------------------------------------------------
28
+ require 'application_messages'
29
+ require 'roster_messages'
30
+ require 'version_discovery_messages'
31
+ require 'service_discovery_messages'
32
+ require 'session_messages'
33
+ require 'presence_messages'
34
+ require 'error_messages'
35
+
36
+ #####-------------------------------------------------------------------------------------------------------
37
+ AgentXmpp.app_path = 'test/helpers'
38
+ AgentXmpp.logger.level = Logger::DEBUG
39
+
40
+ ####------------------------------------------------------------------------------------------------------
41
+ before_start do
42
+ AgentXmpp.logger.info "AgentXmpp::BootApp.before_start"
43
+ end
44
+
45
+ after_connected do |pipe|
46
+ AgentXmpp.logger.info "AgentXmpp::BootApp.after_connected"
47
+ end
48
+
49
+ restarting_client do |pipe|
50
+ AgentXmpp.logger.info "AgentXmpp::BootApp.restarting_client"
51
+ end
52
+
53
+ discovered_pubsub_service do |pipe|
54
+ AgentXmpp.logger.info "discovered_pubsub_service"
55
+ end
56
+
57
+ #####-------------------------------------------------------------------------------------------------------
58
+ execute 'scalar' do
59
+ AgentXmpp.logger.info "ACTION: scalar"
60
+ 'scalar'
61
+ end
62
+
63
+ #.........................................................................................................
64
+ execute 'hash' do
65
+ AgentXmpp.logger.info "ACTION: hash"
66
+ {:attr1 => 'val1', :attr2 => 'val2'}
67
+ end
68
+
69
+ #.........................................................................................................
70
+ execute 'scalar_array' do
71
+ AgentXmpp.logger.info "ACTION: array"
72
+ ['val1', 'val2','val3', 'val4']
73
+ end
74
+
75
+ #.........................................................................................................
76
+ execute 'hash_array' do
77
+ AgentXmpp.logger.info "ACTION: hash_array"
78
+ {:attr1 => ['val11', 'val11'], :attr2 => 'val12'}
79
+ end
80
+
81
+ #.........................................................................................................
82
+ execute 'array_hash' do
83
+ AgentXmpp.logger.info "ACTION: array_hash"
84
+ [{:attr1 => 'val11', :attr2 => 'val12'}, {:attr1 => 'val21', :attr2 => 'val22'}, {:attr1 => 'val31', :attr2 => 'val32'}]
85
+ end
86
+
87
+ #.........................................................................................................
88
+ execute 'array_hash_array' do
89
+ AgentXmpp.logger.info "ACTION: hash_array"
90
+ [{:attr1 => ['val11', 'val11'], :attr2 => 'val12'}, {:attr1 => ['val21', 'val21'], :attr2 => 'val22'}, {:attr1 => ['val31', 'val31'], :attr2 => 'val32'}]
91
+ end
@@ -0,0 +1,206 @@
1
+ ##############################################################################################################
2
+ module ApplicationMessages
3
+
4
+ #####-------------------------------------------------------------------------------------------------------
5
+ class << self
6
+
7
+ #### received messages
8
+ #.........................................................................................................
9
+ def recv_iq_set_command_execute(client, node, from)
10
+ <<-MSG
11
+ <iq from='#{from}' to='#{client.client.jid.to_s}' id='1' type='set' xmlns='jabber:client'>
12
+ <command node='#{node}' action='execute' xmlns='http://jabber.org/protocol/commands'/>
13
+ </iq>
14
+ MSG
15
+ end
16
+
17
+ #.........................................................................................................
18
+ def recv_message_chat(client, from)
19
+ <<-MSG
20
+ <message from='#{from}' to='#{client.client.jid.to_s}' type='chat' xmlns='jabber:client'>
21
+ <body>fuck you</body>
22
+ </message>
23
+ MSG
24
+ end
25
+
26
+ #### sent messages
27
+ #.........................................................................................................
28
+ def send_iq_result_command_x_data_scalar(client, to)
29
+ <<-MSG
30
+ <iq id='1' to='#{to}' type='result' xmlns='jabber:client'>
31
+ <command node='scalar' status='completed' xmlns='http://jabber.org/protocol/commands'>
32
+ <x type='result' xmlns='jabber:x:data'>
33
+ <field>
34
+ <value>scalar</value>
35
+ </field>
36
+ </x>
37
+ </command>
38
+ </iq>
39
+ MSG
40
+ end
41
+
42
+ #.........................................................................................................
43
+ def send_iq_result_command_x_data_hash(client, to)
44
+ <<-MSG
45
+ <iq id='1' to='#{to}' type='result' xmlns='jabber:client'>
46
+ <command node='hash' status='completed' xmlns='http://jabber.org/protocol/commands'>
47
+ <x type='result' xmlns='jabber:x:data'>
48
+ <field var='attr1'>
49
+ <value>val1</value>
50
+ </field>
51
+ <field var='attr2'>
52
+ <value>val2</value>
53
+ </field>
54
+ </x>
55
+ </command>
56
+ </iq>
57
+ MSG
58
+ end
59
+
60
+ #.........................................................................................................
61
+ def send_iq_result_command_x_data_scalar_array(client, to)
62
+ <<-MSG
63
+ <iq id='1' to='#{to}' type='result' xmlns='jabber:client'>
64
+ <command node='scalar_array' status='completed' xmlns='http://jabber.org/protocol/commands'>
65
+ <x type='result' xmlns='jabber:x:data'>
66
+ <field type='list-multi'>
67
+ <value>val1</value>
68
+ <value>val2</value>
69
+ <value>val3</value>
70
+ <value>val4</value>
71
+ </field>
72
+ </x>
73
+ </command>
74
+ </iq>
75
+ MSG
76
+ end
77
+
78
+ #.........................................................................................................
79
+ def send_iq_result_command_x_data_hash_array(client, to)
80
+ <<-MSG
81
+ <iq id='1' to='#{to}' type='result' xmlns='jabber:client'>
82
+ <command node='hash_array' status='completed' xmlns='http://jabber.org/protocol/commands'>
83
+ <x type='result' xmlns='jabber:x:data'>
84
+ <field type='list-multi' var='attr1'>
85
+ <value>val11</value>
86
+ <value>val11</value>
87
+ </field>
88
+ <field var='attr2'>
89
+ <value>val12</value>
90
+ </field>
91
+ </x>
92
+ </command>
93
+ </iq>
94
+ MSG
95
+ end
96
+
97
+ #.........................................................................................................
98
+ def send_iq_result_command_x_data_array_hash(client, to)
99
+ <<-MSG
100
+ <iq id='1' to='#{to}' type='result' xmlns='jabber:client'>
101
+ <command node='array_hash' status='completed' xmlns='http://jabber.org/protocol/commands'>
102
+ <x type='result' xmlns='jabber:x:data'>
103
+ <reported>
104
+ <field var='attr1'/>
105
+ <field var='attr2'/>
106
+ </reported>
107
+ <item>
108
+ <field var='attr1'>
109
+ <value>val11</value>
110
+ </field>
111
+ <field var='attr2'>
112
+ <value>val12</value>
113
+ </field>
114
+ </item>
115
+ <item>
116
+ <field var='attr1'>
117
+ <value>val21</value>
118
+ </field>
119
+ <field var='attr2'>
120
+ <value>val22</value>
121
+ </field>
122
+ </item>
123
+ <item>
124
+ <field var='attr1'>
125
+ <value>val31</value>
126
+ </field>
127
+ <field var='attr2'>
128
+ <value>val32</value>
129
+ </field>
130
+ </item>
131
+ </x>
132
+ </command>
133
+ </iq>
134
+ MSG
135
+ end
136
+
137
+ #.........................................................................................................
138
+ def send_iq_result_command_x_data_array_hash_array(client, to)
139
+ <<-MSG
140
+ <iq id='1' to='#{to}' type='result' xmlns='jabber:client'>
141
+ <command node='array_hash_array' status='completed' xmlns='http://jabber.org/protocol/commands'>
142
+ <x type='result' xmlns='jabber:x:data'>
143
+ <reported>
144
+ <field var='attr1'/>
145
+ <field var='attr2'/>
146
+ </reported>
147
+ <item>
148
+ <field type='list-multi' var='attr1'>
149
+ <value>val11</value>
150
+ <value>val11</value>
151
+ </field>
152
+ <field var='attr2'>
153
+ <value>val12</value>
154
+ </field>
155
+ </item>
156
+ <item>
157
+ <field type='list-multi' var='attr1'>
158
+ <value>val21</value>
159
+ <value>val21</value>
160
+ </field>
161
+ <field var='attr2'>
162
+ <value>val22</value>
163
+ </field>
164
+ </item>
165
+ <item>
166
+ <field type='list-multi' var='attr1'>
167
+ <value>val31</value>
168
+ <value>val31</value>
169
+ </field>
170
+ <field var='attr2'>
171
+ <value>val32</value>
172
+ </field>
173
+ </item>
174
+ </x>
175
+ </command>
176
+ </iq>
177
+ MSG
178
+ end
179
+
180
+ #.........................................................................................................
181
+ def send_error_command_routing(client, node, to)
182
+ <<-MSG
183
+ <iq id='1' to='#{to}' type='error' xmlns='jabber:client'>
184
+ <command node='#{node}' action='execute' xmlns='http://jabber.org/protocol/commands'/>
185
+ <error code='404' type='cancel'>
186
+ <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
187
+ <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>no route for specified command node</text>
188
+ </error>
189
+ </iq>
190
+ MSG
191
+ end
192
+
193
+ #.........................................................................................................
194
+ def send_message_chat(client, to)
195
+ <<-MSG
196
+ <message to='#{to}' type='chat' xmlns='jabber:client'>
197
+ <body>#{AgentXmpp::AGENT_XMPP_NAME} #{AgentXmpp::VERSION}, #{AgentXmpp::OS_VERSION}</body>
198
+ </message>
199
+ MSG
200
+ end
201
+
202
+ ## self
203
+ end
204
+
205
+ #### ApplicationMessages
206
+ end