~jk0/nova/xs-ipv6

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/words/test/test_jabberxmlstream.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (c) 2001-2009 Twisted Matrix Laboratories.
 
2
# See LICENSE for details.
 
3
 
 
4
"""
 
5
Tests for L{twisted.words.protocols.jabber.xmlstream}.
 
6
"""
 
7
 
 
8
from twisted.trial import unittest
 
9
 
 
10
from zope.interface.verify import verifyObject
 
11
 
 
12
from twisted.internet import defer, task
 
13
from twisted.internet.error import ConnectionLost
 
14
from twisted.internet.interfaces import IProtocolFactory
 
15
from twisted.test import proto_helpers
 
16
from twisted.words.test.test_xmlstream import GenericXmlStreamFactoryTestsMixin
 
17
from twisted.words.xish import domish
 
18
from twisted.words.protocols.jabber import error, ijabber, jid, xmlstream
 
19
 
 
20
 
 
21
 
 
22
NS_XMPP_TLS = 'urn:ietf:params:xml:ns:xmpp-tls'
 
23
 
 
24
 
 
25
 
 
26
class HashPasswordTest(unittest.TestCase):
 
27
    """
 
28
    Tests for L{xmlstream.hashPassword}.
 
29
    """
 
30
 
 
31
    def test_basic(self):
 
32
        """
 
33
        The sid and secret are concatenated to calculate sha1 hex digest.
 
34
        """
 
35
        hash = xmlstream.hashPassword(u"12345", u"secret")
 
36
        self.assertEqual('99567ee91b2c7cabf607f10cb9f4a3634fa820e0', hash)
 
37
 
 
38
 
 
39
    def test_sidNotUnicode(self):
 
40
        """
 
41
        The session identifier must be a unicode object.
 
42
        """
 
43
        self.assertRaises(TypeError, xmlstream.hashPassword, "\xc2\xb92345",
 
44
                                                             u"secret")
 
45
 
 
46
 
 
47
    def test_passwordNotUnicode(self):
 
48
        """
 
49
        The password must be a unicode object.
 
50
        """
 
51
        self.assertRaises(TypeError, xmlstream.hashPassword, u"12345",
 
52
                                                             "secr\xc3\xa9t")
 
53
 
 
54
 
 
55
    def test_unicodeSecret(self):
 
56
        """
 
57
        The concatenated sid and password must be encoded to UTF-8 before hashing.
 
58
        """
 
59
        hash = xmlstream.hashPassword(u"12345", u"secr\u00e9t")
 
60
        self.assertEqual('659bf88d8f8e179081f7f3b4a8e7d224652d2853', hash)
 
61
 
 
62
 
 
63
 
 
64
class IQTest(unittest.TestCase):
 
65
    """
 
66
    Tests both IQ and the associated IIQResponseTracker callback.
 
67
    """
 
68
 
 
69
    def setUp(self):
 
70
        authenticator = xmlstream.ConnectAuthenticator('otherhost')
 
71
        authenticator.namespace = 'testns'
 
72
        self.xmlstream = xmlstream.XmlStream(authenticator)
 
73
        self.clock = task.Clock()
 
74
        self.xmlstream._callLater = self.clock.callLater
 
75
        self.xmlstream.makeConnection(proto_helpers.StringTransport())
 
76
        self.xmlstream.dataReceived(
 
77
           "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
 
78
                          "xmlns='testns' from='otherhost' version='1.0'>")
 
79
        self.iq = xmlstream.IQ(self.xmlstream, 'get')
 
80
 
 
81
 
 
82
    def testBasic(self):
 
83
        self.assertEquals(self.iq['type'], 'get')
 
84
        self.assertTrue(self.iq['id'])
 
85
 
 
86
 
 
87
    def testSend(self):
 
88
        self.xmlstream.transport.clear()
 
89
        self.iq.send()
 
90
        self.assertEquals("<iq type='get' id='%s'/>" % self.iq['id'],
 
91
                          self.xmlstream.transport.value())
 
92
 
 
93
 
 
94
    def testResultResponse(self):
 
95
        def cb(result):
 
96
            self.assertEquals(result['type'], 'result')
 
97
 
 
98
        d = self.iq.send()
 
99
        d.addCallback(cb)
 
100
 
 
101
        xs = self.xmlstream
 
102
        xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
 
103
        return d
 
104
 
 
105
 
 
106
    def testErrorResponse(self):
 
107
        d = self.iq.send()
 
108
        self.assertFailure(d, error.StanzaError)
 
109
 
 
110
        xs = self.xmlstream
 
111
        xs.dataReceived("<iq type='error' id='%s'/>" % self.iq['id'])
 
112
        return d
 
113
 
 
114
 
 
115
    def testNonTrackedResponse(self):
 
116
        """
 
117
        Test that untracked iq responses don't trigger any action.
 
118
 
 
119
        Untracked means that the id of the incoming response iq is not
 
120
        in the stream's C{iqDeferreds} dictionary.
 
121
        """
 
122
        xs = self.xmlstream
 
123
        xmlstream.upgradeWithIQResponseTracker(xs)
 
124
 
 
125
        # Make sure we aren't tracking any iq's.
 
126
        self.assertFalse(xs.iqDeferreds)
 
127
 
 
128
        # Set up a fallback handler that checks the stanza's handled attribute.
 
129
        # If that is set to True, the iq tracker claims to have handled the
 
130
        # response.
 
131
        def cb(iq):
 
132
            self.assertFalse(getattr(iq, 'handled', False))
 
133
 
 
134
        xs.addObserver("/iq", cb, -1)
 
135
 
 
136
        # Receive an untracked iq response
 
137
        xs.dataReceived("<iq type='result' id='test'/>")
 
138
 
 
139
 
 
140
    def testCleanup(self):
 
141
        """
 
142
        Test if the deferred associated with an iq request is removed
 
143
        from the list kept in the L{XmlStream} object after it has
 
144
        been fired.
 
145
        """
 
146
 
 
147
        d = self.iq.send()
 
148
        xs = self.xmlstream
 
149
        xs.dataReceived("<iq type='result' id='%s'/>" % self.iq['id'])
 
150
        self.assertNotIn(self.iq['id'], xs.iqDeferreds)
 
151
        return d
 
152
 
 
153
 
 
154
    def testDisconnectCleanup(self):
 
155
        """
 
156
        Test if deferreds for iq's that haven't yet received a response
 
157
        have their errback called on stream disconnect.
 
158
        """
 
159
 
 
160
        d = self.iq.send()
 
161
        xs = self.xmlstream
 
