skates 0.1.11

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 (47) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +113 -0
  3. data/Rakefile +143 -0
  4. data/bin/skates +6 -0
  5. data/lib/skates.rb +108 -0
  6. data/lib/skates/base/controller.rb +116 -0
  7. data/lib/skates/base/stanza.rb +23 -0
  8. data/lib/skates/base/view.rb +58 -0
  9. data/lib/skates/client_connection.rb +210 -0
  10. data/lib/skates/component_connection.rb +87 -0
  11. data/lib/skates/generator.rb +139 -0
  12. data/lib/skates/router.rb +101 -0
  13. data/lib/skates/router/dsl.rb +61 -0
  14. data/lib/skates/runner.rb +137 -0
  15. data/lib/skates/xmpp_connection.rb +172 -0
  16. data/lib/skates/xmpp_parser.rb +117 -0
  17. data/lib/skates/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 +92 -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/skates/app/controllers/controller.rb +7 -0
  34. data/templates/skates/app/stanzas/stanza.rb +6 -0
  35. data/templates/skates/app/views/view.rb +6 -0
  36. data/templates/skates/config/boot.rb +16 -0
  37. data/templates/skates/config/config.yaml +24 -0
  38. data/templates/skates/config/dependencies.rb +1 -0
  39. data/templates/skates/config/routes.rb +22 -0
  40. data/templates/skates/log/development.log +0 -0
  41. data/templates/skates/log/production.log +0 -0
  42. data/templates/skates/log/test.log +0 -0
  43. data/templates/skates/script/component +36 -0
  44. data/templates/skates/tmp/pids/README +2 -0
  45. data/test/skates_test.rb +7 -0
  46. data/test/test_helper.rb +10 -0
  47. metadata +160 -0
@@ -0,0 +1,304 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Skates::ClientConnection do
5
+
6
+ include SkatesSpecHelper
7
+
8
+ before(:each) do
9
+ @params = {"jid" => "jid@server.tld", "password" => "password", "port" => 1234, "host" => "myhost.com"}
10
+ @client = Skates::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 = Skates::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 = Skates::ClientConnection.connect(@params, handler_mock)
44
+ end
45
+
46
+ it "should sort the srv records" do
47
+ @client = Skates::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(Skates::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(Skates::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>skates_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 Skates::ComponentConnection do
5
+
6
+ include SkatesSpecHelper
7
+
8
+ before(:each) do
9
+ @params = {"jid" => "jid@server", "password" => "password", "port" => 1234, "host" => "myhost.com"}
10
+ @component = Skates::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(Skates::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 Skates::Generator::ApplicationGenerator do
4
+ # Hum, how do we spec Templater?
5
+ end
6
+
7
+
8
+ describe Skates::Generator::ControllerGenerator do
9
+ # Hum, how do we spec Templater?
10
+ end