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,134 @@
1
+ ##########################################################################################################
2
+ require 'rubygems'
3
+ require "#{File.dirname(__FILE__)}/../../lib/agent_xmpp"
4
+
5
+ ##########################################################################################################
6
+ # callbacks
7
+ before_start do
8
+ AgentXmpp.logger.level = Logger::DEBUG
9
+ AgentXmpp.logger.info "before_start"
10
+ end
11
+
12
+ #.........................................................................................................
13
+ after_connected do |connection|
14
+ AgentXmpp.logger.info "after_connected"
15
+ end
16
+
17
+ #.........................................................................................................
18
+ restarting_client do |connection|
19
+ AgentXmpp.logger.info "restarting_client"
20
+ end
21
+
22
+ #.........................................................................................................
23
+ discovered_pubsub_node do |service, node|
24
+ AgentXmpp.logger.info "discovered_pubsub_node: #{service}, #{node}"
25
+ if node.eql?(AgentXmpp.user_pubsub_root+'/time')
26
+ AgentXmpp.logger.info "LAUNCHING TIME PUBLISH TASK"
27
+ EventMachine::PeriodicTimer.new(60) do
28
+ publish_time(Time.now.to_s)
29
+ AgentXmpp.logger.info "FIRING EVENT TIME: #{Time.now.to_s}"
30
+ end
31
+ elsif node.eql?(AgentXmpp.user_pubsub_root+'/shot')
32
+ AgentXmpp.logger.info "LAUNCHING SHOT PUBLISH TASK"
33
+ EventMachine::Timer.new(30) do
34
+ publish_shot(Time.now.to_s)
35
+ AgentXmpp.logger.info "FIRING EVENT SHOT: #{Time.now.to_s}"
36
+ end
37
+ end
38
+ end
39
+
40
+ #.........................................................................................................
41
+ discovered_command_nodes do |jid, nodes|
42
+ AgentXmpp.logger.info "discovered_command_nodes"
43
+ nodes.each do |n|
44
+ AgentXmpp.logger.info "COMMAND NODE: #{jid}, #{n}"
45
+ command(:to=>jid, :node=> n) do |status, data|
46
+ AgentXmpp.logger.info "COMMAND RESPONSE: #{status}, #{data.inspect}"
47
+ end
48
+ end
49
+ end
50
+
51
+ #.........................................................................................................
52
+ received_presence do |from, status|
53
+ AgentXmpp.logger.info "received_presence: #{from}, #{status}"
54
+ end
55
+
56
+ ##########################################################################################################
57
+ # command processing
58
+ #.........................................................................................................
59
+ execute 'scalar' do
60
+ AgentXmpp.logger.info "ACTION: scalar"
61
+ 'scalar'
62
+ end
63
+
64
+ #.........................................................................................................
65
+ execute 'hash' do
66
+ AgentXmpp.logger.info "ACTION: hash"
67
+ {:attr1 => 'val1', :attr2 => 'val2'}
68
+ end
69
+
70
+ #.........................................................................................................
71
+ execute 'scalar_array' do
72
+ AgentXmpp.logger.info "ACTION: array"
73
+ ['val1', 'val2','val3', 'val4']
74
+ end
75
+
76
+ #.........................................................................................................
77
+ execute 'hash_array' do
78
+ AgentXmpp.logger.info "ACTION: hash_array"
79
+ {:attr1 => ['val11', 'val11'], :attr2 => 'val12'}
80
+ end
81
+
82
+ #.........................................................................................................
83
+ execute 'array_hash' do
84
+ AgentXmpp.logger.info "ACTION: array_hash"
85
+ [{:attr1 => 'val11', :attr2 => 'val12'},
86
+ {:attr1 => 'val21', :attr2 => 'val22'},
87
+ {:attr1 => 'val31', :attr2 => 'val32'}]
88
+ end
89
+
90
+ #.........................................................................................................
91
+ execute 'array_hash_array' do
92
+ AgentXmpp.logger.info "ACTION: hash_array"
93
+ [{:attr1 => ['val11', 'val11'], :attr2 => 'val12'},
94
+ {:attr1 => ['val21', 'val21'], :attr2 => 'val22'},
95
+ {:attr1 => ['val31', 'val31'], :attr2 => 'val32'}]
96
+ end
97
+
98
+ #.........................................................................................................
99
+ # respond with a result and another command resquest
100
+ execute 'hash_hello' do
101
+ AgentXmpp.logger.info "ACTION: hash_hello"
102
+ command(:to=>params[:from], :node=> 'hello') do |status, data|
103
+ AgentXmpp.logger.info "COMMAND RESPONSE: #{status}, #{data.inspect}"
104
+ end
105
+ {:attr1 => 'val1', :attr2 => 'val2'}
106
+ end
107
+
108
+ ##########################################################################################################
109
+ # chat messages
110
+ chat do
111
+ AgentXmpp.logger.info "CHAT MESSAGE: #{params[:from]}, #{params[:body]}"
112
+ params[:body].reverse
113
+ end
114
+
115
+ ##########################################################################################################
116
+ # pubsub events
117
+ #.........................................................................................................
118
+ # respond with a chat message
119
+ event 'test@planbresearch.com', 'val' do
120
+ AgentXmpp.logger.info "EVENT: test@planbresearch.com/val"
121
+ message(:to=>params[:from], :body=>"Got the event at: " + Time.now.to_s)
122
+ end
123
+
124
+ #.........................................................................................................
125
+ event 'test@planbresearch.com', 'waiting' do
126
+ AgentXmpp.logger.info "EVENT: test@planbresearch.com/waiting"
127
+ p params
128
+ end
129
+
130
+ #.........................................................................................................
131
+ event 'test@plan-b.ath.cx', 'val' do
132
+ AgentXmpp.logger.info "EVENT: test@plan-b.ath.cx/val"
133
+ p params
134
+ 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.did_receive_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.did_receive_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
+ AgentXmpp.roster.resources(@home).should be_empty
25
+ @delegate.did_receive_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.did_receive_presence_method.should be_called
30
+ AgentXmpp.roster.resource(@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.did_receive_presence_unavailable_method.should_not be_called
41
+ AgentXmpp.roster.resource(@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.did_receive_presence_unavailable_method.should be_called
44
+ AgentXmpp.roster.resource(@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.resource(@home).type.should be(:unavailable)
53
+ @delegate.did_receive_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.did_receive_presence_method.should be_called
58
+ AgentXmpp.roster.resource(@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.did_receive_presence_method.should_not be_called
66
+ AgentXmpp.roster.resource(@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.did_receive_presence_method.should be_called
71
+ AgentXmpp.roster.resource(@work).should_not be_nil
72
+ AgentXmpp.roster.resource(@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
+ AgentXmpp.roster.resources(@client.client.jid).should be_empty
80
+ @delegate.did_receive_presence_method.should_not be_called
81
+ @client.receiving(PresenceMessages.recv_presence_self(@client)).should not_respond
82
+ @delegate.did_receive_presence_method.should be_called
83
+ AgentXmpp.roster.resource(@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.roster.has_jid?(@noone).should be(false)
89
+ @delegate.did_receive_presence_method.should_not be_called
90
+ @client.receiving(PresenceMessages.recv_presence_available(@client, @noone.to_s)).should not_respond
91
+ @delegate.did_receive_presence_method.should be_called
92
+ AgentXmpp.roster.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.roster.has_jid?(@home).should be(true)
98
+ @delegate.did_receive_presence_subscribe_method.should_not be_called
99
+ @delegate.did_receive_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.did_receive_presence_subscribe_method.should be_called
104
+ @delegate.did_receive_presence_subscribed_method.should be_called
105
+ AgentXmpp.roster.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.roster.has_jid?(@home).should be(true)
111
+ @delegate.did_receive_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.did_receive_presence_unsubscribed_method.should be_called
116
+ AgentXmpp.roster.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.roster.has_jid?(@noone).should be(false)
122
+ @delegate.did_receive_presence_unsubscribed_method.should_not be_called
123
+ @client.receiving(PresenceMessages.recv_presence_unsubscribed(@client, @noone.bare.to_s)).should not_respond
124
+ @delegate.did_receive_presence_unsubscribed_method.should be_called
125
+ AgentXmpp.roster.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.roster.has_jid?(@noone).should be(false)
131
+ @delegate.did_receive_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.did_receive_presence_subscribe_method.should be_called
135
+ AgentXmpp.roster.has_jid?(@noone).should be(false)
136
+ end
137
+
138
+ end
139
+
@@ -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.did_receive_roster_item_method.should_not be_called
17
+ delegate.did_receive_all_roster_items_method.should_not be_called
18
+ yield client
19
+ delegate.did_receive_roster_item_method.should be_called
20
+ delegate.did_receive_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.roster.find_by_jid(@dev).status.should be(:both)
48
+ AgentXmpp.roster.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.did_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.did_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.roster.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.roster.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.roster.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.did_receive_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.did_receive_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.roster.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.roster.find_by_jid(@dev).status.should be(:both)
108
+ end
109
+
110
+ #### receive roster remove ackgnowledgement
111
+ delegate = client.new_delegate
112
+ delegate.did_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.did_acknowledge_remove_roster_item_method.should be_called
115
+
116
+ #### recieve roster item remove
117
+ delegate.did_remove_roster_item_method.should_not be_called
118
+ delegate.did_receive_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.roster.has_jid?(@troy).should be(false)
121
+ delegate.did_remove_roster_item_method.should be_called
122
+ delegate.did_receive_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.roster.has_jid?(@troy).should be(false)
139
+ end
140
+
141
+ #### receive roster remove ackgnowledgement
142
+ delegate = client.new_delegate
143
+ delegate.did_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.did_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.roster.has_jid?(@troy).should be(false)
176
+ end
177
+
178
+ #### receive roster remove ackgnowledgement
179
+ delegate = client.new_delegate
180
+ delegate.did_receive_remove_roster_item_error_method.should_not be_called
181
+ client.receiving(RosterMessages.recv_error_query_roster_remove(client)).should not_respond
182
+ AgentXmpp.roster.has_jid?(@troy).should be(false)
183
+ delegate.did_receive_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.roster.find_by_jid(@dev).status.should be(:both)
202
+ AgentXmpp.roster.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.did_receive_add_roster_item_error_method.should_not be_called
208
+ client.receiving(RosterMessages.recv_error_query_roster_remove(client)).should not_respond
209
+ delegate.did_receive_add_roster_item_error_method.should be_called
210
+ AgentXmpp.roster.has_jid?(@troy).should be(false)
211
+
212
+ end
213
+
214
+ end