162
        xs.connectionLost("Closed by peer")
 
163
        self.assertFailure(d, ConnectionLost)
 
164
        return d
 
165
 
 
166
 
 
167
    def testNoModifyingDict(self):
 
168
        """
 
169
        Test to make sure the errbacks cannot cause the iteration of the
 
170
        iqDeferreds to blow up in our face.
 
171
        """
 
172
 
 
173
        def eb(failure):
 
174
            d = xmlstream.IQ(self.xmlstream).send()
 
175
            d.addErrback(eb)
 
176
 
 
177
        d = self.iq.send()
 
178
        d.addErrback(eb)
 
179
        self.xmlstream.connectionLost("Closed by peer")
 
180
        return d
 
181
 
 
182
 
 
183
    def testRequestTimingOut(self):
 
184
        """
 
185
        Test that an iq request with a defined timeout times out.
 
186
        """
 
187
        self.iq.timeout = 60
 
188
        d = self.iq.send()
 
189
        self.assertFailure(d, xmlstream.TimeoutError)
 
190
 
 
191
        self.clock.pump([1, 60])
 
192
        self.assertFalse(self.clock.calls)
 
193
        self.assertFalse(self.xmlstream.iqDeferreds)
 
194
        return d
 
195
 
 
196
 
 
197
    def testRequestNotTimingOut(self):
 
198
        """
 
199
        Test that an iq request with a defined timeout does not time out
 
200
        when a response was received before the timeout period elapsed.
 
201
        """
 
202
        self.iq.timeout = 60
 
203
        d = self.iq.send()
 
204
        self.clock.callLater(1, self.xmlstream.dataReceived,
 
205
                             "<iq type='result' id='%s'/>" % self.iq['id'])
 
206
        self.clock.pump([1, 1])
 
207
        self.assertFalse(self.clock.calls)
 
208
        return d
 
209
 
 
210
 
 
211
    def testDisconnectTimeoutCancellation(self):
 
212
        """
 
213
        Test if timeouts for iq's that haven't yet received a response
 
214
        are cancelled on stream disconnect.
 
215
        """
 
216
 
 
217
        self.iq.timeout = 60
 
218
        d = self.iq.send()
 
219
 
 
220
        xs = self.xmlstream
 
221
        xs.connectionLost("Closed by peer")
 
222
        self.assertFailure(d, ConnectionLost)
 
223
        self.assertFalse(self.clock.calls)
 
224
        return d
 
225
 
 
226
 
 
227
 
 
228
class XmlStreamTest(unittest.TestCase):
 
229
 
 
230
    def onStreamStart(self, obj):
 
231
        self.gotStreamStart = True
 
232
 
 
233
 
 
234
    def onStreamEnd(self, obj):
 
235
        self.gotStreamEnd = True
 
236
 
 
237
 
 
238
    def onStreamError(self, obj):
 
239
        self.gotStreamError = True
 
240
 
 
241
 
 
242
    def setUp(self):
 
243
        """
 
244
        Set up XmlStream and several observers.
 
245
        """
 
246
        self.gotStreamStart = False
 
247
        self.gotStreamEnd = False
 
248
        self.gotStreamError = False
 
249
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
250
        xs.addObserver('//event/stream/start', self.onStreamStart)
 
251
        xs.addObserver('//event/stream/end', self.onStreamEnd)
 
252
        xs.addObserver('//event/stream/error', self.onStreamError)
 
253
        xs.makeConnection(proto_helpers.StringTransportWithDisconnection())
 
254
        xs.transport.protocol = xs
 
255
        xs.namespace = 'testns'
 
256
        xs.version = (1, 0)
 
257
        self.xmlstream = xs
 
258
 
 
259
 
 
260
    def test_sendHeaderBasic(self):
 
261
        """
 
262
        Basic test on the header sent by sendHeader.
 
263
        """
 
264
        xs = self.xmlstream
 
265
        xs.sendHeader()
 
266
        splitHeader = self.xmlstream.transport.value()[0:-1].split(' ')
 
267
        self.assertIn("<stream:stream", splitHeader)
 
268
        self.assertIn("xmlns:stream='http://etherx.jabber.org/streams'",
 
269
                      splitHeader)
 
270
        self.assertIn("xmlns='testns'", splitHeader)
 
271
        self.assertIn("version='1.0'", splitHeader)
 
272
        self.assertTrue(xs._headerSent)
 
273
 
 
274
 
 
275
    def test_sendHeaderAdditionalNamespaces(self):
 
276
        """
 
277
        Test for additional namespace declarations.
 
278
        """
 
279
        xs = self.xmlstream
 
280
        xs.prefixes['jabber:server:dialback'] = 'db'
 
281
        xs.sendHeader()
 
282
        splitHeader = self.xmlstream.transport.value()[0:-1].split(' ')
 
283
        self.assertIn("<stream:stream", splitHeader)
 
284
        self.assertIn("xmlns:stream='http://etherx.jabber.org/streams'",
 
285
                      splitHeader)
 
286
        self.assertIn("xmlns:db='jabber:server:dialback'", splitHeader)
 
287
        self.assertIn("xmlns='testns'", splitHeader)
 
288
        self.assertIn("version='1.0'", splitHeader)
 
289
        self.assertTrue(xs._headerSent)
 
290
 
 
291
 
 
292
    def test_sendHeaderInitiating(self):
 
293
        """
 
294
        Test addressing when initiating a stream.
 
295
        """
 
296
        xs = self.xmlstream
 
297
        xs.thisEntity = jid.JID('thisHost')
 
298
        xs.otherEntity = jid.JID('otherHost')
 
299
        xs.initiating = True
 
300
        xs.sendHeader()
 
301
        splitHeader = xs.transport.value()[0:-1].split(' ')
 
302
        self.assertIn("to='otherhost'", splitHeader)
 
303
        self.assertIn("from='thishost'", splitHeader)
 
304
 
 
305
 
 
306
    def test_sendHeaderReceiving(self):
 
307
        """
 
308
        Test addressing when receiving a stream.
 
309
        """
 
310
        xs = self.xmlstream
 
311
        xs.thisEntity = jid.JID('thisHost')
 
312
        xs.otherEntity = jid.JID('otherHost')
 
313
        xs.initiating = False
 
314
        xs.sid = 'session01'
 
315
        xs.sendHeader()
 
316
        splitHeader = xs.transport.value()[0:-1].split(' ')
 
317
        self.assertIn("to='otherhost'", splitHeader)
 
318
        self.assertIn("from='thishost'", splitHeader)
 
