radamanthus-skates 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,233 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Skates::Runner do
5
+ before(:all) do
6
+ FileUtils.chdir("#{FileUtils.pwd}/templates/skates") unless ("#{FileUtils.pwd}" =~ /\/templates\/skates/ )
7
+ end
8
+
9
+ describe ".prepare" do
10
+ before(:each) do
11
+ @config = {"production"=>{"port"=>5278, "auto-reconnect"=>true, "jid"=>"component.server.com", "host"=>"localhost", "password"=>"password"}, "development"=>{"auto-reconnect"=>true, "jid"=>"user@server.com", "application_type"=>"client", "password"=>"password"}, "test"=>{"port"=>5278, "auto-reconnect"=>true, "jid"=>"component.server.com", "host"=>"localhost", "password"=>"password"}}
12
+ Skates.config_file = "config/config.yaml"
13
+ YAML.stub(:load_file).and_return(@config)
14
+ Skates::Runner.stub!(:require_directory).and_return(true)
15
+ end
16
+
17
+ it "should add the environment log file as an outputter to skates's default log" do
18
+ Skates.should_receive(:reopen_logs)
19
+ Skates::Runner.prepare("test")
20
+ end
21
+
22
+ it "should require all models" do
23
+ Skates::Runner.should_receive(:require_directory).with('app/models/*.rb').and_return(true)
24
+ Skates::Runner.prepare("test")
25
+ end
26
+
27
+ it "should require all stanzas" do
28
+ Skates::Runner.should_receive(:require_directory).with('app/stanzas/*.rb').and_return(true)
29
+ Skates::Runner.prepare("test")
30
+ end
31
+
32
+ it "should require all controllers" do
33
+ Skates::Runner.should_receive(:require_directory).with('app/controllers/*_controller.rb').and_return(true)
34
+ Skates::Runner.prepare("test")
35
+ end
36
+
37
+ it "should create a router" do
38
+ router = Skates::StanzaRouter.new
39
+ Skates::StanzaRouter.should_receive(:new).and_return(router)
40
+ Skates.should_receive(:router=).with(router)
41
+ Skates::Runner.prepare("test")
42
+ end
43
+
44
+ it "should load the routes" do
45
+ Skates::Runner.should_receive(:require).with('config/routes.rb')
46
+ Skates::Runner.prepare("test")
47
+ end
48
+
49
+ it "should load the configuration file" do
50
+ YAML.should_receive(:load_file).with('config/config.yaml').and_return(@config)
51
+ Skates::Runner.prepare("test")
52
+ end
53
+
54
+ it "should assign the configuration" do
55
+ Skates::Runner.prepare("test")
56
+ Skates.config.should == {"port"=>5278, "jid"=>"component.server.com", "auto-reconnect"=>true, "host"=>"localhost", "password"=>"password"}
57
+ end
58
+
59
+ it "should cache the views" do
60
+ Skates.should_receive(:cache_views)
61
+ Skates::Runner.prepare("test")
62
+ end
63
+ end
64
+
65
+ describe "require_directory" do
66
+ before(:each) do
67
+ @dir = "/my/dir"
68
+ @files = ["hello.rb", "byebye.rb"]
69
+ Dir.stub!(:glob).with(@dir).and_return(@files)
70
+ @files.each do |f|
71
+ Skates::Runner.stub!(:require).with(f).and_return(true)
72
+ end
73
+ end
74
+ it "should list all files in the directory" do
75
+ Dir.should_receive(:glob).with(@dir).and_return(@files)
76
+ Skates::Runner.require_directory(@dir)
77
+ end
78
+ it "should require each of the files" do
79
+ @files.each do |f|
80
+ Skates::Runner.should_receive(:require).with(f).and_return(true)
81
+ end
82
+ Skates::Runner.require_directory(@dir)
83
+ end
84
+ end
85
+
86
+ describe ".run" do
87
+ before(:each) do
88
+ Skates::ClientConnection.stub!(:connect).and_return(true)
89
+ Skates::ComponentConnection.stub!(:connect).and_return(true)
90
+ EventMachine.stub!(:run).and_yield
91
+ end
92
+
93
+ it "should set the environment" do
94
+ Skates::Runner.run("test")
95
+ Skates.environment.should == "test"
96
+ end
97
+
98
+ it "should epoll the EventMachine" do
99
+ EventMachine.should_receive(:epoll)
100
+ Skates::Runner.run("test")
101
+ end
102
+
103
+ it "should run the EventMachine" do
104
+ EventMachine.should_receive(:run)
105
+ Skates::Runner.run("test")
106
+ end
107
+
108
+ it "should call prepare" do
109
+ Skates::Runner.should_receive(:prepare).with("test")
110
+ Skates::Runner.run("test")
111
+ end
112
+
113
+ it "should connect the client connection if specified by the config" do
114
+ Skates.stub!(:config).and_return({"application_type" => "client"})
115
+ Skates::ClientConnection.should_receive(:connect).with(Skates.config, Skates::Runner)
116
+ Skates::Runner.run("test")
117
+ end
118
+
119
+ it "should connect the component connection if no application_type specified by the config" do
120
+ Skates.stub!(:config).and_return({})
121
+ Skates::ComponentConnection.should_receive(:connect).with(Skates.config, Skates::Runner)
122
+ Skates::Runner.run("test")
123
+ end
124
+
125
+ end
126
+
127
+ describe ".connection_observers" do
128
+ it "should return an array" do
129
+ Skates::Runner.connection_observers.should be_an_instance_of(Array)
130
+ end
131
+ end
132
+
133
+ describe ".add_connection_observer" do
134
+ before(:each) do
135
+ class MyController < Skates::Base::Controller; end
136
+ end
137
+
138
+ it "should not accept non-Skates::Base::Controller subclasses" do
139
+ Skates::Runner.add_connection_observer(Object).should be_false
140
+ end
141
+
142
+ it "should accept" do
143
+ Skates::Runner.add_connection_observer(MyController).should be_true
144
+ end
145
+
146
+ it "should add it to the list of observers" do
147
+ observers = Skates::Runner.connection_observers
148
+ Skates::Runner.add_connection_observer(MyController)
149
+ observers.include?(MyController).should be_true
150
+ end
151
+
152
+ it "should not add it twice" do
153
+ observers = Skates::Runner.connection_observers
154
+ Skates::Runner.add_connection_observer(MyController)
155
+ Skates::Runner.add_connection_observer(MyController)
156
+ observers.should == [MyController]
157
+ end
158
+
159
+ end
160
+
161
+ describe ".on_connected" do
162
+ before(:each) do
163
+ @connection = mock(Object)
164
+ Skates.router = Skates::StanzaRouter.new
165
+ Skates.router.stub!(:connected).with(@connection)
166
+ Skates.router.stub!(:execute_route).with(MyController, "on_connected")
167
+ end
168
+
169
+ it "should call connected on StanzaRouter" do
170
+ Skates.router.should_receive(:connected).with(@connection)
171
+ Skates::Runner.on_connected(@connection)
172
+ end
173
+
174
+ it "should call on_connected on the various observers and send the corresponding response" do
175
+ Skates::Runner.add_connection_observer(MyController)
176
+ Skates.router.should_receive(:execute_route).with(MyController, "on_connected")
177
+ Skates::Runner.on_connected(@connection)
178
+ end
179
+ end
180
+
181
+ describe ".on_disconnected" do
182
+ it "should call on_disconnected on the various observers" do
183
+ class MyObserver < Skates::Base::Controller; def on_disconnected; end; end
184
+ my_observer = MyObserver.new
185
+ Skates::Runner.add_connection_observer(MyObserver)
186
+ MyObserver.should_receive(:new).and_return(my_observer)
187
+ my_observer.should_receive(:on_disconnected)
188
+ Skates::Runner.on_disconnected
189
+ end
190
+
191
+ context "when the application should auto-reconnect" do
192
+ before(:each) do
193
+ Skates.config["auto-reconnect"] = true
194
+ EventMachine.stub!(:reactor_running?).and_return(false)
195
+ EventMachine.stub!(:add_timer).and_yield()
196
+ @delay = 15
197
+ Skates::Runner.stub!(:fib).and_return(@delay)
198
+ end
199
+
200
+ it "should determine when is the best time to reconnect with fibonacci" do
201
+ Skates::Runner.should_receive(:fib).and_return(@delay)
202
+ Skates::Runner.on_disconnected()
203
+ end
204
+
205
+ it "should try to reconnect at the determined time" do
206
+ EventMachine.stub!(:reactor_running?).and_return(true)
207
+ Skates::Runner.should_receive(:reconnect)
208
+ EventMachine.should_receive(:add_timer).with(@delay).and_yield()
209
+ Skates::Runner.on_disconnected()
210
+ end
211
+ end
212
+
213
+ context "when the application should not auto-reconnect" do
214
+ before(:each) do
215
+ Skates.config["auto-reconnect"] = false
216
+ end
217
+
218
+ it "should stop the event loop" do
219
+ connection = mock(Object)
220
+ EventMachine.should_receive(:stop_event_loop)
221
+ Skates::Runner.on_disconnected()
222
+ end
223
+ end
224
+ end
225
+
226
+ describe ".on_stanza" do
227
+ it "should call route on StanzaRouter" do
228
+ stanza = mock(Object)
229
+ Skates.router.should_receive(:route).with(stanza)
230
+ Skates::Runner.on_stanza(stanza)
231
+ end
232
+ end
233
+ end
@@ -0,0 +1,222 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Skates::XmppConnection do
5
+
6
+ include SkatesSpecHelper
7
+
8
+ before(:each) do
9
+ @params = {"jid" => "jid@server", "password" => "password", "port" => 1234, "host" => "myhost.com"}
10
+ @connection = Skates::XmppConnection._connect(@params, handler_mock)
11
+ end
12
+
13
+ describe "_connect" do
14
+ it "should connect EventMachine and return it" do
15
+ EventMachine.should_receive(:connect).with(@params["host"], @params["port"], Skates::XmppConnection, hash_including("handler" => handler_mock)).and_return(@connection)
16
+ Skates::XmppConnection._connect(@params, handler_mock).should == @connection
17
+ end
18
+
19
+ it "should rescue Connection Errors" do
20
+ EventMachine.stub!(:connect).with(@params["host"], @params["port"], Skates::XmppConnection, hash_including("handler" => handler_mock)).and_raise(RuntimeError)
21
+ lambda {
22
+ Skates::XmppConnection._connect(@params, handler_mock)
23
+ }.should raise_error(Skates::NotConnected)
24
+ end
25
+
26
+ end
27
+
28
+ describe "connect" do
29
+ describe "connect" do
30
+ it "should not try to resolve the dns if a host IP has been provided" do
31
+ @params["host"] = "123.123.123.123"
32
+ Skates::XmppConnection.should_not_receive(:resolve)
33
+ Skates::XmppConnection.connect(@params, handler_mock)
34
+ end
35
+
36
+ describe "when a host is provided, which is not an IP" do
37
+ it "should resolve it" do
38
+ @params["host"] = "domain.tld"
39
+ Skates::XmppConnection.should_receive(:resolve)
40
+ Skates::XmppConnection.connect(@params, handler_mock)
41
+ end
42
+ end
43
+
44
+ describe "when no host is provided, and no port either" do
45
+ it "should resolve the host to an IP" do
46
+ Skates::XmppConnection.should_receive(:resolve)
47
+ Skates::XmppConnection.connect(@params, handler_mock)
48
+ end
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "initialize" do
54
+ it "should assign @connected to false" do
55
+ @connection.instance_variable_get("@connected").should be_false
56
+ end
57
+
58
+ it "should assign @jid to params['jid']" do
59
+ @connection.instance_variable_get("@jid").should == @params["jid"]
60
+ end
61
+
62
+ it "should assign @password to params['password']" do
63
+ @connection.instance_variable_get("@password").should == @params["password"]
64
+ end
65
+
66
+ it "should assign @host to params['host']" do
67
+ @connection.instance_variable_get("@host").should == @params["host"]
68
+ end
69
+
70
+ it "should assign @port to params['port']" do
71
+ @connection.instance_variable_get("@port").should == @params["port"]
72
+ end
73
+
74
+ it "should assign @handler to params['handler']" do
75
+ @connection.instance_variable_get("@handler").should == handler_mock
76
+ end
77
+
78
+ it "should assign @buffer to ''" do
79
+ @connection.instance_variable_get("@buffer").should == ""
80
+ end
81
+ end
82
+
83
+ describe "post_init" do
84
+ it "assigne a new parser" do
85
+ parser = Skates::XmppParser.new(@connection.method(:receive_stanza))
86
+ Skates::XmppParser.should_receive(:new).and_return(parser)
87
+ @connection.post_init
88
+ @connection.instance_variable_get("@parser").should == parser
89
+ end
90
+ end
91
+
92
+ describe "connection_completed" do
93
+ it "should set @connected to true" do
94
+ @connection.connection_completed
95
+ @connection.instance_variable_get("@connected").should be_true
96
+ end
97
+ end
98
+
99
+ describe "unbind" do
100
+ it "should set @connected to false" do
101
+ @connection.connection_completed
102
+ @connection.unbind
103
+ @connection.instance_variable_get("@connected").should be_false
104
+ end
105
+ end
106
+
107
+ describe "receive_stanza" do
108
+
109
+ before(:each) do
110
+ @doc = Nokogiri::XML::Document.new
111
+ end
112
+
113
+ describe "with an stanza that starts with stream:error" do
114
+
115
+ before(:each) do
116
+ @error_stanza = Nokogiri::XML::Node.new("stream:error", @doc)
117
+ end
118
+
119
+ it "should close the connection" do
120
+ @connection.should_receive(:close_connection)
121
+ @connection.receive_stanza(@error_stanza)
122
+ end
123
+
124
+ describe "with a malformed stanza error" do
125
+ before(:each) do
126
+ @xml_not_well_formed_stanza = Nokogiri::XML::Node.new("xml-not-well-formed", @doc)
127
+ @xml_not_well_formed_stanza.add_namespace("xmlns", "urn:ietf:params:xml:ns:xmpp-streams")
128
+ @error_stanza.add_child(@xml_not_well_formed_stanza)
129
+ end
130
+
131
+ end
132
+ end
133
+
134
+ describe "with a stanza that is not an error" do
135
+ it "should call the on_stanza block" do
136
+ stanza = Nokogiri::XML::Node.new("message", @doc)
137
+ handler_mock.should_receive(:on_stanza)
138
+ @connection.receive_stanza(stanza)
139
+ end
140
+ end
141
+
142
+ end
143
+
144
+ describe "send_chunk" do
145
+ it "should raise an error if not connected" do
146
+ @connection.instance_variable_set("@connected", false)
147
+ lambda {
148
+ @connection.__send__(:send_chunk, "hello world")
149
+ }.should raise_error(Skates::NotConnected)
150
+ end
151
+
152
+ it "should raise an error if the stanza size is above the limit" do
153
+ @connection.instance_variable_set("@connected", true)
154
+ string = "a" * (Skates::XmppConnection.max_stanza_size + 1)
155
+ lambda {
156
+ @connection.__send__(:send_chunk, string)
157
+ }.should raise_error(Skates::StanzaTooBig)
158
+ end
159
+
160
+ it "should return if the string is blank" do
161
+ @connection.instance_variable_set("@connected", true)
162
+ @connection.should_not_receive(:send_data)
163
+ @connection.__send__(:send_chunk, "")
164
+ end
165
+
166
+ it "should cann send_data with the string" do
167
+ @connection.instance_variable_set("@connected", true)
168
+ string = "hello world"
169
+ @connection.should_receive(:send_data).with(string)
170
+ @connection.__send__(:send_chunk, string)
171
+ end
172
+
173
+ end
174
+
175
+ describe "send_xml" do
176
+
177
+ before(:each) do
178
+ @connection.instance_variable_set("@connected", true)
179
+ @connection.stub!(:send_chunk).and_return(true)
180
+ @doc = Nokogiri::XML::Document.new
181
+ end
182
+
183
+ describe "with a nodeset as argument" do
184
+ before(:each) do
185
+ iq = Nokogiri::XML::Node.new("iq", @doc)
186
+ message = Nokogiri::XML::Node.new("message", @doc)
187
+ presence = Nokogiri::XML::Node.new("presence", @doc)
188
+ @node_set = Nokogiri::XML::NodeSet.new(@doc, [message, presence, iq])
189
+ end
190
+
191
+ it "should call send_chunk for each of the nodes in the set" do
192
+ @node_set.each do |node|
193
+ @connection.should_receive(:send_chunk).with(node.to_s)
194
+ end
195
+ @connection.send_xml(@node_set)
196
+ end
197
+ end
198
+
199
+ describe "with an argument with is not a NodeSet" do
200
+ before(:each) do
201
+ @message = Nokogiri::XML::Node.new("message", @doc)
202
+ end
203
+ it "should call send_chunk for the node" do
204
+ @connection.should_receive(:send_chunk).with(@message.to_s)
205
+ @connection.send_xml(@message)
206
+ end
207
+ end
208
+ end
209
+
210
+ describe "receive_data" do
211
+ before(:each) do
212
+ @connection.instance_variable_get("@parser").stub!(:push).and_return(true)
213
+ end
214
+
215
+ it "should push the received data to the parser" do
216
+ data = "<hello>hello world!</hello>"
217
+ @connection.instance_variable_get("@parser").should_receive(:push).with(data).and_return(true)
218
+ @connection.__send__(:receive_data, data)
219
+ end
220
+ end
221
+
222
+ end