1438
|
1 # Copyright (c) Ralph Meijer. |
|
2 # See LICENSE for details. |
|
3 |
|
4 """ |
|
5 Tests for L{wokkel.pubsub} |
|
6 """ |
|
7 |
|
8 from zope.interface import verify |
|
9 |
|
10 from twisted.trial import unittest |
|
11 from twisted.internet import defer |
|
12 from twisted.words.xish import domish |
|
13 from twisted.words.protocols.jabber import error |
|
14 from twisted.words.protocols.jabber.jid import JID |
|
15 from twisted.words.protocols.jabber.xmlstream import toResponse |
|
16 |
|
17 from wokkel import data_form, disco, iwokkel, shim |
|
18 from wokkel.generic import parseXml |
|
19 from wokkel.test.helpers import TestableRequestHandlerMixin, XmlStreamStub |
|
20 |
|
21 from sat.tmp.wokkel import pubsub |
|
22 |
|
23 NS_PUBSUB = 'http://jabber.org/protocol/pubsub' |
|
24 NS_PUBSUB_NODE_CONFIG = 'http://jabber.org/protocol/pubsub#node_config' |
|
25 NS_PUBSUB_ERRORS = 'http://jabber.org/protocol/pubsub#errors' |
|
26 NS_PUBSUB_EVENT = 'http://jabber.org/protocol/pubsub#event' |
|
27 NS_PUBSUB_OWNER = 'http://jabber.org/protocol/pubsub#owner' |
|
28 NS_PUBSUB_META_DATA = 'http://jabber.org/protocol/pubsub#meta-data' |
|
29 NS_PUBSUB_SUBSCRIBE_OPTIONS = 'http://jabber.org/protocol/pubsub#subscribe_options' |
|
30 |
|
31 def calledAsync(fn): |
|
32 """ |
|
33 Function wrapper that fires a deferred upon calling the given function. |
|
34 """ |
|
35 d = defer.Deferred() |
|
36 |
|
37 def func(*args, **kwargs): |
|
38 try: |
|
39 result = fn(*args, **kwargs) |
|
40 except: |
|
41 d.errback() |
|
42 else: |
|
43 d.callback(result) |
|
44 |
|
45 return d, func |
|
46 |
|
47 |
|
48 class SubscriptionTest(unittest.TestCase): |
|
49 """ |
|
50 Tests for L{pubsub.Subscription}. |
|
51 """ |
|
52 |
|
53 def test_fromElement(self): |
|
54 """ |
|
55 fromElement parses a subscription from XML DOM. |
|
56 """ |
|
57 xml = """ |
|
58 <subscription node='test' jid='user@example.org/Home' |
|
59 subscription='pending'/> |
|
60 """ |
|
61 subscription = pubsub.Subscription.fromElement(parseXml(xml)) |
|
62 self.assertEqual('test', subscription.nodeIdentifier) |
|
63 self.assertEqual(JID('user@example.org/Home'), subscription.subscriber) |
|
64 self.assertEqual('pending', subscription.state) |
|
65 self.assertIdentical(None, subscription.subscriptionIdentifier) |
|
66 |
|
67 |
|
68 def test_fromElementWithSubscriptionIdentifier(self): |
|
69 """ |
|
70 A subscription identifier in the subscription should be parsed, too. |
|
71 """ |
|
72 xml = """ |
|
73 <subscription node='test' jid='user@example.org/Home' subid='1234' |
|
74 subscription='pending'/> |
|
75 """ |
|
76 subscription = pubsub.Subscription.fromElement(parseXml(xml)) |
|
77 self.assertEqual('1234', subscription.subscriptionIdentifier) |
|
78 |
|
79 |
|
80 def test_toElement(self): |
|
81 """ |
|
82 Rendering a Subscription should yield the proper attributes. |
|
83 """ |
|
84 subscription = pubsub.Subscription('test', |
|
85 JID('user@example.org/Home'), |
|
86 'pending') |
|
87 element = subscription.toElement() |
|
88 self.assertEqual('subscription', element.name) |
|
89 self.assertEqual(None, element.uri) |
|
90 self.assertEqual('test', element.getAttribute('node')) |
|
91 self.assertEqual('user@example.org/Home', element.getAttribute('jid')) |
|
92 self.assertEqual('pending', element.getAttribute('subscription')) |
|
93 self.assertFalse(element.hasAttribute('subid')) |
|
94 |
|
95 |
|
96 def test_toElementEmptyNodeIdentifier(self): |
|
97 """ |
|
98 The empty node identifier should not yield a node attribute. |
|
99 """ |
|
100 subscription = pubsub.Subscription('', |
|
101 JID('user@example.org/Home'), |
|
102 'pending') |
|
103 element = subscription.toElement() |
|
104 self.assertFalse(element.hasAttribute('node')) |
|
105 |
|
106 |
|
107 def test_toElementWithSubscriptionIdentifier(self): |
|
108 """ |
|
109 The subscription identifier, if set, is in the subid attribute. |
|
110 """ |
|
111 subscription = pubsub.Subscription('test', |
|
112 JID('user@example.org/Home'), |
|
113 'pending', |
|
114 subscriptionIdentifier='1234') |
|
115 element = subscription.toElement() |
|
116 self.assertEqual('1234', element.getAttribute('subid')) |
|
117 |
|
118 |
|
119 |
|
120 class PubSubClientTest(unittest.TestCase): |
|
121 timeout = 2 |
|
122 |
|
123 def setUp(self): |
|
124 self.stub = XmlStreamStub() |
|
125 self.protocol = pubsub.PubSubClient() |
|
126 self.protocol.xmlstream = self.stub.xmlstream |
|
127 self.protocol.connectionInitialized() |
|
128 |
|
129 |
|
130 def test_interface(self): |
|
131 """ |
|
132 Do instances of L{pubsub.PubSubClient} provide L{iwokkel.IPubSubClient}? |
|
133 """ |
|
134 verify.verifyObject(iwokkel.IPubSubClient, self.protocol) |
|
135 |
|
136 |
|
137 def test_eventItems(self): |
|
138 """ |
|
139 Test receiving an items event resulting in a call to itemsReceived. |
|
140 """ |
|
141 message = domish.Element((None, 'message')) |
|
142 message['from'] = 'pubsub.example.org' |
|
143 message['to'] = 'user@example.org/home' |
|
144 event = message.addElement((NS_PUBSUB_EVENT, 'event')) |
|
145 items = event.addElement('items') |
|
146 items['node'] = 'test' |
|
147 item1 = items.addElement('item') |
|
148 item1['id'] = 'item1' |
|
149 item2 = items.addElement('retract') |
|
150 item2['id'] = 'item2' |
|
151 item3 = items.addElement('item') |
|
152 item3['id'] = 'item3' |
|
153 |
|
154 def itemsReceived(event): |
|
155 self.assertEquals(JID('user@example.org/home'), event.recipient) |
|
156 self.assertEquals(JID('pubsub.example.org'), event.sender) |
|
157 self.assertEquals('test', event.nodeIdentifier) |
|
158 self.assertEquals([item1, item2, item3], event.items) |
|
159 |
|
160 d, self.protocol.itemsReceived = calledAsync(itemsReceived) |
|
161 self.stub.send(message) |
|
162 return d |
|
163 |
|
164 |
|
165 def test_eventItemsCollection(self): |
|
166 """ |
|
167 Test receiving an items event resulting in a call to itemsReceived. |
|
168 """ |
|
169 message = domish.Element((None, 'message')) |
|
170 message['from'] = 'pubsub.example.org' |
|
171 message['to'] = 'user@example.org/home' |
|
172 event = message.addElement((NS_PUBSUB_EVENT, 'event')) |
|
173 items = event.addElement('items') |
|
174 items['node'] = 'test' |
|
175 |
|
176 headers = shim.Headers([('Collection', 'collection')]) |
|
177 message.addChild(headers) |
|
178 |
|
179 def itemsReceived(event): |
|
180 self.assertEquals(JID('user@example.org/home'), event.recipient) |
|
181 self.assertEquals(JID('pubsub.example.org'), event.sender) |
|
182 self.assertEquals('test', event.nodeIdentifier) |
|
183 self.assertEquals({'Collection': ['collection']}, event.headers) |
|
184 |
|
185 d, self.protocol.itemsReceived = calledAsync(itemsReceived) |
|
186 self.stub.send(message) |
|
187 return d |
|
188 |
|
189 |
|
190 def test_eventItemsError(self): |
|
191 """ |
|
192 An error message with embedded event should not be handled. |
|
193 |
|
194 This test uses an items event, which should not result in itemsReceived |
|
195 being called. In general message.handled should be False. |
|
196 """ |
|
197 message = domish.Element((None, 'message')) |
|
198 message['from'] = 'pubsub.example.org' |
|
199 message['to'] = 'user@example.org/home' |
|
200 message['type'] = 'error' |
|
201 event = message.addElement((NS_PUBSUB_EVENT, 'event')) |
|
202 items = event.addElement('items') |
|
203 items['node'] = 'test' |
|
204 |
|
205 class UnexpectedCall(Exception): |
|
206 pass |
|
207 |
|
208 def itemsReceived(event): |
|
209 raise UnexpectedCall("Unexpected call to itemsReceived") |
|
210 |
|
211 self.protocol.itemsReceived = itemsReceived |
|
212 self.stub.send(message) |
|
213 self.assertFalse(message.handled) |
|
214 |
|
215 |
|
216 def test_eventDelete(self): |
|
217 """ |
|
218 Test receiving a delete event resulting in a call to deleteReceived. |
|
219 """ |
|
220 message = domish.Element((None, 'message')) |
|
221 message['from'] = 'pubsub.example.org' |
|
222 message['to'] = 'user@example.org/home' |
|
223 event = message.addElement((NS_PUBSUB_EVENT, 'event')) |
|
224 delete = event.addElement('delete') |
|
225 delete['node'] = 'test' |
|
226 |
|
227 def deleteReceived(event): |
|
228 self.assertEquals(JID('user@example.org/home'), event.recipient) |
|
229 self.assertEquals(JID('pubsub.example.org'), event.sender) |
|
230 self.assertEquals('test', event.nodeIdentifier) |
|
231 |
|
232 d, self.protocol.deleteReceived = calledAsync(deleteReceived) |
|
233 self.stub.send(message) |
|
234 return d |
|
235 |
|
236 |
|
237 def test_eventDeleteRedirect(self): |
|
238 """ |
|
239 Test receiving a delete event with a redirect URI. |
|
240 """ |
|
241 message = domish.Element((None, 'message')) |
|
242 message['from'] = 'pubsub.example.org' |
|
243 message['to'] = 'user@example.org/home' |
|
244 event = message.addElement((NS_PUBSUB_EVENT, 'event')) |
|
245 delete = event.addElement('delete') |
|
246 delete['node'] = 'test' |
|
247 uri = 'xmpp:pubsub.example.org?;node=test2' |
|
248 delete.addElement('redirect')['uri'] = uri |
|
249 |
|
250 def deleteReceived(event): |
|
251 self.assertEquals(JID('user@example.org/home'), event.recipient) |
|
252 self.assertEquals(JID('pubsub.example.org'), event.sender) |
|
253 self.assertEquals('test', event.nodeIdentifier) |
|
254 self.assertEquals(uri, event.redirectURI) |
|
255 |
|
256 d, self.protocol.deleteReceived = calledAsync(deleteReceived) |
|
257 self.stub.send(message) |
|
258 return d |
|
259 |
|
260 |
|
261 def test_event_purge(self): |
|
262 """ |
|
263 Test receiving a purge event resulting in a call to purgeReceived. |
|
264 """ |
|
265 message = domish.Element((None, 'message')) |
|
266 message['from'] = 'pubsub.example.org' |
|
267 message['to'] = 'user@example.org/home' |
|
268 event = message.addElement((NS_PUBSUB_EVENT, 'event')) |
|
269 items = event.addElement('purge') |
|
270 items['node'] = 'test' |
|
271 |
|
272 def purgeReceived(event): |
|
273 self.assertEquals(JID('user@example.org/home'), event.recipient) |
|
274 self.assertEquals(JID('pubsub.example.org'), event.sender) |
|
275 self.assertEquals('test', event.nodeIdentifier) |
|
276 |
|
277 d, self.protocol.purgeReceived = calledAsync(purgeReceived) |
|
278 self.stub.send(message) |
|
279 return d |
|
280 |
|
281 |
|
282 def test_createNode(self): |
|
283 """ |
|
284 Test sending create request. |
|
285 """ |
|
286 |
|
287 def cb(nodeIdentifier): |
|
288 self.assertEquals('test', nodeIdentifier) |
|
289 |
|
290 d = self.protocol.createNode(JID('pubsub.example.org'), 'test') |
|
291 d.addCallback(cb) |
|
292 |
|
293 iq = self.stub.output[-1] |
|
294 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
295 self.assertEquals('set', iq.getAttribute('type')) |
|
296 self.assertEquals('pubsub', iq.pubsub.name) |
|
297 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
298 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
299 'create', NS_PUBSUB)) |
|
300 self.assertEquals(1, len(children)) |
|
301 child = children[0] |
|
302 self.assertEquals('test', child['node']) |
|
303 |
|
304 response = toResponse(iq, 'result') |
|
305 self.stub.send(response) |
|
306 return d |
|
307 |
|
308 |
|
309 def test_createNodeInstant(self): |
|
310 """ |
|
311 Test sending create request resulting in an instant node. |
|
312 """ |
|
313 |
|
314 def cb(nodeIdentifier): |
|
315 self.assertEquals('test', nodeIdentifier) |
|
316 |
|
317 d = self.protocol.createNode(JID('pubsub.example.org')) |
|
318 d.addCallback(cb) |
|
319 |
|
320 iq = self.stub.output[-1] |
|
321 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
322 'create', NS_PUBSUB)) |
|
323 child = children[0] |
|
324 self.assertFalse(child.hasAttribute('node')) |
|
325 |
|
326 response = toResponse(iq, 'result') |
|
327 command = response.addElement((NS_PUBSUB, 'pubsub')) |
|
328 create = command.addElement('create') |
|
329 create['node'] = 'test' |
|
330 self.stub.send(response) |
|
331 return d |
|
332 |
|
333 |
|
334 def test_createNodeRenamed(self): |
|
335 """ |
|
336 Test sending create request resulting in renamed node. |
|
337 """ |
|
338 |
|
339 def cb(nodeIdentifier): |
|
340 self.assertEquals('test2', nodeIdentifier) |
|
341 |
|
342 d = self.protocol.createNode(JID('pubsub.example.org'), 'test') |
|
343 d.addCallback(cb) |
|
344 |
|
345 iq = self.stub.output[-1] |
|
346 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
347 'create', NS_PUBSUB)) |
|
348 child = children[0] |
|
349 self.assertEquals('test', child['node']) |
|
350 |
|
351 response = toResponse(iq, 'result') |
|
352 command = response.addElement((NS_PUBSUB, 'pubsub')) |
|
353 create = command.addElement('create') |
|
354 create['node'] = 'test2' |
|
355 self.stub.send(response) |
|
356 return d |
|
357 |
|
358 |
|
359 def test_createNodeWithSender(self): |
|
360 """ |
|
361 Test sending create request from a specific JID. |
|
362 """ |
|
363 |
|
364 d = self.protocol.createNode(JID('pubsub.example.org'), 'test', |
|
365 sender=JID('user@example.org')) |
|
366 |
|
367 iq = self.stub.output[-1] |
|
368 self.assertEquals('user@example.org', iq['from']) |
|
369 |
|
370 response = toResponse(iq, 'result') |
|
371 self.stub.send(response) |
|
372 return d |
|
373 |
|
374 |
|
375 def test_createNodeWithConfig(self): |
|
376 """ |
|
377 Test sending create request with configuration options |
|
378 """ |
|
379 |
|
380 options = { |
|
381 'pubsub#title': 'Princely Musings (Atom)', |
|
382 'pubsub#deliver_payloads': True, |
|
383 'pubsub#persist_items': '1', |
|
384 'pubsub#max_items': '10', |
|
385 'pubsub#access_model': 'open', |
|
386 'pubsub#type': 'http://www.w3.org/2005/Atom', |
|
387 } |
|
388 |
|
389 d = self.protocol.createNode(JID('pubsub.example.org'), 'test', |
|
390 sender=JID('user@example.org'), |
|
391 options=options) |
|
392 |
|
393 iq = self.stub.output[-1] |
|
394 |
|
395 # check if there is exactly one configure element |
|
396 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
397 'configure', NS_PUBSUB)) |
|
398 self.assertEqual(1, len(children)) |
|
399 |
|
400 # check that it has a configuration form |
|
401 form = data_form.findForm(children[0], NS_PUBSUB_NODE_CONFIG) |
|
402 self.assertEqual('submit', form.formType) |
|
403 |
|
404 |
|
405 response = toResponse(iq, 'result') |
|
406 self.stub.send(response) |
|
407 return d |
|
408 |
|
409 |
|
410 def test_deleteNode(self): |
|
411 """ |
|
412 Test sending delete request. |
|
413 """ |
|
414 |
|
415 d = self.protocol.deleteNode(JID('pubsub.example.org'), 'test') |
|
416 |
|
417 iq = self.stub.output[-1] |
|
418 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
419 self.assertEquals('set', iq.getAttribute('type')) |
|
420 self.assertEquals('pubsub', iq.pubsub.name) |
|
421 self.assertEquals(NS_PUBSUB_OWNER, iq.pubsub.uri) |
|
422 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
423 'delete', NS_PUBSUB_OWNER)) |
|
424 self.assertEquals(1, len(children)) |
|
425 child = children[0] |
|
426 self.assertEquals('test', child['node']) |
|
427 |
|
428 response = toResponse(iq, 'result') |
|
429 self.stub.send(response) |
|
430 return d |
|
431 |
|
432 |
|
433 def test_deleteNodeWithSender(self): |
|
434 """ |
|
435 Test sending delete request. |
|
436 """ |
|
437 |
|
438 d = self.protocol.deleteNode(JID('pubsub.example.org'), 'test', |
|
439 sender=JID('user@example.org')) |
|
440 |
|
441 iq = self.stub.output[-1] |
|
442 self.assertEquals('user@example.org', iq['from']) |
|
443 |
|
444 response = toResponse(iq, 'result') |
|
445 self.stub.send(response) |
|
446 return d |
|
447 |
|
448 |
|
449 def test_publish(self): |
|
450 """ |
|
451 Test sending publish request. |
|
452 """ |
|
453 |
|
454 item = pubsub.Item() |
|
455 d = self.protocol.publish(JID('pubsub.example.org'), 'test', [item]) |
|
456 |
|
457 iq = self.stub.output[-1] |
|
458 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
459 self.assertEquals('set', iq.getAttribute('type')) |
|
460 self.assertEquals('pubsub', iq.pubsub.name) |
|
461 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
462 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
463 'publish', NS_PUBSUB)) |
|
464 self.assertEquals(1, len(children)) |
|
465 child = children[0] |
|
466 self.assertEquals('test', child['node']) |
|
467 items = list(domish.generateElementsQNamed(child.children, |
|
468 'item', NS_PUBSUB)) |
|
469 self.assertEquals(1, len(items)) |
|
470 self.assertIdentical(item, items[0]) |
|
471 |
|
472 response = toResponse(iq, 'result') |
|
473 self.stub.send(response) |
|
474 return d |
|
475 |
|
476 |
|
477 def test_publishNoItems(self): |
|
478 """ |
|
479 Test sending publish request without items. |
|
480 """ |
|
481 |
|
482 d = self.protocol.publish(JID('pubsub.example.org'), 'test') |
|
483 |
|
484 iq = self.stub.output[-1] |
|
485 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
486 self.assertEquals('set', iq.getAttribute('type')) |
|
487 self.assertEquals('pubsub', iq.pubsub.name) |
|
488 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
489 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
490 'publish', NS_PUBSUB)) |
|
491 self.assertEquals(1, len(children)) |
|
492 child = children[0] |
|
493 self.assertEquals('test', child['node']) |
|
494 |
|
495 response = toResponse(iq, 'result') |
|
496 self.stub.send(response) |
|
497 return d |
|
498 |
|
499 |
|
500 def test_publishWithSender(self): |
|
501 """ |
|
502 Test sending publish request from a specific JID. |
|
503 """ |
|
504 |
|
505 item = pubsub.Item() |
|
506 d = self.protocol.publish(JID('pubsub.example.org'), 'test', [item], |
|
507 JID('user@example.org')) |
|
508 |
|
509 iq = self.stub.output[-1] |
|
510 self.assertEquals('user@example.org', iq['from']) |
|
511 |
|
512 response = toResponse(iq, 'result') |
|
513 self.stub.send(response) |
|
514 return d |
|
515 |
|
516 |
|
517 def test_subscribe(self): |
|
518 """ |
|
519 Test sending subscription request. |
|
520 """ |
|
521 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', |
|
522 JID('user@example.org')) |
|
523 |
|
524 iq = self.stub.output[-1] |
|
525 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
526 self.assertEquals('set', iq.getAttribute('type')) |
|
527 self.assertEquals('pubsub', iq.pubsub.name) |
|
528 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
529 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
530 'subscribe', NS_PUBSUB)) |
|
531 self.assertEquals(1, len(children)) |
|
532 child = children[0] |
|
533 self.assertEquals('test', child['node']) |
|
534 self.assertEquals('user@example.org', child['jid']) |
|
535 |
|
536 response = toResponse(iq, 'result') |
|
537 pubsub = response.addElement((NS_PUBSUB, 'pubsub')) |
|
538 subscription = pubsub.addElement('subscription') |
|
539 subscription['node'] = 'test' |
|
540 subscription['jid'] = 'user@example.org' |
|
541 subscription['subscription'] = 'subscribed' |
|
542 self.stub.send(response) |
|
543 return d |
|
544 |
|
545 |
|
546 def test_subscribeReturnsSubscription(self): |
|
547 """ |
|
548 A successful subscription should return a Subscription instance. |
|
549 """ |
|
550 def cb(subscription): |
|
551 self.assertEqual(JID('user@example.org'), subscription.subscriber) |
|
552 |
|
553 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', |
|
554 JID('user@example.org')) |
|
555 d.addCallback(cb) |
|
556 |
|
557 iq = self.stub.output[-1] |
|
558 |
|
559 response = toResponse(iq, 'result') |
|
560 pubsub = response.addElement((NS_PUBSUB, 'pubsub')) |
|
561 subscription = pubsub.addElement('subscription') |
|
562 subscription['node'] = 'test' |
|
563 subscription['jid'] = 'user@example.org' |
|
564 subscription['subscription'] = 'subscribed' |
|
565 self.stub.send(response) |
|
566 return d |
|
567 |
|
568 |
|
569 def test_subscribePending(self): |
|
570 """ |
|
571 Test sending subscription request that results in a pending |
|
572 subscription. |
|
573 """ |
|
574 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', |
|
575 JID('user@example.org')) |
|
576 |
|
577 iq = self.stub.output[-1] |
|
578 response = toResponse(iq, 'result') |
|
579 command = response.addElement((NS_PUBSUB, 'pubsub')) |
|
580 subscription = command.addElement('subscription') |
|
581 subscription['node'] = 'test' |
|
582 subscription['jid'] = 'user@example.org' |
|
583 subscription['subscription'] = 'pending' |
|
584 self.stub.send(response) |
|
585 self.assertFailure(d, pubsub.SubscriptionPending) |
|
586 return d |
|
587 |
|
588 |
|
589 def test_subscribeUnconfigured(self): |
|
590 """ |
|
591 Test sending subscription request that results in an unconfigured |
|
592 subscription. |
|
593 """ |
|
594 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', |
|
595 JID('user@example.org')) |
|
596 |
|
597 iq = self.stub.output[-1] |
|
598 response = toResponse(iq, 'result') |
|
599 command = response.addElement((NS_PUBSUB, 'pubsub')) |
|
600 subscription = command.addElement('subscription') |
|
601 subscription['node'] = 'test' |
|
602 subscription['jid'] = 'user@example.org' |
|
603 subscription['subscription'] = 'unconfigured' |
|
604 self.stub.send(response) |
|
605 self.assertFailure(d, pubsub.SubscriptionUnconfigured) |
|
606 return d |
|
607 |
|
608 |
|
609 def test_subscribeWithOptions(self): |
|
610 options = {'pubsub#deliver': False} |
|
611 |
|
612 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', |
|
613 JID('user@example.org'), |
|
614 options=options) |
|
615 iq = self.stub.output[-1] |
|
616 |
|
617 # Check options present |
|
618 childNames = [] |
|
619 for element in iq.pubsub.elements(): |
|
620 if element.uri == NS_PUBSUB: |
|
621 childNames.append(element.name) |
|
622 |
|
623 self.assertEqual(['subscribe', 'options'], childNames) |
|
624 form = data_form.findForm(iq.pubsub.options, |
|
625 NS_PUBSUB_SUBSCRIBE_OPTIONS) |
|
626 self.assertEqual('submit', form.formType) |
|
627 form.typeCheck({'pubsub#deliver': {'type': 'boolean'}}) |
|
628 self.assertEqual(options, form.getValues()) |
|
629 |
|
630 # Send response |
|
631 response = toResponse(iq, 'result') |
|
632 pubsub = response.addElement((NS_PUBSUB, 'pubsub')) |
|
633 subscription = pubsub.addElement('subscription') |
|
634 subscription['node'] = 'test' |
|
635 subscription['jid'] = 'user@example.org' |
|
636 subscription['subscription'] = 'subscribed' |
|
637 self.stub.send(response) |
|
638 |
|
639 return d |
|
640 |
|
641 |
|
642 def test_subscribeWithSender(self): |
|
643 """ |
|
644 Test sending subscription request from a specific JID. |
|
645 """ |
|
646 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', |
|
647 JID('user@example.org'), |
|
648 sender=JID('user@example.org')) |
|
649 |
|
650 iq = self.stub.output[-1] |
|
651 self.assertEquals('user@example.org', iq['from']) |
|
652 |
|
653 response = toResponse(iq, 'result') |
|
654 pubsub = response.addElement((NS_PUBSUB, 'pubsub')) |
|
655 subscription = pubsub.addElement('subscription') |
|
656 subscription['node'] = 'test' |
|
657 subscription['jid'] = 'user@example.org' |
|
658 subscription['subscription'] = 'subscribed' |
|
659 self.stub.send(response) |
|
660 return d |
|
661 |
|
662 |
|
663 def test_subscribeReturningSubscriptionIdentifier(self): |
|
664 """ |
|
665 Test sending subscription request with subscription identifier. |
|
666 """ |
|
667 def cb(subscription): |
|
668 self.assertEqual('1234', subscription.subscriptionIdentifier) |
|
669 |
|
670 d = self.protocol.subscribe(JID('pubsub.example.org'), 'test', |
|
671 JID('user@example.org')) |
|
672 d.addCallback(cb) |
|
673 |
|
674 iq = self.stub.output[-1] |
|
675 |
|
676 response = toResponse(iq, 'result') |
|
677 pubsub = response.addElement((NS_PUBSUB, 'pubsub')) |
|
678 subscription = pubsub.addElement('subscription') |
|
679 subscription['node'] = 'test' |
|
680 subscription['jid'] = 'user@example.org' |
|
681 subscription['subscription'] = 'subscribed' |
|
682 subscription['subid'] = '1234' |
|
683 self.stub.send(response) |
|
684 return d |
|
685 |
|
686 |
|
687 def test_unsubscribe(self): |
|
688 """ |
|
689 Test sending unsubscription request. |
|
690 """ |
|
691 d = self.protocol.unsubscribe(JID('pubsub.example.org'), 'test', |
|
692 JID('user@example.org')) |
|
693 |
|
694 iq = self.stub.output[-1] |
|
695 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
696 self.assertEquals('set', iq.getAttribute('type')) |
|
697 self.assertEquals('pubsub', iq.pubsub.name) |
|
698 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
699 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
700 'unsubscribe', NS_PUBSUB)) |
|
701 self.assertEquals(1, len(children)) |
|
702 child = children[0] |
|
703 self.assertEquals('test', child['node']) |
|
704 self.assertEquals('user@example.org', child['jid']) |
|
705 |
|
706 self.stub.send(toResponse(iq, 'result')) |
|
707 return d |
|
708 |
|
709 |
|
710 def test_unsubscribeWithSender(self): |
|
711 """ |
|
712 Test sending unsubscription request from a specific JID. |
|
713 """ |
|
714 d = self.protocol.unsubscribe(JID('pubsub.example.org'), 'test', |
|
715 JID('user@example.org'), |
|
716 sender=JID('user@example.org')) |
|
717 |
|
718 iq = self.stub.output[-1] |
|
719 self.assertEquals('user@example.org', iq['from']) |
|
720 self.stub.send(toResponse(iq, 'result')) |
|
721 return d |
|
722 |
|
723 |
|
724 def test_unsubscribeWithSubscriptionIdentifier(self): |
|
725 """ |
|
726 Test sending unsubscription request with subscription identifier. |
|
727 """ |
|
728 d = self.protocol.unsubscribe(JID('pubsub.example.org'), 'test', |
|
729 JID('user@example.org'), |
|
730 subscriptionIdentifier='1234') |
|
731 |
|
732 iq = self.stub.output[-1] |
|
733 child = iq.pubsub.unsubscribe |
|
734 self.assertEquals('1234', child['subid']) |
|
735 |
|
736 self.stub.send(toResponse(iq, 'result')) |
|
737 return d |
|
738 |
|
739 |
|
740 def test_items(self): |
|
741 """ |
|
742 Test sending items request. |
|
743 """ |
|
744 def cb(items): |
|
745 self.assertEquals([], items) |
|
746 |
|
747 d = self.protocol.items(JID('pubsub.example.org'), 'test') |
|
748 d.addCallback(cb) |
|
749 |
|
750 iq = self.stub.output[-1] |
|
751 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
752 self.assertEquals('get', iq.getAttribute('type')) |
|
753 self.assertEquals('pubsub', iq.pubsub.name) |
|
754 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
755 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
756 'items', NS_PUBSUB)) |
|
757 self.assertEquals(1, len(children)) |
|
758 child = children[0] |
|
759 self.assertEquals('test', child['node']) |
|
760 |
|
761 response = toResponse(iq, 'result') |
|
762 items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items') |
|
763 items['node'] = 'test' |
|
764 |
|
765 self.stub.send(response) |
|
766 |
|
767 return d |
|
768 |
|
769 |
|
770 def test_itemsMaxItems(self): |
|
771 """ |
|
772 Test sending items request, with limit on the number of items. |
|
773 """ |
|
774 def cb(items): |
|
775 self.assertEquals(2, len(items)) |
|
776 self.assertEquals([item1, item2], items) |
|
777 |
|
778 d = self.protocol.items(JID('pubsub.example.org'), 'test', maxItems=2) |
|
779 d.addCallback(cb) |
|
780 |
|
781 iq = self.stub.output[-1] |
|
782 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
783 self.assertEquals('get', iq.getAttribute('type')) |
|
784 self.assertEquals('pubsub', iq.pubsub.name) |
|
785 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
786 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
787 'items', NS_PUBSUB)) |
|
788 self.assertEquals(1, len(children)) |
|
789 child = children[0] |
|
790 self.assertEquals('test', child['node']) |
|
791 self.assertEquals('2', child['max_items']) |
|
792 |
|
793 response = toResponse(iq, 'result') |
|
794 items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items') |
|
795 items['node'] = 'test' |
|
796 item1 = items.addElement('item') |
|
797 item1['id'] = 'item1' |
|
798 item2 = items.addElement('item') |
|
799 item2['id'] = 'item2' |
|
800 |
|
801 self.stub.send(response) |
|
802 |
|
803 return d |
|
804 |
|
805 |
|
806 def test_itemsWithItemIdentifiers(self): |
|
807 """ |
|
808 Test sending items request with item identifiers. |
|
809 """ |
|
810 def cb(items): |
|
811 self.assertEquals(2, len(items)) |
|
812 self.assertEquals([item1, item2], items) |
|
813 |
|
814 d = self.protocol.items(JID('pubsub.example.org'), 'test', |
|
815 itemIdentifiers=['item1', 'item2']) |
|
816 d.addCallback(cb) |
|
817 |
|
818 iq = self.stub.output[-1] |
|
819 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
820 self.assertEquals('get', iq.getAttribute('type')) |
|
821 self.assertEquals('pubsub', iq.pubsub.name) |
|
822 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
823 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
824 'items', NS_PUBSUB)) |
|
825 self.assertEquals(1, len(children)) |
|
826 child = children[0] |
|
827 self.assertEquals('test', child['node']) |
|
828 itemIdentifiers = [item.getAttribute('id') for item in |
|
829 domish.generateElementsQNamed(child.children, 'item', |
|
830 NS_PUBSUB)] |
|
831 self.assertEquals(['item1', 'item2'], itemIdentifiers) |
|
832 |
|
833 response = toResponse(iq, 'result') |
|
834 items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items') |
|
835 items['node'] = 'test' |
|
836 item1 = items.addElement('item') |
|
837 item1['id'] = 'item1' |
|
838 item2 = items.addElement('item') |
|
839 item2['id'] = 'item2' |
|
840 |
|
841 self.stub.send(response) |
|
842 |
|
843 return d |
|
844 |
|
845 |
|
846 def test_itemsWithSubscriptionIdentifier(self): |
|
847 """ |
|
848 Test sending items request with a subscription identifier. |
|
849 """ |
|
850 |
|
851 d = self.protocol.items(JID('pubsub.example.org'), 'test', |
|
852 subscriptionIdentifier='1234') |
|
853 |
|
854 iq = self.stub.output[-1] |
|
855 child = iq.pubsub.items |
|
856 self.assertEquals('1234', child['subid']) |
|
857 |
|
858 response = toResponse(iq, 'result') |
|
859 items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items') |
|
860 items['node'] = 'test' |
|
861 |
|
862 self.stub.send(response) |
|
863 return d |
|
864 |
|
865 |
|
866 def test_itemsWithSender(self): |
|
867 """ |
|
868 Test sending items request from a specific JID. |
|
869 """ |
|
870 |
|
871 d = self.protocol.items(JID('pubsub.example.org'), 'test', |
|
872 sender=JID('user@example.org')) |
|
873 |
|
874 iq = self.stub.output[-1] |
|
875 self.assertEquals('user@example.org', iq['from']) |
|
876 |
|
877 response = toResponse(iq, 'result') |
|
878 items = response.addElement((NS_PUBSUB, 'pubsub')).addElement('items') |
|
879 items['node'] = 'test' |
|
880 |
|
881 self.stub.send(response) |
|
882 return d |
|
883 |
|
884 |
|
885 def test_retractItems(self): |
|
886 """ |
|
887 Test sending items retraction. |
|
888 """ |
|
889 d = self.protocol.retractItems(JID('pubsub.example.org'), 'test', |
|
890 itemIdentifiers=['item1', 'item2']) |
|
891 |
|
892 iq = self.stub.output[-1] |
|
893 self.assertEquals('pubsub.example.org', iq.getAttribute('to')) |
|
894 self.assertEquals('set', iq.getAttribute('type')) |
|
895 self.assertEquals('pubsub', iq.pubsub.name) |
|
896 self.assertEquals(NS_PUBSUB, iq.pubsub.uri) |
|
897 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
898 'retract', NS_PUBSUB)) |
|
899 self.assertEquals(1, len(children)) |
|
900 child = children[0] |
|
901 self.assertEquals('test', child['node']) |
|
902 itemIdentifiers = [item.getAttribute('id') for item in |
|
903 domish.generateElementsQNamed(child.children, 'item', |
|
904 NS_PUBSUB)] |
|
905 self.assertEquals(['item1', 'item2'], itemIdentifiers) |
|
906 |
|
907 self.stub.send(toResponse(iq, 'result')) |
|
908 return d |
|
909 |
|
910 |
|
911 def test_retractItemsWithSender(self): |
|
912 """ |
|
913 Test retracting items request from a specific JID. |
|
914 """ |
|
915 d = self.protocol.retractItems(JID('pubsub.example.org'), 'test', |
|
916 itemIdentifiers=['item1', 'item2'], |
|
917 sender=JID('user@example.org')) |
|
918 |
|
919 iq = self.stub.output[-1] |
|
920 self.assertEquals('user@example.org', iq['from']) |
|
921 |
|
922 self.stub.send(toResponse(iq, 'result')) |
|
923 return d |
|
924 |
|
925 |
|
926 def test_getOptions(self): |
|
927 def cb(form): |
|
928 self.assertEqual('form', form.formType) |
|
929 self.assertEqual(NS_PUBSUB_SUBSCRIBE_OPTIONS, form.formNamespace) |
|
930 field = form.fields['pubsub#deliver'] |
|
931 self.assertEqual('boolean', field.fieldType) |
|
932 self.assertIdentical(True, field.value) |
|
933 self.assertEqual('Enable delivery?', field.label) |
|
934 |
|
935 d = self.protocol.getOptions(JID('pubsub.example.org'), 'test', |
|
936 JID('user@example.org'), |
|
937 sender=JID('user@example.org')) |
|
938 d.addCallback(cb) |
|
939 |
|
940 iq = self.stub.output[-1] |
|
941 self.assertEqual('pubsub.example.org', iq.getAttribute('to')) |
|
942 self.assertEqual('get', iq.getAttribute('type')) |
|
943 self.assertEqual('pubsub', iq.pubsub.name) |
|
944 self.assertEqual(NS_PUBSUB, iq.pubsub.uri) |
|
945 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
946 'options', NS_PUBSUB)) |
|
947 self.assertEqual(1, len(children)) |
|
948 child = children[0] |
|
949 self.assertEqual('test', child['node']) |
|
950 |
|
951 self.assertEqual(0, len(child.children)) |
|
952 |
|
953 # Send response |
|
954 form = data_form.Form('form', formNamespace=NS_PUBSUB_SUBSCRIBE_OPTIONS) |
|
955 form.addField(data_form.Field('boolean', var='pubsub#deliver', |
|
956 label='Enable delivery?', |
|
957 value=True)) |
|
958 response = toResponse(iq, 'result') |
|
959 response.addElement((NS_PUBSUB, 'pubsub')) |
|
960 response.pubsub.addElement('options') |
|
961 response.pubsub.options.addChild(form.toElement()) |
|
962 self.stub.send(response) |
|
963 |
|
964 return d |
|
965 |
|
966 |
|
967 def test_getOptionsWithSubscriptionIdentifier(self): |
|
968 """ |
|
969 Getting options with a subid should have the subid in the request. |
|
970 """ |
|
971 |
|
972 d = self.protocol.getOptions(JID('pubsub.example.org'), 'test', |
|
973 JID('user@example.org'), |
|
974 sender=JID('user@example.org'), |
|
975 subscriptionIdentifier='1234') |
|
976 |
|
977 iq = self.stub.output[-1] |
|
978 child = iq.pubsub.options |
|
979 self.assertEqual('1234', child['subid']) |
|
980 |
|
981 # Send response |
|
982 form = data_form.Form('form', formNamespace=NS_PUBSUB_SUBSCRIBE_OPTIONS) |
|
983 form.addField(data_form.Field('boolean', var='pubsub#deliver', |
|
984 label='Enable delivery?', |
|
985 value=True)) |
|
986 response = toResponse(iq, 'result') |
|
987 response.addElement((NS_PUBSUB, 'pubsub')) |
|
988 response.pubsub.addElement('options') |
|
989 response.pubsub.options.addChild(form.toElement()) |
|
990 self.stub.send(response) |
|
991 |
|
992 return d |
|
993 |
|
994 |
|
995 def test_setOptions(self): |
|
996 """ |
|
997 setOptions should send out a options-set request. |
|
998 """ |
|
999 options = {'pubsub#deliver': False} |
|
1000 |
|
1001 d = self.protocol.setOptions(JID('pubsub.example.org'), 'test', |
|
1002 JID('user@example.org'), |
|
1003 options, |
|
1004 sender=JID('user@example.org')) |
|
1005 |
|
1006 iq = self.stub.output[-1] |
|
1007 self.assertEqual('pubsub.example.org', iq.getAttribute('to')) |
|
1008 self.assertEqual('set', iq.getAttribute('type')) |
|
1009 self.assertEqual('pubsub', iq.pubsub.name) |
|
1010 self.assertEqual(NS_PUBSUB, iq.pubsub.uri) |
|
1011 children = list(domish.generateElementsQNamed(iq.pubsub.children, |
|
1012 'options', NS_PUBSUB)) |
|
1013 self.assertEqual(1, len(children)) |
|
1014 child = children[0] |
|
1015 self.assertEqual('test', child['node']) |
|
1016 |
|
1017 form = data_form.findForm(child, NS_PUBSUB_SUBSCRIBE_OPTIONS) |
|
1018 self.assertEqual('submit', form.formType) |
|
1019 form.typeCheck({'pubsub#deliver': {'type': 'boolean'}}) |
|
1020 self.assertEqual(options, form.getValues()) |
|
1021 |
|
1022 response = toResponse(iq, 'result') |
|
1023 self.stub.send(response) |
|
1024 |
|
1025 return d |
|
1026 |
|
1027 |
|
1028 def test_setOptionsWithSubscriptionIdentifier(self): |
|
1029 """ |
|
1030 setOptions should send out a options-set request with subid. |
|
1031 """ |
|
1032 options = {'pubsub#deliver': False} |
|
1033 |
|
1034 d = self.protocol.setOptions(JID('pubsub.example.org'), 'test', |
|
1035 JID('user@example.org'), |
|
1036 options, |
|
1037 subscriptionIdentifier='1234', |
|
1038 sender=JID('user@example.org')) |
|
1039 |
|
1040 iq = self.stub.output[-1] |
|
1041 child = iq.pubsub.options |
|
1042 self.assertEqual('1234', child['subid']) |
|
1043 |
|
1044 form = data_form.findForm(child, NS_PUBSUB_SUBSCRIBE_OPTIONS) |
|
1045 self.assertEqual('submit', form.formType) |
|
1046 form.typeCheck({'pubsub#deliver': {'type': 'boolean'}}) |
|
1047 self.assertEqual(options, form.getValues()) |
|
1048 |
|
1049 response = toResponse(iq, 'result') |
|
1050 self.stub.send(response) |
|
1051 |
|
1052 return d |
|
1053 |
|
1054 |
|
1055 class PubSubRequestTest(unittest.TestCase): |
|
1056 |
|
1057 def test_fromElementUnknown(self): |
|
1058 """ |
|
1059 An unknown verb raises NotImplementedError. |
|
1060 """ |
|
1061 |
|
1062 xml = """ |
|
1063 <iq type='set' to='pubsub.example.org' |
|
1064 from='user@example.org'> |
|
1065 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1066 <non-existing-verb/> |
|
1067 </pubsub> |
|
1068 </iq> |
|
1069 """ |
|
1070 |
|
1071 self.assertRaises(NotImplementedError, |
|
1072 pubsub.PubSubRequest.fromElement, parseXml(xml)) |
|
1073 |
|
1074 |
|
1075 def test_fromElementKnownBadCombination(self): |
|
1076 """ |
|
1077 Multiple verbs in an unknown configuration raises NotImplementedError. |
|
1078 """ |
|
1079 |
|
1080 xml = """ |
|
1081 <iq type='set' to='pubsub.example.org' |
|
1082 from='user@example.org'> |
|
1083 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1084 <publish/> |
|
1085 <create/> |
|
1086 </pubsub> |
|
1087 </iq> |
|
1088 """ |
|
1089 |
|
1090 self.assertRaises(NotImplementedError, |
|
1091 pubsub.PubSubRequest.fromElement, parseXml(xml)) |
|
1092 |
|
1093 def test_fromElementPublish(self): |
|
1094 """ |
|
1095 Test parsing a publish request. |
|
1096 """ |
|
1097 |
|
1098 xml = """ |
|
1099 <iq type='set' to='pubsub.example.org' |
|
1100 from='user@example.org'> |
|
1101 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1102 <publish node='test'/> |
|
1103 </pubsub> |
|
1104 </iq> |
|
1105 """ |
|
1106 |
|
1107 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1108 self.assertEqual('publish', request.verb) |
|
1109 self.assertEqual(JID('user@example.org'), request.sender) |
|
1110 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1111 self.assertEqual('test', request.nodeIdentifier) |
|
1112 self.assertEqual([], request.items) |
|
1113 |
|
1114 |
|
1115 def test_fromElementPublishItems(self): |
|
1116 """ |
|
1117 Test parsing a publish request with items. |
|
1118 """ |
|
1119 |
|
1120 xml = """ |
|
1121 <iq type='set' to='pubsub.example.org' |
|
1122 from='user@example.org'> |
|
1123 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1124 <publish node='test'> |
|
1125 <item id="item1"/> |
|
1126 <item id="item2"/> |
|
1127 </publish> |
|
1128 </pubsub> |
|
1129 </iq> |
|
1130 """ |
|
1131 |
|
1132 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1133 self.assertEqual(2, len(request.items)) |
|
1134 self.assertEqual(u'item1', request.items[0]["id"]) |
|
1135 self.assertEqual(u'item2', request.items[1]["id"]) |
|
1136 |
|
1137 |
|
1138 def test_fromElementPublishItemsOptions(self): |
|
1139 """ |
|
1140 Test parsing a publish request with items and options. |
|
1141 |
|
1142 Note that publishing options are not supported, but passing them |
|
1143 shouldn't affect processing of the publish request itself. |
|
1144 """ |
|
1145 |
|
1146 xml = """ |
|
1147 <iq type='set' to='pubsub.example.org' |
|
1148 from='user@example.org'> |
|
1149 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1150 <publish node='test'> |
|
1151 <item id="item1"/> |
|
1152 <item id="item2"/> |
|
1153 </publish> |
|
1154 <publish-options/> |
|
1155 </pubsub> |
|
1156 </iq> |
|
1157 """ |
|
1158 |
|
1159 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1160 self.assertEqual(2, len(request.items)) |
|
1161 self.assertEqual(u'item1', request.items[0]["id"]) |
|
1162 self.assertEqual(u'item2', request.items[1]["id"]) |
|
1163 |
|
1164 def test_fromElementPublishNoNode(self): |
|
1165 """ |
|
1166 A publish request to the root node should raise an exception. |
|
1167 """ |
|
1168 xml = """ |
|
1169 <iq type='set' to='pubsub.example.org' |
|
1170 from='user@example.org'> |
|
1171 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1172 <publish/> |
|
1173 </pubsub> |
|
1174 </iq> |
|
1175 """ |
|
1176 |
|
1177 err = self.assertRaises(error.StanzaError, |
|
1178 pubsub.PubSubRequest.fromElement, |
|
1179 parseXml(xml)) |
|
1180 self.assertEqual('bad-request', err.condition) |
|
1181 self.assertEqual(NS_PUBSUB_ERRORS, err.appCondition.uri) |
|
1182 self.assertEqual('nodeid-required', err.appCondition.name) |
|
1183 |
|
1184 |
|
1185 def test_fromElementSubscribe(self): |
|
1186 """ |
|
1187 Test parsing a subscription request. |
|
1188 """ |
|
1189 |
|
1190 xml = """ |
|
1191 <iq type='set' to='pubsub.example.org' |
|
1192 from='user@example.org'> |
|
1193 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1194 <subscribe node='test' jid='user@example.org/Home'/> |
|
1195 </pubsub> |
|
1196 </iq> |
|
1197 """ |
|
1198 |
|
1199 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1200 self.assertEqual('subscribe', request.verb) |
|
1201 self.assertEqual(JID('user@example.org'), request.sender) |
|
1202 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1203 self.assertEqual('test', request.nodeIdentifier) |
|
1204 self.assertEqual(JID('user@example.org/Home'), request.subscriber) |
|
1205 |
|
1206 |
|
1207 def test_fromElementSubscribeEmptyNode(self): |
|
1208 """ |
|
1209 Test parsing a subscription request to the root node. |
|
1210 """ |
|
1211 |
|
1212 xml = """ |
|
1213 <iq type='set' to='pubsub.example.org' |
|
1214 from='user@example.org'> |
|
1215 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1216 <subscribe jid='user@example.org/Home'/> |
|
1217 </pubsub> |
|
1218 </iq> |
|
1219 """ |
|
1220 |
|
1221 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1222 self.assertEqual('', request.nodeIdentifier) |
|
1223 |
|
1224 |
|
1225 def test_fromElementSubscribeNoJID(self): |
|
1226 """ |
|
1227 Subscribe requests without a JID should raise a bad-request exception. |
|
1228 """ |
|
1229 xml = """ |
|
1230 <iq type='set' to='pubsub.example.org' |
|
1231 from='user@example.org'> |
|
1232 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1233 <subscribe node='test'/> |
|
1234 </pubsub> |
|
1235 </iq> |
|
1236 """ |
|
1237 err = self.assertRaises(error.StanzaError, |
|
1238 pubsub.PubSubRequest.fromElement, |
|
1239 parseXml(xml)) |
|
1240 self.assertEqual('bad-request', err.condition) |
|
1241 self.assertEqual(NS_PUBSUB_ERRORS, err.appCondition.uri) |
|
1242 self.assertEqual('jid-required', err.appCondition.name) |
|
1243 |
|
1244 |
|
1245 def test_fromElementSubscribeWithOptions(self): |
|
1246 """ |
|
1247 Test parsing a subscription request. |
|
1248 """ |
|
1249 |
|
1250 xml = """ |
|
1251 <iq type='set' to='pubsub.example.org' |
|
1252 from='user@example.org'> |
|
1253 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1254 <subscribe node='test' jid='user@example.org/Home'/> |
|
1255 <options> |
|
1256 <x xmlns="jabber:x:data" type='submit'> |
|
1257 <field var='FORM_TYPE' type='hidden'> |
|
1258 <value>http://jabber.org/protocol/pubsub#subscribe_options</value> |
|
1259 </field> |
|
1260 <field var='pubsub#deliver' type='boolean' |
|
1261 label='Enable delivery?'> |
|
1262 <value>1</value> |
|
1263 </field> |
|
1264 </x> |
|
1265 </options> |
|
1266 </pubsub> |
|
1267 </iq> |
|
1268 """ |
|
1269 |
|
1270 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1271 self.assertEqual('subscribe', request.verb) |
|
1272 request.options.typeCheck({'pubsub#deliver': {'type': 'boolean'}}) |
|
1273 self.assertEqual({'pubsub#deliver': True}, request.options.getValues()) |
|
1274 |
|
1275 |
|
1276 def test_fromElementSubscribeWithOptionsBadFormType(self): |
|
1277 """ |
|
1278 The options form should have the right type. |
|
1279 """ |
|
1280 |
|
1281 xml = """ |
|
1282 <iq type='set' to='pubsub.example.org' |
|
1283 from='user@example.org'> |
|
1284 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1285 <subscribe node='test' jid='user@example.org/Home'/> |
|
1286 <options> |
|
1287 <x xmlns="jabber:x:data" type='result'> |
|
1288 <field var='FORM_TYPE' type='hidden'> |
|
1289 <value>http://jabber.org/protocol/pubsub#subscribe_options</value> |
|
1290 </field> |
|
1291 <field var='pubsub#deliver' type='boolean' |
|
1292 label='Enable delivery?'> |
|
1293 <value>1</value> |
|
1294 </field> |
|
1295 </x> |
|
1296 </options> |
|
1297 </pubsub> |
|
1298 </iq> |
|
1299 """ |
|
1300 |
|
1301 err = self.assertRaises(error.StanzaError, |
|
1302 pubsub.PubSubRequest.fromElement, |
|
1303 parseXml(xml)) |
|
1304 self.assertEqual('bad-request', err.condition) |
|
1305 self.assertEqual("Unexpected form type 'result'", err.text) |
|
1306 self.assertEqual(None, err.appCondition) |
|
1307 |
|
1308 |
|
1309 def test_fromElementSubscribeWithOptionsEmpty(self): |
|
1310 """ |
|
1311 When no (suitable) form is found, the options are empty. |
|
1312 """ |
|
1313 |
|
1314 xml = """ |
|
1315 <iq type='set' to='pubsub.example.org' |
|
1316 from='user@example.org'> |
|
1317 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1318 <subscribe node='test' jid='user@example.org/Home'/> |
|
1319 <options/> |
|
1320 </pubsub> |
|
1321 </iq> |
|
1322 """ |
|
1323 |
|
1324 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1325 self.assertEqual('subscribe', request.verb) |
|
1326 self.assertEqual({}, request.options.getValues()) |
|
1327 |
|
1328 |
|
1329 def test_fromElementUnsubscribe(self): |
|
1330 """ |
|
1331 Test parsing an unsubscription request. |
|
1332 """ |
|
1333 |
|
1334 xml = """ |
|
1335 <iq type='set' to='pubsub.example.org' |
|
1336 from='user@example.org'> |
|
1337 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1338 <unsubscribe node='test' jid='user@example.org/Home'/> |
|
1339 </pubsub> |
|
1340 </iq> |
|
1341 """ |
|
1342 |
|
1343 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1344 self.assertEqual('unsubscribe', request.verb) |
|
1345 self.assertEqual(JID('user@example.org'), request.sender) |
|
1346 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1347 self.assertEqual('test', request.nodeIdentifier) |
|
1348 self.assertEqual(JID('user@example.org/Home'), request.subscriber) |
|
1349 |
|
1350 |
|
1351 def test_fromElementUnsubscribeWithSubscriptionIdentifier(self): |
|
1352 """ |
|
1353 Test parsing an unsubscription request with subscription identifier. |
|
1354 """ |
|
1355 |
|
1356 xml = """ |
|
1357 <iq type='set' to='pubsub.example.org' |
|
1358 from='user@example.org'> |
|
1359 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1360 <unsubscribe node='test' jid='user@example.org/Home' |
|
1361 subid='1234'/> |
|
1362 </pubsub> |
|
1363 </iq> |
|
1364 """ |
|
1365 |
|
1366 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1367 self.assertEqual('1234', request.subscriptionIdentifier) |
|
1368 |
|
1369 |
|
1370 def test_fromElementUnsubscribeNoJID(self): |
|
1371 """ |
|
1372 Unsubscribe requests without a JID should raise a bad-request exception. |
|
1373 """ |
|
1374 xml = """ |
|
1375 <iq type='set' to='pubsub.example.org' |
|
1376 from='user@example.org'> |
|
1377 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1378 <unsubscribe node='test'/> |
|
1379 </pubsub> |
|
1380 </iq> |
|
1381 """ |
|
1382 err = self.assertRaises(error.StanzaError, |
|
1383 pubsub.PubSubRequest.fromElement, |
|
1384 parseXml(xml)) |
|
1385 self.assertEqual('bad-request', err.condition) |
|
1386 self.assertEqual(NS_PUBSUB_ERRORS, err.appCondition.uri) |
|
1387 self.assertEqual('jid-required', err.appCondition.name) |
|
1388 |
|
1389 |
|
1390 def test_fromElementOptionsGet(self): |
|
1391 """ |
|
1392 Test parsing a request for getting subscription options. |
|
1393 """ |
|
1394 |
|
1395 xml = """ |
|
1396 <iq type='get' to='pubsub.example.org' |
|
1397 from='user@example.org'> |
|
1398 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1399 <options node='test' jid='user@example.org/Home'/> |
|
1400 </pubsub> |
|
1401 </iq> |
|
1402 """ |
|
1403 |
|
1404 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1405 self.assertEqual('optionsGet', request.verb) |
|
1406 self.assertEqual(JID('user@example.org'), request.sender) |
|
1407 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1408 self.assertEqual('test', request.nodeIdentifier) |
|
1409 self.assertEqual(JID('user@example.org/Home'), request.subscriber) |
|
1410 |
|
1411 |
|
1412 def test_fromElementOptionsGetWithSubscriptionIdentifier(self): |
|
1413 """ |
|
1414 Test parsing a request for getting subscription options with subid. |
|
1415 """ |
|
1416 |
|
1417 xml = """ |
|
1418 <iq type='get' to='pubsub.example.org' |
|
1419 from='user@example.org'> |
|
1420 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1421 <options node='test' jid='user@example.org/Home' |
|
1422 subid='1234'/> |
|
1423 </pubsub> |
|
1424 </iq> |
|
1425 """ |
|
1426 |
|
1427 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1428 self.assertEqual('1234', request.subscriptionIdentifier) |
|
1429 |
|
1430 |
|
1431 def test_fromElementOptionsSet(self): |
|
1432 """ |
|
1433 Test parsing a request for setting subscription options. |
|
1434 """ |
|
1435 |
|
1436 xml = """ |
|
1437 <iq type='set' to='pubsub.example.org' |
|
1438 from='user@example.org'> |
|
1439 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1440 <options node='test' jid='user@example.org/Home'> |
|
1441 <x xmlns='jabber:x:data' type='submit'> |
|
1442 <field var='FORM_TYPE' type='hidden'> |
|
1443 <value>http://jabber.org/protocol/pubsub#subscribe_options</value> |
|
1444 </field> |
|
1445 <field var='pubsub#deliver'><value>1</value></field> |
|
1446 </x> |
|
1447 </options> |
|
1448 </pubsub> |
|
1449 </iq> |
|
1450 """ |
|
1451 |
|
1452 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1453 self.assertEqual('optionsSet', request.verb) |
|
1454 self.assertEqual(JID('user@example.org'), request.sender) |
|
1455 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1456 self.assertEqual('test', request.nodeIdentifier) |
|
1457 self.assertEqual(JID('user@example.org/Home'), request.subscriber) |
|
1458 self.assertEqual({'pubsub#deliver': '1'}, request.options.getValues()) |
|
1459 |
|
1460 |
|
1461 def test_fromElementOptionsSetWithSubscriptionIdentifier(self): |
|
1462 """ |
|
1463 Test parsing a request for setting subscription options with subid. |
|
1464 """ |
|
1465 |
|
1466 xml = """ |
|
1467 <iq type='set' to='pubsub.example.org' |
|
1468 from='user@example.org'> |
|
1469 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1470 <options node='test' jid='user@example.org/Home' |
|
1471 subid='1234'> |
|
1472 <x xmlns='jabber:x:data' type='submit'> |
|
1473 <field var='FORM_TYPE' type='hidden'> |
|
1474 <value>http://jabber.org/protocol/pubsub#subscribe_options</value> |
|
1475 </field> |
|
1476 <field var='pubsub#deliver'><value>1</value></field> |
|
1477 </x> |
|
1478 </options> |
|
1479 </pubsub> |
|
1480 </iq> |
|
1481 """ |
|
1482 |
|
1483 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1484 self.assertEqual('1234', request.subscriptionIdentifier) |
|
1485 |
|
1486 |
|
1487 def test_fromElementOptionsSetCancel(self): |
|
1488 """ |
|
1489 Test parsing a request for cancelling setting subscription options. |
|
1490 """ |
|
1491 |
|
1492 xml = """ |
|
1493 <iq type='set' to='pubsub.example.org' |
|
1494 from='user@example.org'> |
|
1495 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1496 <options node='test' jid='user@example.org/Home'> |
|
1497 <x xmlns='jabber:x:data' type='cancel'/> |
|
1498 </options> |
|
1499 </pubsub> |
|
1500 </iq> |
|
1501 """ |
|
1502 |
|
1503 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1504 self.assertEqual('cancel', request.options.formType) |
|
1505 |
|
1506 |
|
1507 def test_fromElementOptionsSetBadFormType(self): |
|
1508 """ |
|
1509 On a options set request unknown fields should be ignored. |
|
1510 """ |
|
1511 |
|
1512 xml = """ |
|
1513 <iq type='set' to='pubsub.example.org' |
|
1514 from='user@example.org'> |
|
1515 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1516 <options node='test' jid='user@example.org/Home'> |
|
1517 <x xmlns='jabber:x:data' type='result'> |
|
1518 <field var='FORM_TYPE' type='hidden'> |
|
1519 <value>http://jabber.org/protocol/pubsub#subscribe_options</value> |
|
1520 </field> |
|
1521 <field var='pubsub#deliver'><value>1</value></field> |
|
1522 </x> |
|
1523 </options> |
|
1524 </pubsub> |
|
1525 </iq> |
|
1526 """ |
|
1527 |
|
1528 err = self.assertRaises(error.StanzaError, |
|
1529 pubsub.PubSubRequest.fromElement, |
|
1530 parseXml(xml)) |
|
1531 self.assertEqual('bad-request', err.condition) |
|
1532 self.assertEqual("Unexpected form type 'result'", err.text) |
|
1533 self.assertEqual(None, err.appCondition) |
|
1534 |
|
1535 |
|
1536 def test_fromElementOptionsSetNoForm(self): |
|
1537 """ |
|
1538 On a options set request a form is required. |
|
1539 """ |
|
1540 |
|
1541 xml = """ |
|
1542 <iq type='set' to='pubsub.example.org' |
|
1543 from='user@example.org'> |
|
1544 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1545 <options node='test' jid='user@example.org/Home'/> |
|
1546 </pubsub> |
|
1547 </iq> |
|
1548 """ |
|
1549 err = self.assertRaises(error.StanzaError, |
|
1550 pubsub.PubSubRequest.fromElement, |
|
1551 parseXml(xml)) |
|
1552 self.assertEqual('bad-request', err.condition) |
|
1553 self.assertEqual(None, err.appCondition) |
|
1554 |
|
1555 |
|
1556 def test_fromElementSubscriptions(self): |
|
1557 """ |
|
1558 Test parsing a request for all subscriptions. |
|
1559 """ |
|
1560 |
|
1561 xml = """ |
|
1562 <iq type='get' to='pubsub.example.org' |
|
1563 from='user@example.org'> |
|
1564 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1565 <subscriptions/> |
|
1566 </pubsub> |
|
1567 </iq> |
|
1568 """ |
|
1569 |
|
1570 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1571 self.assertEqual('subscriptions', request.verb) |
|
1572 self.assertEqual(JID('user@example.org'), request.sender) |
|
1573 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1574 |
|
1575 |
|
1576 def test_fromElementAffiliations(self): |
|
1577 """ |
|
1578 Test parsing a request for all affiliations. |
|
1579 """ |
|
1580 |
|
1581 xml = """ |
|
1582 <iq type='get' to='pubsub.example.org' |
|
1583 from='user@example.org'> |
|
1584 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1585 <affiliations/> |
|
1586 </pubsub> |
|
1587 </iq> |
|
1588 """ |
|
1589 |
|
1590 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1591 self.assertEqual('affiliations', request.verb) |
|
1592 self.assertEqual(JID('user@example.org'), request.sender) |
|
1593 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1594 |
|
1595 |
|
1596 def test_fromElementCreate(self): |
|
1597 """ |
|
1598 Test parsing a request to create a node. |
|
1599 """ |
|
1600 |
|
1601 xml = """ |
|
1602 <iq type='set' to='pubsub.example.org' |
|
1603 from='user@example.org'> |
|
1604 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1605 <create node='mynode'/> |
|
1606 </pubsub> |
|
1607 </iq> |
|
1608 """ |
|
1609 |
|
1610 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1611 self.assertEqual('create', request.verb) |
|
1612 self.assertEqual(JID('user@example.org'), request.sender) |
|
1613 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1614 self.assertEqual('mynode', request.nodeIdentifier) |
|
1615 self.assertIdentical(None, request.options) |
|
1616 |
|
1617 |
|
1618 def test_fromElementCreateInstant(self): |
|
1619 """ |
|
1620 Test parsing a request to create an instant node. |
|
1621 """ |
|
1622 |
|
1623 xml = """ |
|
1624 <iq type='set' to='pubsub.example.org' |
|
1625 from='user@example.org'> |
|
1626 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1627 <create/> |
|
1628 </pubsub> |
|
1629 </iq> |
|
1630 """ |
|
1631 |
|
1632 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1633 self.assertIdentical(None, request.nodeIdentifier) |
|
1634 |
|
1635 |
|
1636 def test_fromElementCreateConfigureEmpty(self): |
|
1637 """ |
|
1638 Test parsing a request to create a node with an empty configuration. |
|
1639 """ |
|
1640 |
|
1641 xml = """ |
|
1642 <iq type='set' to='pubsub.example.org' |
|
1643 from='user@example.org'> |
|
1644 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1645 <create node='mynode'/> |
|
1646 <configure/> |
|
1647 </pubsub> |
|
1648 </iq> |
|
1649 """ |
|
1650 |
|
1651 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1652 self.assertEqual({}, request.options.getValues()) |
|
1653 self.assertEqual(u'mynode', request.nodeIdentifier) |
|
1654 |
|
1655 |
|
1656 def test_fromElementCreateConfigureEmptyWrongOrder(self): |
|
1657 """ |
|
1658 Test parsing a request to create a node and configure, wrong order. |
|
1659 |
|
1660 The C{configure} element should come after the C{create} request, |
|
1661 but we should accept both orders. |
|
1662 """ |
|
1663 |
|
1664 xml = """ |
|
1665 <iq type='set' to='pubsub.example.org' |
|
1666 from='user@example.org'> |
|
1667 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1668 <configure/> |
|
1669 <create node='mynode'/> |
|
1670 </pubsub> |
|
1671 </iq> |
|
1672 """ |
|
1673 |
|
1674 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1675 self.assertEqual({}, request.options.getValues()) |
|
1676 self.assertEqual(u'mynode', request.nodeIdentifier) |
|
1677 |
|
1678 |
|
1679 def test_fromElementCreateConfigure(self): |
|
1680 """ |
|
1681 Test parsing a request to create a node. |
|
1682 """ |
|
1683 |
|
1684 xml = """ |
|
1685 <iq type='set' to='pubsub.example.org' |
|
1686 from='user@example.org'> |
|
1687 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1688 <create node='mynode'/> |
|
1689 <configure> |
|
1690 <x xmlns='jabber:x:data' type='submit'> |
|
1691 <field var='FORM_TYPE' type='hidden'> |
|
1692 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
1693 </field> |
|
1694 <field var='pubsub#access_model'><value>open</value></field> |
|
1695 <field var='pubsub#persist_items'><value>0</value></field> |
|
1696 </x> |
|
1697 </configure> |
|
1698 </pubsub> |
|
1699 </iq> |
|
1700 """ |
|
1701 |
|
1702 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1703 values = request.options |
|
1704 self.assertIn('pubsub#access_model', values) |
|
1705 self.assertEqual(u'open', values['pubsub#access_model']) |
|
1706 self.assertIn('pubsub#persist_items', values) |
|
1707 self.assertEqual(u'0', values['pubsub#persist_items']) |
|
1708 |
|
1709 |
|
1710 def test_fromElementCreateConfigureBadFormType(self): |
|
1711 """ |
|
1712 The form of a node creation request should have the right type. |
|
1713 """ |
|
1714 |
|
1715 xml = """ |
|
1716 <iq type='set' to='pubsub.example.org' |
|
1717 from='user@example.org'> |
|
1718 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1719 <create node='mynode'/> |
|
1720 <configure> |
|
1721 <x xmlns='jabber:x:data' type='result'> |
|
1722 <field var='FORM_TYPE' type='hidden'> |
|
1723 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
1724 </field> |
|
1725 <field var='pubsub#access_model'><value>open</value></field> |
|
1726 <field var='pubsub#persist_items'><value>0</value></field> |
|
1727 </x> |
|
1728 </configure> |
|
1729 </pubsub> |
|
1730 </iq> |
|
1731 """ |
|
1732 |
|
1733 err = self.assertRaises(error.StanzaError, |
|
1734 pubsub.PubSubRequest.fromElement, |
|
1735 parseXml(xml)) |
|
1736 self.assertEqual('bad-request', err.condition) |
|
1737 self.assertEqual("Unexpected form type 'result'", err.text) |
|
1738 self.assertEqual(None, err.appCondition) |
|
1739 |
|
1740 |
|
1741 def test_fromElementDefault(self): |
|
1742 """ |
|
1743 Parsing default node configuration request sets required attributes. |
|
1744 |
|
1745 Besides C{verb}, C{sender} and C{recipient}, we expect C{nodeType} |
|
1746 to be set. If not passed it receives the default C{u'leaf'}. |
|
1747 """ |
|
1748 |
|
1749 xml = """ |
|
1750 <iq type='get' to='pubsub.example.org' |
|
1751 from='user@example.org'> |
|
1752 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1753 <default/> |
|
1754 </pubsub> |
|
1755 </iq> |
|
1756 """ |
|
1757 |
|
1758 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1759 self.assertEquals(u'default', request.verb) |
|
1760 self.assertEquals(JID('user@example.org'), request.sender) |
|
1761 self.assertEquals(JID('pubsub.example.org'), request.recipient) |
|
1762 self.assertEquals(u'leaf', request.nodeType) |
|
1763 |
|
1764 |
|
1765 def test_fromElementDefaultCollection(self): |
|
1766 """ |
|
1767 Parsing default request for collection sets nodeType to collection. |
|
1768 """ |
|
1769 |
|
1770 xml = """ |
|
1771 <iq type='get' to='pubsub.example.org' |
|
1772 from='user@example.org'> |
|
1773 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1774 <default> |
|
1775 <x xmlns='jabber:x:data' type='submit'> |
|
1776 <field var='FORM_TYPE' type='hidden'> |
|
1777 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
1778 </field> |
|
1779 <field var='pubsub#node_type'> |
|
1780 <value>collection</value> |
|
1781 </field> |
|
1782 </x> |
|
1783 </default> |
|
1784 |
|
1785 </pubsub> |
|
1786 </iq> |
|
1787 """ |
|
1788 |
|
1789 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1790 self.assertEquals('collection', request.nodeType) |
|
1791 |
|
1792 |
|
1793 def test_fromElementConfigureGet(self): |
|
1794 """ |
|
1795 Test parsing a node configuration get request. |
|
1796 """ |
|
1797 |
|
1798 xml = """ |
|
1799 <iq type='get' to='pubsub.example.org' |
|
1800 from='user@example.org'> |
|
1801 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1802 <configure node='test'/> |
|
1803 </pubsub> |
|
1804 </iq> |
|
1805 """ |
|
1806 |
|
1807 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1808 self.assertEqual('configureGet', request.verb) |
|
1809 self.assertEqual(JID('user@example.org'), request.sender) |
|
1810 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1811 self.assertEqual('test', request.nodeIdentifier) |
|
1812 |
|
1813 |
|
1814 def test_fromElementConfigureSet(self): |
|
1815 """ |
|
1816 On a node configuration set request the Data Form is parsed. |
|
1817 """ |
|
1818 |
|
1819 xml = """ |
|
1820 <iq type='set' to='pubsub.example.org' |
|
1821 from='user@example.org'> |
|
1822 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1823 <configure node='test'> |
|
1824 <x xmlns='jabber:x:data' type='submit'> |
|
1825 <field var='FORM_TYPE' type='hidden'> |
|
1826 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
1827 </field> |
|
1828 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
1829 <field var='pubsub#persist_items'><value>1</value></field> |
|
1830 </x> |
|
1831 </configure> |
|
1832 </pubsub> |
|
1833 </iq> |
|
1834 """ |
|
1835 |
|
1836 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1837 self.assertEqual('configureSet', request.verb) |
|
1838 self.assertEqual(JID('user@example.org'), request.sender) |
|
1839 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1840 self.assertEqual('test', request.nodeIdentifier) |
|
1841 self.assertEqual({'pubsub#deliver_payloads': '0', |
|
1842 'pubsub#persist_items': '1'}, |
|
1843 request.options.getValues()) |
|
1844 |
|
1845 |
|
1846 def test_fromElementConfigureSetCancel(self): |
|
1847 """ |
|
1848 The node configuration is cancelled, so no options. |
|
1849 """ |
|
1850 |
|
1851 xml = """ |
|
1852 <iq type='set' to='pubsub.example.org' |
|
1853 from='user@example.org'> |
|
1854 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1855 <configure node='test'> |
|
1856 <x xmlns='jabber:x:data' type='cancel'/> |
|
1857 </configure> |
|
1858 </pubsub> |
|
1859 </iq> |
|
1860 """ |
|
1861 |
|
1862 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1863 self.assertEqual('cancel', request.options.formType) |
|
1864 |
|
1865 |
|
1866 def test_fromElementConfigureSetBadFormType(self): |
|
1867 """ |
|
1868 The form of a node configuraton set request should have the right type. |
|
1869 """ |
|
1870 |
|
1871 xml = """ |
|
1872 <iq type='set' to='pubsub.example.org' |
|
1873 from='user@example.org'> |
|
1874 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1875 <configure node='test'> |
|
1876 <x xmlns='jabber:x:data' type='result'> |
|
1877 <field var='FORM_TYPE' type='hidden'> |
|
1878 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
1879 </field> |
|
1880 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
1881 <field var='x-myfield'><value>1</value></field> |
|
1882 </x> |
|
1883 </configure> |
|
1884 </pubsub> |
|
1885 </iq> |
|
1886 """ |
|
1887 |
|
1888 err = self.assertRaises(error.StanzaError, |
|
1889 pubsub.PubSubRequest.fromElement, |
|
1890 parseXml(xml)) |
|
1891 self.assertEqual('bad-request', err.condition) |
|
1892 self.assertEqual("Unexpected form type 'result'", err.text) |
|
1893 self.assertEqual(None, err.appCondition) |
|
1894 |
|
1895 |
|
1896 def test_fromElementConfigureSetNoForm(self): |
|
1897 """ |
|
1898 On a node configuration set request a form is required. |
|
1899 """ |
|
1900 |
|
1901 xml = """ |
|
1902 <iq type='set' to='pubsub.example.org' |
|
1903 from='user@example.org'> |
|
1904 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1905 <configure node='test'/> |
|
1906 </pubsub> |
|
1907 </iq> |
|
1908 """ |
|
1909 err = self.assertRaises(error.StanzaError, |
|
1910 pubsub.PubSubRequest.fromElement, |
|
1911 parseXml(xml)) |
|
1912 self.assertEqual('bad-request', err.condition) |
|
1913 self.assertEqual(None, err.appCondition) |
|
1914 |
|
1915 |
|
1916 def test_fromElementItems(self): |
|
1917 """ |
|
1918 Test parsing an items request. |
|
1919 """ |
|
1920 xml = """ |
|
1921 <iq type='get' to='pubsub.example.org' |
|
1922 from='user@example.org'> |
|
1923 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1924 <items node='test'/> |
|
1925 </pubsub> |
|
1926 </iq> |
|
1927 """ |
|
1928 |
|
1929 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1930 self.assertEqual('items', request.verb) |
|
1931 self.assertEqual(JID('user@example.org'), request.sender) |
|
1932 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1933 self.assertEqual('test', request.nodeIdentifier) |
|
1934 self.assertIdentical(None, request.maxItems) |
|
1935 self.assertIdentical(None, request.subscriptionIdentifier) |
|
1936 self.assertEqual([], request.itemIdentifiers) |
|
1937 |
|
1938 |
|
1939 def test_fromElementItemsSubscriptionIdentifier(self): |
|
1940 """ |
|
1941 Test parsing an items request with subscription identifier. |
|
1942 """ |
|
1943 xml = """ |
|
1944 <iq type='get' to='pubsub.example.org' |
|
1945 from='user@example.org'> |
|
1946 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1947 <items node='test' subid='1234'/> |
|
1948 </pubsub> |
|
1949 </iq> |
|
1950 """ |
|
1951 |
|
1952 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1953 self.assertEqual('1234', request.subscriptionIdentifier) |
|
1954 |
|
1955 |
|
1956 def test_fromElementRetract(self): |
|
1957 """ |
|
1958 Test parsing a retract request. |
|
1959 """ |
|
1960 |
|
1961 xml = """ |
|
1962 <iq type='set' to='pubsub.example.org' |
|
1963 from='user@example.org'> |
|
1964 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
1965 <retract node='test'> |
|
1966 <item id='item1'/> |
|
1967 <item id='item2'/> |
|
1968 </retract> |
|
1969 </pubsub> |
|
1970 </iq> |
|
1971 """ |
|
1972 |
|
1973 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1974 self.assertEqual('retract', request.verb) |
|
1975 self.assertEqual(JID('user@example.org'), request.sender) |
|
1976 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1977 self.assertEqual('test', request.nodeIdentifier) |
|
1978 self.assertEqual(['item1', 'item2'], request.itemIdentifiers) |
|
1979 |
|
1980 |
|
1981 def test_fromElementPurge(self): |
|
1982 """ |
|
1983 Test parsing a purge request. |
|
1984 """ |
|
1985 |
|
1986 xml = """ |
|
1987 <iq type='set' to='pubsub.example.org' |
|
1988 from='user@example.org'> |
|
1989 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
1990 <purge node='test'/> |
|
1991 </pubsub> |
|
1992 </iq> |
|
1993 """ |
|
1994 |
|
1995 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
1996 self.assertEqual('purge', request.verb) |
|
1997 self.assertEqual(JID('user@example.org'), request.sender) |
|
1998 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
1999 self.assertEqual('test', request.nodeIdentifier) |
|
2000 |
|
2001 |
|
2002 def test_fromElementDelete(self): |
|
2003 """ |
|
2004 Test parsing a delete request. |
|
2005 """ |
|
2006 |
|
2007 xml = """ |
|
2008 <iq type='set' to='pubsub.example.org' |
|
2009 from='user@example.org'> |
|
2010 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
2011 <delete node='test'/> |
|
2012 </pubsub> |
|
2013 </iq> |
|
2014 """ |
|
2015 |
|
2016 request = pubsub.PubSubRequest.fromElement(parseXml(xml)) |
|
2017 self.assertEqual('delete', request.verb) |
|
2018 self.assertEqual(JID('user@example.org'), request.sender) |
|
2019 self.assertEqual(JID('pubsub.example.org'), request.recipient) |
|
2020 self.assertEqual('test', request.nodeIdentifier) |
|
2021 |
|
2022 |
|
2023 |
|
2024 class PubSubServiceTest(unittest.TestCase, TestableRequestHandlerMixin): |
|
2025 """ |
|
2026 Tests for L{pubsub.PubSubService}. |
|
2027 """ |
|
2028 |
|
2029 def setUp(self): |
|
2030 self.stub = XmlStreamStub() |
|
2031 self.resource = pubsub.PubSubResource() |
|
2032 self.service = pubsub.PubSubService(self.resource) |
|
2033 self.service.send = self.stub.xmlstream.send |
|
2034 |
|
2035 def test_interface(self): |
|
2036 """ |
|
2037 Do instances of L{pubsub.PubSubService} provide L{iwokkel.IPubSubService}? |
|
2038 """ |
|
2039 verify.verifyObject(iwokkel.IPubSubService, self.service) |
|
2040 |
|
2041 |
|
2042 def test_interfaceIDisco(self): |
|
2043 """ |
|
2044 Do instances of L{pubsub.PubSubService} provide L{iwokkel.IDisco}? |
|
2045 """ |
|
2046 verify.verifyObject(iwokkel.IDisco, self.service) |
|
2047 |
|
2048 |
|
2049 def test_connectionMade(self): |
|
2050 """ |
|
2051 Verify setup of observers in L{pubsub.connectionMade}. |
|
2052 """ |
|
2053 requests = [] |
|
2054 |
|
2055 def handleRequest(iq): |
|
2056 requests.append(iq) |
|
2057 |
|
2058 self.service.xmlstream = self.stub.xmlstream |
|
2059 self.service.handleRequest = handleRequest |
|
2060 self.service.connectionMade() |
|
2061 |
|
2062 for namespace in (NS_PUBSUB, NS_PUBSUB_OWNER): |
|
2063 for stanzaType in ('get', 'set'): |
|
2064 iq = domish.Element((None, 'iq')) |
|
2065 iq['type'] = stanzaType |
|
2066 iq.addElement((namespace, 'pubsub')) |
|
2067 self.stub.xmlstream.dispatch(iq) |
|
2068 |
|
2069 self.assertEqual(4, len(requests)) |
|
2070 |
|
2071 |
|
2072 def test_getDiscoInfo(self): |
|
2073 """ |
|
2074 Test getDiscoInfo calls getNodeInfo and returns some minimal info. |
|
2075 """ |
|
2076 def cb(info): |
|
2077 discoInfo = disco.DiscoInfo() |
|
2078 for item in info: |
|
2079 discoInfo.append(item) |
|
2080 self.assertIn(('pubsub', 'service'), discoInfo.identities) |
|
2081 self.assertIn(disco.NS_DISCO_ITEMS, discoInfo.features) |
|
2082 |
|
2083 d = self.service.getDiscoInfo(JID('user@example.org/home'), |
|
2084 JID('pubsub.example.org'), '') |
|
2085 d.addCallback(cb) |
|
2086 return d |
|
2087 |
|
2088 |
|
2089 def test_getDiscoInfoNodeType(self): |
|
2090 """ |
|
2091 Test getDiscoInfo with node type. |
|
2092 """ |
|
2093 def cb(info): |
|
2094 discoInfo = disco.DiscoInfo() |
|
2095 for item in info: |
|
2096 discoInfo.append(item) |
|
2097 self.assertIn(('pubsub', 'collection'), discoInfo.identities) |
|
2098 |
|
2099 def getInfo(requestor, target, nodeIdentifier): |
|
2100 return defer.succeed({'type': 'collection', |
|
2101 'meta-data': {}}) |
|
2102 |
|
2103 self.resource.getInfo = getInfo |
|
2104 d = self.service.getDiscoInfo(JID('user@example.org/home'), |
|
2105 JID('pubsub.example.org'), '') |
|
2106 d.addCallback(cb) |
|
2107 return d |
|
2108 |
|
2109 |
|
2110 def test_getDiscoInfoMetaData(self): |
|
2111 """ |
|
2112 Test getDiscoInfo with returned meta data. |
|
2113 """ |
|
2114 def cb(info): |
|
2115 discoInfo = disco.DiscoInfo() |
|
2116 for item in info: |
|
2117 discoInfo.append(item) |
|
2118 |
|
2119 self.assertIn(('pubsub', 'leaf'), discoInfo.identities) |
|
2120 self.assertIn(NS_PUBSUB_META_DATA, discoInfo.extensions) |
|
2121 form = discoInfo.extensions[NS_PUBSUB_META_DATA] |
|
2122 self.assertIn('pubsub#node_type', form.fields) |
|
2123 |
|
2124 def getInfo(requestor, target, nodeIdentifier): |
|
2125 metaData = [{'var': 'pubsub#persist_items', |
|
2126 'label': 'Persist items to storage', |
|
2127 'value': True}] |
|
2128 return defer.succeed({'type': 'leaf', 'meta-data': metaData}) |
|
2129 |
|
2130 self.resource.getInfo = getInfo |
|
2131 d = self.service.getDiscoInfo(JID('user@example.org/home'), |
|
2132 JID('pubsub.example.org'), '') |
|
2133 d.addCallback(cb) |
|
2134 return d |
|
2135 |
|
2136 |
|
2137 def test_getDiscoInfoResourceFeatures(self): |
|
2138 """ |
|
2139 Test getDiscoInfo with the resource features. |
|
2140 """ |
|
2141 def cb(info): |
|
2142 discoInfo = disco.DiscoInfo() |
|
2143 for item in info: |
|
2144 discoInfo.append(item) |
|
2145 self.assertIn('http://jabber.org/protocol/pubsub#publish', |
|
2146 discoInfo.features) |
|
2147 |
|
2148 self.resource.features = ['publish'] |
|
2149 d = self.service.getDiscoInfo(JID('user@example.org/home'), |
|
2150 JID('pubsub.example.org'), '') |
|
2151 d.addCallback(cb) |
|
2152 return d |
|
2153 |
|
2154 |
|
2155 def test_getDiscoInfoBadResponse(self): |
|
2156 """ |
|
2157 If getInfo returns invalid response, it should be logged, then ignored. |
|
2158 """ |
|
2159 def cb(info): |
|
2160 self.assertEquals([], info) |
|
2161 self.assertEqual(1, len(self.flushLoggedErrors(TypeError))) |
|
2162 |
|
2163 def getInfo(requestor, target, nodeIdentifier): |
|
2164 return defer.succeed('bad response') |
|
2165 |
|
2166 self.resource.getInfo = getInfo |
|
2167 d = self.service.getDiscoInfo(JID('user@example.org/home'), |
|
2168 JID('pubsub.example.org'), 'test') |
|
2169 d.addCallback(cb) |
|
2170 return d |
|
2171 |
|
2172 |
|
2173 def test_getDiscoInfoException(self): |
|
2174 """ |
|
2175 If getInfo returns invalid response, it should be logged, then ignored. |
|
2176 """ |
|
2177 def cb(info): |
|
2178 self.assertEquals([], info) |
|
2179 self.assertEqual(1, len(self.flushLoggedErrors(NotImplementedError))) |
|
2180 |
|
2181 def getInfo(requestor, target, nodeIdentifier): |
|
2182 return defer.fail(NotImplementedError()) |
|
2183 |
|
2184 self.resource.getInfo = getInfo |
|
2185 d = self.service.getDiscoInfo(JID('user@example.org/home'), |
|
2186 JID('pubsub.example.org'), 'test') |
|
2187 d.addCallback(cb) |
|
2188 return d |
|
2189 |
|
2190 |
|
2191 def test_getDiscoItemsRoot(self): |
|
2192 """ |
|
2193 Test getDiscoItems on the root node. |
|
2194 """ |
|
2195 def getNodes(requestor, service, nodeIdentifier): |
|
2196 return defer.succeed(['node1', 'node2']) |
|
2197 |
|
2198 def cb(items): |
|
2199 self.assertEqual(2, len(items)) |
|
2200 item1, item2 = items |
|
2201 |
|
2202 self.assertEqual(JID('pubsub.example.org'), item1.entity) |
|
2203 self.assertEqual('node1', item1.nodeIdentifier) |
|
2204 |
|
2205 self.assertEqual(JID('pubsub.example.org'), item2.entity) |
|
2206 self.assertEqual('node2', item2.nodeIdentifier) |
|
2207 |
|
2208 self.resource.getNodes = getNodes |
|
2209 d = self.service.getDiscoItems(JID('user@example.org/home'), |
|
2210 JID('pubsub.example.org'), |
|
2211 '') |
|
2212 d.addCallback(cb) |
|
2213 return d |
|
2214 |
|
2215 |
|
2216 def test_getDiscoItemsRootHideNodes(self): |
|
2217 """ |
|
2218 Test getDiscoItems on the root node. |
|
2219 """ |
|
2220 def getNodes(requestor, service, nodeIdentifier): |
|
2221 raise Exception("Unexpected call to getNodes") |
|
2222 |
|
2223 def cb(items): |
|
2224 self.assertEqual([], items) |
|
2225 |
|
2226 self.service.hideNodes = True |
|
2227 self.resource.getNodes = getNodes |
|
2228 d = self.service.getDiscoItems(JID('user@example.org/home'), |
|
2229 JID('pubsub.example.org'), |
|
2230 '') |
|
2231 d.addCallback(cb) |
|
2232 return d |
|
2233 |
|
2234 |
|
2235 def test_getDiscoItemsNonRoot(self): |
|
2236 """ |
|
2237 Test getDiscoItems on a non-root node. |
|
2238 """ |
|
2239 def getNodes(requestor, service, nodeIdentifier): |
|
2240 return defer.succeed(['node1', 'node2']) |
|
2241 |
|
2242 def cb(items): |
|
2243 self.assertEqual(2, len(items)) |
|
2244 |
|
2245 self.resource.getNodes = getNodes |
|
2246 d = self.service.getDiscoItems(JID('user@example.org/home'), |
|
2247 JID('pubsub.example.org'), |
|
2248 'test') |
|
2249 d.addCallback(cb) |
|
2250 return d |
|
2251 |
|
2252 |
|
2253 def test_on_publish(self): |
|
2254 """ |
|
2255 A publish request should result in L{PubSubService.publish} being |
|
2256 called. |
|
2257 """ |
|
2258 |
|
2259 xml = """ |
|
2260 <iq type='set' to='pubsub.example.org' |
|
2261 from='user@example.org'> |
|
2262 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2263 <publish node='test'/> |
|
2264 </pubsub> |
|
2265 </iq> |
|
2266 """ |
|
2267 |
|
2268 def publish(request): |
|
2269 return defer.succeed(None) |
|
2270 |
|
2271 self.resource.publish = publish |
|
2272 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2273 return self.handleRequest(xml) |
|
2274 |
|
2275 |
|
2276 def test_on_subscribe(self): |
|
2277 """ |
|
2278 A successful subscription should return the current subscription. |
|
2279 """ |
|
2280 |
|
2281 xml = """ |
|
2282 <iq type='set' to='pubsub.example.org' |
|
2283 from='user@example.org'> |
|
2284 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2285 <subscribe node='test' jid='user@example.org/Home'/> |
|
2286 </pubsub> |
|
2287 </iq> |
|
2288 """ |
|
2289 |
|
2290 def subscribe(request): |
|
2291 return defer.succeed(pubsub.Subscription(request.nodeIdentifier, |
|
2292 request.subscriber, |
|
2293 'subscribed')) |
|
2294 |
|
2295 def cb(element): |
|
2296 self.assertEqual('pubsub', element.name) |
|
2297 self.assertEqual(NS_PUBSUB, element.uri) |
|
2298 subscription = element.subscription |
|
2299 self.assertEqual(NS_PUBSUB, subscription.uri) |
|
2300 self.assertEqual('test', subscription['node']) |
|
2301 self.assertEqual('user@example.org/Home', subscription['jid']) |
|
2302 self.assertEqual('subscribed', subscription['subscription']) |
|
2303 |
|
2304 self.resource.subscribe = subscribe |
|
2305 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2306 d = self.handleRequest(xml) |
|
2307 d.addCallback(cb) |
|
2308 return d |
|
2309 |
|
2310 |
|
2311 def test_on_subscribeEmptyNode(self): |
|
2312 """ |
|
2313 A successful subscription on root node should return no node attribute. |
|
2314 """ |
|
2315 |
|
2316 xml = """ |
|
2317 <iq type='set' to='pubsub.example.org' |
|
2318 from='user@example.org'> |
|
2319 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2320 <subscribe jid='user@example.org/Home'/> |
|
2321 </pubsub> |
|
2322 </iq> |
|
2323 """ |
|
2324 |
|
2325 def subscribe(request): |
|
2326 return defer.succeed(pubsub.Subscription(request.nodeIdentifier, |
|
2327 request.subscriber, |
|
2328 'subscribed')) |
|
2329 |
|
2330 def cb(element): |
|
2331 self.assertFalse(element.subscription.hasAttribute('node')) |
|
2332 |
|
2333 self.resource.subscribe = subscribe |
|
2334 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2335 d = self.handleRequest(xml) |
|
2336 d.addCallback(cb) |
|
2337 return d |
|
2338 |
|
2339 |
|
2340 def test_on_subscribeSubscriptionIdentifier(self): |
|
2341 """ |
|
2342 If a subscription returns a subid, this should be available. |
|
2343 """ |
|
2344 |
|
2345 xml = """ |
|
2346 <iq type='set' to='pubsub.example.org' |
|
2347 from='user@example.org'> |
|
2348 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2349 <subscribe node='test' jid='user@example.org/Home'/> |
|
2350 </pubsub> |
|
2351 </iq> |
|
2352 """ |
|
2353 |
|
2354 def subscribe(request): |
|
2355 subscription = pubsub.Subscription(request.nodeIdentifier, |
|
2356 request.subscriber, |
|
2357 'subscribed', |
|
2358 subscriptionIdentifier='1234') |
|
2359 return defer.succeed(subscription) |
|
2360 |
|
2361 def cb(element): |
|
2362 self.assertEqual('1234', element.subscription.getAttribute('subid')) |
|
2363 |
|
2364 self.resource.subscribe = subscribe |
|
2365 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2366 d = self.handleRequest(xml) |
|
2367 d.addCallback(cb) |
|
2368 return d |
|
2369 |
|
2370 |
|
2371 def test_on_unsubscribe(self): |
|
2372 """ |
|
2373 A successful unsubscription should return an empty response. |
|
2374 """ |
|
2375 |
|
2376 xml = """ |
|
2377 <iq type='set' to='pubsub.example.org' |
|
2378 from='user@example.org'> |
|
2379 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2380 <unsubscribe node='test' jid='user@example.org/Home'/> |
|
2381 </pubsub> |
|
2382 </iq> |
|
2383 """ |
|
2384 |
|
2385 def unsubscribe(request): |
|
2386 return defer.succeed(None) |
|
2387 |
|
2388 def cb(element): |
|
2389 self.assertIdentical(None, element) |
|
2390 |
|
2391 self.resource.unsubscribe = unsubscribe |
|
2392 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2393 d = self.handleRequest(xml) |
|
2394 d.addCallback(cb) |
|
2395 return d |
|
2396 |
|
2397 |
|
2398 def test_on_unsubscribeSubscriptionIdentifier(self): |
|
2399 """ |
|
2400 A successful unsubscription with subid should return an empty response. |
|
2401 """ |
|
2402 |
|
2403 xml = """ |
|
2404 <iq type='set' to='pubsub.example.org' |
|
2405 from='user@example.org'> |
|
2406 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2407 <unsubscribe node='test' jid='user@example.org/Home' subid='1234'/> |
|
2408 </pubsub> |
|
2409 </iq> |
|
2410 """ |
|
2411 |
|
2412 def unsubscribe(request): |
|
2413 self.assertEqual('1234', request.subscriptionIdentifier) |
|
2414 return defer.succeed(None) |
|
2415 |
|
2416 def cb(element): |
|
2417 self.assertIdentical(None, element) |
|
2418 |
|
2419 self.resource.unsubscribe = unsubscribe |
|
2420 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2421 d = self.handleRequest(xml) |
|
2422 d.addCallback(cb) |
|
2423 return d |
|
2424 |
|
2425 |
|
2426 def test_on_optionsGet(self): |
|
2427 """ |
|
2428 Getting subscription options is not supported. |
|
2429 """ |
|
2430 |
|
2431 xml = """ |
|
2432 <iq type='get' to='pubsub.example.org' |
|
2433 from='user@example.org'> |
|
2434 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2435 <options node='test' jid='user@example.org/Home'/> |
|
2436 </pubsub> |
|
2437 </iq> |
|
2438 """ |
|
2439 |
|
2440 def cb(result): |
|
2441 self.assertEquals('feature-not-implemented', result.condition) |
|
2442 self.assertEquals('unsupported', result.appCondition.name) |
|
2443 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
2444 |
|
2445 d = self.handleRequest(xml) |
|
2446 self.assertFailure(d, error.StanzaError) |
|
2447 d.addCallback(cb) |
|
2448 return d |
|
2449 |
|
2450 |
|
2451 def test_on_optionsSet(self): |
|
2452 """ |
|
2453 Setting subscription options is not supported. |
|
2454 """ |
|
2455 |
|
2456 xml = """ |
|
2457 <iq type='set' to='pubsub.example.org' |
|
2458 from='user@example.org'> |
|
2459 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2460 <options node='test' jid='user@example.org/Home'> |
|
2461 <x xmlns='jabber:x:data' type='submit'> |
|
2462 <field var='FORM_TYPE' type='hidden'> |
|
2463 <value>http://jabber.org/protocol/pubsub#subscribe_options</value> |
|
2464 </field> |
|
2465 <field var='pubsub#deliver'><value>1</value></field> |
|
2466 </x> |
|
2467 </options> |
|
2468 </pubsub> |
|
2469 </iq> |
|
2470 """ |
|
2471 |
|
2472 def cb(result): |
|
2473 self.assertEquals('feature-not-implemented', result.condition) |
|
2474 self.assertEquals('unsupported', result.appCondition.name) |
|
2475 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
2476 |
|
2477 d = self.handleRequest(xml) |
|
2478 self.assertFailure(d, error.StanzaError) |
|
2479 d.addCallback(cb) |
|
2480 return d |
|
2481 |
|
2482 |
|
2483 def test_on_subscriptions(self): |
|
2484 """ |
|
2485 A subscriptions request should result in |
|
2486 L{PubSubService.subscriptions} being called and the result prepared |
|
2487 for the response. |
|
2488 """ |
|
2489 |
|
2490 xml = """ |
|
2491 <iq type='get' to='pubsub.example.org' |
|
2492 from='user@example.org'> |
|
2493 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2494 <subscriptions/> |
|
2495 </pubsub> |
|
2496 </iq> |
|
2497 """ |
|
2498 |
|
2499 def subscriptions(request): |
|
2500 subscription = pubsub.Subscription('test', JID('user@example.org'), |
|
2501 'subscribed') |
|
2502 return defer.succeed([subscription]) |
|
2503 |
|
2504 def cb(element): |
|
2505 self.assertEqual('pubsub', element.name) |
|
2506 self.assertEqual(NS_PUBSUB, element.uri) |
|
2507 self.assertEqual(NS_PUBSUB, element.subscriptions.uri) |
|
2508 children = list(element.subscriptions.elements()) |
|
2509 self.assertEqual(1, len(children)) |
|
2510 subscription = children[0] |
|
2511 self.assertEqual('subscription', subscription.name) |
|
2512 self.assertEqual(NS_PUBSUB, subscription.uri, NS_PUBSUB) |
|
2513 self.assertEqual('user@example.org', subscription['jid']) |
|
2514 self.assertEqual('test', subscription['node']) |
|
2515 self.assertEqual('subscribed', subscription['subscription']) |
|
2516 |
|
2517 self.resource.subscriptions = subscriptions |
|
2518 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2519 d = self.handleRequest(xml) |
|
2520 d.addCallback(cb) |
|
2521 return d |
|
2522 |
|
2523 |
|
2524 def test_on_subscriptionsWithSubscriptionIdentifier(self): |
|
2525 """ |
|
2526 A subscriptions request response should include subids, if set. |
|
2527 """ |
|
2528 |
|
2529 xml = """ |
|
2530 <iq type='get' to='pubsub.example.org' |
|
2531 from='user@example.org'> |
|
2532 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2533 <subscriptions/> |
|
2534 </pubsub> |
|
2535 </iq> |
|
2536 """ |
|
2537 |
|
2538 def subscriptions(request): |
|
2539 subscription = pubsub.Subscription('test', JID('user@example.org'), |
|
2540 'subscribed', |
|
2541 subscriptionIdentifier='1234') |
|
2542 return defer.succeed([subscription]) |
|
2543 |
|
2544 def cb(element): |
|
2545 subscription = element.subscriptions.subscription |
|
2546 self.assertEqual('1234', subscription['subid']) |
|
2547 |
|
2548 self.resource.subscriptions = subscriptions |
|
2549 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2550 d = self.handleRequest(xml) |
|
2551 d.addCallback(cb) |
|
2552 return d |
|
2553 |
|
2554 |
|
2555 def test_on_affiliations(self): |
|
2556 """ |
|
2557 A subscriptions request should result in |
|
2558 L{PubSubService.affiliations} being called and the result prepared |
|
2559 for the response. |
|
2560 """ |
|
2561 |
|
2562 xml = """ |
|
2563 <iq type='get' to='pubsub.example.org' |
|
2564 from='user@example.org'> |
|
2565 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2566 <affiliations/> |
|
2567 </pubsub> |
|
2568 </iq> |
|
2569 """ |
|
2570 |
|
2571 def affiliations(request): |
|
2572 affiliation = ('test', 'owner') |
|
2573 return defer.succeed([affiliation]) |
|
2574 |
|
2575 def cb(element): |
|
2576 self.assertEqual('pubsub', element.name) |
|
2577 self.assertEqual(NS_PUBSUB, element.uri) |
|
2578 self.assertEqual(NS_PUBSUB, element.affiliations.uri) |
|
2579 children = list(element.affiliations.elements()) |
|
2580 self.assertEqual(1, len(children)) |
|
2581 affiliation = children[0] |
|
2582 self.assertEqual('affiliation', affiliation.name) |
|
2583 self.assertEqual(NS_PUBSUB, affiliation.uri) |
|
2584 self.assertEqual('test', affiliation['node']) |
|
2585 self.assertEqual('owner', affiliation['affiliation']) |
|
2586 |
|
2587 self.resource.affiliations = affiliations |
|
2588 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2589 d = self.handleRequest(xml) |
|
2590 d.addCallback(cb) |
|
2591 return d |
|
2592 |
|
2593 |
|
2594 def test_on_create(self): |
|
2595 """ |
|
2596 Replies to create node requests don't return the created node. |
|
2597 """ |
|
2598 |
|
2599 xml = """ |
|
2600 <iq type='set' to='pubsub.example.org' |
|
2601 from='user@example.org'> |
|
2602 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2603 <create node='mynode'/> |
|
2604 </pubsub> |
|
2605 </iq> |
|
2606 """ |
|
2607 |
|
2608 def create(request): |
|
2609 return defer.succeed(request.nodeIdentifier) |
|
2610 |
|
2611 def cb(element): |
|
2612 self.assertIdentical(None, element) |
|
2613 |
|
2614 self.resource.create = create |
|
2615 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2616 d = self.handleRequest(xml) |
|
2617 d.addCallback(cb) |
|
2618 return d |
|
2619 |
|
2620 |
|
2621 def test_on_createChanged(self): |
|
2622 """ |
|
2623 Replies to create node requests return the created node if changed. |
|
2624 """ |
|
2625 |
|
2626 xml = """ |
|
2627 <iq type='set' to='pubsub.example.org' |
|
2628 from='user@example.org'> |
|
2629 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2630 <create node='mynode'/> |
|
2631 </pubsub> |
|
2632 </iq> |
|
2633 """ |
|
2634 |
|
2635 def create(request): |
|
2636 return defer.succeed(u'myrenamednode') |
|
2637 |
|
2638 def cb(element): |
|
2639 self.assertEqual('pubsub', element.name) |
|
2640 self.assertEqual(NS_PUBSUB, element.uri) |
|
2641 self.assertEqual(NS_PUBSUB, element.create.uri) |
|
2642 self.assertEqual(u'myrenamednode', |
|
2643 element.create.getAttribute('node')) |
|
2644 |
|
2645 self.resource.create = create |
|
2646 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2647 d = self.handleRequest(xml) |
|
2648 d.addCallback(cb) |
|
2649 return d |
|
2650 |
|
2651 |
|
2652 def test_on_createInstant(self): |
|
2653 """ |
|
2654 Replies to create instant node requests return the created node. |
|
2655 """ |
|
2656 |
|
2657 xml = """ |
|
2658 <iq type='set' to='pubsub.example.org' |
|
2659 from='user@example.org'> |
|
2660 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2661 <create/> |
|
2662 </pubsub> |
|
2663 </iq> |
|
2664 """ |
|
2665 |
|
2666 def create(request): |
|
2667 return defer.succeed(u'random') |
|
2668 |
|
2669 def cb(element): |
|
2670 self.assertEqual('pubsub', element.name) |
|
2671 self.assertEqual(NS_PUBSUB, element.uri) |
|
2672 self.assertEqual(NS_PUBSUB, element.create.uri) |
|
2673 self.assertEqual(u'random', element.create.getAttribute('node')) |
|
2674 |
|
2675 self.resource.create = create |
|
2676 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2677 d = self.handleRequest(xml) |
|
2678 d.addCallback(cb) |
|
2679 return d |
|
2680 |
|
2681 |
|
2682 def test_on_createWithConfig(self): |
|
2683 """ |
|
2684 On a node create with configuration request the Data Form is parsed and |
|
2685 L{PubSubResource.create} is called with the passed options. |
|
2686 """ |
|
2687 |
|
2688 xml = """ |
|
2689 <iq type='set' to='pubsub.example.org' |
|
2690 from='user@example.org'> |
|
2691 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
2692 <create node='mynode'/> |
|
2693 <configure> |
|
2694 <x xmlns='jabber:x:data' type='submit'> |
|
2695 <field var='FORM_TYPE' type='hidden'> |
|
2696 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
2697 </field> |
|
2698 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
2699 <field var='pubsub#persist_items'><value>1</value></field> |
|
2700 </x> |
|
2701 </configure> |
|
2702 </pubsub> |
|
2703 </iq> |
|
2704 """ |
|
2705 |
|
2706 def getConfigurationOptions(): |
|
2707 return { |
|
2708 "pubsub#persist_items": |
|
2709 {"type": "boolean", |
|
2710 "label": "Persist items to storage"}, |
|
2711 "pubsub#deliver_payloads": |
|
2712 {"type": "boolean", |
|
2713 "label": "Deliver payloads with event notifications"} |
|
2714 } |
|
2715 |
|
2716 def create(request): |
|
2717 self.assertEqual({'pubsub#deliver_payloads': False, |
|
2718 'pubsub#persist_items': True}, |
|
2719 request.options.getValues()) |
|
2720 return defer.succeed(None) |
|
2721 |
|
2722 self.resource.getConfigurationOptions = getConfigurationOptions |
|
2723 self.resource.create = create |
|
2724 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2725 return self.handleRequest(xml) |
|
2726 |
|
2727 |
|
2728 def test_on_default(self): |
|
2729 """ |
|
2730 A default request returns default options filtered by available fields. |
|
2731 """ |
|
2732 |
|
2733 xml = """ |
|
2734 <iq type='get' to='pubsub.example.org' |
|
2735 from='user@example.org'> |
|
2736 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
2737 <default/> |
|
2738 </pubsub> |
|
2739 </iq> |
|
2740 """ |
|
2741 fieldDefs = { |
|
2742 "pubsub#persist_items": |
|
2743 {"type": "boolean", |
|
2744 "label": "Persist items to storage"}, |
|
2745 "pubsub#deliver_payloads": |
|
2746 {"type": "boolean", |
|
2747 "label": "Deliver payloads with event notifications"} |
|
2748 } |
|
2749 |
|
2750 def getConfigurationOptions(): |
|
2751 return fieldDefs |
|
2752 |
|
2753 def default(request): |
|
2754 return defer.succeed({'pubsub#persist_items': 'false', |
|
2755 'x-myfield': '1'}) |
|
2756 |
|
2757 def cb(element): |
|
2758 self.assertEquals('pubsub', element.name) |
|
2759 self.assertEquals(NS_PUBSUB_OWNER, element.uri) |
|
2760 self.assertEquals(NS_PUBSUB_OWNER, element.default.uri) |
|
2761 form = data_form.Form.fromElement(element.default.x) |
|
2762 self.assertEquals(NS_PUBSUB_NODE_CONFIG, form.formNamespace) |
|
2763 form.typeCheck(fieldDefs) |
|
2764 self.assertIn('pubsub#persist_items', form.fields) |
|
2765 self.assertFalse(form.fields['pubsub#persist_items'].value) |
|
2766 self.assertNotIn('x-myfield', form.fields) |
|
2767 |
|
2768 self.resource.getConfigurationOptions = getConfigurationOptions |
|
2769 self.resource.default = default |
|
2770 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2771 d = self.handleRequest(xml) |
|
2772 d.addCallback(cb) |
|
2773 return d |
|
2774 |
|
2775 |
|
2776 def test_on_defaultUnknownNodeType(self): |
|
2777 """ |
|
2778 Unknown node types yield non-acceptable. |
|
2779 |
|
2780 Both C{getConfigurationOptions} and C{default} must not be called. |
|
2781 """ |
|
2782 |
|
2783 xml = """ |
|
2784 <iq type='get' to='pubsub.example.org' |
|
2785 from='user@example.org'> |
|
2786 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
2787 <default> |
|
2788 <x xmlns='jabber:x:data' type='submit'> |
|
2789 <field var='FORM_TYPE' type='hidden'> |
|
2790 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
2791 </field> |
|
2792 <field var='pubsub#node_type'> |
|
2793 <value>unknown</value> |
|
2794 </field> |
|
2795 </x> |
|
2796 </default> |
|
2797 |
|
2798 </pubsub> |
|
2799 </iq> |
|
2800 """ |
|
2801 |
|
2802 def getConfigurationOptions(): |
|
2803 self.fail("Unexpected call to getConfigurationOptions") |
|
2804 |
|
2805 def default(request): |
|
2806 self.fail("Unexpected call to default") |
|
2807 |
|
2808 def cb(result): |
|
2809 self.assertEquals('not-acceptable', result.condition) |
|
2810 |
|
2811 self.resource.getConfigurationOptions = getConfigurationOptions |
|
2812 self.resource.default = default |
|
2813 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2814 d = self.handleRequest(xml) |
|
2815 self.assertFailure(d, error.StanzaError) |
|
2816 d.addCallback(cb) |
|
2817 return d |
|
2818 |
|
2819 |
|
2820 def test_on_configureGet(self): |
|
2821 """ |
|
2822 On a node configuration get |
|
2823 requestL{PubSubResource.configureGet} is called and results in a |
|
2824 data form with the configuration. |
|
2825 """ |
|
2826 |
|
2827 xml = """ |
|
2828 <iq type='get' to='pubsub.example.org' |
|
2829 from='user@example.org'> |
|
2830 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
2831 <configure node='test'/> |
|
2832 </pubsub> |
|
2833 </iq> |
|
2834 """ |
|
2835 |
|
2836 def getConfigurationOptions(): |
|
2837 return { |
|
2838 "pubsub#persist_items": |
|
2839 {"type": "boolean", |
|
2840 "label": "Persist items to storage"}, |
|
2841 "pubsub#deliver_payloads": |
|
2842 {"type": "boolean", |
|
2843 "label": "Deliver payloads with event notifications"}, |
|
2844 "pubsub#owner": |
|
2845 {"type": "jid-single", |
|
2846 "label": "Owner of the node"} |
|
2847 } |
|
2848 |
|
2849 def configureGet(request): |
|
2850 return defer.succeed({'pubsub#deliver_payloads': '0', |
|
2851 'pubsub#persist_items': '1', |
|
2852 'pubsub#owner': JID('user@example.org'), |
|
2853 'x-myfield': 'a'}) |
|
2854 |
|
2855 def cb(element): |
|
2856 self.assertEqual('pubsub', element.name) |
|
2857 self.assertEqual(NS_PUBSUB_OWNER, element.uri) |
|
2858 self.assertEqual(NS_PUBSUB_OWNER, element.configure.uri) |
|
2859 form = data_form.Form.fromElement(element.configure.x) |
|
2860 self.assertEqual(NS_PUBSUB_NODE_CONFIG, form.formNamespace) |
|
2861 fields = form.fields |
|
2862 |
|
2863 self.assertIn('pubsub#deliver_payloads', fields) |
|
2864 field = fields['pubsub#deliver_payloads'] |
|
2865 self.assertEqual('boolean', field.fieldType) |
|
2866 field.typeCheck() |
|
2867 self.assertEqual(False, field.value) |
|
2868 |
|
2869 self.assertIn('pubsub#persist_items', fields) |
|
2870 field = fields['pubsub#persist_items'] |
|
2871 self.assertEqual('boolean', field.fieldType) |
|
2872 field.typeCheck() |
|
2873 self.assertEqual(True, field.value) |
|
2874 |
|
2875 self.assertIn('pubsub#owner', fields) |
|
2876 field = fields['pubsub#owner'] |
|
2877 self.assertEqual('jid-single', field.fieldType) |
|
2878 field.typeCheck() |
|
2879 self.assertEqual(JID('user@example.org'), field.value) |
|
2880 |
|
2881 self.assertNotIn('x-myfield', fields) |
|
2882 |
|
2883 self.resource.getConfigurationOptions = getConfigurationOptions |
|
2884 self.resource.configureGet = configureGet |
|
2885 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2886 d = self.handleRequest(xml) |
|
2887 d.addCallback(cb) |
|
2888 return d |
|
2889 |
|
2890 |
|
2891 def test_on_configureSet(self): |
|
2892 """ |
|
2893 On a node configuration set request the Data Form is parsed and |
|
2894 L{PubSubResource.configureSet} is called with the passed options. |
|
2895 """ |
|
2896 |
|
2897 xml = """ |
|
2898 <iq type='set' to='pubsub.example.org' |
|
2899 from='user@example.org'> |
|
2900 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
2901 <configure node='test'> |
|
2902 <x xmlns='jabber:x:data' type='submit'> |
|
2903 <field var='FORM_TYPE' type='hidden'> |
|
2904 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
2905 </field> |
|
2906 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
2907 <field var='pubsub#persist_items'><value>1</value></field> |
|
2908 </x> |
|
2909 </configure> |
|
2910 </pubsub> |
|
2911 </iq> |
|
2912 """ |
|
2913 |
|
2914 def getConfigurationOptions(): |
|
2915 return { |
|
2916 "pubsub#persist_items": |
|
2917 {"type": "boolean", |
|
2918 "label": "Persist items to storage"}, |
|
2919 "pubsub#deliver_payloads": |
|
2920 {"type": "boolean", |
|
2921 "label": "Deliver payloads with event notifications"} |
|
2922 } |
|
2923 |
|
2924 def configureSet(request): |
|
2925 self.assertEqual({'pubsub#deliver_payloads': False, |
|
2926 'pubsub#persist_items': True}, |
|
2927 request.options.getValues()) |
|
2928 return defer.succeed(None) |
|
2929 |
|
2930 self.resource.getConfigurationOptions = getConfigurationOptions |
|
2931 self.resource.configureSet = configureSet |
|
2932 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2933 return self.handleRequest(xml) |
|
2934 |
|
2935 |
|
2936 def test_on_configureSetCancel(self): |
|
2937 """ |
|
2938 The node configuration is cancelled, |
|
2939 L{PubSubResource.configureSet} not called. |
|
2940 """ |
|
2941 |
|
2942 xml = """ |
|
2943 <iq type='set' to='pubsub.example.org' |
|
2944 from='user@example.org'> |
|
2945 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
2946 <configure node='test'> |
|
2947 <x xmlns='jabber:x:data' type='cancel'> |
|
2948 <field var='FORM_TYPE' type='hidden'> |
|
2949 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
2950 </field> |
|
2951 </x> |
|
2952 </configure> |
|
2953 </pubsub> |
|
2954 </iq> |
|
2955 """ |
|
2956 |
|
2957 def configureSet(request): |
|
2958 self.fail("Unexpected call to setConfiguration") |
|
2959 |
|
2960 self.resource.configureSet = configureSet |
|
2961 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
2962 return self.handleRequest(xml) |
|
2963 |
|
2964 |
|
2965 def test_on_configureSetIgnoreUnknown(self): |
|
2966 """ |
|
2967 On a node configuration set request unknown fields should be ignored. |
|
2968 """ |
|
2969 |
|
2970 xml = """ |
|
2971 <iq type='set' to='pubsub.example.org' |
|
2972 from='user@example.org'> |
|
2973 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
2974 <configure node='test'> |
|
2975 <x xmlns='jabber:x:data' type='submit'> |
|
2976 <field var='FORM_TYPE' type='hidden'> |
|
2977 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
2978 </field> |
|
2979 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
2980 <field var='x-myfield'><value>1</value></field> |
|
2981 </x> |
|
2982 </configure> |
|
2983 </pubsub> |
|
2984 </iq> |
|
2985 """ |
|
2986 |
|
2987 def getConfigurationOptions(): |
|
2988 return { |
|
2989 "pubsub#persist_items": |
|
2990 {"type": "boolean", |
|
2991 "label": "Persist items to storage"}, |
|
2992 "pubsub#deliver_payloads": |
|
2993 {"type": "boolean", |
|
2994 "label": "Deliver payloads with event notifications"} |
|
2995 } |
|
2996 |
|
2997 def configureSet(request): |
|
2998 self.assertEquals(['pubsub#deliver_payloads'], |
|
2999 request.options.keys()) |
|
3000 |
|
3001 self.resource.getConfigurationOptions = getConfigurationOptions |
|
3002 self.resource.configureSet = configureSet |
|
3003 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3004 return self.handleRequest(xml) |
|
3005 |
|
3006 |
|
3007 def test_on_configureSetBadFormType(self): |
|
3008 """ |
|
3009 On a node configuration set request unknown fields should be ignored. |
|
3010 """ |
|
3011 |
|
3012 xml = """ |
|
3013 <iq type='set' to='pubsub.example.org' |
|
3014 from='user@example.org'> |
|
3015 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3016 <configure node='test'> |
|
3017 <x xmlns='jabber:x:data' type='result'> |
|
3018 <field var='FORM_TYPE' type='hidden'> |
|
3019 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
3020 </field> |
|
3021 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
3022 <field var='x-myfield'><value>1</value></field> |
|
3023 </x> |
|
3024 </configure> |
|
3025 </pubsub> |
|
3026 </iq> |
|
3027 """ |
|
3028 |
|
3029 def cb(result): |
|
3030 self.assertEquals('bad-request', result.condition) |
|
3031 self.assertEqual("Unexpected form type 'result'", result.text) |
|
3032 |
|
3033 d = self.handleRequest(xml) |
|
3034 self.assertFailure(d, error.StanzaError) |
|
3035 d.addCallback(cb) |
|
3036 return d |
|
3037 |
|
3038 |
|
3039 def test_on_items(self): |
|
3040 """ |
|
3041 On a items request, return all items for the given node. |
|
3042 """ |
|
3043 xml = """ |
|
3044 <iq type='get' to='pubsub.example.org' |
|
3045 from='user@example.org'> |
|
3046 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3047 <items node='test'/> |
|
3048 </pubsub> |
|
3049 </iq> |
|
3050 """ |
|
3051 |
|
3052 def items(request): |
|
3053 return defer.succeed([pubsub.Item('current')]) |
|
3054 |
|
3055 def cb(element): |
|
3056 self.assertEqual(NS_PUBSUB, element.uri) |
|
3057 self.assertEqual(NS_PUBSUB, element.items.uri) |
|
3058 self.assertEqual(1, len(element.items.children)) |
|
3059 item = element.items.children[-1] |
|
3060 self.assertTrue(domish.IElement.providedBy(item)) |
|
3061 self.assertEqual('item', item.name) |
|
3062 self.assertEqual(NS_PUBSUB, item.uri) |
|
3063 self.assertEqual('current', item['id']) |
|
3064 |
|
3065 self.resource.items = items |
|
3066 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3067 d = self.handleRequest(xml) |
|
3068 d.addCallback(cb) |
|
3069 return d |
|
3070 |
|
3071 |
|
3072 def test_on_retract(self): |
|
3073 """ |
|
3074 A retract request should result in L{PubSubResource.retract} |
|
3075 being called. |
|
3076 """ |
|
3077 |
|
3078 xml = """ |
|
3079 <iq type='set' to='pubsub.example.org' |
|
3080 from='user@example.org'> |
|
3081 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3082 <retract node='test'> |
|
3083 <item id='item1'/> |
|
3084 <item id='item2'/> |
|
3085 </retract> |
|
3086 </pubsub> |
|
3087 </iq> |
|
3088 """ |
|
3089 |
|
3090 def retract(request): |
|
3091 return defer.succeed(None) |
|
3092 |
|
3093 self.resource.retract = retract |
|
3094 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3095 return self.handleRequest(xml) |
|
3096 |
|
3097 |
|
3098 def test_on_purge(self): |
|
3099 """ |
|
3100 A purge request should result in L{PubSubResource.purge} being |
|
3101 called. |
|
3102 """ |
|
3103 |
|
3104 xml = """ |
|
3105 <iq type='set' to='pubsub.example.org' |
|
3106 from='user@example.org'> |
|
3107 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3108 <purge node='test'/> |
|
3109 </pubsub> |
|
3110 </iq> |
|
3111 """ |
|
3112 |
|
3113 def purge(request): |
|
3114 return defer.succeed(None) |
|
3115 |
|
3116 self.resource.purge = purge |
|
3117 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3118 return self.handleRequest(xml) |
|
3119 |
|
3120 |
|
3121 def test_on_delete(self): |
|
3122 """ |
|
3123 A delete request should result in L{PubSubResource.delete} being |
|
3124 called. |
|
3125 """ |
|
3126 |
|
3127 xml = """ |
|
3128 <iq type='set' to='pubsub.example.org' |
|
3129 from='user@example.org'> |
|
3130 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3131 <delete node='test'/> |
|
3132 </pubsub> |
|
3133 </iq> |
|
3134 """ |
|
3135 |
|
3136 def delete(request): |
|
3137 return defer.succeed(None) |
|
3138 |
|
3139 self.resource.delete = delete |
|
3140 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3141 return self.handleRequest(xml) |
|
3142 |
|
3143 |
|
3144 def test_notifyPublish(self): |
|
3145 """ |
|
3146 Publish notifications are sent to the subscribers. |
|
3147 """ |
|
3148 subscriber = JID('user@example.org') |
|
3149 subscriptions = [pubsub.Subscription('test', subscriber, 'subscribed')] |
|
3150 items = [pubsub.Item('current')] |
|
3151 notifications = [(subscriber, subscriptions, items)] |
|
3152 self.service.notifyPublish(JID('pubsub.example.org'), 'test', |
|
3153 notifications) |
|
3154 message = self.stub.output[-1] |
|
3155 |
|
3156 self.assertEquals('message', message.name) |
|
3157 self.assertIdentical(None, message.uri) |
|
3158 self.assertEquals('user@example.org', message['to']) |
|
3159 self.assertEquals('pubsub.example.org', message['from']) |
|
3160 self.assertTrue(message.event) |
|
3161 self.assertEquals(NS_PUBSUB_EVENT, message.event.uri) |
|
3162 self.assertTrue(message.event.items) |
|
3163 self.assertEquals(NS_PUBSUB_EVENT, message.event.items.uri) |
|
3164 self.assertTrue(message.event.items.hasAttribute('node')) |
|
3165 self.assertEquals('test', message.event.items['node']) |
|
3166 itemElements = list(domish.generateElementsQNamed( |
|
3167 message.event.items.children, 'item', NS_PUBSUB_EVENT)) |
|
3168 self.assertEquals(1, len(itemElements)) |
|
3169 self.assertEquals('current', itemElements[0].getAttribute('id')) |
|
3170 |
|
3171 |
|
3172 def test_notifyPublishCollection(self): |
|
3173 """ |
|
3174 Publish notifications are sent to the subscribers of collections. |
|
3175 |
|
3176 The node the item was published to is on the C{items} element, while |
|
3177 the subscribed-to node is in the C{'Collections'} SHIM header. |
|
3178 """ |
|
3179 subscriber = JID('user@example.org') |
|
3180 subscriptions = [pubsub.Subscription('', subscriber, 'subscribed')] |
|
3181 items = [pubsub.Item('current')] |
|
3182 notifications = [(subscriber, subscriptions, items)] |
|
3183 self.service.notifyPublish(JID('pubsub.example.org'), 'test', |
|
3184 notifications) |
|
3185 message = self.stub.output[-1] |
|
3186 |
|
3187 self.assertTrue(message.event.items.hasAttribute('node')) |
|
3188 self.assertEquals('test', message.event.items['node']) |
|
3189 headers = shim.extractHeaders(message) |
|
3190 self.assertIn('Collection', headers) |
|
3191 self.assertIn('', headers['Collection']) |
|
3192 |
|
3193 |
|
3194 def test_notifyDelete(self): |
|
3195 """ |
|
3196 Subscribers should be sent a delete notification. |
|
3197 """ |
|
3198 subscriptions = [JID('user@example.org')] |
|
3199 self.service.notifyDelete(JID('pubsub.example.org'), 'test', |
|
3200 subscriptions) |
|
3201 message = self.stub.output[-1] |
|
3202 |
|
3203 self.assertEquals('message', message.name) |
|
3204 self.assertIdentical(None, message.uri) |
|
3205 self.assertEquals('user@example.org', message['to']) |
|
3206 self.assertEquals('pubsub.example.org', message['from']) |
|
3207 self.assertTrue(message.event) |
|
3208 self.assertEqual(NS_PUBSUB_EVENT, message.event.uri) |
|
3209 self.assertTrue(message.event.delete) |
|
3210 self.assertEqual(NS_PUBSUB_EVENT, message.event.delete.uri) |
|
3211 self.assertTrue(message.event.delete.hasAttribute('node')) |
|
3212 self.assertEqual('test', message.event.delete['node']) |
|
3213 |
|
3214 |
|
3215 def test_notifyDeleteRedirect(self): |
|
3216 """ |
|
3217 Subscribers should be sent a delete notification with redirect. |
|
3218 """ |
|
3219 redirectURI = 'xmpp:pubsub.example.org?;node=test2' |
|
3220 subscriptions = [JID('user@example.org')] |
|
3221 self.service.notifyDelete(JID('pubsub.example.org'), 'test', |
|
3222 subscriptions, redirectURI) |
|
3223 message = self.stub.output[-1] |
|
3224 |
|
3225 self.assertEquals('message', message.name) |
|
3226 self.assertIdentical(None, message.uri) |
|
3227 self.assertEquals('user@example.org', message['to']) |
|
3228 self.assertEquals('pubsub.example.org', message['from']) |
|
3229 self.assertTrue(message.event) |
|
3230 self.assertEqual(NS_PUBSUB_EVENT, message.event.uri) |
|
3231 self.assertTrue(message.event.delete) |
|
3232 self.assertEqual(NS_PUBSUB_EVENT, message.event.delete.uri) |
|
3233 self.assertTrue(message.event.delete.hasAttribute('node')) |
|
3234 self.assertEqual('test', message.event.delete['node']) |
|
3235 self.assertTrue(message.event.delete.redirect) |
|
3236 self.assertEqual(NS_PUBSUB_EVENT, message.event.delete.redirect.uri) |
|
3237 self.assertTrue(message.event.delete.redirect.hasAttribute('uri')) |
|
3238 self.assertEqual(redirectURI, message.event.delete.redirect['uri']) |
|
3239 |
|
3240 |
|
3241 def test_on_subscriptionsGet(self): |
|
3242 """ |
|
3243 Getting subscription options is not supported. |
|
3244 """ |
|
3245 |
|
3246 xml = """ |
|
3247 <iq type='get' to='pubsub.example.org' |
|
3248 from='user@example.org'> |
|
3249 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3250 <subscriptions/> |
|
3251 </pubsub> |
|
3252 </iq> |
|
3253 """ |
|
3254 |
|
3255 def cb(result): |
|
3256 self.assertEquals('feature-not-implemented', result.condition) |
|
3257 self.assertEquals('unsupported', result.appCondition.name) |
|
3258 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3259 self.assertEquals('manage-subscriptions', |
|
3260 result.appCondition['feature']) |
|
3261 |
|
3262 d = self.handleRequest(xml) |
|
3263 self.assertFailure(d, error.StanzaError) |
|
3264 d.addCallback(cb) |
|
3265 return d |
|
3266 |
|
3267 |
|
3268 def test_on_subscriptionsSet(self): |
|
3269 """ |
|
3270 Setting subscription options is not supported. |
|
3271 """ |
|
3272 |
|
3273 xml = """ |
|
3274 <iq type='set' to='pubsub.example.org' |
|
3275 from='user@example.org'> |
|
3276 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3277 <subscriptions/> |
|
3278 </pubsub> |
|
3279 </iq> |
|
3280 """ |
|
3281 |
|
3282 def cb(result): |
|
3283 self.assertEquals('feature-not-implemented', result.condition) |
|
3284 self.assertEquals('unsupported', result.appCondition.name) |
|
3285 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3286 self.assertEquals('manage-subscriptions', |
|
3287 result.appCondition['feature']) |
|
3288 |
|
3289 d = self.handleRequest(xml) |
|
3290 self.assertFailure(d, error.StanzaError) |
|
3291 d.addCallback(cb) |
|
3292 return d |
|
3293 |
|
3294 |
|
3295 def test_on_affiliationsGet(self): |
|
3296 """ |
|
3297 Getting node affiliations should have. |
|
3298 """ |
|
3299 |
|
3300 xml = """ |
|
3301 <iq type='get' to='pubsub.example.org' |
|
3302 from='user@example.org'> |
|
3303 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3304 <affiliations node='test'/> |
|
3305 </pubsub> |
|
3306 </iq> |
|
3307 """ |
|
3308 |
|
3309 def affiliationsGet(request): |
|
3310 self.assertEquals('test', request.nodeIdentifier) |
|
3311 return defer.succeed({JID('user@example.org'): 'owner'}) |
|
3312 |
|
3313 def cb(element): |
|
3314 self.assertEquals(u'pubsub', element.name) |
|
3315 self.assertEquals(NS_PUBSUB_OWNER, element.uri) |
|
3316 self.assertEquals(NS_PUBSUB_OWNER, element.affiliations.uri) |
|
3317 self.assertEquals(u'test', element.affiliations[u'node']) |
|
3318 children = list(element.affiliations.elements()) |
|
3319 self.assertEquals(1, len(children)) |
|
3320 affiliation = children[0] |
|
3321 self.assertEquals(u'affiliation', affiliation.name) |
|
3322 self.assertEquals(NS_PUBSUB_OWNER, affiliation.uri) |
|
3323 self.assertEquals(u'user@example.org', affiliation[u'jid']) |
|
3324 self.assertEquals(u'owner', affiliation[u'affiliation']) |
|
3325 |
|
3326 self.resource.affiliationsGet = affiliationsGet |
|
3327 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3328 d = self.handleRequest(xml) |
|
3329 d.addCallback(cb) |
|
3330 return d |
|
3331 |
|
3332 |
|
3333 def test_on_affiliationsGetEmptyNode(self): |
|
3334 """ |
|
3335 Getting node affiliations without node should assume empty node. |
|
3336 """ |
|
3337 |
|
3338 xml = """ |
|
3339 <iq type='get' to='pubsub.example.org' |
|
3340 from='user@example.org'> |
|
3341 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3342 <affiliations/> |
|
3343 </pubsub> |
|
3344 </iq> |
|
3345 """ |
|
3346 |
|
3347 def affiliationsGet(request): |
|
3348 self.assertEqual('', request.nodeIdentifier) |
|
3349 return defer.succeed({}) |
|
3350 |
|
3351 def cb(element): |
|
3352 self.assertFalse(element.affiliations.hasAttribute(u'node')) |
|
3353 |
|
3354 self.resource.affiliationsGet = affiliationsGet |
|
3355 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3356 d = self.handleRequest(xml) |
|
3357 d.addCallback(cb) |
|
3358 return d |
|
3359 |
|
3360 |
|
3361 def test_on_affiliationsSet(self): |
|
3362 """ |
|
3363 Setting node affiliations has the affiliations to be modified. |
|
3364 """ |
|
3365 |
|
3366 xml = """ |
|
3367 <iq type='set' to='pubsub.example.org' |
|
3368 from='user@example.org'> |
|
3369 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3370 <affiliations node='test'> |
|
3371 <affiliation jid='other@example.org' affiliation='publisher'/> |
|
3372 </affiliations> |
|
3373 </pubsub> |
|
3374 </iq> |
|
3375 """ |
|
3376 |
|
3377 def affiliationsSet(request): |
|
3378 self.assertEquals(u'test', request.nodeIdentifier) |
|
3379 otherJID = JID(u'other@example.org') |
|
3380 self.assertIn(otherJID, request.affiliations) |
|
3381 self.assertEquals(u'publisher', request.affiliations[otherJID]) |
|
3382 |
|
3383 self.resource.affiliationsSet = affiliationsSet |
|
3384 return self.handleRequest(xml) |
|
3385 |
|
3386 |
|
3387 def test_on_affiliationsSetBareJID(self): |
|
3388 """ |
|
3389 Affiliations are always on the bare JID. |
|
3390 """ |
|
3391 |
|
3392 xml = """ |
|
3393 <iq type='set' to='pubsub.example.org' |
|
3394 from='user@example.org'> |
|
3395 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3396 <affiliations node='test'> |
|
3397 <affiliation jid='other@example.org/Home' |
|
3398 affiliation='publisher'/> |
|
3399 </affiliations> |
|
3400 </pubsub> |
|
3401 </iq> |
|
3402 """ |
|
3403 |
|
3404 def affiliationsSet(request): |
|
3405 otherJID = JID(u'other@example.org') |
|
3406 self.assertIn(otherJID, request.affiliations) |
|
3407 |
|
3408 self.resource.affiliationsSet = affiliationsSet |
|
3409 return self.handleRequest(xml) |
|
3410 |
|
3411 |
|
3412 def test_on_affiliationsSetMultipleForSameEntity(self): |
|
3413 """ |
|
3414 Setting node affiliations can only have one item per entity. |
|
3415 """ |
|
3416 |
|
3417 xml = """ |
|
3418 <iq type='set' to='pubsub.example.org' |
|
3419 from='user@example.org'> |
|
3420 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3421 <affiliations node='test'> |
|
3422 <affiliation jid='other@example.org' affiliation='publisher'/> |
|
3423 <affiliation jid='other@example.org' affiliation='owner'/> |
|
3424 </affiliations> |
|
3425 </pubsub> |
|
3426 </iq> |
|
3427 """ |
|
3428 |
|
3429 def cb(result): |
|
3430 self.assertEquals('bad-request', result.condition) |
|
3431 |
|
3432 d = self.handleRequest(xml) |
|
3433 self.assertFailure(d, error.StanzaError) |
|
3434 d.addCallback(cb) |
|
3435 return d |
|
3436 |
|
3437 |
|
3438 def test_on_affiliationsSetMissingJID(self): |
|
3439 """ |
|
3440 Setting node affiliations must include a JID per affiliation. |
|
3441 """ |
|
3442 |
|
3443 xml = """ |
|
3444 <iq type='set' to='pubsub.example.org' |
|
3445 from='user@example.org'> |
|
3446 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3447 <affiliations node='test'> |
|
3448 <affiliation affiliation='publisher'/> |
|
3449 </affiliations> |
|
3450 </pubsub> |
|
3451 </iq> |
|
3452 """ |
|
3453 |
|
3454 def cb(result): |
|
3455 self.assertEquals('bad-request', result.condition) |
|
3456 |
|
3457 d = self.handleRequest(xml) |
|
3458 self.assertFailure(d, error.StanzaError) |
|
3459 d.addCallback(cb) |
|
3460 return d |
|
3461 |
|
3462 |
|
3463 def test_on_affiliationsSetMissingAffiliation(self): |
|
3464 """ |
|
3465 Setting node affiliations must include an affiliation. |
|
3466 """ |
|
3467 |
|
3468 xml = """ |
|
3469 <iq type='set' to='pubsub.example.org' |
|
3470 from='user@example.org'> |
|
3471 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3472 <affiliations node='test'> |
|
3473 <affiliation jid='other@example.org'/> |
|
3474 </affiliations> |
|
3475 </pubsub> |
|
3476 </iq> |
|
3477 """ |
|
3478 |
|
3479 def cb(result): |
|
3480 self.assertEquals('bad-request', result.condition) |
|
3481 |
|
3482 d = self.handleRequest(xml) |
|
3483 self.assertFailure(d, error.StanzaError) |
|
3484 d.addCallback(cb) |
|
3485 return d |
|
3486 |
|
3487 |
|
3488 |
|
3489 class PubSubServiceWithoutResourceTest(unittest.TestCase, TestableRequestHandlerMixin): |
|
3490 |
|
3491 def setUp(self): |
|
3492 self.stub = XmlStreamStub() |
|
3493 self.service = pubsub.PubSubService() |
|
3494 self.service.send = self.stub.xmlstream.send |
|
3495 |
|
3496 |
|
3497 def test_getDiscoInfo(self): |
|
3498 """ |
|
3499 Test getDiscoInfo calls getNodeInfo and returns some minimal info. |
|
3500 """ |
|
3501 def cb(info): |
|
3502 discoInfo = disco.DiscoInfo() |
|
3503 for item in info: |
|
3504 discoInfo.append(item) |
|
3505 self.assertIn(('pubsub', 'service'), discoInfo.identities) |
|
3506 self.assertIn(disco.NS_DISCO_ITEMS, discoInfo.features) |
|
3507 |
|
3508 d = self.service.getDiscoInfo(JID('user@example.org/home'), |
|
3509 JID('pubsub.example.org'), '') |
|
3510 d.addCallback(cb) |
|
3511 return d |
|
3512 |
|
3513 |
|
3514 def test_publish(self): |
|
3515 """ |
|
3516 Non-overridden L{PubSubService.publish} yields unsupported error. |
|
3517 """ |
|
3518 |
|
3519 xml = """ |
|
3520 <iq type='set' to='pubsub.example.org' |
|
3521 from='user@example.org'> |
|
3522 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3523 <publish node='mynode'/> |
|
3524 </pubsub> |
|
3525 </iq> |
|
3526 """ |
|
3527 |
|
3528 def cb(result): |
|
3529 self.assertEquals('feature-not-implemented', result.condition) |
|
3530 self.assertEquals('unsupported', result.appCondition.name) |
|
3531 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3532 self.assertEquals('publish', result.appCondition['feature']) |
|
3533 |
|
3534 d = self.handleRequest(xml) |
|
3535 self.assertFailure(d, error.StanzaError) |
|
3536 d.addCallback(cb) |
|
3537 return d |
|
3538 |
|
3539 |
|
3540 def test_subscribe(self): |
|
3541 """ |
|
3542 Non-overridden L{PubSubService.subscribe} yields unsupported error. |
|
3543 """ |
|
3544 |
|
3545 xml = """ |
|
3546 <iq type='set' to='pubsub.example.org' |
|
3547 from='user@example.org'> |
|
3548 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3549 <subscribe node='test' jid='user@example.org/Home'/> |
|
3550 </pubsub> |
|
3551 </iq> |
|
3552 """ |
|
3553 |
|
3554 def cb(result): |
|
3555 self.assertEquals('feature-not-implemented', result.condition) |
|
3556 self.assertEquals('unsupported', result.appCondition.name) |
|
3557 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3558 self.assertEquals('subscribe', result.appCondition['feature']) |
|
3559 |
|
3560 d = self.handleRequest(xml) |
|
3561 self.assertFailure(d, error.StanzaError) |
|
3562 d.addCallback(cb) |
|
3563 return d |
|
3564 |
|
3565 |
|
3566 def test_unsubscribe(self): |
|
3567 """ |
|
3568 Non-overridden L{PubSubService.unsubscribe} yields unsupported error. |
|
3569 """ |
|
3570 |
|
3571 xml = """ |
|
3572 <iq type='set' to='pubsub.example.org' |
|
3573 from='user@example.org'> |
|
3574 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3575 <unsubscribe node='test' jid='user@example.org/Home'/> |
|
3576 </pubsub> |
|
3577 </iq> |
|
3578 """ |
|
3579 |
|
3580 def cb(result): |
|
3581 self.assertEquals('feature-not-implemented', result.condition) |
|
3582 self.assertEquals('unsupported', result.appCondition.name) |
|
3583 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3584 self.assertEquals('subscribe', result.appCondition['feature']) |
|
3585 |
|
3586 d = self.handleRequest(xml) |
|
3587 self.assertFailure(d, error.StanzaError) |
|
3588 d.addCallback(cb) |
|
3589 return d |
|
3590 |
|
3591 |
|
3592 def test_subscriptions(self): |
|
3593 """ |
|
3594 Non-overridden L{PubSubService.subscriptions} yields unsupported error. |
|
3595 """ |
|
3596 |
|
3597 xml = """ |
|
3598 <iq type='get' to='pubsub.example.org' |
|
3599 from='user@example.org'> |
|
3600 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3601 <subscriptions/> |
|
3602 </pubsub> |
|
3603 </iq> |
|
3604 """ |
|
3605 |
|
3606 def cb(result): |
|
3607 self.assertEquals('feature-not-implemented', result.condition) |
|
3608 self.assertEquals('unsupported', result.appCondition.name) |
|
3609 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3610 self.assertEquals('retrieve-subscriptions', |
|
3611 result.appCondition['feature']) |
|
3612 |
|
3613 d = self.handleRequest(xml) |
|
3614 self.assertFailure(d, error.StanzaError) |
|
3615 d.addCallback(cb) |
|
3616 return d |
|
3617 |
|
3618 |
|
3619 def test_affiliations(self): |
|
3620 """ |
|
3621 Non-overridden L{PubSubService.affiliations} yields unsupported error. |
|
3622 """ |
|
3623 |
|
3624 xml = """ |
|
3625 <iq type='get' to='pubsub.example.org' |
|
3626 from='user@example.org'> |
|
3627 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3628 <affiliations/> |
|
3629 </pubsub> |
|
3630 </iq> |
|
3631 """ |
|
3632 |
|
3633 def cb(result): |
|
3634 self.assertEquals('feature-not-implemented', result.condition) |
|
3635 self.assertEquals('unsupported', result.appCondition.name) |
|
3636 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3637 self.assertEquals('retrieve-affiliations', |
|
3638 result.appCondition['feature']) |
|
3639 |
|
3640 d = self.handleRequest(xml) |
|
3641 self.assertFailure(d, error.StanzaError) |
|
3642 d.addCallback(cb) |
|
3643 return d |
|
3644 |
|
3645 |
|
3646 def test_create(self): |
|
3647 """ |
|
3648 Non-overridden L{PubSubService.create} yields unsupported error. |
|
3649 """ |
|
3650 |
|
3651 xml = """ |
|
3652 <iq type='set' to='pubsub.example.org' |
|
3653 from='user@example.org'> |
|
3654 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3655 <create node='mynode'/> |
|
3656 </pubsub> |
|
3657 </iq> |
|
3658 """ |
|
3659 |
|
3660 def cb(result): |
|
3661 self.assertEquals('feature-not-implemented', result.condition) |
|
3662 self.assertEquals('unsupported', result.appCondition.name) |
|
3663 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3664 self.assertEquals('create-nodes', result.appCondition['feature']) |
|
3665 |
|
3666 d = self.handleRequest(xml) |
|
3667 self.assertFailure(d, error.StanzaError) |
|
3668 d.addCallback(cb) |
|
3669 return d |
|
3670 |
|
3671 |
|
3672 def test_getDefaultConfiguration(self): |
|
3673 """ |
|
3674 Non-overridden L{PubSubService.getDefaultConfiguration} yields |
|
3675 unsupported error. |
|
3676 """ |
|
3677 |
|
3678 xml = """ |
|
3679 <iq type='get' to='pubsub.example.org' |
|
3680 from='user@example.org'> |
|
3681 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3682 <default/> |
|
3683 </pubsub> |
|
3684 </iq> |
|
3685 """ |
|
3686 |
|
3687 def cb(result): |
|
3688 self.assertEquals('feature-not-implemented', result.condition) |
|
3689 self.assertEquals('unsupported', result.appCondition.name) |
|
3690 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3691 self.assertEquals('retrieve-default', result.appCondition['feature']) |
|
3692 |
|
3693 d = self.handleRequest(xml) |
|
3694 self.assertFailure(d, error.StanzaError) |
|
3695 d.addCallback(cb) |
|
3696 return d |
|
3697 |
|
3698 |
|
3699 def test_getConfiguration(self): |
|
3700 """ |
|
3701 Non-overridden L{PubSubService.getConfiguration} yields unsupported |
|
3702 error. |
|
3703 """ |
|
3704 |
|
3705 xml = """ |
|
3706 <iq type='get' to='pubsub.example.org' |
|
3707 from='user@example.org'> |
|
3708 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3709 <configure/> |
|
3710 </pubsub> |
|
3711 </iq> |
|
3712 """ |
|
3713 |
|
3714 def cb(result): |
|
3715 self.assertEquals('feature-not-implemented', result.condition) |
|
3716 self.assertEquals('unsupported', result.appCondition.name) |
|
3717 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3718 self.assertEquals('config-node', result.appCondition['feature']) |
|
3719 |
|
3720 d = self.handleRequest(xml) |
|
3721 self.assertFailure(d, error.StanzaError) |
|
3722 d.addCallback(cb) |
|
3723 return d |
|
3724 |
|
3725 |
|
3726 def test_setConfiguration(self): |
|
3727 """ |
|
3728 Non-overridden L{PubSubService.setConfiguration} yields unsupported |
|
3729 error. |
|
3730 """ |
|
3731 |
|
3732 xml = """ |
|
3733 <iq type='set' to='pubsub.example.org' |
|
3734 from='user@example.org'> |
|
3735 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3736 <configure node='test'> |
|
3737 <x xmlns='jabber:x:data' type='submit'> |
|
3738 <field var='FORM_TYPE' type='hidden'> |
|
3739 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
3740 </field> |
|
3741 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
3742 <field var='pubsub#persist_items'><value>1</value></field> |
|
3743 </x> |
|
3744 </configure> |
|
3745 </pubsub> |
|
3746 </iq> |
|
3747 """ |
|
3748 |
|
3749 def cb(result): |
|
3750 self.assertEquals('feature-not-implemented', result.condition) |
|
3751 self.assertEquals('unsupported', result.appCondition.name) |
|
3752 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3753 self.assertEquals('config-node', result.appCondition['feature']) |
|
3754 |
|
3755 d = self.handleRequest(xml) |
|
3756 self.assertFailure(d, error.StanzaError) |
|
3757 d.addCallback(cb) |
|
3758 return d |
|
3759 |
|
3760 |
|
3761 def test_setConfigurationOptionsDict(self): |
|
3762 """ |
|
3763 Options should be passed as a dictionary, not a form. |
|
3764 """ |
|
3765 |
|
3766 xml = """ |
|
3767 <iq type='set' to='pubsub.example.org' |
|
3768 from='user@example.org'> |
|
3769 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3770 <configure node='test'> |
|
3771 <x xmlns='jabber:x:data' type='submit'> |
|
3772 <field var='FORM_TYPE' type='hidden'> |
|
3773 <value>http://jabber.org/protocol/pubsub#node_config</value> |
|
3774 </field> |
|
3775 <field var='pubsub#deliver_payloads'><value>0</value></field> |
|
3776 <field var='pubsub#persist_items'><value>1</value></field> |
|
3777 </x> |
|
3778 </configure> |
|
3779 </pubsub> |
|
3780 </iq> |
|
3781 """ |
|
3782 |
|
3783 def getConfigurationOptions(): |
|
3784 return { |
|
3785 "pubsub#persist_items": |
|
3786 {"type": "boolean", |
|
3787 "label": "Persist items to storage"}, |
|
3788 "pubsub#deliver_payloads": |
|
3789 {"type": "boolean", |
|
3790 "label": "Deliver payloads with event notifications"} |
|
3791 } |
|
3792 |
|
3793 def setConfiguration(requestor, service, nodeIdentifier, options): |
|
3794 self.assertIn('pubsub#deliver_payloads', options) |
|
3795 self.assertFalse(options['pubsub#deliver_payloads']) |
|
3796 self.assertIn('pubsub#persist_items', options) |
|
3797 self.assertTrue(options['pubsub#persist_items']) |
|
3798 |
|
3799 self.service.getConfigurationOptions = getConfigurationOptions |
|
3800 self.service.setConfiguration = setConfiguration |
|
3801 return self.handleRequest(xml) |
|
3802 |
|
3803 |
|
3804 def test_items(self): |
|
3805 """ |
|
3806 Non-overridden L{PubSubService.items} yields unsupported error. |
|
3807 """ |
|
3808 xml = """ |
|
3809 <iq type='get' to='pubsub.example.org' |
|
3810 from='user@example.org'> |
|
3811 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3812 <items node='test'/> |
|
3813 </pubsub> |
|
3814 </iq> |
|
3815 """ |
|
3816 |
|
3817 def cb(result): |
|
3818 self.assertEquals('feature-not-implemented', result.condition) |
|
3819 self.assertEquals('unsupported', result.appCondition.name) |
|
3820 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3821 self.assertEquals('retrieve-items', result.appCondition['feature']) |
|
3822 |
|
3823 d = self.handleRequest(xml) |
|
3824 self.assertFailure(d, error.StanzaError) |
|
3825 d.addCallback(cb) |
|
3826 return d |
|
3827 |
|
3828 |
|
3829 def test_retract(self): |
|
3830 """ |
|
3831 Non-overridden L{PubSubService.retract} yields unsupported error. |
|
3832 """ |
|
3833 xml = """ |
|
3834 <iq type='set' to='pubsub.example.org' |
|
3835 from='user@example.org'> |
|
3836 <pubsub xmlns='http://jabber.org/protocol/pubsub'> |
|
3837 <retract node='test'> |
|
3838 <item id='item1'/> |
|
3839 <item id='item2'/> |
|
3840 </retract> |
|
3841 </pubsub> |
|
3842 </iq> |
|
3843 """ |
|
3844 |
|
3845 def cb(result): |
|
3846 self.assertEquals('feature-not-implemented', result.condition) |
|
3847 self.assertEquals('unsupported', result.appCondition.name) |
|
3848 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3849 self.assertEquals('retract-items', result.appCondition['feature']) |
|
3850 |
|
3851 d = self.handleRequest(xml) |
|
3852 self.assertFailure(d, error.StanzaError) |
|
3853 d.addCallback(cb) |
|
3854 return d |
|
3855 |
|
3856 |
|
3857 def test_purge(self): |
|
3858 """ |
|
3859 Non-overridden L{PubSubService.purge} yields unsupported error. |
|
3860 """ |
|
3861 xml = """ |
|
3862 <iq type='set' to='pubsub.example.org' |
|
3863 from='user@example.org'> |
|
3864 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3865 <purge node='test'/> |
|
3866 </pubsub> |
|
3867 </iq> |
|
3868 """ |
|
3869 |
|
3870 def cb(result): |
|
3871 self.assertEquals('feature-not-implemented', result.condition) |
|
3872 self.assertEquals('unsupported', result.appCondition.name) |
|
3873 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3874 self.assertEquals('purge-nodes', result.appCondition['feature']) |
|
3875 |
|
3876 d = self.handleRequest(xml) |
|
3877 self.assertFailure(d, error.StanzaError) |
|
3878 d.addCallback(cb) |
|
3879 return d |
|
3880 |
|
3881 |
|
3882 def test_delete(self): |
|
3883 """ |
|
3884 Non-overridden L{PubSubService.delete} yields unsupported error. |
|
3885 """ |
|
3886 xml = """ |
|
3887 <iq type='set' to='pubsub.example.org' |
|
3888 from='user@example.org'> |
|
3889 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3890 <delete node='test'/> |
|
3891 </pubsub> |
|
3892 </iq> |
|
3893 """ |
|
3894 |
|
3895 def cb(result): |
|
3896 self.assertEquals('feature-not-implemented', result.condition) |
|
3897 self.assertEquals('unsupported', result.appCondition.name) |
|
3898 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3899 self.assertEquals('delete-nodes', result.appCondition['feature']) |
|
3900 |
|
3901 d = self.handleRequest(xml) |
|
3902 self.assertFailure(d, error.StanzaError) |
|
3903 d.addCallback(cb) |
|
3904 return d |
|
3905 |
|
3906 |
|
3907 def test_unknown(self): |
|
3908 """ |
|
3909 Unknown verb yields unsupported error. |
|
3910 """ |
|
3911 xml = """ |
|
3912 <iq type='get' to='pubsub.example.org' |
|
3913 from='user@example.org'> |
|
3914 <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> |
|
3915 <affiliations node='test'/> |
|
3916 </pubsub> |
|
3917 </iq> |
|
3918 """ |
|
3919 |
|
3920 def cb(result): |
|
3921 self.assertEquals('feature-not-implemented', result.condition) |
|
3922 self.assertEquals('unsupported', result.appCondition.name) |
|
3923 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3924 |
|
3925 d = self.handleRequest(xml) |
|
3926 self.assertFailure(d, error.StanzaError) |
|
3927 d.addCallback(cb) |
|
3928 return d |
|
3929 |
|
3930 |
|
3931 |
|
3932 class PubSubResourceTest(unittest.TestCase): |
|
3933 |
|
3934 def setUp(self): |
|
3935 self.resource = pubsub.PubSubResource() |
|
3936 |
|
3937 |
|
3938 def test_interface(self): |
|
3939 """ |
|
3940 Do instances of L{pubsub.PubSubResource} provide L{iwokkel.IPubSubResource}? |
|
3941 """ |
|
3942 verify.verifyObject(iwokkel.IPubSubResource, self.resource) |
|
3943 |
|
3944 |
|
3945 def test_getNodes(self): |
|
3946 """ |
|
3947 Default getNodes returns an empty list. |
|
3948 """ |
|
3949 def cb(nodes): |
|
3950 self.assertEquals([], nodes) |
|
3951 |
|
3952 d = self.resource.getNodes(JID('user@example.org/home'), |
|
3953 JID('pubsub.example.org'), |
|
3954 '') |
|
3955 d.addCallback(cb) |
|
3956 return d |
|
3957 |
|
3958 |
|
3959 def test_publish(self): |
|
3960 """ |
|
3961 Non-overridden L{PubSubResource.publish} yields unsupported |
|
3962 error. |
|
3963 """ |
|
3964 |
|
3965 def cb(result): |
|
3966 self.assertEquals('feature-not-implemented', result.condition) |
|
3967 self.assertEquals('unsupported', result.appCondition.name) |
|
3968 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3969 self.assertEquals('publish', result.appCondition['feature']) |
|
3970 |
|
3971 d = self.resource.publish(pubsub.PubSubRequest()) |
|
3972 self.assertFailure(d, error.StanzaError) |
|
3973 d.addCallback(cb) |
|
3974 return d |
|
3975 |
|
3976 |
|
3977 def test_subscribe(self): |
|
3978 """ |
|
3979 Non-overridden subscriptions yields unsupported error. |
|
3980 """ |
|
3981 |
|
3982 def cb(result): |
|
3983 self.assertEquals('feature-not-implemented', result.condition) |
|
3984 self.assertEquals('unsupported', result.appCondition.name) |
|
3985 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
3986 self.assertEquals('subscribe', result.appCondition['feature']) |
|
3987 |
|
3988 d = self.resource.subscribe(pubsub.PubSubRequest()) |
|
3989 self.assertFailure(d, error.StanzaError) |
|
3990 d.addCallback(cb) |
|
3991 return d |
|
3992 |
|
3993 |
|
3994 def test_unsubscribe(self): |
|
3995 """ |
|
3996 Non-overridden unsubscribe yields unsupported error. |
|
3997 """ |
|
3998 |
|
3999 def cb(result): |
|
4000 self.assertEquals('feature-not-implemented', result.condition) |
|
4001 self.assertEquals('unsupported', result.appCondition.name) |
|
4002 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4003 self.assertEquals('subscribe', result.appCondition['feature']) |
|
4004 |
|
4005 d = self.resource.unsubscribe(pubsub.PubSubRequest()) |
|
4006 self.assertFailure(d, error.StanzaError) |
|
4007 d.addCallback(cb) |
|
4008 return d |
|
4009 |
|
4010 |
|
4011 def test_subscriptions(self): |
|
4012 """ |
|
4013 Non-overridden subscriptions yields unsupported error. |
|
4014 """ |
|
4015 |
|
4016 def cb(result): |
|
4017 self.assertEquals('feature-not-implemented', result.condition) |
|
4018 self.assertEquals('unsupported', result.appCondition.name) |
|
4019 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4020 self.assertEquals('retrieve-subscriptions', |
|
4021 result.appCondition['feature']) |
|
4022 |
|
4023 d = self.resource.subscriptions(pubsub.PubSubRequest()) |
|
4024 self.assertFailure(d, error.StanzaError) |
|
4025 d.addCallback(cb) |
|
4026 return d |
|
4027 |
|
4028 |
|
4029 def test_affiliations(self): |
|
4030 """ |
|
4031 Non-overridden affiliations yields unsupported error. |
|
4032 """ |
|
4033 |
|
4034 def cb(result): |
|
4035 self.assertEquals('feature-not-implemented', result.condition) |
|
4036 self.assertEquals('unsupported', result.appCondition.name) |
|
4037 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4038 self.assertEquals('retrieve-affiliations', |
|
4039 result.appCondition['feature']) |
|
4040 |
|
4041 d = self.resource.affiliations(pubsub.PubSubRequest()) |
|
4042 self.assertFailure(d, error.StanzaError) |
|
4043 d.addCallback(cb) |
|
4044 return d |
|
4045 |
|
4046 |
|
4047 def test_create(self): |
|
4048 """ |
|
4049 Non-overridden create yields unsupported error. |
|
4050 """ |
|
4051 |
|
4052 def cb(result): |
|
4053 self.assertEquals('feature-not-implemented', result.condition) |
|
4054 self.assertEquals('unsupported', result.appCondition.name) |
|
4055 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4056 self.assertEquals('create-nodes', result.appCondition['feature']) |
|
4057 |
|
4058 d = self.resource.create(pubsub.PubSubRequest()) |
|
4059 self.assertFailure(d, error.StanzaError) |
|
4060 d.addCallback(cb) |
|
4061 return d |
|
4062 |
|
4063 |
|
4064 def test_default(self): |
|
4065 """ |
|
4066 Non-overridden default yields unsupported error. |
|
4067 """ |
|
4068 |
|
4069 def cb(result): |
|
4070 self.assertEquals('feature-not-implemented', result.condition) |
|
4071 self.assertEquals('unsupported', result.appCondition.name) |
|
4072 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4073 self.assertEquals('retrieve-default', |
|
4074 result.appCondition['feature']) |
|
4075 |
|
4076 d = self.resource.default(pubsub.PubSubRequest()) |
|
4077 self.assertFailure(d, error.StanzaError) |
|
4078 d.addCallback(cb) |
|
4079 return d |
|
4080 |
|
4081 |
|
4082 def test_configureGet(self): |
|
4083 """ |
|
4084 Non-overridden configureGet yields unsupported |
|
4085 error. |
|
4086 """ |
|
4087 |
|
4088 def cb(result): |
|
4089 self.assertEquals('feature-not-implemented', result.condition) |
|
4090 self.assertEquals('unsupported', result.appCondition.name) |
|
4091 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4092 self.assertEquals('config-node', result.appCondition['feature']) |
|
4093 |
|
4094 d = self.resource.configureGet(pubsub.PubSubRequest()) |
|
4095 self.assertFailure(d, error.StanzaError) |
|
4096 d.addCallback(cb) |
|
4097 return d |
|
4098 |
|
4099 |
|
4100 def test_configureSet(self): |
|
4101 """ |
|
4102 Non-overridden configureSet yields unsupported error. |
|
4103 """ |
|
4104 |
|
4105 def cb(result): |
|
4106 self.assertEquals('feature-not-implemented', result.condition) |
|
4107 self.assertEquals('unsupported', result.appCondition.name) |
|
4108 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4109 self.assertEquals('config-node', result.appCondition['feature']) |
|
4110 |
|
4111 d = self.resource.configureSet(pubsub.PubSubRequest()) |
|
4112 self.assertFailure(d, error.StanzaError) |
|
4113 d.addCallback(cb) |
|
4114 return d |
|
4115 |
|
4116 |
|
4117 def test_items(self): |
|
4118 """ |
|
4119 Non-overridden items yields unsupported error. |
|
4120 """ |
|
4121 |
|
4122 def cb(result): |
|
4123 self.assertEquals('feature-not-implemented', result.condition) |
|
4124 self.assertEquals('unsupported', result.appCondition.name) |
|
4125 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4126 self.assertEquals('retrieve-items', result.appCondition['feature']) |
|
4127 |
|
4128 d = self.resource.items(pubsub.PubSubRequest()) |
|
4129 self.assertFailure(d, error.StanzaError) |
|
4130 d.addCallback(cb) |
|
4131 return d |
|
4132 |
|
4133 |
|
4134 def test_retract(self): |
|
4135 """ |
|
4136 Non-overridden retract yields unsupported error. |
|
4137 """ |
|
4138 |
|
4139 def cb(result): |
|
4140 self.assertEquals('feature-not-implemented', result.condition) |
|
4141 self.assertEquals('unsupported', result.appCondition.name) |
|
4142 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4143 self.assertEquals('retract-items', result.appCondition['feature']) |
|
4144 |
|
4145 d = self.resource.retract(pubsub.PubSubRequest()) |
|
4146 self.assertFailure(d, error.StanzaError) |
|
4147 d.addCallback(cb) |
|
4148 return d |
|
4149 |
|
4150 |
|
4151 def test_purge(self): |
|
4152 """ |
|
4153 Non-overridden purge yields unsupported error. |
|
4154 """ |
|
4155 |
|
4156 def cb(result): |
|
4157 self.assertEquals('feature-not-implemented', result.condition) |
|
4158 self.assertEquals('unsupported', result.appCondition.name) |
|
4159 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4160 self.assertEquals('purge-nodes', result.appCondition['feature']) |
|
4161 |
|
4162 d = self.resource.purge(pubsub.PubSubRequest()) |
|
4163 self.assertFailure(d, error.StanzaError) |
|
4164 d.addCallback(cb) |
|
4165 return d |
|
4166 |
|
4167 |
|
4168 def test_delete(self): |
|
4169 """ |
|
4170 Non-overridden delete yields unsupported error. |
|
4171 """ |
|
4172 |
|
4173 def cb(result): |
|
4174 self.assertEquals('feature-not-implemented', result.condition) |
|
4175 self.assertEquals('unsupported', result.appCondition.name) |
|
4176 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4177 self.assertEquals('delete-nodes', result.appCondition['feature']) |
|
4178 |
|
4179 d = self.resource.delete(pubsub.PubSubRequest()) |
|
4180 self.assertFailure(d, error.StanzaError) |
|
4181 d.addCallback(cb) |
|
4182 return d |
|
4183 |
|
4184 |
|
4185 def test_affiliationsGet(self): |
|
4186 """ |
|
4187 Non-overridden owner affiliations get yields unsupported error. |
|
4188 """ |
|
4189 |
|
4190 def cb(result): |
|
4191 self.assertEquals('feature-not-implemented', result.condition) |
|
4192 self.assertEquals('unsupported', result.appCondition.name) |
|
4193 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4194 self.assertEquals('modify-affiliations', |
|
4195 result.appCondition['feature']) |
|
4196 |
|
4197 d = self.resource.affiliationsGet(pubsub.PubSubRequest()) |
|
4198 self.assertFailure(d, error.StanzaError) |
|
4199 d.addCallback(cb) |
|
4200 return d |
|
4201 |
|
4202 |
|
4203 def test_affiliationsSet(self): |
|
4204 """ |
|
4205 Non-overridden owner affiliations set yields unsupported error. |
|
4206 """ |
|
4207 |
|
4208 def cb(result): |
|
4209 self.assertEquals('feature-not-implemented', result.condition) |
|
4210 self.assertEquals('unsupported', result.appCondition.name) |
|
4211 self.assertEquals(NS_PUBSUB_ERRORS, result.appCondition.uri) |
|
4212 self.assertEquals('modify-affiliations', |
|
4213 result.appCondition['feature']) |
|
4214 |
|
4215 d = self.resource.affiliationsSet(pubsub.PubSubRequest()) |
|
4216 self.assertFailure(d, error.StanzaError) |
|
4217 d.addCallback(cb) |
|
4218 return d |