319
        self.assertIn("id='session01'", splitHeader)
 
320
 
 
321
 
 
322
    def test_receiveStreamError(self):
 
323
        """
 
324
        Test events when a stream error is received.
 
325
        """
 
326
        xs = self.xmlstream
 
327
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
328
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
329
                        "from='example.com' id='12345' version='1.0'>")
 
330
        xs.dataReceived("<stream:error/>")
 
331
        self.assertTrue(self.gotStreamError)
 
332
        self.assertTrue(self.gotStreamEnd)
 
333
 
 
334
 
 
335
    def test_sendStreamErrorInitiating(self):
 
336
        """
 
337
        Test sendStreamError on an initiating xmlstream with a header sent.
 
338
 
 
339
        An error should be sent out and the connection lost.
 
340
        """
 
341
        xs = self.xmlstream
 
342
        xs.initiating = True
 
343
        xs.sendHeader()
 
344
        xs.transport.clear()
 
345
        xs.sendStreamError(error.StreamError('version-unsupported'))
 
346
        self.assertNotEqual('', xs.transport.value())
 
347
        self.assertTrue(self.gotStreamEnd)
 
348
 
 
349
 
 
350
    def test_sendStreamErrorInitiatingNoHeader(self):
 
351
        """
 
352
        Test sendStreamError on an initiating xmlstream without having sent a
 
353
        header.
 
354
 
 
355
        In this case, no header should be generated. Also, the error should
 
356
        not be sent out on the stream. Just closing the connection.
 
357
        """
 
358
        xs = self.xmlstream
 
359
        xs.initiating = True
 
360
        xs.transport.clear()
 
361
        xs.sendStreamError(error.StreamError('version-unsupported'))
 
362
        self.assertNot(xs._headerSent)
 
363
        self.assertEqual('', xs.transport.value())
 
364
        self.assertTrue(self.gotStreamEnd)
 
365
 
 
366
 
 
367
    def test_sendStreamErrorReceiving(self):
 
368
        """
 
369
        Test sendStreamError on a receiving xmlstream with a header sent.
 
370
 
 
371
        An error should be sent out and the connection lost.
 
372
        """
 
373
        xs = self.xmlstream
 
374
        xs.initiating = False
 
375
        xs.sendHeader()
 
376
        xs.transport.clear()
 
377
        xs.sendStreamError(error.StreamError('version-unsupported'))
 
378
        self.assertNotEqual('', xs.transport.value())
 
379
        self.assertTrue(self.gotStreamEnd)
 
380
 
 
381
 
 
382
    def test_sendStreamErrorReceivingNoHeader(self):
 
383
        """
 
384
        Test sendStreamError on a receiving xmlstream without having sent a
 
385
        header.
 
386
 
 
387
        In this case, a header should be generated. Then, the error should
 
388
        be sent out on the stream followed by closing the connection.
 
389
        """
 
390
        xs = self.xmlstream
 
391
        xs.initiating = False
 
392
        xs.transport.clear()
 
393
        xs.sendStreamError(error.StreamError('version-unsupported'))
 
394
        self.assertTrue(xs._headerSent)
 
395
        self.assertNotEqual('', xs.transport.value())
 
396
        self.assertTrue(self.gotStreamEnd)
 
397
 
 
398
 
 
399
    def test_reset(self):
 
400
        """
 
401
        Test resetting the XML stream to start a new layer.
 
402
        """
 
403
        xs = self.xmlstream
 
404
        xs.sendHeader()
 
405
        stream = xs.stream
 
406
        xs.reset()
 
407
        self.assertNotEqual(stream, xs.stream)
 
408
        self.assertNot(xs._headerSent)
 
409
 
 
410
 
 
411
    def test_send(self):
 
412
        """
 
413
        Test send with various types of objects.
 
414
        """
 
415
        xs = self.xmlstream
 
416
        xs.send('<presence/>')
 
417
        self.assertEqual(xs.transport.value(), '<presence/>')
 
418
 
 
419
        xs.transport.clear()
 
420
        el = domish.Element(('testns', 'presence'))
 
421
        xs.send(el)
 
422
        self.assertEqual(xs.transport.value(), '<presence/>')
 
423
 
 
424
        xs.transport.clear()
 
425
        el = domish.Element(('http://etherx.jabber.org/streams', 'features'))
 
426
        xs.send(el)
 
427
        self.assertEqual(xs.transport.value(), '<stream:features/>')
 
428
 
 
429
 
 
430
    def test_authenticator(self):
 
431
        """
 
432
        Test that the associated authenticator is correctly called.
 
433
        """
 
434
        connectionMadeCalls = []
 
435
        streamStartedCalls = []
 
436
        associateWithStreamCalls = []
 
437
 
 
438
        class TestAuthenticator:
 
439
            def connectionMade(self):
 
440
                connectionMadeCalls.append(None)
 
441
 
 
442
            def streamStarted(self, rootElement):
 
443
                streamStartedCalls.append(rootElement)
 
444
 
 
445
            def associateWithStream(self, xs):
 
446
                associateWithStreamCalls.append(xs)
 
447
 
 
448
        a = TestAuthenticator()
 
449
        xs = xmlstream.XmlStream(a)
 
450
        self.assertEqual([xs], associateWithStreamCalls)
 
451
        xs.connectionMade()
 
452
        self.assertEqual([None], connectionMadeCalls)
 
453
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
454
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
455
                        "from='example.com' id='12345'>")
 
456
        self.assertEqual(1, len(streamStartedCalls))
 
457
        xs.reset()
 
458
        self.assertEqual([None], connectionMadeCalls)
 
459
 
 
460
 
 
461
 
 
462
class TestError(Exception):
 
463
    pass
 
464
 
 
465
 
 
466
 
 
467
class AuthenticatorTest(unittest.TestCase):
 
468
    def setUp(self):
 
469
        self.authenticator = xmlstream.Authenticator()
 
470
        self.xmlstream = xmlstream.XmlStream(self.authenticator)
 
471
 
 
472
 
 
473
    def test_streamStart(self):
 
474
        """
 
475
        Test streamStart to fill the appropriate attributes from the
 
476
        stream header.
 
477
        """
 
478
        xs = self.xmlstream
 
479
        xs.makeConnection(proto_helpers.StringTransport())
 
480
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
481
                         "xmlns:stream='http://etherx.jabber.org/streams' "
 
482
                         "from='example.org' to='example.com' id='12345' "
 
483
                         "version='1.0'>")
 
484
        self.assertEqual((1, 0), xs.version)
 
485
        self.assertIdentical(None, xs.sid)
 
