julien51-babylon 0.1.0 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,222 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+ require File.dirname(__FILE__) + '/../../em_mock'
3
+
4
+ describe Babylon::XmppConnection do
5
+
6
+ include BabylonSpecHelper
7
+
8
+ before(:each) do
9
+ @params = {"jid" => "jid@server", "password" => "password", "port" => 1234, "host" => "myhost.com"}
10
+ @connection = Babylon::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"], Babylon::XmppConnection, hash_including("handler" => handler_mock)).and_return(@connection)
16
+ Babylon::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"], Babylon::XmppConnection, hash_including("handler" => handler_mock)).and_raise(RuntimeError)
21
+ lambda {
22
+ Babylon::XmppConnection.connect(@params, handler_mock)
23
+ }.should raise_error(Babylon::NotConnected)
24
+ end
25
+
26
+ end
27
+
28
+ describe "initialize" do
29
+ it "should assign @connected to false" do
30
+ @connection.instance_variable_get("@connected").should be_false
31
+ end
32
+
33
+ it "should assign @jid to params['jid']" do
34
+ @connection.instance_variable_get("@jid").should == @params["jid"]
35
+ end
36
+
37
+ it "should assign @password to params['password']" do
38
+ @connection.instance_variable_get("@password").should == @params["password"]
39
+ end
40
+
41
+ it "should assign @host to params['host']" do
42
+ @connection.instance_variable_get("@host").should == @params["host"]
43
+ end
44
+
45
+ it "should assign @port to params['port']" do
46
+ @connection.instance_variable_get("@port").should == @params["port"]
47
+ end
48
+
49
+ it "should assign @handler to params['handler']" do
50
+ @connection.instance_variable_get("@handler").should == handler_mock
51
+ end
52
+
53
+ it "should assign @buffer to ''" do
54
+ @connection.instance_variable_get("@buffer").should == ""
55
+ end
56
+ end
57
+
58
+ describe "post_init" do
59
+ it "assigne a new parser" do
60
+ parser = Babylon::XmppParser.new(@connection.method(:receive_stanza))
61
+ Babylon::XmppParser.should_receive(:new).and_return(parser)
62
+ @connection.post_init
63
+ @connection.instance_variable_get("@parser").should == parser
64
+ end
65
+
66
+ end
67
+
68
+ describe "connection_completed" do
69
+ it "should write a log message" do
70
+ Babylon.logger.should_receive(:debug).with("CONNECTED")
71
+ @connection.connection_completed
72
+ end
73
+ it "should set @connected to true" do
74
+ @connection.connection_completed
75
+ @connection.instance_variable_get("@connected").should be_true
76
+ end
77
+ end
78
+
79
+ describe "unbind" do
80
+ it "should write a log message, and call on_disconnected" do
81
+ Babylon.logger.should_receive(:debug).with("DISCONNECTED")
82
+ handler_mock.should_receive(:on_disconnected)
83
+ @connection.unbind
84
+ end
85
+ it "should set @connected to false" do
86
+ @connection.connection_completed
87
+ @connection.unbind
88
+ @connection.instance_variable_get("@connected").should be_false
89
+ end
90
+ end
91
+
92
+ describe "receive_stanza" do
93
+
94
+ before(:each) do
95
+ @doc = Nokogiri::XML::Document.new
96
+ end
97
+
98
+ it "should write a log message for debug" do
99
+ Babylon.logger.should_receive(:debug).with(/PARSED/)
100
+ @connection.receive_stanza(Nokogiri::XML::Node.new("node", @doc))
101
+ end
102
+
103
+ describe "with an stanza that starts with stream:error" do
104
+
105
+ before(:each) do
106
+ @error_stanza = Nokogiri::XML::Node.new("stream:error", @doc)
107
+ end
108
+
109
+ it "should close the connection" do
110
+ @connection.should_receive(:close_connection)
111
+ @connection.receive_stanza(@error_stanza)
112
+ end
113
+
114
+ describe "with a malformed stanza error" do
115
+ before(:each) do
116
+ @xml_not_well_formed_stanza = Nokogiri::XML::Node.new("xml-not-well-formed", @doc)
117
+ @xml_not_well_formed_stanza.add_namespace("xmlns", "urn:ietf:params:xml:ns:xmpp-streams")
118
+ @error_stanza.add_child(@xml_not_well_formed_stanza)
119
+ end
120
+
121
+ it "should write an error to the log and raise an error" do
122
+ Babylon.logger.should_receive(:error).with(/DISCONNECTED DUE TO MALFORMED STANZA/)
123
+ lambda {@connection.receive_stanza(@error_stanza)}.should raise_error(Babylon::XmlNotWellFormed)
124
+ end
125
+ end
126
+ end
127
+
128
+ describe "with a stanza that is not an error" do
129
+ it "should call the on_stanza block" do
130
+ stanza = Nokogiri::XML::Node.new("message", @doc)
131
+ handler_mock.should_receive(:on_stanza)
132
+ @connection.receive_stanza(stanza)
133
+ end
134
+ end
135
+
136
+ end
137
+
138
+ describe "send_chunk" do
139
+ it "should raise an error if not connected" do
140
+ @connection.instance_variable_set("@connected", false)
141
+ lambda {
142
+ @connection.__send__(:send_chunk, "hello world")
143
+ }.should raise_error(Babylon::NotConnected)
144
+ end
145
+
146
+ it "should raise an error if the stanza size is above the limit" do
147
+ @connection.instance_variable_set("@connected", true)
148
+ string = "a" * (Babylon::XmppConnection.max_stanza_size + 1)
149
+ lambda {
150
+ @connection.__send__(:send_chunk, string)
151
+ }.should raise_error(Babylon::StanzaTooBig)
152
+ end
153
+
154
+ it "should return if the string is blank" do
155
+ @connection.instance_variable_set("@connected", true)
156
+ @connection.should_not_receive(:send_data)
157
+ @connection.__send__(:send_chunk, "")
158
+ end
159
+
160
+ it "should cann send_data with the string" do
161
+ @connection.instance_variable_set("@connected", true)
162
+ string = "hello world"
163
+ @connection.should_receive(:send_data).with(string)
164
+ @connection.__send__(:send_chunk, string)
165
+ end
166
+
167
+ end
168
+
169
+ describe "send_xml" do
170
+
171
+ before(:each) do
172
+ @connection.instance_variable_set("@connected", true)
173
+ @connection.stub!(:send_chunk).and_return(true)
174
+ @doc = Nokogiri::XML::Document.new
175
+ end
176
+
177
+ describe "with a nodeset as argument" do
178
+ before(:each) do
179
+ iq = Nokogiri::XML::Node.new("iq", @doc)
180
+ message = Nokogiri::XML::Node.new("message", @doc)
181
+ presence = Nokogiri::XML::Node.new("presence", @doc)
182
+ @node_set = Nokogiri::XML::NodeSet.new(@doc, [message, presence, iq])
183
+ end
184
+
185
+ it "should call send_chunk for each of the nodes in the set" do
186
+ @node_set.each do |node|
187
+ @connection.should_receive(:send_chunk).with(node.to_s)
188
+ end
189
+ @connection.send_xml(@node_set)
190
+ end
191
+ end
192
+
193
+ describe "with an argument with is not a NodeSet" do
194
+ before(:each) do
195
+ @message = Nokogiri::XML::Node.new("message", @doc)
196
+ end
197
+ it "should call send_chunk for the node" do
198
+ @connection.should_receive(:send_chunk).with(@message.to_s)
199
+ @connection.send_xml(@message)
200
+ end
201
+ end
202
+ end
203
+
204
+ describe "receive_data" do
205
+ before(:each) do
206
+ @connection.instance_variable_get("@parser").stub!(:push).and_return(true)
207
+ end
208
+
209
+ it "should show a message on the log" do
210
+ data = "<hello>hello world!</hello>"
211
+ Babylon.logger.should_receive(:debug).with("RECEIVED : #{data}")
212
+ @connection.__send__(:receive_data, data)
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
@@ -0,0 +1,268 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Babylon::XmppParser do
4
+
5
+ before(:each) do
6
+ @last_stanza = ""
7
+ @proc = mock(Proc, :call => true)
8
+ @parser = Babylon::XmppParser.new(@proc)
9
+ end
10
+
11
+ describe ".reset" do
12
+ it "should reset the document to nil" do
13
+ @parser.reset
14
+ @parser.elem.should be_nil
15
+ end
16
+
17
+ it "should reset the element to nil (no element is being parsed)" do
18
+ @parser.reset
19
+ @parser.elem.should be_nil
20
+ end
21
+
22
+ it "should reset the parser to a parser" do
23
+ new_parser = Nokogiri::XML::SAX::PushParser.new(@parser, "UTF-8")
24
+ Nokogiri::XML::SAX::PushParser.should_receive(:new).with(@parser, "UTF-8").and_return(new_parser)
25
+ @parser.reset
26
+ @parser.parser.should == new_parser
27
+ end
28
+ end
29
+
30
+ describe ".push" do
31
+ it "should send the data to the parser" do
32
+ data = "<name>me</name>"
33
+ @parser.parser.should_receive(:<<).with(data)
34
+ @parser.push(data)
35
+ end
36
+ end
37
+
38
+ describe ".characters" do
39
+ before(:each) do
40
+ @parser.doc = Nokogiri::XML::Document.new
41
+ @parser.elem = Nokogiri::XML::Element.new("element", @parser.doc)
42
+ end
43
+
44
+ it "should add the characters to the buffer" do
45
+ chars = "hello my name is julien"
46
+ @parser.characters(chars)
47
+ @parser.instance_variable_get("@buffer").should == chars
48
+ end
49
+
50
+ it "should concatenate the text if we receive in both pieces" do
51
+ chars = "hello my name is julien"
52
+ @parser.characters(chars)
53
+ @parser.instance_variable_get("@buffer").should == chars
54
+ chars2 = "and I'm french!"
55
+ @parser.characters(chars2)
56
+ @parser.instance_variable_get("@buffer").should == chars + chars2
57
+ end
58
+ end
59
+
60
+ describe ".start_element" do
61
+
62
+ before(:each) do
63
+ @new_elem_name = "new"
64
+ @new_elem_attributes = ["to", "you@yourserver.com/home", "xmlns", "http://ns.com"]
65
+ end
66
+
67
+ it "should create a new doc if we don't have one" do
68
+ new_doc = Nokogiri::XML::Document.new
69
+ @parser.doc = nil
70
+ Nokogiri::XML::Document.should_receive(:new).and_return(new_doc)
71
+ @parser.start_element(@new_elem_name, @new_elem_attributes)
72
+ @parser.doc.should == new_doc
73
+ end
74
+
75
+ it "should not create a new doc we already have one" do
76
+ @parser.doc = Nokogiri::XML::Document.new
77
+ Nokogiri::XML::Document.should_not_receive(:new)
78
+ @parser.start_element(@new_elem_name, @new_elem_attributes)
79
+ end
80
+
81
+ it "should create a new element" do
82
+ @doc = Nokogiri::XML::Document.new
83
+ @parser.doc = @doc
84
+ @new_elem = Nokogiri::XML::Element.new(@new_elem_name, @parser.doc)
85
+ Nokogiri::XML::Element.should_receive(:new).and_return(@new_elem)
86
+ @parser.start_element(@new_elem_name, @new_elem_attributes)
87
+ end
88
+
89
+ it "should add the new element as a child to the current element if there is one" do
90
+ @doc = Nokogiri::XML::Document.new
91
+ @parser.doc = @doc
92
+ @current = Nokogiri::XML::Element.new("element", @parser.doc)
93
+ @parser.elem = @current
94
+ @new_elem = Nokogiri::XML::Element.new(@new_elem_name, @parser.doc)
95
+ Nokogiri::XML::Element.stub!(:new).and_return(@new_elem)
96
+ @parser.start_element(@new_elem_name, @new_elem_attributes)
97
+ @new_elem.parent.should == @current
98
+ end
99
+
100
+ it "should add the new element as the child of the doc if there is none" do
101
+ @doc = Nokogiri::XML::Document.new
102
+ @parser.doc = @doc
103
+ @new_elem = Nokogiri::XML::Element.new(@new_elem_name, @parser.doc)
104
+ Nokogiri::XML::Element.stub!(:new).and_return(@new_elem)
105
+ @parser.start_element(@new_elem_name, @new_elem_attributes)
106
+ @new_elem.parent.should == @doc
107
+ end
108
+
109
+ it "should add the right attributes and namespaces to the newly created element" do
110
+ @parser.start_element(@new_elem_name, @new_elem_attributes)
111
+ @parser.elem["to"].should == "you@yourserver.com/home"
112
+ # TODO : FIX NAMESPACES : @parser.elem.namespaces.should == {"xmlns"=>"http://ns.com"}
113
+ @parser.elem.namespaces.should == {}
114
+ end
115
+
116
+ describe "when the new element is of name stream:stream" do
117
+ it "should callback" do
118
+ @proc.should_receive(:call)
119
+ @parser.start_element("stream:stream", [])
120
+ end
121
+
122
+ it "should reinit to nil the doc and the elem" do
123
+ @parser.start_element("stream:stream", [])
124
+ @parser.doc.should == nil
125
+ @parser.elem.should == nil
126
+ end
127
+ end
128
+ end
129
+
130
+ describe ".end_element" do
131
+ before(:each) do
132
+ @doc = Nokogiri::XML::Document.new
133
+ @parser.doc = @doc
134
+ @current = Nokogiri::XML::Element.new("element", @parser.doc)
135
+ @parser.elem = @current
136
+ end
137
+
138
+ it "should add the content of the buffer to the @elem" do
139
+ @elem = Nokogiri::XML::Element.new("element", @parser.doc)
140
+ chars = "hello world"
141
+ @parser.instance_variable_set("@buffer", chars)
142
+ @parser.elem = @elem
143
+ @parser.end_element("element")
144
+ @elem.content.should == chars
145
+ end
146
+
147
+ describe "when we're finishing the doc's root" do
148
+ before(:each) do
149
+ @parser.doc.root = @current
150
+ end
151
+
152
+ it "should callback" do
153
+ @proc.should_receive(:call)
154
+ @parser.end_element("element")
155
+ end
156
+
157
+ it "should reinit to nil the doc and the elem" do
158
+ @parser.end_element("element")
159
+ @parser.doc.should == nil
160
+ @parser.elem.should == nil
161
+ end
162
+ end
163
+
164
+ describe "when we're finishing another element" do
165
+ before(:each) do
166
+ @parser.doc.root = Nokogiri::XML::Element.new("root", @parser.doc)
167
+ @current.parent = @parser.doc.root
168
+ end
169
+
170
+ it "should go back up one level" do
171
+ @parser.end_element("element")
172
+ @parser.elem = @current.parent
173
+ end
174
+ end
175
+ end
176
+
177
+ describe ".add_namespaces_and_attributes_to_node" do
178
+ before(:each) do
179
+ @doc = Nokogiri::XML::Document.new
180
+ @parser.doc = @doc
181
+ @element = Nokogiri::XML::Element.new("element", @parser.doc)
182
+ @attrs = ["from", "me", "xmlns:atom", "http://www.w3.org/2005/Atom" ,"to", "you", "xmlns", "http://namespace.com"]
183
+ @parser.elem = @element
184
+ end
185
+
186
+ it "should assign even elements to attributes value or namespaces urls" do
187
+ @parser.__send__(:add_namespaces_and_attributes_to_current_node, @attrs)
188
+ even = []
189
+ @attrs.size.times do |i|
190
+ even << @attrs[i*2]
191
+ end
192
+ even.compact!
193
+ @element.attributes.keys.each do |k|
194
+ even.should include(k)
195
+ end
196
+ end
197
+
198
+ it "should assign odd elements to attributes names of namespaces prefixes" do
199
+ @parser.__send__(:add_namespaces_and_attributes_to_current_node, @attrs)
200
+ even = []
201
+ @attrs.size.times do |i|
202
+ even << @attrs[i*2+1]
203
+ end
204
+ even.compact!
205
+ @element.attributes.values.each do |v|
206
+ even.should include("#{v}")
207
+ end
208
+ end
209
+
210
+ it "should add namespace for each attribute name that starts with xmlns" do
211
+ @parser.__send__(:add_namespaces_and_attributes_to_current_node, @attrs)
212
+ # TODO: FIX NAMESPACES @element.namespaces.values.should == ["http://www.w3.org/2005/Atom", "http://namespace.com"]
213
+ @element.namespaces.values.should == []
214
+ end
215
+ end
216
+
217
+ describe "a communication with an XMPP Client" do
218
+
219
+ before(:each) do
220
+ @stanzas = []
221
+ @proc = Proc.new { |stanza|
222
+ @stanzas << stanza
223
+ }
224
+ @parser = Babylon::XmppParser.new(@proc)
225
+ end
226
+
227
+ it "should parse the right information" do
228
+ string = "<stream:stream
229
+ xmlns:stream='http://etherx.jabber.org/streams'
230
+ xmlns='jabber:component:accept'
231
+ from='plays.shakespeare.lit'
232
+ id='3BF96D32'>
233
+ <handshake/>
234
+ <message from='juliet@example.com'
235
+ to='romeo@example.net'
236
+ xml:lang='en'>
237
+ <body>Art thou not Romeo, and a Montague?</body>
238
+ <link href='http://sfbay.craigslist.org/search/sss?query=%2522mac+mini%2522+Intel+Core+Duo&amp;minAsk=min&amp;maxAsk=max&amp;format=rss&amp;format=rss' />
239
+ </message>"
240
+ pieces = rand(string.size/30)
241
+ # So we have to pick 'pieces' number between 0 and string.size
242
+ indices = []
243
+ pieces.times do |i|
244
+ indices[i] = rand(string.size)
245
+ end
246
+ # Now let's sort indices
247
+ indices.sort!
248
+ substrings = []
249
+ prev_index = 0
250
+ indices.each do |index|
251
+ substrings << string[prev_index, (index-prev_index)]
252
+ prev_index = index
253
+ end
254
+ substrings << string[prev_index, string.size]
255
+ #Just to make sure we split the string the right way!
256
+ substrings.join("").should == string
257
+
258
+ substrings.each do |s|
259
+ @parser.push(s)
260
+ end
261
+
262
+ @stanzas.join("").should == "<stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\" xmlns=\"jabber:component:accept\" from=\"plays.shakespeare.lit\" id=\"3BF96D32\"/><handshake/><message from=\"juliet@example.com\" to=\"romeo@example.net\" xml:lang=\"en\">\n <body>Art thou not Romeo, and a Montague?</body>\n <link href=\"http://sfbay.craigslist.org/search/sss?query=%2522mac+mini%2522+Intel+Core+Duo&amp;minAsk=min&amp;maxAsk=max&amp;format=rss&amp;format=rss\"/>\n</message>"
263
+ @stanzas.last.at("link")["href"].should == "http://sfbay.craigslist.org/search/sss?query=%2522mac+mini%2522+Intel+Core+Duo&minAsk=min&maxAsk=max&format=rss&format=rss"
264
+ end
265
+
266
+ end
267
+
268
+ end