mohiam-babylon 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +111 -0
  3. data/Rakefile +145 -0
  4. data/bin/babylon +6 -0
  5. data/lib/babylon.rb +119 -0
  6. data/lib/babylon/base/controller.rb +116 -0
  7. data/lib/babylon/base/stanza.rb +23 -0
  8. data/lib/babylon/base/view.rb +49 -0
  9. data/lib/babylon/client_connection.rb +210 -0
  10. data/lib/babylon/component_connection.rb +87 -0
  11. data/lib/babylon/generator.rb +139 -0
  12. data/lib/babylon/router.rb +103 -0
  13. data/lib/babylon/router/dsl.rb +61 -0
  14. data/lib/babylon/runner.rb +148 -0
  15. data/lib/babylon/xmpp_connection.rb +172 -0
  16. data/lib/babylon/xmpp_parser.rb +111 -0
  17. data/lib/babylon/xpath_helper.rb +13 -0
  18. data/spec/bin/babylon_spec.rb +0 -0
  19. data/spec/em_mock.rb +42 -0
  20. data/spec/lib/babylon/base/controller_spec.rb +205 -0
  21. data/spec/lib/babylon/base/stanza_spec.rb +15 -0
  22. data/spec/lib/babylon/base/view_spec.rb +86 -0
  23. data/spec/lib/babylon/client_connection_spec.rb +304 -0
  24. data/spec/lib/babylon/component_connection_spec.rb +135 -0
  25. data/spec/lib/babylon/generator_spec.rb +10 -0
  26. data/spec/lib/babylon/router/dsl_spec.rb +72 -0
  27. data/spec/lib/babylon/router_spec.rb +189 -0
  28. data/spec/lib/babylon/runner_spec.rb +213 -0
  29. data/spec/lib/babylon/xmpp_connection_spec.rb +197 -0
  30. data/spec/lib/babylon/xmpp_parser_spec.rb +275 -0
  31. data/spec/lib/babylon/xpath_helper_spec.rb +25 -0
  32. data/spec/spec_helper.rb +34 -0
  33. data/templates/babylon/app/controllers/controller.rb +7 -0
  34. data/templates/babylon/app/stanzas/stanza.rb +6 -0
  35. data/templates/babylon/app/views/view.rb +6 -0
  36. data/templates/babylon/config/boot.rb +16 -0
  37. data/templates/babylon/config/config.yaml +24 -0
  38. data/templates/babylon/config/dependencies.rb +1 -0
  39. data/templates/babylon/config/routes.rb +22 -0
  40. data/templates/babylon/log/development.log +0 -0
  41. data/templates/babylon/log/production.log +0 -0
  42. data/templates/babylon/log/test.log +52 -0
  43. data/templates/babylon/script/component +46 -0
  44. data/templates/babylon/tmp/pids/README +2 -0
  45. data/test/babylon_test.rb +7 -0
  46. data/test/test_helper.rb +10 -0
  47. metadata +179 -0