486
        self.assertEqual('invalid', xs.namespace)
 
487
        self.assertIdentical(None, xs.otherEntity)
 
488
        self.assertEqual(None, xs.thisEntity)
 
489
 
 
490
 
 
491
    def test_streamStartLegacy(self):
 
492
        """
 
493
        Test streamStart to fill the appropriate attributes from the
 
494
        stream header for a pre-XMPP-1.0 header.
 
495
        """
 
496
        xs = self.xmlstream
 
497
        xs.makeConnection(proto_helpers.StringTransport())
 
498
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
499
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
500
                        "from='example.com' id='12345'>")
 
501
        self.assertEqual((0, 0), xs.version)
 
502
 
 
503
 
 
504
    def test_streamBadVersionOneDigit(self):
 
505
        """
 
506
        Test streamStart to fill the appropriate attributes from the
 
507
        stream header for a version with only one digit.
 
508
        """
 
509
        xs = self.xmlstream
 
510
        xs.makeConnection(proto_helpers.StringTransport())
 
511
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
512
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
513
                        "from='example.com' id='12345' version='1'>")
 
514
        self.assertEqual((0, 0), xs.version)
 
515
 
 
516
 
 
517
    def test_streamBadVersionNoNumber(self):
 
518
        """
 
519
        Test streamStart to fill the appropriate attributes from the
 
520
        stream header for a malformed version.
 
521
        """
 
522
        xs = self.xmlstream
 
523
        xs.makeConnection(proto_helpers.StringTransport())
 
524
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
525
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
526
                        "from='example.com' id='12345' version='blah'>")
 
527
        self.assertEqual((0, 0), xs.version)
 
528
 
 
529
 
 
530
 
 
531
class ConnectAuthenticatorTest(unittest.TestCase):
 
532
 
 
533
    def setUp(self):
 
534
        self.gotAuthenticated = False
 
535
        self.initFailure = None
 
536
        self.authenticator = xmlstream.ConnectAuthenticator('otherHost')
 
537
        self.xmlstream = xmlstream.XmlStream(self.authenticator)
 
538
        self.xmlstream.addObserver('//event/stream/authd', self.onAuthenticated)
 
539
        self.xmlstream.addObserver('//event/xmpp/initfailed', self.onInitFailed)
 
540
 
 
541
 
 
542
    def onAuthenticated(self, obj):
 
543
        self.gotAuthenticated = True
 
544
 
 
545
 
 
546
    def onInitFailed(self, failure):
 
547
        self.initFailure = failure
 
548
 
 
549
 
 
550
    def testSucces(self):
 
551
        """
 
552
        Test successful completion of an initialization step.
 
553
        """
 
554
        class Initializer:
 
555
            def initialize(self):
 
556
                pass
 
557
 
 
558
        init = Initializer()
 
559
        self.xmlstream.initializers = [init]
 
560
 
 
561
        self.authenticator.initializeStream()
 
562
        self.assertEqual([], self.xmlstream.initializers)
 
563
        self.assertTrue(self.gotAuthenticated)
 
564
 
 
565
 
 
566
    def testFailure(self):
 
567
        """
 
568
        Test failure of an initialization step.
 
569
        """
 
570
        class Initializer:
 
571
            def initialize(self):
 
572
                raise TestError
 
573
 
 
574
        init = Initializer()
 
575
        self.xmlstream.initializers = [init]
 
576
 
 
577
        self.authenticator.initializeStream()
 
578
        self.assertEqual([init], self.xmlstream.initializers)
 
579
        self.assertFalse(self.gotAuthenticated)
 
580
        self.assertNotIdentical(None, self.initFailure)
 
581
        self.assertTrue(self.initFailure.check(TestError))
 
582
 
 
583
 
 
584
    def test_streamStart(self):
 
585
        """
 
586
        Test streamStart to fill the appropriate attributes from the
 
587
        stream header.
 
588
        """
 
589
        self.authenticator.namespace = 'testns'
 
590
        xs = self.xmlstream
 
591
        xs.makeConnection(proto_helpers.StringTransport())
 
592
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
593
                         "xmlns:stream='http://etherx.jabber.org/streams' "
 
594
                         "from='example.com' to='example.org' id='12345' "
 
595
                         "version='1.0'>")
 
596
        self.assertEqual((1, 0), xs.version)
 
597
        self.assertEqual('12345', xs.sid)
 
598
        self.assertEqual('testns', xs.namespace)
 
599
        self.assertEqual('example.com', xs.otherEntity.host)
 
600
        self.assertIdentical(None, xs.thisEntity)
 
601
        self.assertNot(self.gotAuthenticated)
 
602
        xs.dataReceived("<stream:features>"
 
603
                          "<test xmlns='testns'/>"
 
604
                        "</stream:features>")
 
605
        self.assertIn(('testns', 'test'), xs.features)
 
606
        self.assertTrue(self.gotAuthenticated)
 
607
 
 
608
 
 
609
 
 
610
class ListenAuthenticatorTest(unittest.TestCase):
 
611
    def setUp(self):
 
612
        self.authenticator = xmlstream.ListenAuthenticator()
 
613
        self.xmlstream = xmlstream.XmlStream(self.authenticator)
 
614
 
 
615
 
 
616
    def test_streamStart(self):
 
617
        """
 
618
        Test streamStart to fill the appropriate attributes from the
 
619
        stream header.
 
620
        """
 
621
        xs = self.xmlstream
 
622
        xs.makeConnection(proto_helpers.StringTransport())
 
623
        self.assertIdentical(None, xs.sid)
 
624
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
625
                         "xmlns:stream='http://etherx.jabber.org/streams' "
 
626
                         "from='example.org' to='example.com' id='12345' "
 
627
                         "version='1.0'>")
 
628
        self.assertEqual((1, 0), xs.version)
 
629
        self.assertNotIdentical(None, xs.sid)
 
630
        self.assertNotEquals('12345', xs.sid)
 
631
        self.assertEqual('jabber:client', xs.namespace)
 
632
        self.assertIdentical(None, xs.otherEntity)
 
633
        self.assertEqual('example.com', xs.thisEntity.host)
 
634
 
 
635
 
 
636
 
 
637
class TLSInitiatingInitializerTest(unittest.TestCase):
 
638
    def setUp(self):
 
639
        self.output = []
 
640
        self.done = []
 
641
 
 
642
        self.savedSSL = xmlstream.ssl
 
643
 
 
644
        self.authenticator = xmlstream.Authenticator()
 
645
        self.xmlstream = xmlstream.XmlStream(self.authenticator)
 
