troystribling-agent_xmpp 0.0.0 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/README.rdoc +397 -2
  2. data/Rakefile +33 -21
  3. data/VERSION +1 -1
  4. data/agent_xmpp.gemspec +78 -33
  5. data/lib/agent_xmpp.rb +11 -7
  6. data/lib/agent_xmpp/app.rb +0 -5
  7. data/lib/agent_xmpp/app/boot.rb +47 -33
  8. data/lib/agent_xmpp/app/controller.rb +135 -19
  9. data/lib/agent_xmpp/client.rb +6 -1
  10. data/lib/agent_xmpp/client/client.rb +22 -155
  11. data/lib/agent_xmpp/client/connection.rb +41 -250
  12. data/lib/agent_xmpp/client/message_delegate.rb +706 -0
  13. data/lib/agent_xmpp/client/message_pipe.rb +176 -0
  14. data/lib/agent_xmpp/client/publish_model.rb +65 -0
  15. data/lib/agent_xmpp/{app/format.rb → client/response.rb} +19 -24
  16. data/lib/agent_xmpp/client/roster_model.rb +139 -0
  17. data/lib/agent_xmpp/client/services_model.rb +97 -0
  18. data/lib/agent_xmpp/config.rb +45 -0
  19. data/lib/agent_xmpp/main.rb +126 -0
  20. data/lib/agent_xmpp/patches.rb +6 -2
  21. data/lib/agent_xmpp/patches/{standard_library_patches/array.rb → array.rb} +14 -7
  22. data/lib/agent_xmpp/patches/{standard_library_patches/float.rb → float.rb} +0 -0
  23. data/lib/agent_xmpp/patches/{standard_library_patches/hash.rb → hash.rb} +3 -3
  24. data/lib/agent_xmpp/patches/{standard_library_patches/object.rb → object.rb} +3 -3
  25. data/lib/agent_xmpp/patches/rexml.rb +69 -0
  26. data/lib/agent_xmpp/patches/{standard_library_patches/string.rb → string.rb} +5 -0
  27. data/lib/agent_xmpp/xmpp.rb +17 -0
  28. data/lib/agent_xmpp/xmpp/element.rb +159 -0
  29. data/lib/agent_xmpp/xmpp/error_response.rb +179 -0
  30. data/lib/agent_xmpp/xmpp/iq.rb +90 -0
  31. data/lib/agent_xmpp/xmpp/iq_command.rb +47 -0
  32. data/lib/agent_xmpp/xmpp/iq_disco.rb +205 -0
  33. data/lib/agent_xmpp/xmpp/iq_pubsub.rb +268 -0
  34. data/lib/agent_xmpp/xmpp/iq_roster.rb +183 -0
  35. data/lib/agent_xmpp/xmpp/iq_version.rb +89 -0
  36. data/lib/agent_xmpp/xmpp/jid.rb +150 -0
  37. data/lib/agent_xmpp/xmpp/message.rb +82 -0
  38. data/lib/agent_xmpp/xmpp/presence.rb +127 -0
  39. data/lib/agent_xmpp/xmpp/sasl.rb +241 -0
  40. data/lib/agent_xmpp/xmpp/stanza.rb +107 -0
  41. data/lib/agent_xmpp/xmpp/x_data.rb +269 -0
  42. data/test/app/app.rb +134 -0
  43. data/test/cases/test_application_message_processing.rb +65 -0
  44. data/test/cases/test_errors.rb +24 -0
  45. data/test/cases/test_presence_management.rb +139 -0
  46. data/test/cases/test_roster_management.rb +214 -0
  47. data/test/cases/test_service_discovery.rb +168 -0
  48. data/test/cases/test_session_management.rb +120 -0
  49. data/test/cases/test_version_discovery.rb +67 -0
  50. data/test/helpers/matchers.rb +23 -0
  51. data/test/helpers/mocks.rb +82 -0
  52. data/test/helpers/test_case_extensions.rb +45 -0
  53. data/test/helpers/test_client.rb +44 -0
  54. data/test/helpers/test_delegate.rb +61 -0
  55. data/test/helpers/test_helper.rb +91 -0
  56. data/test/messages/application_messages.rb +206 -0
  57. data/test/messages/error_messages.rb +35 -0
  58. data/test/messages/presence_messages.rb +66 -0
  59. data/test/messages/roster_messages.rb +126 -0
  60. data/test/messages/service_discovery_messages.rb +201 -0
  61. data/test/messages/session_messages.rb +158 -0
  62. data/test/messages/version_discovery_messages.rb +69 -0
  63. data/test/peer/peer.rb +36 -0
  64. data/test/xml_messages.txt +197 -0
  65. metadata +82 -42
  66. data/bin/agent_xmpp +0 -56
  67. data/lib/agent_xmpp/app/chat_message_body_controller.rb +0 -16
  68. data/lib/agent_xmpp/app/map.rb +0 -45
  69. data/lib/agent_xmpp/app/routes.rb +0 -77
  70. data/lib/agent_xmpp/app/view.rb +0 -49
  71. data/lib/agent_xmpp/client/parser.rb +0 -71
  72. data/lib/agent_xmpp/patches/standard_library_patches.rb +0 -5
  73. data/lib/agent_xmpp/patches/xmpp4r_patches.rb +0 -3
  74. data/lib/agent_xmpp/patches/xmpp4r_patches/command.rb +0 -26
  75. data/lib/agent_xmpp/patches/xmpp4r_patches/iq.rb +0 -26
  76. data/lib/agent_xmpp/patches/xmpp4r_patches/x_data.rb +0 -116
  77. data/lib/agent_xmpp/utils.rb +0 -2
  78. data/lib/agent_xmpp/utils/logger.rb +0 -24
  79. data/lib/agent_xmpp/utils/roster.rb +0 -23
  80. data/lib/agent_xmpp/version.rb +0 -6
  81. data/test/agent_xmpp_test.rb +0 -7
  82. data/test/test_helper.rb +0 -10
@@ -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.did_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.did_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.did_receive_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.did_receive_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,61 @@
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 :did_connect, :did_disconnect, :did_not_connect
33
+
34
+ #### authentication
35
+ delegate_callbacks :did_authenticate, :did_bind, :did_start_session, :did_receive_preauthenticate_features,
36
+ :did_receive_postauthenticate_features
37
+
38
+ #### presence
39
+ delegate_callbacks :did_receive_presence, :did_receive_presence_subscribe, :did_receive_presence_unsubscribed,
40
+ :did_receive_presence_subscribed, :did_receive_presence_unavailable
41
+
42
+ #### roster management
43
+ delegate_callbacks :did_receive_roster_item, :did_receive_all_roster_items, :did_acknowledge_add_roster_item,
44
+ :did_receive_roster_result, :did_receive_roster_set, :did_remove_roster_item, :did_acknowledge_remove_roster_item,
45
+ :did_receive_remove_roster_item_error, :did_receive_add_roster_item_error
46
+
47
+ #### service discovery management
48
+ delegate_callbacks :did_receive_version_result, :did_receive_version_get, :did_receive_version_error, :did_receive_discoinfo_result,
49
+ :did_receive_discoinfo_get, :did_receive_discoitems_get, :did_receive_discoitems_result,
50
+ :did_receive_discoinfo_error, :did_receive_discoitems_error
51
+
52
+ #### errors
53
+ delegate_callbacks :did_receive_unsupported_message
54
+
55
+ #---------------------------------------------------------------------------------------------------------
56
+ def initialize
57
+ @@callback_methods.each{|m| send("#{m.to_s}_method=".to_sym, false)}
58
+ end
59
+
60
+ #### TestDelegate
61
+ 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