source: wokkel/test/test_disco.py @ 103:e17a30fe7144

Last change on this file since 103:e17a30fe7144 was 103:e17a30fe7144, checked in by Ralph Meijer <ralphm@…>, 9 years ago

Reimplement _DiscoRequest as generic.Request.

Author: ralphm, Goffi.
Fixes: #73.

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