646
        self.xmlstream.send = self.output.append
 
647
        self.xmlstream.connectionMade()
 
648
        self.xmlstream.dataReceived("<stream:stream xmlns='jabber:client' "
 
649
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
650
                        "from='example.com' id='12345' version='1.0'>")
 
651
        self.init = xmlstream.TLSInitiatingInitializer(self.xmlstream)
 
652
 
 
653
 
 
654
    def tearDown(self):
 
655
        xmlstream.ssl = self.savedSSL
 
656
 
 
657
 
 
658
    def testWantedSupported(self):
 
659
        """
 
660
        Test start when TLS is wanted and the SSL library available.
 
661
        """
 
662
        self.xmlstream.transport = proto_helpers.StringTransport()
 
663
        self.xmlstream.transport.startTLS = lambda ctx: self.done.append('TLS')
 
664
        self.xmlstream.reset = lambda: self.done.append('reset')
 
665
        self.xmlstream.sendHeader = lambda: self.done.append('header')
 
666
 
 
667
        d = self.init.start()
 
668
        d.addCallback(self.assertEquals, xmlstream.Reset)
 
669
        starttls = self.output[0]
 
670
        self.assertEquals('starttls', starttls.name)
 
671
        self.assertEquals(NS_XMPP_TLS, starttls.uri)
 
672
        self.xmlstream.dataReceived("<proceed xmlns='%s'/>" % NS_XMPP_TLS)
 
673
        self.assertEquals(['TLS', 'reset', 'header'], self.done)
 
674
 
 
675
        return d
 
676
 
 
677
    if not xmlstream.ssl:
 
678
        testWantedSupported.skip = "SSL not available"
 
679
 
 
680
 
 
681
    def testWantedNotSupportedNotRequired(self):
 
682
        """
 
683
        Test start when TLS is wanted and the SSL library available.
 
684
        """
 
685
        xmlstream.ssl = None
 
686
 
 
687
        d = self.init.start()
 
688
        d.addCallback(self.assertEquals, None)
 
689
        self.assertEquals([], self.output)
 
690
 
 
691
        return d
 
692
 
 
693
 
 
694
    def testWantedNotSupportedRequired(self):
 
695
        """
 
696
        Test start when TLS is wanted and the SSL library available.
 
697
        """
 
698
        xmlstream.ssl = None
 
699
        self.init.required = True
 
700
 
 
701
        d = self.init.start()
 
702
        self.assertFailure(d, xmlstream.TLSNotSupported)
 
703
        self.assertEquals([], self.output)
 
704
 
 
705
        return d
 
706
 
 
707
 
 
708
    def testNotWantedRequired(self):
 
709
        """
 
710
        Test start when TLS is not wanted, but required by the server.
 
711
        """
 
712
        tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
 
713
        tls.addElement('required')
 
714
        self.xmlstream.features = {(tls.uri, tls.name): tls}
 
715
        self.init.wanted = False
 
716
 
 
717
        d = self.init.start()
 
718
        self.assertEquals([], self.output)
 
719
        self.assertFailure(d, xmlstream.TLSRequired)
 
720
 
 
721
        return d
 
722
 
 
723
 
 
724
    def testNotWantedNotRequired(self):
 
725
        """
 
726
        Test start when TLS is not wanted, but required by the server.
 
727
        """
 
728
        tls = domish.Element(('urn:ietf:params:xml:ns:xmpp-tls', 'starttls'))
 
729
        self.xmlstream.features = {(tls.uri, tls.name): tls}
 
730
        self.init.wanted = False
 
731
 
 
732
        d = self.init.start()
 
733
        d.addCallback(self.assertEqual, None)
 
734
        self.assertEquals([], self.output)
 
735
        return d
 
736
 
 
737
 
 
738
    def testFailed(self):
 
739
        """
 
740
        Test failed TLS negotiation.
 
741
        """
 
742
        # Pretend that ssl is supported, it isn't actually used when the
 
743
        # server starts out with a failure in response to our initial
 
744
        # C{starttls} stanza.
 
745
        xmlstream.ssl = 1
 
746
 
 
747
        d = self.init.start()
 
748
        self.assertFailure(d, xmlstream.TLSFailed)
 
749
        self.xmlstream.dataReceived("<failure xmlns='%s'/>" % NS_XMPP_TLS)
 
750
        return d
 
751
 
 
752
 
 
753
 
 
754
class TestFeatureInitializer(xmlstream.BaseFeatureInitiatingInitializer):
 
755
    feature = ('testns', 'test')
 
756
 
 
757
    def start(self):
 
758
        return defer.succeed(None)
 
759
 
 
760
 
 
761
 
 
762
class BaseFeatureInitiatingInitializerTest(unittest.TestCase):
 
763
 
 
764
    def setUp(self):
 
765
        self.xmlstream = xmlstream.XmlStream(xmlstream.Authenticator())
 
766
        self.init = TestFeatureInitializer(self.xmlstream)
 
767
 
 
768
 
 
769
    def testAdvertized(self):
 
770
        """
 
771
        Test that an advertized feature results in successful initialization.
 
772
        """
 
773
        self.xmlstream.features = {self.init.feature:
 
774
                                   domish.Element(self.init.feature)}
 
775
        return self.init.initialize()
 
776
 
 
777
 
 
778
    def testNotAdvertizedRequired(self):
 
779
        """
 
780
        Test that when the feature is not advertized, but required by the
 
781
        initializer, an exception is raised.
 
782
        """
 
783
        self.init.required = True
 
784
        self.assertRaises(xmlstream.FeatureNotAdvertized, self.init.initialize)
 
785
 
 
786
 
 
787
    def testNotAdvertizedNotRequired(self):
 
788
        """
 
789
        Test that when the feature is not advertized, and not required by the
 
790
        initializer, the initializer silently succeeds.
 
791
        """
 
792
        self.init.required = False
 
793
        self.assertIdentical(None, self.init.initialize())
 
794
 
 
795
 
 
796
 
 
797
class ToResponseTest(unittest.TestCase):
 
798
 
 
799
    def test_toResponse(self):
 
800
        """
 
801
        Test that a response stanza is generated with addressing swapped.
 
802
        """
 
803
        stanza = domish.Element(('jabber:client', 'iq'))
 
804
        stanza['type'] = 'get'
 
805
        stanza['to'] = 'user1@example.com'
 
806
        stanza['from'] = 'user2@example.com/resource'
 
807
        stanza['id'] = 'stanza1'
 
808
        response = xmlstream.toResponse(stanza, 'result')
 
