[34] | 1 | diff -r 7740d56a1644 wokkel/disco.py |
---|
| 2 | --- a/wokkel/disco.py Mon Jan 18 09:16:50 2010 +0100 |
---|
| 3 | +++ b/wokkel/disco.py Thu Jan 21 11:39:08 2010 +0100 |
---|
| 4 | @@ -495,10 +495,7 @@ |
---|
| 5 | """ |
---|
| 6 | Gather results from a list of deferreds. |
---|
| 7 | |
---|
| 8 | - Similar to L{defer.gatherResults}, but flattens the returned results, |
---|
| 9 | - consumes errors after the first one and fires the errback of the |
---|
| 10 | - returned deferred with the failure of the first deferred that fires its |
---|
| 11 | - errback. |
---|
| 12 | + Similar to L{defer.gatherResults}, but flattens the returned results. |
---|
| 13 | |
---|
| 14 | @param deferredList: List of deferreds for which the results should be |
---|
| 15 | gathered. |
---|
| 16 | @@ -512,13 +509,9 @@ |
---|
| 17 | results.extend(value) |
---|
| 18 | return results |
---|
| 19 | |
---|
| 20 | - def eb(failure): |
---|
| 21 | - failure.trap(defer.FirstError) |
---|
| 22 | - return failure.value.subFailure |
---|
| 23 | - |
---|
| 24 | d = defer.DeferredList(deferredList, fireOnOneErrback=1, |
---|
| 25 | consumeErrors=1) |
---|
| 26 | - d.addCallbacks(cb, eb) |
---|
| 27 | + d.addCallback(cb) |
---|
| 28 | return d |
---|
| 29 | |
---|
| 30 | |
---|
| 31 | diff -r 7740d56a1644 wokkel/pubsub.py |
---|
| 32 | --- a/wokkel/pubsub.py Mon Jan 18 09:16:50 2010 +0100 |
---|
| 33 | +++ b/wokkel/pubsub.py Thu Jan 21 11:39:08 2010 +0100 |
---|
| 34 | @@ -1011,7 +1011,7 @@ |
---|
| 35 | @type pubSubFeatures: C{list} or C{None} |
---|
| 36 | """ |
---|
| 37 | |
---|
| 38 | - implements(IPubSubService) |
---|
| 39 | + implements(IPubSubService, disco.IDisco) |
---|
| 40 | |
---|
| 41 | iqHandlers = { |
---|
| 42 | '/*': '_onPubSubRequest', |
---|
| 43 | @@ -1057,10 +1057,10 @@ |
---|
| 44 | self.xmlstream.addObserver(PUBSUB_REQUEST, self.handleRequest) |
---|
| 45 | |
---|
| 46 | |
---|
| 47 | - def getDiscoInfo(self, requestor, target, nodeIdentifier): |
---|
| 48 | - def toInfo(nodeInfo, info): |
---|
| 49 | + def getDiscoInfo(self, requestor, target, nodeIdentifier=''): |
---|
| 50 | + def toInfo(nodeInfo): |
---|
| 51 | if not nodeInfo: |
---|
| 52 | - return info |
---|
| 53 | + return |
---|
| 54 | |
---|
| 55 | (nodeType, metaData) = nodeInfo['type'], nodeInfo['meta-data'] |
---|
| 56 | info.append(disco.DiscoIdentity('pubsub', nodeType)) |
---|
| 57 | @@ -1080,7 +1080,7 @@ |
---|
| 58 | |
---|
| 59 | info.append(form) |
---|
| 60 | |
---|
| 61 | - return info |
---|
| 62 | + return |
---|
| 63 | |
---|
| 64 | info = [] |
---|
| 65 | |
---|
| 66 | @@ -1106,12 +1106,13 @@ |
---|
| 67 | for feature in features]) |
---|
| 68 | |
---|
| 69 | d = defer.maybeDeferred(getInfo, requestor, target, nodeIdentifier or '') |
---|
| 70 | - d.addCallback(toInfo, info) |
---|
| 71 | + d.addCallback(toInfo) |
---|
| 72 | d.addErrback(log.err) |
---|
| 73 | + d.addCallback(lambda _: info) |
---|
| 74 | return d |
---|
| 75 | |
---|
| 76 | |
---|
| 77 | - def getDiscoItems(self, requestor, target, nodeIdentifier): |
---|
| 78 | + def getDiscoItems(self, requestor, target, nodeIdentifier=''): |
---|
| 79 | if self.hideNodes: |
---|
| 80 | d = defer.succeed([]) |
---|
| 81 | elif self.resource is not None: |
---|
| 82 | diff -r 7740d56a1644 wokkel/test/test_disco.py |
---|
| 83 | --- a/wokkel/test/test_disco.py Mon Jan 18 09:16:50 2010 +0100 |
---|
| 84 | +++ b/wokkel/test/test_disco.py Thu Jan 21 11:39:08 2010 +0100 |
---|
| 85 | @@ -9,9 +9,10 @@ |
---|
| 86 | |
---|
| 87 | from twisted.internet import defer |
---|
| 88 | from twisted.trial import unittest |
---|
| 89 | +from twisted.words.protocols.jabber.error import StanzaError |
---|
| 90 | from twisted.words.protocols.jabber.jid import JID |
---|
| 91 | from twisted.words.protocols.jabber.xmlstream import toResponse |
---|
| 92 | -from twisted.words.xish import domish |
---|
| 93 | +from twisted.words.xish import domish, utility |
---|
| 94 | |
---|
| 95 | from wokkel import data_form, disco |
---|
| 96 | from wokkel.generic import parseXml |
---|
| 97 | @@ -596,6 +597,46 @@ |
---|
| 98 | self.service = disco.DiscoHandler() |
---|
| 99 | |
---|
| 100 | |
---|
| 101 | + def test_connectionInitializedObserveInfo(self): |
---|
| 102 | + """ |
---|
| 103 | + An observer for Disco Info requests is setup on stream initialization. |
---|
| 104 | + """ |
---|
| 105 | + xml = """<iq from='test@example.com' to='example.com' |
---|
| 106 | + type='get'> |
---|
| 107 | + <query xmlns='%s'/> |
---|
| 108 | + </iq>""" % NS_DISCO_INFO |
---|
| 109 | + |
---|
| 110 | + def handleRequest(iq): |
---|
| 111 | + called.append(iq) |
---|
| 112 | + |
---|
| 113 | + called = [] |
---|
| 114 | + self.service.xmlstream = utility.EventDispatcher() |
---|
| 115 | + self.service.handleRequest = handleRequest |
---|
| 116 | + self.service.connectionInitialized() |
---|
| 117 | + self.service.xmlstream.dispatch(parseXml(xml)) |
---|
| 118 | + self.assertEqual(1, len(called)) |
---|
| 119 | + |
---|
| 120 | + |
---|
| 121 | + def test_connectionInitializedObserveItems(self): |
---|
| 122 | + """ |
---|
| 123 | + An observer for Disco Items requests is setup on stream initialization. |
---|
| 124 | + """ |
---|
| 125 | + xml = """<iq from='test@example.com' to='example.com' |
---|
| 126 | + type='get'> |
---|
| 127 | + <query xmlns='%s'/> |
---|
| 128 | + </iq>""" % NS_DISCO_ITEMS |
---|
| 129 | + |
---|
| 130 | + def handleRequest(iq): |
---|
| 131 | + called.append(iq) |
---|
| 132 | + |
---|
| 133 | + called = [] |
---|
| 134 | + self.service.xmlstream = utility.EventDispatcher() |
---|
| 135 | + self.service.handleRequest = handleRequest |
---|
| 136 | + self.service.connectionInitialized() |
---|
| 137 | + self.service.xmlstream.dispatch(parseXml(xml)) |
---|
| 138 | + self.assertEqual(1, len(called)) |
---|
| 139 | + |
---|
| 140 | + |
---|
| 141 | def test_onDiscoInfo(self): |
---|
| 142 | """ |
---|
| 143 | C{onDiscoInfo} should process an info request and return a response. |
---|
| 144 | @@ -661,6 +702,30 @@ |
---|
| 145 | return d |
---|
| 146 | |
---|
| 147 | |
---|
| 148 | + def test_onDiscoInfoWithNodeNoResults(self): |
---|
| 149 | + """ |
---|
| 150 | + An info request for a node with no results returns items-not-found. |
---|
| 151 | + """ |
---|
| 152 | + xml = """<iq from='test@example.com' to='example.com' |
---|
| 153 | + type='get'> |
---|
| 154 | + <query xmlns='%s' node='test'/> |
---|
| 155 | + </iq>""" % NS_DISCO_INFO |
---|
| 156 | + |
---|
| 157 | + def cb(exc): |
---|
| 158 | + self.assertEquals('item-not-found', exc.condition) |
---|
| 159 | + |
---|
| 160 | + def info(requestor, target, nodeIdentifier): |
---|
| 161 | + self.assertEqual('test', nodeIdentifier) |
---|
| 162 | + |
---|
| 163 | + return defer.succeed([]) |
---|
| 164 | + |
---|
| 165 | + self.service.info = info |
---|
| 166 | + d = self.handleRequest(xml) |
---|
| 167 | + self.assertFailure(d, StanzaError) |
---|
| 168 | + d.addCallback(cb) |
---|
| 169 | + return d |
---|
| 170 | + |
---|
| 171 | + |
---|
| 172 | def test_onDiscoItems(self): |
---|
| 173 | """ |
---|
| 174 | C{onDiscoItems} should process an items request and return a response. |
---|
| 175 | diff -r 7740d56a1644 wokkel/test/test_pubsub.py |
---|
| 176 | --- a/wokkel/test/test_pubsub.py Mon Jan 18 09:16:50 2010 +0100 |
---|
| 177 | +++ b/wokkel/test/test_pubsub.py Thu Jan 21 11:39:08 2010 +0100 |
---|
| 178 | @@ -1903,6 +1903,13 @@ |
---|
| 179 | verify.verifyObject(iwokkel.IPubSubService, self.service) |
---|
| 180 | |
---|
| 181 | |
---|
| 182 | + def test_interfaceIDisco(self): |
---|
| 183 | + """ |
---|
| 184 | + Do instances of L{pubsub.PubSubService} provide L{iwokkel.IDisco}? |
---|
| 185 | + """ |
---|
| 186 | + verify.verifyObject(iwokkel.IDisco, self.service) |
---|
| 187 | + |
---|
| 188 | + |
---|
| 189 | def test_connectionMade(self): |
---|
| 190 | """ |
---|
| 191 | Verify setup of observers in L{pubsub.connectionMade}. |
---|
| 192 | @@ -2009,6 +2016,42 @@ |
---|
| 193 | return d |
---|
| 194 | |
---|
| 195 | |
---|
| 196 | + def test_getDiscoInfoBadResponse(self): |
---|
| 197 | + """ |
---|
| 198 | + If getInfo returns invalid response, it should be logged, then ignored. |
---|
| 199 | + """ |
---|
| 200 | + def cb(info): |
---|
| 201 | + self.assertEquals([], info) |
---|
| 202 | + self.assertEqual(1, len(self.flushLoggedErrors(TypeError))) |
---|
| 203 | + |
---|
| 204 | + def getInfo(requestor, target, nodeIdentifier): |
---|
| 205 | + return defer.succeed('bad response') |
---|
| 206 | + |
---|
| 207 | + self.resource.getInfo = getInfo |
---|
| 208 | + d = self.service.getDiscoInfo(JID('user@example.org/home'), |
---|
| 209 | + JID('pubsub.example.org'), 'test') |
---|
| 210 | + d.addCallback(cb) |
---|
| 211 | + return d |
---|
| 212 | + |
---|
| 213 | + |
---|
| 214 | + def test_getDiscoInfoException(self): |
---|
| 215 | + """ |
---|
| 216 | + If getInfo returns invalid response, it should be logged, then ignored. |
---|
| 217 | + """ |
---|
| 218 | + def cb(info): |
---|
| 219 | + self.assertEquals([], info) |
---|
| 220 | + self.assertEqual(1, len(self.flushLoggedErrors(NotImplementedError))) |
---|
| 221 | + |
---|
| 222 | + def getInfo(requestor, target, nodeIdentifier): |
---|
| 223 | + return defer.fail(NotImplementedError()) |
---|
| 224 | + |
---|
| 225 | + self.resource.getInfo = getInfo |
---|
| 226 | + d = self.service.getDiscoInfo(JID('user@example.org/home'), |
---|
| 227 | + JID('pubsub.example.org'), 'test') |
---|
| 228 | + d.addCallback(cb) |
---|
| 229 | + return d |
---|
| 230 | + |
---|
| 231 | + |
---|
| 232 | def test_getDiscoItemsRoot(self): |
---|
| 233 | """ |
---|
| 234 | Test getDiscoItems on the root node. |
---|