source: wokkel/test/test_generic.py @ 184:a9ab7d3945e2

Last change on this file since 184:a9ab7d3945e2 was 184:a9ab7d3945e2, checked in by Ralph Meijer <ralphm@…>, 7 years ago

Deprecate prepareIDNName.

C{unicode.encode('idna')} does exactly the same as the recently
introduced L{generic.prepareIDNName}.

  • Property exe set to *
File size: 10.2 KB
Line 
1# Copyright (c) Ralph Meijer.
2# See LICENSE for details.
3
4"""
5Tests for L{wokkel.generic}.
6"""
7
8import re
9
10from twisted.python import deprecate
11from twisted.python.versions import Version
12from twisted.trial import unittest
13from twisted.trial.util import suppress as SUPPRESS
14from twisted.words.xish import domish
15from twisted.words.protocols.jabber.jid import JID
16
17from wokkel import generic
18from wokkel.test.helpers import XmlStreamStub
19
20NS_VERSION = 'jabber:iq:version'
21
22class VersionHandlerTest(unittest.TestCase):
23    """
24    Tests for L{wokkel.generic.VersionHandler}.
25    """
26
27    def test_onVersion(self):
28        """
29        Test response to incoming version request.
30        """
31        self.stub = XmlStreamStub()
32        self.protocol = generic.VersionHandler('Test', '0.1.0')
33        self.protocol.xmlstream = self.stub.xmlstream
34        self.protocol.send = self.stub.xmlstream.send
35        self.protocol.connectionInitialized()
36
37        iq = domish.Element((None, 'iq'))
38        iq['from'] = 'user@example.org/Home'
39        iq['to'] = 'example.org'
40        iq['type'] = 'get'
41        iq.addElement((NS_VERSION, 'query'))
42        self.stub.send(iq)
43
44        response = self.stub.output[-1]
45        self.assertEquals('user@example.org/Home', response['to'])
46        self.assertEquals('example.org', response['from'])
47        self.assertEquals('result', response['type'])
48        self.assertEquals(NS_VERSION, response.query.uri)
49        elements = list(domish.generateElementsQNamed(response.query.children,
50                                                      'name', NS_VERSION))
51        self.assertEquals(1, len(elements))
52        self.assertEquals('Test', unicode(elements[0]))
53        elements = list(domish.generateElementsQNamed(response.query.children,
54                                                      'version', NS_VERSION))
55        self.assertEquals(1, len(elements))
56        self.assertEquals('0.1.0', unicode(elements[0]))
57
58
59
60class XmlPipeTest(unittest.TestCase):
61    """
62    Tests for L{wokkel.generic.XmlPipe}.
63    """
64
65    def setUp(self):
66        self.pipe = generic.XmlPipe()
67
68
69    def test_sendFromSource(self):
70        """
71        Send an element from the source and observe it from the sink.
72        """
73        def cb(obj):
74            called.append(obj)
75
76        called = []
77        self.pipe.sink.addObserver('/test[@xmlns="testns"]', cb)
78        element = domish.Element(('testns', 'test'))
79        self.pipe.source.send(element)
80        self.assertEquals([element], called)
81
82
83    def test_sendFromSink(self):
84        """
85        Send an element from the sink and observe it from the source.
86        """
87        def cb(obj):
88            called.append(obj)
89
90        called = []
91        self.pipe.source.addObserver('/test[@xmlns="testns"]', cb)
92        element = domish.Element(('testns', 'test'))
93        self.pipe.sink.send(element)
94        self.assertEquals([element], called)
95
96
97
98class StanzaTest(unittest.TestCase):
99    """
100    Tests for L{generic.Stanza}.
101    """
102
103    def test_fromElement(self):
104        xml = """
105        <message type='chat' from='other@example.org' to='user@example.org'/>
106        """
107
108        stanza = generic.Stanza.fromElement(generic.parseXml(xml))
109        self.assertEqual('chat', stanza.stanzaType)
110        self.assertEqual(JID('other@example.org'), stanza.sender)
111        self.assertEqual(JID('user@example.org'), stanza.recipient)
112
113
114    def test_fromElementChildParser(self):
115        """
116        Child elements for which no parser is defined are ignored.
117        """
118        xml = """
119        <message from='other@example.org' to='user@example.org'>
120          <x xmlns='http://example.org/'/>
121        </message>
122        """
123
124        class Message(generic.Stanza):
125            childParsers = {('http://example.org/', 'x'): '_childParser_x'}
126            elements = []
127
128            def _childParser_x(self, element):
129                self.elements.append(element)
130
131        message = Message.fromElement(generic.parseXml(xml))
132        self.assertEqual(1, len(message.elements))
133
134
135    def test_fromElementChildParserAll(self):
136        """
137        Child elements for which no parser is defined are ignored.
138        """
139        xml = """
140        <message from='other@example.org' to='user@example.org'>
141          <x xmlns='http://example.org/'/>
142        </message>
143        """
144
145        class Message(generic.Stanza):
146            childParsers = {None: '_childParser'}
147            elements = []
148
149            def _childParser(self, element):
150                self.elements.append(element)
151
152        message = Message.fromElement(generic.parseXml(xml))
153        self.assertEqual(1, len(message.elements))
154
155
156    def test_fromElementChildParserUnknown(self):
157        """
158        Child elements for which no parser is defined are ignored.
159        """
160        xml = """
161        <message from='other@example.org' to='user@example.org'>
162          <x xmlns='http://example.org/'/>
163        </message>
164        """
165        generic.Stanza.fromElement(generic.parseXml(xml))
166
167
168
169
170class RequestTest(unittest.TestCase):
171    """
172    Tests for L{generic.Request}.
173    """
174
175    def setUp(self):
176        self.request = generic.Request()
177
178
179    def test_requestParser(self):
180        """
181        The request's child element is passed to requestParser.
182        """
183        xml = """
184        <iq type='get'>
185          <query xmlns='jabber:iq:version'/>
186        </iq>
187        """
188
189        class VersionRequest(generic.Request):
190            elements = []
191
192            def parseRequest(self, element):
193                self.elements.append((element.uri, element.name))
194
195        request = VersionRequest.fromElement(generic.parseXml(xml))
196        self.assertEqual([(NS_VERSION, 'query')], request.elements)
197
198
199    def test_toElementStanzaKind(self):
200        """
201        A request is an iq stanza.
202        """
203        element = self.request.toElement()
204        self.assertIdentical(None, element.uri)
205        self.assertEquals('iq', element.name)
206
207
208    def test_toElementStanzaType(self):
209        """
210        The request has type 'get'.
211        """
212        self.assertEquals('get', self.request.stanzaType)
213        element = self.request.toElement()
214        self.assertEquals('get', element.getAttribute('type'))
215
216
217    def test_toElementStanzaTypeSet(self):
218        """
219        The request has type 'set'.
220        """
221        self.request.stanzaType = 'set'
222        element = self.request.toElement()
223        self.assertEquals('set', element.getAttribute('type'))
224
225
226    def test_toElementStanzaID(self):
227        """
228        A request, when rendered, has an identifier.
229        """
230        element = self.request.toElement()
231        self.assertNotIdentical(None, self.request.stanzaID)
232        self.assertEquals(self.request.stanzaID, element.getAttribute('id'))
233
234
235    def test_toElementRecipient(self):
236        """
237        A request without recipient, has no 'to' attribute.
238        """
239        self.request = generic.Request(recipient=JID('other@example.org'))
240        self.assertEquals(JID('other@example.org'), self.request.recipient)
241        element = self.request.toElement()
242        self.assertEquals(u'other@example.org', element.getAttribute('to'))
243
244
245    def test_toElementRecipientNone(self):
246        """
247        A request without recipient, has no 'to' attribute.
248        """
249        element = self.request.toElement()
250        self.assertFalse(element.hasAttribute('to'))
251
252
253    def test_toElementSender(self):
254        """
255        A request with sender, has a 'from' attribute.
256        """
257        self.request = generic.Request(sender=JID('user@example.org'))
258        self.assertEquals(JID('user@example.org'), self.request.sender)
259        element = self.request.toElement()
260        self.assertEquals(u'user@example.org', element.getAttribute('from'))
261
262
263    def test_toElementSenderNone(self):
264        """
265        A request without sender, has no 'from' attribute.
266        """
267        element = self.request.toElement()
268        self.assertFalse(element.hasAttribute('from'))
269
270
271    def test_timeoutDefault(self):
272        """
273        The default is no timeout.
274        """
275        self.assertIdentical(None, self.request.timeout)
276
277
278
279class PrepareIDNNameTests(unittest.TestCase):
280    """
281    Tests for L{wokkel.generic.prepareIDNName}.
282    """
283
284    suppress = [SUPPRESS(category=DeprecationWarning,
285                         message=re.escape(
286                             deprecate.getDeprecationWarningString(
287                                 generic.prepareIDNName,
288                                 Version("Wokkel", 0, 8, 0),
289                                 replacement="unicode.encode('idna')")))]
290
291
292    def test_deprecated(self):
293        """
294        prepareIDNName is deprecated.
295        """
296        self.callDeprecated((Version("Wokkel", 0, 8, 0),
297                             "unicode.encode('idna')"),
298                            generic.prepareIDNName, (b"example.com"))
299    test_deprecated.suppress = []
300
301
302    def test_bytestring(self):
303        """
304        An ASCII-encoded byte string is left as-is.
305        """
306        name = b"example.com"
307        result = generic.prepareIDNName(name)
308        self.assertEqual(b"example.com", result)
309
310
311    def test_unicode(self):
312        """
313        A unicode all-ASCII name is converted to an ASCII byte string.
314        """
315        name = u"example.com"
316        result = generic.prepareIDNName(name)
317        self.assertEqual(b"example.com", result)
318
319
320    def test_unicodeNonASCII(self):
321        """
322        A unicode with non-ASCII is converted to its ACE equivalent.
323        """
324        name = u"\u00e9chec.example.com"
325        result = generic.prepareIDNName(name)
326        self.assertEqual(b"xn--chec-9oa.example.com", result)
327
328
329    def test_unicodeHalfwidthIdeographicFullStop(self):
330        """
331        Exotic dots in unicode names are converted to Full Stop.
332        """
333        name = u"\u00e9chec.example\uff61com"
334        result = generic.prepareIDNName(name)
335        self.assertEqual(b"xn--chec-9oa.example.com", result)
336
337
338    def test_unicodeTrailingDot(self):
339        """
340        Unicode names with trailing dots retain the trailing dot.
341
342        L{encodings.idna.ToASCII} doesn't allow the empty string as the input,
343        hence the implementation needs to strip a trailing dot, and re-add it
344        after encoding the labels.
345        """
346        name = u"example.com."
347        result = generic.prepareIDNName(name)
348        self.assertEqual(b"example.com.", result)
Note: See TracBrowser for help on using the repository browser.