809
        self.assertNotIdentical(stanza, response)
 
810
        self.assertEqual(response['from'], 'user1@example.com')
 
811
        self.assertEqual(response['to'], 'user2@example.com/resource')
 
812
        self.assertEqual(response['type'], 'result')
 
813
        self.assertEqual(response['id'], 'stanza1')
 
814
 
 
815
 
 
816
    def test_toResponseNoFrom(self):
 
817
        """
 
818
        Test that a response is generated from a stanza without a from address.
 
819
        """
 
820
        stanza = domish.Element(('jabber:client', 'iq'))
 
821
        stanza['type'] = 'get'
 
822
        stanza['to'] = 'user1@example.com'
 
823
        response = xmlstream.toResponse(stanza)
 
824
        self.assertEqual(response['from'], 'user1@example.com')
 
825
        self.assertFalse(response.hasAttribute('to'))
 
826
 
 
827
 
 
828
    def test_toResponseNoTo(self):
 
829
        """
 
830
        Test that a response is generated from a stanza without a to address.
 
831
        """
 
832
        stanza = domish.Element(('jabber:client', 'iq'))
 
833
        stanza['type'] = 'get'
 
834
        stanza['from'] = 'user2@example.com/resource'
 
835
        response = xmlstream.toResponse(stanza)
 
836
        self.assertFalse(response.hasAttribute('from'))
 
837
        self.assertEqual(response['to'], 'user2@example.com/resource')
 
838
 
 
839
 
 
840
    def test_toResponseNoAddressing(self):
 
841
        """
 
842
        Test that a response is generated from a stanza without any addressing.
 
843
        """
 
844
        stanza = domish.Element(('jabber:client', 'message'))
 
845
        stanza['type'] = 'chat'
 
846
        response = xmlstream.toResponse(stanza)
 
847
        self.assertFalse(response.hasAttribute('to'))
 
848
        self.assertFalse(response.hasAttribute('from'))
 
849
 
 
850
 
 
851
    def test_noID(self):
 
852
        """
 
853
        Test that a proper response is generated without id attribute.
 
854
        """
 
855
        stanza = domish.Element(('jabber:client', 'message'))
 
856
        response = xmlstream.toResponse(stanza)
 
857
        self.assertFalse(response.hasAttribute('id'))
 
858
 
 
859
 
 
860
    def test_noType(self):
 
861
        """
 
862
        Test that a proper response is generated without type attribute.
 
863
        """
 
864
        stanza = domish.Element(('jabber:client', 'message'))
 
865
        response = xmlstream.toResponse(stanza)
 
866
        self.assertFalse(response.hasAttribute('type'))
 
867
 
 
868
 
 
869
class DummyFactory(object):
 
870
    """
 
871
    Dummy XmlStream factory that only registers bootstrap observers.
 
872
    """
 
873
    def __init__(self):
 
874
        self.callbacks = {}
 
875
 
 
876
 
 
877
    def addBootstrap(self, event, callback):
 
878
        self.callbacks[event] = callback
 
879
 
 
880
 
 
881
 
 
882
class DummyXMPPHandler(xmlstream.XMPPHandler):
 
883
    """
 
884
    Dummy XMPP subprotocol handler to count the methods are called on it.
 
885
    """
 
886
    def __init__(self):
 
887
        self.doneMade = 0
 
888
        self.doneInitialized = 0
 
889
        self.doneLost = 0
 
890
 
 
891
 
 
892
    def makeConnection(self, xs):
 
893
        self.connectionMade()
 
894
 
 
895
 
 
896
    def connectionMade(self):
 
897
        self.doneMade += 1
 
898
 
 
899
 
 
900
    def connectionInitialized(self):
 
901
        self.doneInitialized += 1
 
902
 
 
903
 
 
904
    def connectionLost(self, reason):
 
905
        self.doneLost += 1
 
906
 
 
907
 
 
908
 
 
909
class XMPPHandlerTest(unittest.TestCase):
 
910
    """
 
911
    Tests for L{xmlstream.XMPPHandler}.
 
912
    """
 
913
 
 
914
    def test_interface(self):
 
915
        """
 
916
        L{xmlstream.XMPPHandler} implements L{ijabber.IXMPPHandler}.
 
917
        """
 
918
        verifyObject(ijabber.IXMPPHandler, xmlstream.XMPPHandler())
 
919
 
 
920
 
 
921
    def test_send(self):
 
922
        """
 
923
        Test that data is passed on for sending by the stream manager.
 
924
        """
 
925
        class DummyStreamManager(object):
 
926
            def __init__(self):
 
927
                self.outlist = []
 
928
 
 
929
            def send(self, data):
 
930
                self.outlist.append(data)
 
931
 
 
932
        handler = xmlstream.XMPPHandler()
 
933
        handler.parent = DummyStreamManager()
 
934
        handler.send('<presence/>')
 
935
        self.assertEquals(['<presence/>'], handler.parent.outlist)
 
936
 
 
937
 
 
938
    def test_makeConnection(self):
 
939
        """
 
940
        Test that makeConnection saves the XML stream and calls connectionMade.
 
941
        """
 
942
        class TestXMPPHandler(xmlstream.XMPPHandler):
 
943
            def connectionMade(self):
 
944
                self.doneMade = True
 
945
 
 
946
        handler = TestXMPPHandler()
 
947
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
948
        handler.makeConnection(xs)
 
949
        self.assertTrue(handler.doneMade)
 
950
        self.assertIdentical(xs, handler.xmlstream)
 
951
 
 
952
 
 
953
    def test_connectionLost(self):
 
954
        """
 
955
        Test that connectionLost forgets the XML stream.
 
956
        """
 
957
        handler = xmlstream.XMPPHandler()
 
958
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
959
        handler.makeConnection(xs)
 
960
        handler.connectionLost(Exception())
 
961
        self.assertIdentical(None, handler.xmlstream)
 
962
 
 
963
 
 
964
 
 
965
class XMPPHandlerCollectionTest(unittest.TestCase):
 
966
    """
 
967
    Tests for L{xmlstream.XMPPHandlerCollection}.
 
968
    """
 
969
 
 
970
    def setUp(self):
 
971
        self.collection = xmlstream.XMPPHandlerCollection()
 
972
 
 
973
 
 
974
    def test_interface(self):
 
975
        """
 
976
        L{xmlstream.StreamManager} implements L{ijabber.IXMPPHandlerCollection}.
 
977
        """
 
978
        verifyObject(ijabber.IXMPPHandlerCollection, self.collection)
 
