source: wokkel/test/test_client.py @ 178:37f36ea93838

Last change on this file since 178:37f36ea93838 was 178:37f36ea93838, checked in by Ralph Meijer <ralphm@…>, 8 years ago

Properly encode IDN domain names for SRV lookups.

Before Twisted 12.3.0, the SRV lookup done for outgoing
connections succeeded if passed a unicode string with all-ASCII
code points. A recent change made the DNS code more strict, and
only byte string are accepted as domain name. See
http://twistedmatrix.com/trac/ticket/6245 for details.

This change makes sure domain names are encoded to their ASCII
Compatible Equivalent (ACE) version before passing the resulting
byte string to twisted.names.srvconnect.SRVConnector, as per
RFC 3490.

Note that while connecting to servers with an IDN domain name
now works properly, authentication using MD5-Digest SASL mechanism
will fail until http://twistedmatrix.com/trac/ticket/5066 has been
resolved.

Fixes: #77.

  • Property exe set to *
File size: 5.0 KB
Line 
1# Copyright (c) Ralph Meijer.
2# See LICENSE for details.
3
4"""
5Tests for L{wokkel.client}.
6"""
7
8from twisted.internet import defer
9from twisted.trial import unittest
10from twisted.words.protocols.jabber import xmlstream
11from twisted.words.protocols.jabber.client import XMPPAuthenticator
12from twisted.words.protocols.jabber.jid import JID
13from twisted.words.protocols.jabber.xmlstream import STREAM_AUTHD_EVENT
14from twisted.words.protocols.jabber.xmlstream import INIT_FAILED_EVENT
15from twisted.words.protocols.jabber.xmlstream import XMPPHandler
16
17from wokkel import client
18
19class XMPPClientTest(unittest.TestCase):
20    """
21    Tests for L{client.XMPPClient}.
22    """
23
24    def setUp(self):
25        self.client = client.XMPPClient(JID('user@example.org'), 'secret')
26
27
28    def test_jid(self):
29        """
30        Make sure the JID we pass is stored on the client.
31        """
32        self.assertEquals(JID('user@example.org'), self.client.jid)
33
34
35    def test_jidWhenInitialized(self):
36        """
37        Make sure that upon login, the JID is updated from the authenticator.
38        """
39        xs = self.client.factory.buildProtocol(None)
40        self.client.factory.authenticator.jid = JID('user@example.org/test')
41        xs.dispatch(xs, xmlstream.STREAM_AUTHD_EVENT)
42        self.assertEquals(JID('user@example.org/test'), self.client.jid)
43
44
45    def test_domain(self):
46        """
47        The domain to connect to is a byte string derived from the JID host.
48        """
49        self.assertIsInstance(self.client.domain, bytes)
50        self.assertEqual(b'example.org', self.client.domain)
51
52
53
54class DeferredClientFactoryTest(unittest.TestCase):
55    """
56    Tests for L{client.DeferredClientFactory}.
57    """
58
59    def setUp(self):
60        self.factory = client.DeferredClientFactory(JID('user@example.org'),
61                                                    'secret')
62
63
64    def test_buildProtocol(self):
65        """
66        The authenticator factory should be passed to its protocol and it
67        should instantiate the authenticator and save it.
68        L{xmlstream.XmlStream}s do that, but we also want to ensure it really
69        is one.
70        """
71        xs = self.factory.buildProtocol(None)
72        self.assertIdentical(self.factory, xs.factory)
73        self.assertIsInstance(xs, xmlstream.XmlStream)
74        self.assertIsInstance(xs.authenticator, XMPPAuthenticator)
75
76
77    def test_deferredOnInitialized(self):
78        """
79        Test the factory's deferred on stream initialization.
80        """
81
82        xs = self.factory.buildProtocol(None)
83        xs.dispatch(xs, STREAM_AUTHD_EVENT)
84        return self.factory.deferred
85
86
87    def test_deferredOnNotInitialized(self):
88        """
89        Test the factory's deferred on failed stream initialization.
90        """
91
92        class TestException(Exception):
93            pass
94
95        xs = self.factory.buildProtocol(None)
96        xs.dispatch(TestException(), INIT_FAILED_EVENT)
97        self.assertFailure(self.factory.deferred, TestException)
98        return self.factory.deferred
99
100
101    def test_deferredOnConnectionFailure(self):
102        """
103        Test the factory's deferred on connection faulure.
104        """
105
106        class TestException(Exception):
107            pass
108
109        self.factory.buildProtocol(None)
110        self.factory.clientConnectionFailed(self, TestException())
111        self.assertFailure(self.factory.deferred, TestException)
112        return self.factory.deferred
113
114
115    def test_addHandler(self):
116        """
117        Test the addition of a protocol handler.
118        """
119        handler = XMPPHandler()
120        handler.setHandlerParent(self.factory.streamManager)
121        self.assertIn(handler, self.factory.streamManager)
122        self.assertIdentical(self.factory.streamManager, handler.parent)
123
124
125    def test_removeHandler(self):
126        """
127        Test removal of a protocol handler.
128        """
129        handler = XMPPHandler()
130        handler.setHandlerParent(self.factory.streamManager)
131        handler.disownHandlerParent(self.factory.streamManager)
132        self.assertNotIn(handler, self.factory.streamManager)
133        self.assertIdentical(None, handler.parent)
134
135
136
137class ClientCreatorTest(unittest.TestCase):
138    """
139    Tests for L{client.clientCreator}.
140    """
141
142    def test_call(self):
143        """
144        The factory is passed to an SRVConnector and a connection initiated.
145        """
146
147        d1 = defer.Deferred()
148        factory = client.DeferredClientFactory(JID('user@example.org'),
149                                               'secret')
150
151        def cb(connector):
152            self.assertEqual('xmpp-client', connector.service)
153            self.assertIsInstance(connector.domain, bytes)
154            self.assertEqual(b'example.org', connector.domain)
155            self.assertEqual(factory, connector.factory)
156
157        def connect(connector):
158            d1.callback(connector)
159
160        d1.addCallback(cb)
161        self.patch(client.SRVConnector, 'connect', connect)
162
163        d2 = client.clientCreator(factory)
164        self.assertEqual(factory.deferred, d2)
165
166        return d1
Note: See TracBrowser for help on using the repository browser.