@@ -0,0 +1,304 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Babylon::ClientConnection do
5
+
6
+ include BabylonSpecHelper
7
+
8
+ before(:each) do
9
+ @params = {"jid" => "jid@server.tld", "password" => "password", "port" => 1234, "host" => "myhost.com"}
10
+ @client = Babylon::ClientConnection.connect(@params, handler_mock)
11
+ @client.stub!(:send_xml).and_return(true)
12
+ end
13
+
14
+ describe "initialize" do
15
+ it "should set the state to :wait_for_stream" do
16
+ @client.instance_variable_get("@state").should == :wait_for_stream
17
+ end
18
+ end
19
+
20
+ describe "connect" do
21
+ it "should not try to resolve the dns if both the port and host are provided" do
22
+ Resolv::DNS.should_not_receive(:open)
23
+ @client = Babylon::ClientConnection.connect(@params, handler_mock)
24
+ end
25
+
26
+ describe "when host and port are not provided" do
27
+ before(:each) do
28
+ @params.delete("host")
29
+ @params.delete("port")
30
+ @srv = [
31
+ mock(Resolv::DNS::Resource, :priority => 10, :target => "xmpp.server.tld", :port => 1234),
32
+ mock(Resolv::DNS::Resource, :priority => 3, :target => "xmpp2.server.tld", :port => 4567),
33
+ mock(Resolv::DNS::Resource, :priority => 100, :target => "xmpp3.server.tld", :port => 8910)
34
+ ]
35
+ @mock_dns = mock(Object)
36
+ Resolv::DNS.stub!(:open).and_yield(@mock_dns)
37
+ @mock_dns.stub!(:getresources).with("_xmpp-client._tcp.server.tld", Resolv::DNS::Resource::IN::SRV).and_return(@srv)
38
+ end
39
+
40
+ it "should get resources assiated with _xmpp-client._tcp.host.tld}" do
41
+ Resolv::DNS.should_receive(:open).and_yield(@mock_dns)
42
+ @mock_dns.should_receive(:getresources).with("_xmpp-client._tcp.server.tld", Resolv::DNS::Resource::IN::SRV).and_return(@srv)
43
+ @client = Babylon::ClientConnection.connect(@params, handler_mock)
44
+ end
45
+
46
+ it "should sort the srv records" do
47
+ @client = Babylon::ClientConnection.connect(@params, handler_mock)
48
+ @srv.map {|srv| srv.target }.should == ["xmpp2.server.tld", "xmpp.server.tld", "xmpp3.server.tld"]
49
+ end
50
+
51
+ it "should try to connect to each record until one of the them actually connects"
52
+ end
53
+ end
54
+
55
+ describe "stream_stanza" do
56
+ it "should be of the right form" do
57
+ @client.stream_stanza.should == "<?xml version=\"1.0\"?>\n<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" to=\"server.tld\" version=\"1.0\">\n "
58
+ end
59
+ end
60
+
61
+ describe "connection_completed" do
62
+ it "should send_xml the stream_stanza" do
63
+ @client.should_receive(:send_xml).with(@client.stream_stanza)
64
+ @client.connection_completed
65
+ end
66
+ end
67
+
68
+ describe "receive_stanza" do
69
+ before(:each) do
70
+ @doc = Nokogiri::XML::Document.new
71
+ end
72
+ describe "when connected" do
73
+ before(:each) do
74
+ @client.instance_variable_set("@state", :connected)
75
+ end
76
+ it "should call super"
77
+ end
78
+
79
+ describe "when wait_for_stream_authenticated" do
80
+ before(:each) do
81
+ @client.instance_variable_set("@state", :wait_for_stream_authenticated)
82
+ @stanza = Nokogiri::XML::Node.new("stream:stream", @doc)
83
+ @stanza["id"] = "123"
84
+ end
85
+ it "should change state to wait_for_bind if the stanza is stream:stream with an id" do
86
+ @client.receive_stanza(@stanza)
87
+ @client.instance_variable_get("@state").should == :wait_for_bind
88
+ end
89
+ end
90
+
91
+ describe "when wait_for_stream" do
92
+ before(:each) do
93
+ @client.instance_variable_set("@state", :wait_for_stream)
94
+ @stanza = Nokogiri::XML::Node.new("stream:stream", @doc)
95
+ @stanza["id"] = "123"
96
+ end
97
+ it "should change state to wait_for_auth_mechanisms if the stanza is stream:stream with an id" do
98
+ @client.receive_stanza(@stanza)
99
+ @client.instance_variable_get("@state").should == :wait_for_auth_mechanisms
100
+ end
101
+ end
102
+
103
+ describe "when wait_for_auth_mechanisms" do
104
+ before(:each) do
105
+ @client.instance_variable_set("@state", :wait_for_auth_mechanisms)
106
+ end
107
+
108
+ describe "if the stanza is stream:features" do
109
+ before(:each) do
110
+ @stanza = Nokogiri::XML::Node.new("stream:features", @doc)
111
+ @stanza["id"] = "123"
112
+ end
113
+
114
+ describe "if the stanza has startls" do
115
+ before(:each) do
116
+ @stanza.add_child(Nokogiri::XML::Node.new("starttls", @doc))
117
+ end
118
+ it "should send start tls" do
119
+ @client.should_receive(:send_xml).with('<starttls xmlns="urn:ietf:params:xml:ns:xmpp-tls"/>')
120
+ @client.receive_stanza(@stanza)
121
+ end
122
+ end
123
+
124
+ describe "if the stanza has mechanisms" do
125
+ before(:each) do
126
+ mechanisms = Nokogiri::XML::Node.new("mechanisms", @doc)
127
+ mechanism = Nokogiri::XML::Node.new("mechanism", @doc)
128
+ mechanism.content = "PLAIN"
129
+ mechanisms.add_child(mechanism)
130
+ @stanza.add_child(mechanisms)
131
+ end
132
+
133
+ it "should send authentication" do
134
+ @client.should_receive(:send_xml).with("<auth mechanism=\"PLAIN\" xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">amlkQHNlcnZlci50bGQAamlkAHBhc3N3b3Jk</auth>")
135
+ @client.receive_stanza(@stanza)
136
+ end
137
+ end
138
+
139
+ end
140
+ end
141
+
142
+ describe "when wait_for_success" do
143
+ before(:each) do
144
+ @client.instance_variable_set("@state", :wait_for_success)
145
+ end
146
+ describe "when stanza is success" do
147
+ before(:each) do
148
+ @stanza = Nokogiri::XML::Node.new("success", @doc)
149
+ end
150
+
151
+ it "should reset the parser" do
152
+ @client.instance_variable_get("@parser").should_receive(:reset)
153
+ @client.receive_stanza(@stanza)
154
+ end
155
+
156
+ it "should send stream_stanza" do
157
+ @client.should_receive(:send_xml).with("<?xml version=\"1.0\"?>\n<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" to=\"server.tld\" version=\"1.0\">\n ")
158
+ @client.receive_stanza(@stanza)
159
+ end
160
+
161
+ it "should change state to wait_for_stream_authenticated" do
162
+ @client.receive_stanza(@stanza)
163
+ @client.instance_variable_get("@state").should == :wait_for_stream_authenticated
164
+ end
165
+
166
+ end
167
+ describe "when stanza is failure" do
168
+ before(:each) do
169
+ @stanza = Nokogiri::XML::Node.new("failure", @doc)
170
+ end
171
+ it "should raise AuthenticationError if stanza has bad-auth" do
172
+ @stanza.add_child(Nokogiri::XML::Node.new("bad-auth", @doc))
173
+ lambda {
174
+ @client.receive_stanza(@stanza)
175
+ }.should raise_error(Babylon::AuthenticationError)
176
+ end
177
+
178
+ it "should raise AuthenticationError if stanza has not-authorized" do
179
+ @stanza.add_child(Nokogiri::XML::Node.new("not-authorized", @doc))
180
+ lambda {
181
+ @client.receive_stanza(@stanza)
182
+ }.should raise_error(Babylon::AuthenticationError)
183
+ end
184
+ end
185
+ end
186
+
187
+ describe "when wait_for_bind" do
188
+ before(:each) do
189
+ @client.instance_variable_set("@state", :wait_for_bind)
190
+ end
191
+
192
+ describe "if stanza is stream:features" do
193
+ before(:each) do
194
+ @stanza = Nokogiri::XML::Node.new("stream:features", @doc)
195
+ end
196
+
197
+ describe "if stanza has bind" do
198
+ before(:each) do
199
+ bind = Nokogiri::XML::Node.new("bind", @doc)
200
+ @stanza.add_child(bind)
201
+ end
202
+
203
+ it "should send_xml with the bind iq" do
204
+ @client.should_receive(:binding_iq_id).twice.and_return(123)
205
+ @client.should_receive(:send_xml).with("<iq type=\"set\" id=\"123\">\n <bind xmlns=\"urn:ietf:params:xml:ns:xmpp-bind\">\n <resource>babylon_client_123</resource>\n </bind>\n</iq>")
206
+ @client.receive_stanza(@stanza)
207
+ end
208
+
209
+ it "should set the state to :wait_for_confirmed_binding" do
210
+ @client.receive_stanza(@stanza)
211
+ @client.instance_variable_get("@state").should == :wait_for_confirmed_binding
212
+ end
213
+ end
214
+ end
215
+ end
216
+
217
+ describe "when wait_for_confirmed_binding" do
218
+ before(:each) do
219
+ @client.instance_variable_set("@state", :wait_for_confirmed_binding)
220
+ end
221
+ describe "if stanza is iq with type=result and the righ binding_iq_id" do
222
+ before(:each) do
223
+ binding_iq_id = 123
224
+ @stanza = Nokogiri::XML::Node.new("iq", @doc)
225
+ @stanza["type"] = "result"
226
+ @stanza["id"] = binding_iq_id.to_s
227
+ @client.stub!(:binding_iq_id).and_return(binding_iq_id)
228
+ end
229
+
230
+ it "should send_xml with the session iq" do
231
+ @client.should_receive(:session_iq_id).and_return(123)
232
+ @client.should_receive(:send_xml).with("<iq type=\"set\" id=\"123\">\n <session xmlns=\"urn:ietf:params:xml:ns:xmpp-session\"/>\n</iq>")
233
+ @client.receive_stanza(@stanza)
234
+ end
235
+
236
+ it "should set the state to :wait_for_confirmed_session" do
237
+ @client.receive_stanza(@stanza)
238
+ @client.instance_variable_get("@state").should == :wait_for_confirmed_session
239
+ end
240
+ end
241
+
242
+ end
243
+
244
+ describe "when wait_for_confirmed_session" do
245
+ before(:each) do
246
+ @client.instance_variable_set("@state", :wait_for_confirmed_session)
247
+ end
248
+
249
+ describe "if stanza is iq with type=result and the righ session_iq_id" do
250
+ before(:each) do
251
+ session_iq_id = 123
252
+ @stanza = Nokogiri::XML::Node.new("iq", @doc)
253
+ @stanza["type"] = "result"
254
+ @stanza["id"] = session_iq_id.to_s
255
+ @client.stub!(:session_iq_id).and_return(session_iq_id)
256
+ end
257
+
258
+ it "should send_xml the initial presence" do
259
+ @client.should_receive(:send_xml).with("<presence/>")
260
+ @client.receive_stanza(@stanza)
261
+ end
262
+
263
+ it "should set the state to :connected" do
264
+ @client.receive_stanza(@stanza)
265
+ @client.instance_variable_get("@state").should == :connected
266
+ end
267
+ end
268
+ end
269
+
270
+ describe "when wait_for_proceed" do
271
+ before(:each) do
272
+ @client.instance_variable_set("@state", :wait_for_proceed)
273
+ @client.stub!(:start_tls).and_return(true)
274
+ end
275
+
276
+ it "should start_tls" do
277
+ @client.should_receive(:start_tls)
278
+ @client.receive_stanza(@stanza)
279
+ end
280
+
281
+ it "reset the parser" do
282
+ @client.instance_variable_get("@parser").should_receive(:reset)
283
+ @client.receive_stanza(@stanza)
284
+ end
285
+
286
+ it "should set the state to :wait_for_stream" do
287
+ @client.receive_stanza(@stanza)
288
+ @client.instance_variable_get("@state").should == :wait_for_stream
289
+ end
290
+
291
+ it "should send the stream stanza" do
292
+ @client.should_receive(:send_xml).with("<?xml version=\"1.0\"?>\n<stream:stream xmlns=\"jabber:client\" xmlns:stream=\"http://etherx.jabber.org/streams\" to=\"server.tld\" version=\"1.0\">\n ")
293
+ @client.receive_stanza(@stanza)
294
+ end
295
+ end
296
+ end
297
+
298
+ describe "stream_namespace" do
299
+ it "should return jabber:client" do
300
+ @client.stream_namespace.should == "jabber:client"
301
+ end
302
+ end
303
+
304
+ end
@@ -0,0 +1,135 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Babylon::ComponentConnection do
5
+
6
+ include BabylonSpecHelper
7
+
8
+ before(:each) do
9
+ @params = {"jid" => "jid@server", "password" => "password", "port" => 1234, "host" => "myhost.com"}
10
+ @component = Babylon::ComponentConnection.connect(@params, handler_mock)
11
+ @component.stub!(:send_xml).and_return(true)
12
+ end
13
+
14
+ describe "initialize" do
15
+ it "should set the state to :wait_for_stream" do
16
+ @component.instance_variable_get("@state").should == :wait_for_stream
17
+ end
18
+ end
19
+
20
+ describe "connection_completed" do
21
+ it "should send a <stream> element that initiates the communication" do
22
+ @component.should_receive(:send_xml).with("<?xml version=\"1.0\"?>\n<stream:stream xmlns=\"jabber:component:accept\" xmlns:stream=\"http://etherx.jabber.org/streams\" to=\"jid@server\">\n ")
23
+ @component.connection_completed
24
+ end
25
+ end
26
+
27
+ describe "receive_stanza" do
28
+
29
+ before(:each) do
30
+ @component.instance_variable_set("@connected", true)
31
+ @doc = Nokogiri::XML::Document.new
32
+ @stanza = Nokogiri::XML::Node.new("presence", @doc)
33
+ end
34
+
35
+ describe "when connected" do
36
+ before(:each) do
37
+ @component.instance_variable_set("@state", :connected)
38
+ end
39
+ it "should call the receive_stanza on super"
40
+ end
41
+
42
+ describe "when waiting for stream" do
43
+ before(:each) do
44
+ @component.connection_completed
45
+ @component.instance_variable_set("@state", :wait_for_stream)
46
+ end
47
+
48
+ describe "if the stanza is stream" do
49
+ before(:each) do
50
+ @stanza = Nokogiri::XML::Node.new("stream:stream", @doc)
51
+ @stanza["xmlns:stream"] = 'http://etherx.jabber.org/streams'
52
+ @stanza["xmlns"] = 'jabber:component:accept'
53
+ @stanza["from"] = 'plays.shakespeare.lit'
54
+ @stanza["id"] = "1234"
55
+ end
56
+
57
+ it "should send a handshake" do
58
+ @component.should_receive(:handshake)
59
+ @component.receive_stanza(@stanza)
60
+ end
61
+
62
+ it "should change state to wait_for_handshake" do
63
+ @component.receive_stanza(@stanza)
64
+ @component.instance_variable_get("@state").should == :wait_for_handshake
65
+ end
66
+
67
+ end
68
+
69
+ describe "if the stanza is not stream or deosn't have an id" do
70
+ it "should raise an error" do
71
+ lambda {@component.receive_stanza(Nokogiri::XML::Node.new("else", @doc))}.should raise_error
72
+ end
73
+ end
74
+
75
+ end
76
+
77
+ describe "when waiting for handshake" do
78
+ before(:each) do
79
+ @component.instance_variable_set("@state", :wait_for_handshake)
80
+ end
81
+
82
+ describe "if we actually get a handshake stanza" do
83
+
84
+ before(:each) do
85
+ @handshake = Nokogiri::XML::Node.new("handshake", @doc)
86
+ end
87
+
88
+ it "should set the status as connected" do
89
+ @component.receive_stanza(@handshake)
90
+ @component.instance_variable_get("@state").should == :connected
91
+ end
92
+
93
+ it "should call the connection callback" do
94
+ handler_mock.should_receive(:on_connected).with(@component)
95
+ @component.receive_stanza(@handshake)
96
+ end
97
+ end
98
+
99
+ describe "if we receive a stream:error" do
100
+ it "should raise an Authentication Error" do
101
+ lambda {@component.receive_stanza(Nokogiri::XML::Node.new("stream:error", @doc))}.should raise_error(Babylon::AuthenticationError)
102
+ end
103
+ end
104
+
105
+ describe "if we receive something else" do
106
+ it "should raise an error" do
107
+ lambda {@component.receive_stanza(Nokogiri::XML::Node.new("else", @doc))}.should raise_error
108
+ end
109
+ end
110
+
111
+ end
112
+
113
+ end
114
+
115
+ describe "stream_namespace" do
116
+ it "should return jabber:component:accept" do
117
+ @component.stream_namespace.should == 'jabber:component:accept'
118
+ end
119
+ end
120
+
121
+ describe "handshake" do
122
+ it "should build a handshake Element with the password and the id of the stanza" do
123
+ @component.connection_completed
124
+ doc = Nokogiri::XML::Document.new
125
+ stanza = Nokogiri::XML::Node.new("stream:stream", doc)
126
+ stanza["xmlns:stream"] = 'http://etherx.jabber.org/streams'
127
+ stanza["xmlns"] = 'jabber:component:accept'
128
+ stanza["from"] = 'plays.shakespeare.lit'
129
+ stanza["id"] = "1234"
130
+ @component.__send__(:handshake, stanza).xpath("//handshake").first.content.should == Digest::SHA1::hexdigest(stanza.attributes['id'].content + @params["password"])
131
+ end
132
+
133
+ end
134
+
135
+ end
@@ -0,0 +1,10 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Babylon::Generator::ApplicationGenerator do
4
+ # Hum, how do we spec Templater?
5
+ end
6
+
7
+
8
+ describe Babylon::Generator::ControllerGenerator do
9
+ # Hum, how do we spec Templater?
10
+ end