979
 
 
980
 
 
981
    def test_addHandler(self):
 
982
        """
 
983
        Test the addition of a protocol handler.
 
984
        """
 
985
        handler = DummyXMPPHandler()
 
986
        handler.setHandlerParent(self.collection)
 
987
        self.assertIn(handler, self.collection)
 
988
        self.assertIdentical(self.collection, handler.parent)
 
989
 
 
990
 
 
991
    def test_removeHandler(self):
 
992
        """
 
993
        Test removal of a protocol handler.
 
994
        """
 
995
        handler = DummyXMPPHandler()
 
996
        handler.setHandlerParent(self.collection)
 
997
        handler.disownHandlerParent(self.collection)
 
998
        self.assertNotIn(handler, self.collection)
 
999
        self.assertIdentical(None, handler.parent)
 
1000
 
 
1001
 
 
1002
 
 
1003
class StreamManagerTest(unittest.TestCase):
 
1004
    """
 
1005
    Tests for L{xmlstream.StreamManager}.
 
1006
    """
 
1007
 
 
1008
    def setUp(self):
 
1009
        factory = DummyFactory()
 
1010
        self.streamManager = xmlstream.StreamManager(factory)
 
1011
 
 
1012
 
 
1013
    def test_basic(self):
 
1014
        """
 
1015
        Test correct initialization and setup of factory observers.
 
1016
        """
 
1017
        sm = self.streamManager
 
1018
        self.assertIdentical(None, sm.xmlstream)
 
1019
        self.assertEquals([], sm.handlers)
 
1020
        self.assertEquals(sm._connected,
 
1021
                          sm.factory.callbacks['//event/stream/connected'])
 
1022
        self.assertEquals(sm._authd,
 
1023
                          sm.factory.callbacks['//event/stream/authd'])
 
1024
        self.assertEquals(sm._disconnected,
 
1025
                          sm.factory.callbacks['//event/stream/end'])
 
1026
        self.assertEquals(sm.initializationFailed,
 
1027
                          sm.factory.callbacks['//event/xmpp/initfailed'])
 
1028
 
 
1029
 
 
1030
    def test_connected(self):
 
1031
        """
 
1032
        Test that protocol handlers have their connectionMade method called
 
1033
        when the XML stream is connected.
 
1034
        """
 
1035
        sm = self.streamManager
 
1036
        handler = DummyXMPPHandler()
 
1037
        handler.setHandlerParent(sm)
 
1038
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
1039
        sm._connected(xs)
 
1040
        self.assertEquals(1, handler.doneMade)
 
1041
        self.assertEquals(0, handler.doneInitialized)
 
1042
        self.assertEquals(0, handler.doneLost)
 
1043
 
 
1044
 
 
1045
    def test_connectedLogTrafficFalse(self):
 
1046
        """
 
1047
        Test raw data functions unset when logTraffic is set to False.
 
1048
        """
 
1049
        sm = self.streamManager
 
1050
        handler = DummyXMPPHandler()
 
1051
        handler.setHandlerParent(sm)
 
1052
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
1053
        sm._connected(xs)
 
1054
        self.assertIdentical(None, xs.rawDataInFn)
 
1055
        self.assertIdentical(None, xs.rawDataOutFn)
 
1056
 
 
1057
 
 
1058
    def test_connectedLogTrafficTrue(self):
 
1059
        """
 
1060
        Test raw data functions set when logTraffic is set to True.
 
1061
        """
 
1062
        sm = self.streamManager
 
1063
        sm.logTraffic = True
 
1064
        handler = DummyXMPPHandler()
 
1065
        handler.setHandlerParent(sm)
 
1066
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
1067
        sm._connected(xs)
 
1068
        self.assertNotIdentical(None, xs.rawDataInFn)
 
1069
        self.assertNotIdentical(None, xs.rawDataOutFn)
 
1070
 
 
1071
 
 
1072
    def test_authd(self):
 
1073
        """
 
1074
        Test that protocol handlers have their connectionInitialized method
 
1075
        called when the XML stream is initialized.
 
1076
        """
 
1077
        sm = self.streamManager
 
1078
        handler = DummyXMPPHandler()
 
1079
        handler.setHandlerParent(sm)
 
1080
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
1081
        sm._authd(xs)
 
1082
        self.assertEquals(0, handler.doneMade)
 
1083
        self.assertEquals(1, handler.doneInitialized)
 
1084
        self.assertEquals(0, handler.doneLost)
 
1085
 
 
1086
 
 
1087
    def test_disconnected(self):
 
1088
        """
 
1089
        Test that protocol handlers have their connectionLost method
 
1090
        called when the XML stream is disconnected.
 
1091
        """
 
1092
        sm = self.streamManager
 
1093
        handler = DummyXMPPHandler()
 
1094
        handler.setHandlerParent(sm)
 
1095
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
1096
        sm._disconnected(xs)
 
1097
        self.assertEquals(0, handler.doneMade)
 
1098
        self.assertEquals(0, handler.doneInitialized)
 
1099
        self.assertEquals(1, handler.doneLost)
 
1100
 
 
1101
 
 
1102
    def test_addHandler(self):
 
1103
        """
 
1104
        Test the addition of a protocol handler while not connected.
 
1105
        """
 
1106
        sm = self.streamManager
 
1107
        handler = DummyXMPPHandler()
 
1108
        handler.setHandlerParent(sm)
 
1109
 
 
1110
        self.assertEquals(0, handler.doneMade)
 
1111
        self.assertEquals(0, handler.doneInitialized)
 
1112
        self.assertEquals(0, handler.doneLost)
 
1113
 
 
1114
 
 
1115
    def test_addHandlerInitialized(self):
 
1116
        """
 
1117
        Test the addition of a protocol handler after the stream
 
1118
        have been initialized.
 
1119
 
 
1120
        Make sure that the handler will have the connected stream
 
1121
        passed via C{makeConnection} and have C{connectionInitialized}
 
1122
        called.
 
1123
        """
 
1124
        sm = self.streamManager
 
1125
        xs = xmlstream.XmlStream(xmlstream.Authenticator())
 
1126
        sm._connected(xs)
 
1127
        sm._authd(xs)
 
1128
        handler = DummyXMPPHandler()
 
1129
        handler.setHandlerParent(sm)
 
1130
 
 
1131
        self.assertEquals(1, handler.doneMade)
 
1132
        self.assertEquals(1, handler.doneInitialized)
 
1133
        self.assertEquals(0, handler.doneLost)
 
1134
 
 
1135
 
 
1136
    def test_sendInitialized(self):
 
