diff --git a/wokkel/compat.py b/wokkel/compat.py index 69d34d8..58d1b27 100644 --- a/wokkel/compat.py +++ b/wokkel/compat.py @@ -1,11 +1,10 @@ # -*- test-case-name: wokkel.test.test_compat -*- # -# Copyright (c) 2001-2008 Twisted Matrix Laboratories. +# Copyright (c) 2001-2009 Twisted Matrix Laboratories. # See LICENSE for details. from twisted.internet import protocol from twisted.words.protocols.jabber import xmlstream -from twisted.words.xish import domish class BootstrapMixin(object): """ @@ -94,3 +93,25 @@ def buildProtocol(self, addr): xs.factory = self self.installBootstraps(xs) return xs + + + +class IQ(xmlstream.IQ): + def __init__(self, *args, **kwargs): + # Make sure we have a reactor parameter + try: + reactor = kwargs['reactor'] + except KeyError: + from twisted.internet import reactor + kwargs['reactor'] = reactor + + # Check if IQ's init accepts the reactor parameter + try: + xmlstream.IQ.__init__(self, *args, **kwargs) + except TypeError: + # Guess not. Remove the reactor parameter and try again. + del kwargs['reactor'] + xmlstream.IQ.__init__(self, *args, **kwargs) + + # Patch the XmlStream instance so that it has a _callLater + self._xmlstream._callLater = reactor.callLater diff --git a/wokkel/disco.py b/wokkel/disco.py index 6e7b358..14b9437 100644 --- a/wokkel/disco.py +++ b/wokkel/disco.py @@ -11,10 +11,11 @@ """ from twisted.internet import defer -from twisted.words.protocols.jabber import error, jid, xmlstream +from twisted.words.protocols.jabber import error, jid from twisted.words.xish import domish from wokkel import data_form +from wokkel.compat import IQ from wokkel.iwokkel import IDisco from wokkel.subprotocols import IQHandlerMixin, XMPPHandler @@ -345,7 +346,7 @@ def fromElement(element): -class _DiscoRequest(xmlstream.IQ): +class _DiscoRequest(IQ): """ Element representing an XMPP service discovery request. """ @@ -361,7 +362,7 @@ def __init__(self, xs, namespace, nodeIdentifier=''): @param nodeIdentifier: Node to request info from. @type nodeIdentifier: C{unicode} """ - xmlstream.IQ.__init__(self, xs, "get") + IQ.__init__(self, xs, "get") query = self.addElement((namespace, 'query')) if nodeIdentifier: query['node'] = nodeIdentifier diff --git a/wokkel/pubsub.py b/wokkel/pubsub.py index 32e945f..5651be2 100644 --- a/wokkel/pubsub.py +++ b/wokkel/pubsub.py @@ -1,6 +1,6 @@ # -*- test-case-name: wokkel.test.test_pubsub -*- # -# Copyright (c) 2003-2008 Ralph Meijer +# Copyright (c) 2003-2009 Ralph Meijer # See LICENSE for details. """ @@ -14,10 +14,11 @@ from twisted.internet import defer from twisted.python import log -from twisted.words.protocols.jabber import jid, error, xmlstream +from twisted.words.protocols.jabber import jid, error from twisted.words.xish import domish from wokkel import disco, data_form, generic, shim +from wokkel.compat import IQ from wokkel.subprotocols import IQHandlerMixin, XMPPHandler from wokkel.iwokkel import IPubSubClient, IPubSubService, IPubSubResource @@ -475,9 +476,9 @@ def send(self, xs): Send this request to its recipient. This renders all of the relevant parameters for this specific - requests into an L{xmlstream.IQ}, and invoke its C{send} method. + requests into an L{IQ}, and invoke its C{send} method. This returns a deferred that fires upon reception of a response. See - L{xmlstream.IQ} for details. + L{IQ} for details. @param xs: The XML stream to send the request on. @type xs: L{xmlstream.XmlStream} @@ -491,7 +492,7 @@ def send(self, xs): except KeyError: raise NotImplementedError() - iq = xmlstream.IQ(xs, self.stanzaType) + iq = IQ(xs, self.stanzaType) iq.addElement((childURI, 'pubsub')) verbElement = iq.pubsub.addElement(childName) diff --git a/wokkel/test/test_compat.py b/wokkel/test/test_compat.py index 38835df..510f2b6 100644 --- a/wokkel/test/test_compat.py +++ b/wokkel/test/test_compat.py @@ -6,13 +6,14 @@ Tests for L{wokkel.compat}. """ +from zope.interface import implements from zope.interface.verify import verifyObject -from twisted.internet import defer, protocol -from twisted.internet.interfaces import IProtocolFactory +from twisted.internet import protocol, task +from twisted.internet.interfaces import IProtocolFactory, IReactorTime from twisted.trial import unittest -from twisted.words.xish import domish, utility +from twisted.words.xish import utility from twisted.words.protocols.jabber import xmlstream -from wokkel.compat import BootstrapMixin, XmlStreamServerFactory +from wokkel.compat import BootstrapMixin, IQ, XmlStreamServerFactory class DummyProtocol(protocol.Protocol, utility.EventDispatcher): """ @@ -165,3 +166,44 @@ def test_buildProtocolStoresFactory(self): """ xs = self.factory.buildProtocol(None) self.assertIdentical(self.factory, xs.factory) + + + +class FakeReactor(object): + + implements(IReactorTime) + def __init__(self): + self.clock = task.Clock() + self.callLater = self.clock.callLater + self.getDelayedCalls = self.clock.getDelayedCalls + + + +class IQTest(unittest.TestCase): + """ + Tests for L{IQ}. + """ + + def setUp(self): + self.reactor = FakeReactor() + self.clock = self.reactor.clock + + + def testRequestTimingOutEventDispatcher(self): + """ + Test that an iq request with a defined timeout times out. + """ + from twisted.words.xish import utility + output = [] + xs = utility.EventDispatcher() + xs.send = output.append + + self.iq = IQ(xs, reactor=self.reactor) + self.iq.timeout = 60 + d = self.iq.send() + self.assertFailure(d, xmlstream.TimeoutError) + + self.clock.pump([1, 60]) + self.assertFalse(self.reactor.getDelayedCalls()) + self.assertFalse(xs.iqDeferreds) + return d diff --git a/wokkel/test/test_disco.py b/wokkel/test/test_disco.py index 26eb2f9..35e9156 100644 --- a/wokkel/test/test_disco.py +++ b/wokkel/test/test_disco.py @@ -525,7 +525,7 @@ def test_requestItemsFrom(self): self.assertEqual(u'test.example.org', iq.getAttribute(u'from')) response = toResponse(iq, u'result') - query = response.addElement((NS_DISCO_ITEMS, u'query')) + response.addElement((NS_DISCO_ITEMS, u'query')) self.stub.send(response) return d @@ -581,7 +581,7 @@ def test_requestInfoFrom(self): self.assertEqual(u'test.example.org', iq.getAttribute(u'from')) response = toResponse(iq, u'result') - query = response.addElement((NS_DISCO_INFO, u'query')) + response.addElement((NS_DISCO_INFO, u'query')) self.stub.send(response) return d diff --git a/wokkel/xmppim.py b/wokkel/xmppim.py index a50369c..3cf8071 100644 --- a/wokkel/xmppim.py +++ b/wokkel/xmppim.py @@ -13,9 +13,9 @@ """ from twisted.words.protocols.jabber.jid import JID -from twisted.words.protocols.jabber.xmlstream import IQ from twisted.words.xish import domish +from wokkel.compat import IQ from wokkel.subprotocols import XMPPHandler NS_XML = 'http://www.w3.org/XML/1998/namespace'