source: wokkel/test/test_disco.py @ 198:7110457aff51

Last change on this file since 198:7110457aff51 was 198:7110457aff51, checked in by Ralph Meijer <ralphm@…>, 4 years ago

imported patch py3-disco.patch

  • Property exe set to *
File size: 30.9 KB
Line 
1# Copyright (c) Ralph Meijer.
2# See LICENSE for details.
3
4"""
5Tests for L{wokkel.disco}.
6"""
7
8from __future__ import division, absolute_import
9
10from zope.interface import implementer
11
12from twisted.internet import defer
13from twisted.trial import unittest
14from twisted.words.protocols.jabber.error import StanzaError
15from twisted.words.protocols.jabber.jid import JID
16from twisted.words.protocols.jabber.xmlstream import toResponse
17from twisted.words.xish import domish, utility
18
19from wokkel import data_form, disco
20from wokkel.generic import parseXml
21from wokkel.subprotocols import XMPPHandler
22from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub
23
24NS_DISCO_INFO = 'http://jabber.org/protocol/disco#info'
25NS_DISCO_ITEMS = 'http://jabber.org/protocol/disco#items'
26
27class DiscoFeatureTest(unittest.TestCase):
28    """
29    Tests for L{disco.DiscoFeature}.
30    """
31
32    def test_init(self):
33        """
34        Test initialization with a with feature namespace URI.
35        """
36        feature = disco.DiscoFeature(u'testns')
37        self.assertEqual(u'testns', feature)
38
39
40    def test_toElement(self):
41        """
42        Test proper rendering to a DOM representation.
43
44        The returned element should be properly named and have a C{var}
45        attribute that holds the feature namespace URI.
46        """
47        feature = disco.DiscoFeature(u'testns')
48        element = feature.toElement()
49        self.assertEqual(NS_DISCO_INFO, element.uri)
50        self.assertEqual(u'feature', element.name)
51        self.assertTrue(element.hasAttribute(u'var'))
52        self.assertEqual(u'testns', element[u'var'])
53
54
55    def test_fromElement(self):
56        """
57        Test creating L{disco.DiscoFeature} from L{domish.Element}.
58        """
59        element = domish.Element((NS_DISCO_INFO, u'feature'))
60        element['var'] = u'testns'
61        feature = disco.DiscoFeature.fromElement(element)
62        self.assertEqual(u'testns', feature)
63
64
65
66class DiscoIdentityTest(unittest.TestCase):
67    """
68    Tests for L{disco.DiscoIdentity}.
69    """
70
71    def test_init(self):
72        """
73        Test initialization with a category, type and name.
74        """
75        identity = disco.DiscoIdentity(u'conference', u'text', u'The chatroom')
76        self.assertEqual(u'conference', identity.category)
77        self.assertEqual(u'text', identity.type)
78        self.assertEqual(u'The chatroom', identity.name)
79
80
81    def test_toElement(self):
82        """
83        Test proper rendering to a DOM representation.
84
85        The returned element should be properly named and have C{conference},
86        C{type}, and C{name} attributes.
87        """
88        identity = disco.DiscoIdentity(u'conference', u'text', u'The chatroom')
89        element = identity.toElement()
90        self.assertEqual(NS_DISCO_INFO, element.uri)
91        self.assertEqual(u'identity', element.name)
92        self.assertEqual(u'conference', element.getAttribute(u'category'))
93        self.assertEqual(u'text', element.getAttribute(u'type'))
94        self.assertEqual(u'The chatroom', element.getAttribute(u'name'))
95
96
97    def test_toElementWithoutName(self):
98        """
99        Test proper rendering to a DOM representation without a name.
100
101        The returned element should be properly named and have C{conference},
102        C{type} attributes, no C{name} attribute.
103        """
104        identity = disco.DiscoIdentity(u'conference', u'text')
105        element = identity.toElement()
106        self.assertEqual(NS_DISCO_INFO, element.uri)
107        self.assertEqual(u'identity', element.name)
108        self.assertEqual(u'conference', element.getAttribute(u'category'))
109        self.assertEqual(u'text', element.getAttribute(u'type'))
110        self.assertFalse(element.hasAttribute(u'name'))
111
112
113    def test_fromElement(self):
114        """
115        Test creating L{disco.DiscoIdentity} from L{domish.Element}.
116        """
117        element = domish.Element((NS_DISCO_INFO, u'identity'))
118        element['category'] = u'conference'
119        element['type'] = u'text'
120        element['name'] = u'The chatroom'
121        identity = disco.DiscoIdentity.fromElement(element)
122        self.assertEqual(u'conference', identity.category)
123        self.assertEqual(u'text', identity.type)
124        self.assertEqual(u'The chatroom', identity.name)
125
126
127    def test_fromElementWithoutName(self):
128        """
129        Test creating L{disco.DiscoIdentity} from L{domish.Element}, no name.
130        """
131        element = domish.Element((NS_DISCO_INFO, u'identity'))
132        element['category'] = u'conference'
133        element['type'] = u'text'
134        identity = disco.DiscoIdentity.fromElement(element)
135        self.assertEqual(u'conference', identity.category)
136        self.assertEqual(u'text', identity.type)
137        self.assertEqual(None, identity.name)
138
139
140
141class DiscoInfoTest(unittest.TestCase):
142    """
143    Tests for L{disco.DiscoInfo}.
144    """
145
146    def test_toElement(self):
147        """
148        Test C{toElement} creates a correctly namespaced element, no node.
149        """
150        info = disco.DiscoInfo()
151        element = info.toElement()
152
153        self.assertEqual(NS_DISCO_INFO, element.uri)
154        self.assertEqual(u'query', element.name)
155        self.assertFalse(element.hasAttribute(u'node'))
156
157
158    def test_toElementNode(self):
159        """
160        Test C{toElement} with a node.
161        """
162        info = disco.DiscoInfo()
163        info.nodeIdentifier = u'test'
164        element = info.toElement()
165
166        self.assertEqual(u'test', element.getAttribute(u'node'))
167
168
169    def test_toElementChildren(self):
170        """
171        Test C{toElement} creates a DOM with proper childs.
172        """
173        info = disco.DiscoInfo()
174        info.append(disco.DiscoFeature(u'jabber:iq:register'))
175        info.append(disco.DiscoIdentity(u'conference', u'text'))
176        info.append(data_form.Form(u'result'))
177        element = info.toElement()
178
179        featureElements = domish.generateElementsQNamed(element.children,
180                                                        u'feature',
181                                                        NS_DISCO_INFO)
182        self.assertEqual(1, len(list(featureElements)))
183
184        identityElements = domish.generateElementsQNamed(element.children,
185                                                         u'identity',
186                                                         NS_DISCO_INFO)
187        self.assertEqual(1, len(list(identityElements)))
188
189        extensionElements = domish.generateElementsQNamed(element.children,
190                                                         u'x',
191                                                         data_form.NS_X_DATA)
192        self.assertEqual(1, len(list(extensionElements)))
193
194
195    def test_fromElement(self):
196        """
197        Test properties when creating L{disco.DiscoInfo} from L{domish.Element}.
198        """
199        xml = """<query xmlns='http://jabber.org/protocol/disco#info'>
200                   <identity category='conference'
201                             type='text'
202                             name='A Dark Cave'/>
203                   <feature var='http://jabber.org/protocol/muc'/>
204                   <feature var='jabber:iq:register'/>
205                   <x xmlns='jabber:x:data' type='result'>
206                     <field var='FORM_TYPE' type='hidden'>
207                       <value>http://jabber.org/protocol/muc#roominfo</value>
208                     </field>
209                   </x>
210                 </query>"""
211
212        element = parseXml(xml)
213        info = disco.DiscoInfo.fromElement(element)
214
215        self.assertIn(u'http://jabber.org/protocol/muc', info.features)
216        self.assertIn(u'jabber:iq:register', info.features)
217
218        self.assertIn((u'conference', u'text'), info.identities)
219        self.assertEqual(u'A Dark Cave',
220                          info.identities[(u'conference', u'text')])
221
222        self.assertIn(u'http://jabber.org/protocol/muc#roominfo',
223                      info.extensions)
224
225
226    def test_fromElementItems(self):
227        """
228        Test items when creating L{disco.DiscoInfo} from L{domish.Element}.
229        """
230        xml = """<query xmlns='http://jabber.org/protocol/disco#info'>
231                   <identity category='conference'
232                             type='text'
233                             name='A Dark Cave'/>
234                   <feature var='http://jabber.org/protocol/muc'/>
235                   <feature var='jabber:iq:register'/>
236                   <x xmlns='jabber:x:data' type='result'>
237                     <field var='FORM_TYPE' type='hidden'>
238                       <value>http://jabber.org/protocol/muc#roominfo</value>
239                     </field>
240                   </x>
241                 </query>"""
242
243        element = parseXml(xml)
244        info = disco.DiscoInfo.fromElement(element)
245
246        info = list(info)
247        self.assertEqual(4, len(info))
248
249        identity = info[0]
250        self.assertEqual(u'conference', identity.category)
251
252        self.assertEqual(u'http://jabber.org/protocol/muc', info[1])
253        self.assertEqual(u'jabber:iq:register', info[2])
254
255        extension = info[3]
256        self.assertEqual(u'http://jabber.org/protocol/muc#roominfo',
257                         extension.formNamespace)
258
259
260    def test_fromElementNoNode(self):
261        """
262        Test creating L{disco.DiscoInfo} from L{domish.Element}, no node.
263        """
264        xml = """<query xmlns='http://jabber.org/protocol/disco#info'/>"""
265
266        element = parseXml(xml)
267        info = disco.DiscoInfo.fromElement(element)
268
269        self.assertEqual(u'', info.nodeIdentifier)
270
271
272    def test_fromElementNode(self):
273        """
274        Test creating L{disco.DiscoInfo} from L{domish.Element}, with node.
275        """
276        xml = """<query xmlns='http://jabber.org/protocol/disco#info'
277                        node='test'>
278                 </query>"""
279
280        element = parseXml(xml)
281        info = disco.DiscoInfo.fromElement(element)
282
283        self.assertEqual(u'test', info.nodeIdentifier)
284
285
286
287class DiscoItemTest(unittest.TestCase):
288    """
289    Tests for L{disco.DiscoItem}.
290    """
291
292    def test_init(self):
293        """
294        Test initialization with a category, type and name.
295        """
296        item = disco.DiscoItem(JID(u'example.org'), u'test', u'The node')
297        self.assertEqual(JID(u'example.org'), item.entity)
298        self.assertEqual(u'test', item.nodeIdentifier)
299        self.assertEqual(u'The node', item.name)
300
301
302    def test_toElement(self):
303        """
304        Test proper rendering to a DOM representation.
305
306        The returned element should be properly named and have C{jid}, C{node},
307        and C{name} attributes.
308        """
309        item = disco.DiscoItem(JID(u'example.org'), u'test', u'The node')
310        element = item.toElement()
311        self.assertEqual(NS_DISCO_ITEMS, element.uri)
312        self.assertEqual(u'item', element.name)
313        self.assertEqual(u'example.org', element.getAttribute(u'jid'))
314        self.assertEqual(u'test', element.getAttribute(u'node'))
315        self.assertEqual(u'The node', element.getAttribute(u'name'))
316
317
318    def test_toElementWithoutName(self):
319        """
320        Test proper rendering to a DOM representation without a name.
321
322        The returned element should be properly named and have C{jid}, C{node}
323        attributes, no C{name} attribute.
324        """
325        item = disco.DiscoItem(JID(u'example.org'), u'test')
326        element = item.toElement()
327        self.assertEqual(NS_DISCO_ITEMS, element.uri)
328        self.assertEqual(u'item', element.name)
329        self.assertEqual(u'example.org', element.getAttribute(u'jid'))
330        self.assertEqual(u'test', element.getAttribute(u'node'))
331        self.assertFalse(element.hasAttribute(u'name'))
332
333
334    def test_fromElement(self):
335        """
336        Test creating L{disco.DiscoItem} from L{domish.Element}.
337        """
338        element = domish.Element((NS_DISCO_ITEMS, u'item'))
339        element[u'jid'] = u'example.org'
340        element[u'node'] = u'test'
341        element[u'name'] = u'The node'
342        item = disco.DiscoItem.fromElement(element)
343        self.assertEqual(JID(u'example.org'), item.entity)
344        self.assertEqual(u'test', item.nodeIdentifier)
345        self.assertEqual(u'The node', item.name)
346
347    def test_fromElementNoNode(self):
348        """
349        Test creating L{disco.DiscoItem} from L{domish.Element}, no node.
350        """
351        element = domish.Element((NS_DISCO_ITEMS, u'item'))
352        element[u'jid'] = u'example.org'
353        element[u'name'] = u'The node'
354        item = disco.DiscoItem.fromElement(element)
355        self.assertEqual(JID(u'example.org'), item.entity)
356        self.assertEqual(u'', item.nodeIdentifier)
357        self.assertEqual(u'The node', item.name)
358
359
360    def test_fromElementNoName(self):
361        """
362        Test creating L{disco.DiscoItem} from L{domish.Element}, no name.
363        """
364        element = domish.Element((NS_DISCO_ITEMS, u'item'))
365        element[u'jid'] = u'example.org'
366        element[u'node'] = u'test'
367        item = disco.DiscoItem.fromElement(element)
368        self.assertEqual(JID(u'example.org'), item.entity)
369        self.assertEqual(u'test', item.nodeIdentifier)
370        self.assertEqual(None, item.name)
371
372    def test_fromElementBadJID(self):
373        """
374        Test creating L{disco.DiscoItem} from L{domish.Element}, bad JID.
375        """
376        element = domish.Element((NS_DISCO_ITEMS, u'item'))
377        element[u'jid'] = u'ex@@@ample.org'
378        item = disco.DiscoItem.fromElement(element)
379        self.assertIdentical(None, item.entity)
380
381
382
383class DiscoItemsTest(unittest.TestCase):
384    """
385    Tests for L{disco.DiscoItems}.
386    """
387
388    def test_toElement(self):
389        """
390        Test C{toElement} creates a correctly namespaced element, no node.
391        """
392        items = disco.DiscoItems()
393        element = items.toElement()
394
395        self.assertEqual(NS_DISCO_ITEMS, element.uri)
396        self.assertEqual(u'query', element.name)
397        self.assertFalse(element.hasAttribute(u'node'))
398
399
400    def test_toElementNode(self):
401        """
402        Test C{toElement} with a node.
403        """
404        items = disco.DiscoItems()
405        items.nodeIdentifier = u'test'
406        element = items.toElement()
407
408        self.assertEqual(u'test', element.getAttribute(u'node'))
409
410
411    def test_toElementChildren(self):
412        """
413        Test C{toElement} creates a DOM with proper childs.
414        """
415        items = disco.DiscoItems()
416        items.append(disco.DiscoItem(JID(u'example.org'), u'test', u'A node'))
417        element = items.toElement()
418
419        itemElements = domish.generateElementsQNamed(element.children,
420                                                     u'item',
421                                                     NS_DISCO_ITEMS)
422        self.assertEqual(1, len(list(itemElements)))
423
424
425    def test_fromElement(self):
426        """
427        Test creating L{disco.DiscoItems} from L{domish.Element}.
428        """
429        xml = """<query xmlns='http://jabber.org/protocol/disco#items'>
430                   <item jid='example.org' node='test' name='A node'/>
431                 </query>"""
432
433        element = parseXml(xml)
434        items = disco.DiscoItems.fromElement(element)
435
436        items = list(items)
437        self.assertEqual(1, len(items))
438        item = items[0]
439
440        self.assertEqual(JID(u'example.org'), item.entity)
441        self.assertEqual(u'test', item.nodeIdentifier)
442        self.assertEqual(u'A node', item.name)
443
444
445    def test_fromElementNoNode(self):
446        """
447        Test creating L{disco.DiscoItems} from L{domish.Element}, no node.
448        """
449        xml = """<query xmlns='http://jabber.org/protocol/disco#items'/>"""
450
451        element = parseXml(xml)
452        items = disco.DiscoItems.fromElement(element)
453
454        self.assertEqual(u'', items.nodeIdentifier)
455
456
457    def test_fromElementNode(self):
458        """
459        Test creating L{disco.DiscoItems} from L{domish.Element}, with node.
460        """
461        xml = """<query xmlns='http://jabber.org/protocol/disco#items'
462                        node='test'>
463                 </query>"""
464
465        element = parseXml(xml)
466        items = disco.DiscoItems.fromElement(element)
467
468        self.assertEqual(u'test', items.nodeIdentifier)
469
470
471
472class DiscoClientProtocolTest(unittest.TestCase):
473    """
474    Tests for L{disco.DiscoClientProtocol}.
475    """
476
477    def setUp(self):
478        """
479        Set up stub and protocol for testing.
480        """
481        self.stub = XmlStreamStub()
482        self.patch(XMPPHandler, 'request', self.request)
483        self.protocol = disco.DiscoClientProtocol()
484
485
486    def request(self, request):
487        element = request.toElement()
488        self.stub.xmlstream.send(element)
489        return defer.Deferred()
490
491
492    def test_requestItems(self):
493        """
494        Test request sent out by C{requestItems} and parsing of response.
495        """
496        def cb(items):
497            items = list(items)
498            self.assertEqual(2, len(items))
499            self.assertEqual(JID(u'test.example.org'), items[0].entity)
500
501        d = self.protocol.requestItems(JID(u'example.org'),u"foo")
502        d.addCallback(cb)
503
504        iq = self.stub.output[-1]
505        self.assertEqual(u'example.org', iq.getAttribute(u'to'))
506        self.assertEqual(u'get', iq.getAttribute(u'type'))
507        self.assertEqual(u'foo', iq.query.getAttribute(u'node'))
508        self.assertEqual(NS_DISCO_ITEMS, iq.query.uri)
509
510        response = toResponse(iq, u'result')
511        query = response.addElement((NS_DISCO_ITEMS, u'query'))
512
513        element = query.addElement(u'item')
514        element[u'jid'] = u'test.example.org'
515        element[u'node'] = u'music'
516        element[u'name'] = u'Music from the time of Shakespeare'
517
518        element = query.addElement(u'item')
519        element[u'jid'] = u"test2.example.org"
520
521        d.callback(response)
522        return d
523
524
525    def test_requestItemsFrom(self):
526        """
527        A disco items request can be sent with an explicit sender address.
528        """
529        d = self.protocol.requestItems(JID(u'example.org'),
530                                       sender=JID(u'test.example.org'))
531
532        iq = self.stub.output[-1]
533        self.assertEqual(u'test.example.org', iq.getAttribute(u'from'))
534
535        response = toResponse(iq, u'result')
536        response.addElement((NS_DISCO_ITEMS, u'query'))
537
538        d.callback(response)
539        return d
540
541
542    def test_requestInfo(self):
543        """
544        Test request sent out by C{requestInfo} and parsing of response.
545        """
546        def cb(info):
547            self.assertIn((u'conference', u'text'), info.identities)
548            self.assertIn(u'http://jabber.org/protocol/disco#info',
549                          info.features)
550            self.assertIn(u'http://jabber.org/protocol/muc',
551                          info.features)
552
553        d = self.protocol.requestInfo(JID(u'example.org'),'foo')
554        d.addCallback(cb)
555
556        iq = self.stub.output[-1]
557        self.assertEqual(u'example.org', iq.getAttribute(u'to'))
558        self.assertEqual(u'get', iq.getAttribute(u'type'))
559        self.assertEqual(u'foo', iq.query.getAttribute(u'node'))
560        self.assertEqual(NS_DISCO_INFO, iq.query.uri)
561
562        response = toResponse(iq, u'result')
563        query = response.addElement((NS_DISCO_INFO, u'query'))
564
565        element = query.addElement(u"identity")
566        element[u'category'] = u'conference' # required
567        element[u'type'] = u'text' # required
568        element[u"name"] = u'Romeo and Juliet, Act II, Scene II' # optional
569
570        element = query.addElement("feature")
571        element[u'var'] = u'http://jabber.org/protocol/disco#info' # required
572
573        element = query.addElement(u"feature")
574        element[u'var'] = u'http://jabber.org/protocol/muc'
575
576        d.callback(response)
577        return d
578
579
580    def test_requestInfoFrom(self):
581        """
582        A disco info request can be sent with an explicit sender address.
583        """
584        d = self.protocol.requestInfo(JID(u'example.org'),
585                                      sender=JID(u'test.example.org'))
586
587        iq = self.stub.output[-1]
588        self.assertEqual(u'test.example.org', iq.getAttribute(u'from'))
589
590        response = toResponse(iq, u'result')
591        response.addElement((NS_DISCO_INFO, u'query'))
592
593        d.callback(response)
594        return d
595
596
597
598class DiscoHandlerTest(unittest.TestCase, TestableRequestHandlerMixin):
599    """
600    Tests for L{disco.DiscoHandler}.
601    """
602
603    def setUp(self):
604        self.service = disco.DiscoHandler()
605
606
607    def test_connectionInitializedObserveInfo(self):
608        """
609        An observer for Disco Info requests is setup on stream initialization.
610        """
611        xml = """<iq from='test@example.com' to='example.com'
612                     type='get'>
613                   <query xmlns='%s'/>
614                 </iq>""" % NS_DISCO_INFO
615
616        def handleRequest(iq):
617            called.append(iq)
618
619        called = []
620        self.service.xmlstream = utility.EventDispatcher()
621        self.service.handleRequest = handleRequest
622        self.service.connectionInitialized()
623        self.service.xmlstream.dispatch(parseXml(xml))
624        self.assertEqual(1, len(called))
625
626
627    def test_connectionInitializedObserveItems(self):
628        """
629        An observer for Disco Items requests is setup on stream initialization.
630        """
631        xml = """<iq from='test@example.com' to='example.com'
632                     type='get'>
633                   <query xmlns='%s'/>
634                 </iq>""" % NS_DISCO_ITEMS
635
636        def handleRequest(iq):
637            called.append(iq)
638
639        called = []
640        self.service.xmlstream = utility.EventDispatcher()
641        self.service.handleRequest = handleRequest
642        self.service.connectionInitialized()
643        self.service.xmlstream.dispatch(parseXml(xml))
644        self.assertEqual(1, len(called))
645
646
647    def test_onDiscoInfo(self):
648        """
649        C{onDiscoInfo} should process an info request and return a response.
650
651        The request should be parsed, C{info} called with the extracted
652        parameters, and then the result should be formatted into a proper
653        response element.
654        """
655        xml = """<iq from='test@example.com' to='example.com'
656                     type='get'>
657                   <query xmlns='%s'/>
658                 </iq>""" % NS_DISCO_INFO
659
660        def cb(element):
661            self.assertEqual('query', element.name)
662            self.assertEqual(NS_DISCO_INFO, element.uri)
663            self.assertEqual(NS_DISCO_INFO, element.identity.uri)
664            self.assertEqual('dummy', element.identity['category'])
665            self.assertEqual('generic', element.identity['type'])
666            self.assertEqual('Generic Dummy Entity', element.identity['name'])
667            self.assertEqual(NS_DISCO_INFO, element.feature.uri)
668            self.assertEqual('jabber:iq:version', element.feature['var'])
669
670        def info(requestor, target, nodeIdentifier):
671            self.assertEqual(JID('test@example.com'), requestor)
672            self.assertEqual(JID('example.com'), target)
673            self.assertEqual('', nodeIdentifier)
674
675            return defer.succeed([
676                disco.DiscoIdentity('dummy', 'generic', 'Generic Dummy Entity'),
677                disco.DiscoFeature('jabber:iq:version')
678            ])
679
680        self.service.info = info
681        d = self.handleRequest(xml)
682        d.addCallback(cb)
683        return d
684
685
686    def test_onDiscoInfoWithNoFromAttribute(self):
687        """
688        Disco info request without a from attribute has requestor None.
689        """
690        xml = """<iq to='example.com'
691                     type='get'>
692                   <query xmlns='%s'/>
693                 </iq>""" % NS_DISCO_INFO
694
695        def info(requestor, target, nodeIdentifier):
696            self.assertEqual(None, requestor)
697
698            return defer.succeed([
699                disco.DiscoIdentity('dummy', 'generic', 'Generic Dummy Entity'),
700                disco.DiscoFeature('jabber:iq:version')
701            ])
702
703        self.service.info = info
704        d = self.handleRequest(xml)
705        return d
706
707
708    def test_onDiscoInfoWithNoToAttribute(self):
709        """
710        Disco info request without a to attribute has target None.
711        """
712        xml = """<iq from='test@example.com'
713                     type='get'>
714                   <query xmlns='%s'/>
715                 </iq>""" % NS_DISCO_INFO
716
717        def info(requestor, target, nodeIdentifier):
718            self.assertEqual(JID('test@example.com'), requestor)
719
720            return defer.succeed([
721                disco.DiscoIdentity('dummy', 'generic', 'Generic Dummy Entity'),
722                disco.DiscoFeature('jabber:iq:version')
723            ])
724
725        self.service.info = info
726        d = self.handleRequest(xml)
727        return d
728
729
730    def test_onDiscoInfoWithNode(self):
731        """
732        An info request for a node should return it in the response.
733        """
734        xml = """<iq from='test@example.com' to='example.com'
735                     type='get'>
736                   <query xmlns='%s' node='test'/>
737                 </iq>""" % NS_DISCO_INFO
738
739        def cb(element):
740            self.assertTrue(element.hasAttribute('node'))
741            self.assertEqual('test', element['node'])
742
743        def info(requestor, target, nodeIdentifier):
744            self.assertEqual('test', nodeIdentifier)
745
746            return defer.succeed([
747                disco.DiscoFeature('jabber:iq:version')
748            ])
749
750        self.service.info = info
751        d = self.handleRequest(xml)
752        d.addCallback(cb)
753        return d
754
755
756    def test_onDiscoInfoWithNodeNoResults(self):
757        """
758        An info request for a node with no results returns items-not-found.
759        """
760        xml = """<iq from='test@example.com' to='example.com'
761                     type='get'>
762                   <query xmlns='%s' node='test'/>
763                 </iq>""" % NS_DISCO_INFO
764
765        def cb(exc):
766            self.assertEquals('item-not-found', exc.condition)
767
768        def info(requestor, target, nodeIdentifier):
769            self.assertEqual('test', nodeIdentifier)
770
771            return defer.succeed([])
772
773        self.service.info = info
774        d = self.handleRequest(xml)
775        self.assertFailure(d, StanzaError)
776        d.addCallback(cb)
777        return d
778
779
780    def test_onDiscoItems(self):
781        """
782        C{onDiscoItems} should process an items request and return a response.
783
784        The request should be parsed, C{items} called with the extracted
785        parameters, and then the result should be formatted into a proper
786        response element.
787        """
788        xml = """<iq from='test@example.com' to='example.com'
789                     type='get'>
790                   <query xmlns='%s'/>
791                 </iq>""" % NS_DISCO_ITEMS
792
793        def cb(element):
794            self.assertEqual('query', element.name)
795            self.assertEqual(NS_DISCO_ITEMS, element.uri)
796            self.assertEqual(NS_DISCO_ITEMS, element.item.uri)
797            self.assertEqual('example.com', element.item['jid'])
798            self.assertEqual('test', element.item['node'])
799            self.assertEqual('Test node', element.item['name'])
800
801        def items(requestor, target, nodeIdentifier):
802            self.assertEqual(JID('test@example.com'), requestor)
803            self.assertEqual(JID('example.com'), target)
804            self.assertEqual('', nodeIdentifier)
805
806            return defer.succeed([
807                disco.DiscoItem(JID('example.com'), 'test', 'Test node'),
808            ])
809
810        self.service.items = items
811        d = self.handleRequest(xml)
812        d.addCallback(cb)
813        return d
814
815
816    def test_onDiscoItemsWithNode(self):
817        """
818        An items request for a node should return it in the response.
819        """
820        xml = """<iq from='test@example.com' to='example.com'
821                     type='get'>
822                   <query xmlns='%s' node='test'/>
823                 </iq>""" % NS_DISCO_ITEMS
824
825        def cb(element):
826            self.assertTrue(element.hasAttribute('node'))
827            self.assertEqual('test', element['node'])
828
829        def items(requestor, target, nodeIdentifier):
830            self.assertEqual('test', nodeIdentifier)
831
832            return defer.succeed([
833                disco.DiscoFeature('jabber:iq:version')
834            ])
835
836        self.service.items = items
837        d = self.handleRequest(xml)
838        d.addCallback(cb)
839        return d
840
841
842    def test_info(self):
843        """
844        C{info} should gather disco info from sibling handlers.
845        """
846        discoItems = [disco.DiscoIdentity('dummy', 'generic',
847                                          'Generic Dummy Entity'),
848                      disco.DiscoFeature('jabber:iq:version')
849        ]
850
851        @implementer(disco.IDisco)
852        class DiscoResponder(XMPPHandler):
853
854            def getDiscoInfo(self, requestor, target, nodeIdentifier):
855                if not nodeIdentifier:
856                    return defer.succeed(discoItems)
857                else:
858                    return defer.succeed([])
859
860        def cb(result):
861            self.assertEquals(discoItems, result)
862
863        self.service.parent = [self.service, DiscoResponder()]
864        d = self.service.info(JID('test@example.com'), JID('example.com'), '')
865        d.addCallback(cb)
866        return d
867
868
869    def test_infoNotDeferred(self):
870        """
871        C{info} should gather disco info from sibling handlers.
872        """
873        discoItems = [disco.DiscoIdentity('dummy', 'generic',
874                                          'Generic Dummy Entity'),
875                      disco.DiscoFeature('jabber:iq:version')
876        ]
877
878        @implementer(disco.IDisco)
879        class DiscoResponder(XMPPHandler):
880
881            def getDiscoInfo(self, requestor, target, nodeIdentifier):
882                if not nodeIdentifier:
883                    return discoItems
884                else:
885                    return []
886
887        def cb(result):
888            self.assertEquals(discoItems, result)
889
890        self.service.parent = [self.service, DiscoResponder()]
891        d = self.service.info(JID('test@example.com'), JID('example.com'), '')
892        d.addCallback(cb)
893        return d
894
895
896    def test_items(self):
897        """
898        C{info} should gather disco items from sibling handlers.
899        """
900        discoItems = [disco.DiscoItem(JID('example.com'), 'test', 'Test node')]
901
902        @implementer(disco.IDisco)
903        class DiscoResponder(XMPPHandler):
904
905            def getDiscoItems(self, requestor, target, nodeIdentifier):
906                if not nodeIdentifier:
907                    return defer.succeed(discoItems)
908                else:
909                    return defer.succeed([])
910
911        def cb(result):
912            self.assertEquals(discoItems, result)
913
914        self.service.parent = [self.service, DiscoResponder()]
915        d = self.service.items(JID('test@example.com'), JID('example.com'), '')
916        d.addCallback(cb)
917        return d
918
919
920    def test_itemsNotDeferred(self):
921        """
922        C{info} should also collect results not returned via a deferred.
923        """
924        discoItems = [disco.DiscoItem(JID('example.com'), 'test', 'Test node')]
925
926        @implementer(disco.IDisco)
927        class DiscoResponder(XMPPHandler):
928
929            def getDiscoItems(self, requestor, target, nodeIdentifier):
930                if not nodeIdentifier:
931                    return discoItems
932                else:
933                    return []
934
935        def cb(result):
936            self.assertEquals(discoItems, result)
937
938        self.service.parent = [self.service, DiscoResponder()]
939        d = self.service.items(JID('test@example.com'), JID('example.com'), '')
940        d.addCallback(cb)
941        return d
Note: See TracBrowser for help on using the repository browser.