1137
        """
 
1138
        Test send when the stream has been initialized.
 
1139
 
 
1140
        The data should be sent directly over the XML stream.
 
1141
        """
 
1142
        factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
 
1143
        sm = xmlstream.StreamManager(factory)
 
1144
        xs = factory.buildProtocol(None)
 
1145
        xs.transport = proto_helpers.StringTransport()
 
1146
        xs.connectionMade()
 
1147
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
1148
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
1149
                        "from='example.com' id='12345'>")
 
1150
        xs.dispatch(xs, "//event/stream/authd")
 
1151
        sm.send("<presence/>")
 
1152
        self.assertEquals("<presence/>", xs.transport.value())
 
1153
 
 
1154
 
 
1155
    def test_sendNotConnected(self):
 
1156
        """
 
1157
        Test send when there is no established XML stream.
 
1158
 
 
1159
        The data should be cached until an XML stream has been established and
 
1160
        initialized.
 
1161
        """
 
1162
        factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
 
1163
        sm = xmlstream.StreamManager(factory)
 
1164
        handler = DummyXMPPHandler()
 
1165
        sm.addHandler(handler)
 
1166
 
 
1167
        xs = factory.buildProtocol(None)
 
1168
        xs.transport = proto_helpers.StringTransport()
 
1169
        sm.send("<presence/>")
 
1170
        self.assertEquals("", xs.transport.value())
 
1171
        self.assertEquals("<presence/>", sm._packetQueue[0])
 
1172
 
 
1173
        xs.connectionMade()
 
1174
        self.assertEquals("", xs.transport.value())
 
1175
        self.assertEquals("<presence/>", sm._packetQueue[0])
 
1176
 
 
1177
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
1178
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
1179
                        "from='example.com' id='12345'>")
 
1180
        xs.dispatch(xs, "//event/stream/authd")
 
1181
 
 
1182
        self.assertEquals("<presence/>", xs.transport.value())
 
1183
        self.assertFalse(sm._packetQueue)
 
1184
 
 
1185
 
 
1186
    def test_sendNotInitialized(self):
 
1187
        """
 
1188
        Test send when the stream is connected but not yet initialized.
 
1189
 
 
1190
        The data should be cached until the XML stream has been initialized.
 
1191
        """
 
1192
        factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
 
1193
        sm = xmlstream.StreamManager(factory)
 
1194
        xs = factory.buildProtocol(None)
 
1195
        xs.transport = proto_helpers.StringTransport()
 
1196
        xs.connectionMade()
 
1197
        xs.dataReceived("<stream:stream xmlns='jabber:client' "
 
1198
                        "xmlns:stream='http://etherx.jabber.org/streams' "
 
1199
                        "from='example.com' id='12345'>")
 
1200
        sm.send("<presence/>")
 
1201
        self.assertEquals("", xs.transport.value())
 
1202
        self.assertEquals("<presence/>", sm._packetQueue[0])
 
1203
 
 
1204
 
 
1205
    def test_sendDisconnected(self):
 
1206
        """
 
1207
        Test send after XML stream disconnection.
 
1208
 
 
1209
        The data should be cached until a new XML stream has been established
 
1210
        and initialized.
 
1211
        """
 
1212
        factory = xmlstream.XmlStreamFactory(xmlstream.Authenticator())
 
1213
        sm = xmlstream.StreamManager(factory)
 
1214
        handler = DummyXMPPHandler()
 
1215
        sm.addHandler(handler)
 
1216
 
 
1217
        xs = factory.buildProtocol(None)
 
1218
        xs.connectionMade()
 
1219
        xs.transport = proto_helpers.StringTransport()
 
1220
        xs.connectionLost(None)
 
1221
 
 
1222
        sm.send("<presence/>")
 
1223
        self.assertEquals("", xs.transport.value())
 
1224
        self.assertEquals("<presence/>", sm._packetQueue[0])
 
1225
 
 
1226
 
 
1227
 
 
1228
class XmlStreamServerFactoryTest(GenericXmlStreamFactoryTestsMixin):
 
1229
    """
 
1230
    Tests for L{xmlstream.XmlStreamServerFactory}.
 
1231
    """
 
1232
 
 
1233
    def setUp(self):
 
1234
        """
 
1235
        Set up a server factory with a authenticator factory function.
 
1236
        """
 
1237
        class TestAuthenticator(object):
 
1238
            def __init__(self):
 
1239
                self.xmlstreams = []
 
1240
 
 
1241
            def associateWithStream(self, xs):
 
1242
                self.xmlstreams.append(xs)
 
1243
 
 
1244
        def authenticatorFactory():
 
1245
            return TestAuthenticator()
 
1246
 
 
1247
        self.factory = xmlstream.XmlStreamServerFactory(authenticatorFactory)
 
1248
 
 
1249
 
 
1250
    def test_interface(self):
 
1251
        """
 
1252
        L{XmlStreamServerFactory} is a L{Factory}.
 
1253
        """
 
1254
        verifyObject(IProtocolFactory, self.factory)
 
1255
 
 
1256
 
 
1257
    def test_buildProtocolAuthenticatorInstantiation(self):
 
1258
        """
 
1259
        The authenticator factory should be used to instantiate the
 
1260
        authenticator and pass it to the protocol.
 
1261
 
 
1262
        The default protocol, L{XmlStream} stores the authenticator it is
 
1263
        passed, and calls its C{associateWithStream} method. so we use that to
 
1264
        check whether our authenticator factory is used and the protocol
 
1265
        instance gets an authenticator.
 
1266
        """
 
1267
        xs = self.factory.buildProtocol(None)
 
1268
        self.assertEquals([xs], xs.authenticator.xmlstreams)
 
1269
 
 
1270
 
 
1271
    def test_buildProtocolXmlStream(self):
 
1272
        """
 
1273
        The protocol factory creates Jabber XML Stream protocols by default.
 
1274
        """
 
1275
        xs = self.factory.buildProtocol(None)
 
1276
        self.assertIsInstance(xs, xmlstream.XmlStream)
 
1277
 
 
1278
 
 
1279
    def test_buildProtocolTwice(self):
 
1280
        """
 
1281
        Subsequent calls to buildProtocol should result in different instances
 
1282
        of the protocol, as well as their authenticators.
 
1283
        """
 
1284
        xs1 = self.factory.buildProtocol(None)
 
1285
        xs2 = self.factory.buildProtocol(None)
 
1286
        self.assertNotIdentical(xs1, xs2)
 
1287
        self.assertNotIdentical(xs1.authenticator, xs2.authenticator)