def test_full_cycle(self): # foo logs in. xml = """<presence from='*****@*****.**' to='example.com'> <query xmlns='http://jarn.com/ns/collaborative-editing' node='hamlet'/> </presence>""" self.stub.send(parseXml(xml)) # bar logs in. xml = """<presence from='*****@*****.**' to='example.com'> <query xmlns='http://jarn.com/ns/collaborative-editing' node='hamlet'/> </presence>""" self.stub.send(parseXml(xml)) # foo changes the Sheakespearean text to plain english, # and creates a patch. original2plain_patch = self.dmp.patch_make(self.original, self.plain) original2plain_text = self.dmp.patch_toText(original2plain_patch) xml = "<iq from='*****@*****.**' to='example.com' type='set'>" + \ "<patch xmlns='http://jarn.com/ns/collaborative-editing' node='hamlet'>" + \ original2plain_text + \ "</patch></iq>" self.stub.send(parseXml(xml)) # Before receiving a patch from the server bar has already updated # his own version to trekkie and sends it away. original2trekkie_patch = self.dmp.patch_make(self.original, self.trekkie) original2trekkie_text = self.dmp.patch_toText(original2trekkie_patch) xml = "<iq from='*****@*****.**' to='example.com' type='set'>" + \ "<patch xmlns='http://jarn.com/ns/collaborative-editing' node='hamlet'>" + \ original2trekkie_text + \ "</patch></iq>" self.stub.send(parseXml(xml)) # So now, both have obtained a patch to apply each other changes on # the already changed document. They are the same and merged perfectly. iq_to_foo = self.stub.output[-1] plain2final_text = iq_to_foo.patch.children[0] plain2final_patch = self.dmp.patch_fromText(plain2final_text) foo_result = self.dmp.patch_apply(plain2final_patch, self.plain) foo_final = foo_result[0] self.assertEqual(self.final, foo_final) iq_to_bar = self.stub.output[-3] trekkie2final_text = iq_to_bar.patch.children[0] trekkie2final_patch = self.dmp.patch_fromText(trekkie2final_text) bar_result = self.dmp.patch_apply(trekkie2final_patch, self.trekkie) bar_final = bar_result[0] self.assertEqual(self.final, bar_final)
def _translate(tx, recipient, out): qlist = ['SELECT `id`, `timestamp`, `content`, `expire_timestamp` FROM stanzas_%s WHERE `recipient` = ?' % (t, ) for t in self.tables] qargs = [recipient.user for t in self.tables] tx.execute('SELECT * FROM (' + ' UNION '.join(qlist) + ') a ORDER BY `timestamp`', qargs) data = tx.fetchall() for row in data: stanzaId = str(row[0]) d = { 'id': stanzaId, 'timestamp': datetime.datetime.utcfromtimestamp(row[1] / 1e3), 'expire': datetime.datetime.utcfromtimestamp(row[3]) if row[3] else None } d['stanza'] = generic.parseXml(row[2].decode('utf-8').encode('utf-8')) """ Add a <storage/> element to the stanza; this way components have a way to know if stanza is coming from storage. """ stor = d['stanza'].addElement((xmlstream2.NS_XMPP_STORAGE, 'storage')) stor['id'] = stanzaId out.append(d) return out
def test_noHeaders(self): """ A stanza without headers results in an empty dictionary. """ stanza = parseXml("""<message/>""") headers = shim.extractHeaders(stanza) self.assertEquals({}, headers)
def _translate(tx, recipient, out): qlist = [ "SELECT `id`, `timestamp`, `content`, `expire_timestamp` FROM stanzas_%s WHERE `recipient` = ?" % (t,) for t in self.tables ] qargs = [recipient.user for t in self.tables] tx.execute("SELECT * FROM (" + " UNION ".join(qlist) + ") a ORDER BY `timestamp`", qargs) data = tx.fetchall() for row in data: stanzaId = str(row[0]) d = { "id": stanzaId, "timestamp": datetime.datetime.utcfromtimestamp(row[1] / 1e3), "expire": datetime.datetime.utcfromtimestamp(row[3]) if row[3] else None, } d["stanza"] = generic.parseXml(row[2].decode("utf-8").encode("utf-8")) """ Add a <storage/> element to the stanza; this way components have a way to know if stanza is coming from storage. """ stor = d["stanza"].addElement((xmlstream2.NS_XMPP_STORAGE, "storage")) stor["id"] = stanzaId out.append(d) return out
def test_fromElement(self): """ Test properties when creating L{disco.DiscoInfo} from L{domish.Element}. """ xml = """<query xmlns='http://jabber.org/protocol/disco#info'> <identity category='conference' type='text' name='A Dark Cave'/> <feature var='http://jabber.org/protocol/muc'/> <feature var='jabber:iq:register'/> <x xmlns='jabber:x:data' type='result'> <field var='FORM_TYPE' type='hidden'> <value>http://jabber.org/protocol/muc#roominfo</value> </field> </x> </query>""" element = parseXml(xml) info = disco.DiscoInfo.fromElement(element) self.assertIn(u'http://jabber.org/protocol/muc', info.features) self.assertIn(u'jabber:iq:register', info.features) self.assertIn((u'conference', u'text'), info.identities) self.assertEqual(u'A Dark Cave', info.identities[(u'conference', u'text')]) self.assertIn(u'http://jabber.org/protocol/muc#roominfo', info.extensions)
def test_fromElementItems(self): """ Test items when creating L{disco.DiscoInfo} from L{domish.Element}. """ xml = """<query xmlns='http://jabber.org/protocol/disco#info'> <identity category='conference' type='text' name='A Dark Cave'/> <feature var='http://jabber.org/protocol/muc'/> <feature var='jabber:iq:register'/> <x xmlns='jabber:x:data' type='result'> <field var='FORM_TYPE' type='hidden'> <value>http://jabber.org/protocol/muc#roominfo</value> </field> </x> </query>""" element = parseXml(xml) info = disco.DiscoInfo.fromElement(element) info = list(info) self.assertEqual(4, len(info)) identity = info[0] self.assertEqual(u'conference', identity.category) self.assertEqual(u'http://jabber.org/protocol/muc', info[1]) self.assertEqual(u'jabber:iq:register', info[2]) extension = info[3] self.assertEqual(u'http://jabber.org/protocol/muc#roominfo', extension.formNamespace)
def test_getAffiliationsForJid_current(self, sendMock): xml = """ <iq type='result' from='pubsub.shakespeare.lit' to='*****@*****.**' id='affil1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <affiliations> <affiliation node='node1' affiliation='owner'/> <affiliation node='node2' affiliation='publisher'/> <affiliation node='node5' affiliation='outcast'/> <affiliation node='node6' affiliation='owner'/> </affiliations> </pubsub> </iq> """ el = parseXml(xml) sendMock.side_effect = utils.good_side_effect(el) xs = Mock() d = psaff.getAffiliationsForJid(jid.JID('*****@*****.**'), xs) def cb(affs): expected = { 'node1': 'owner', 'node2': 'publisher', 'node5': 'outcast', 'node6': 'owner' } self.assertEquals(expected, affs) sendMock.assert_called_once_with(xs) d.addCallback(cb) return d
def test_getAffiliations_current(self, sendMock): xml = """ <iq type='result' from='pubsub.shakespeare.lit' to='[email protected]/elsinore' id='ent1'> <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'> <affiliations node='princely_musings'> <affiliation jid='*****@*****.**' affiliation='owner'/> <affiliation jid='*****@*****.**' affiliation='outcast'/> </affiliations> </pubsub> </iq> """ el = parseXml(xml) sendMock.side_effect = utils.good_side_effect(el) xs = Mock() d = psaff.getAffiliations(jid.JID('[email protected]/elsinore'), 'princely_musings', xs) def cb(affs): expected = { jid.internJID('*****@*****.**').userhostJID(): 'owner', jid.internJID('*****@*****.**').userhostJID(): 'outcast', } self.assertEquals(expected, affs) sendMock.assert_called_once_with(xs) d.addCallback(cb) return d
def test_getShadowCopyIQ(self): # User [email protected] joins self.protocol.mock_text['test-node'] = 'foo' xml = """<presence from='*****@*****.**' to='example.com'> <query xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </presence>""" self.stub.send(parseXml(xml)) # And requests the shadow copy of 'test-node' xml = """<iq from='*****@*****.**' to='example.com' type='get'> <shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </iq>""" self.stub.send(parseXml(xml)) response = self.stub.output[-1] self.assertEqual( "<iq to='*****@*****.**' from='example.com' type='result'>" + "<shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'>foo</shadowcopy>" + "</iq>", response.toXml()) # Requesting the shadow copy of an non-existent node should result in Unauthorized error xml = """<iq from='*****@*****.**' to='example.com' type='get'> <shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='unknown-node'/> </iq>""" self.stub.send(parseXml(xml)) response = self.stub.output[-1] self.assertEqual( "<iq to='*****@*****.**' from='example.com' type='error'>" + "<error xmlns='http://jarn.com/ns/collaborative-editing'>Unauthorized</error></iq>", response.toXml()) # User [email protected] who has not sent a presence to the component should not be able # to retrieve the text. xml = """<iq from='*****@*****.**' to='example.com' type='get'> <shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </iq>""" self.stub.send(parseXml(xml)) response = self.stub.output[-1] self.assertEqual( "<iq to='*****@*****.**' from='example.com' type='error'>" + "<error xmlns='http://jarn.com/ns/collaborative-editing'>Unauthorized</error></iq>", response.toXml())
def test_fromElement(self): xml = """ <message type='chat' from='*****@*****.**' to='*****@*****.**'/> """ stanza = generic.Stanza.fromElement(generic.parseXml(xml)) self.assertEqual('chat', stanza.stanzaType) self.assertEqual(JID('*****@*****.**'), stanza.sender) self.assertEqual(JID('*****@*****.**'), stanza.recipient)
def test_fromElementNoNode(self): """ Test creating L{disco.DiscoItems} from L{domish.Element}, no node. """ xml = """<query xmlns='http://jabber.org/protocol/disco#items'/>""" element = parseXml(xml) items = disco.DiscoItems.fromElement(element) self.assertEqual(u'', items.nodeIdentifier)
def parseResponse(self, contents, protocol): self.client = protocol try: element = parseXml(contents) body_tag = element elements = element.children except Exception, ex: log.err(str(ex)) raise
def test_fromElementBadStamp(self): """ A malformed timestamp results in C{None} for the stamp attribute. """ xml = parseXml(u""" <delay xmlns="urn:xmpp:delay" stamp="foobar"/> """) delay = Delay.fromElement(xml) self.assertIdentical(None, delay.stamp)
def test_fromElementMissingStamp(self): """ A missing timestamp results in C{None} for the stamp attribute. """ xml = parseXml(u""" <delay xmlns="urn:xmpp:delay"/> """) delay = Delay.fromElement(xml) self.assertIdentical(None, delay.stamp)
def test_fromElementChildParserUnknown(self): """ Child elements for which no parser is defined are ignored. """ xml = """ <message from='*****@*****.**' to='*****@*****.**'> <x xmlns='http://example.org/'/> </message> """ generic.Stanza.fromElement(generic.parseXml(xml))
def render_POST(self, request): if request.requestHeaders.hasHeader(b'Event'): payload = None else: payload = parseXml(request.content.read()) self.callback(payload, request.requestHeaders) request.setResponseCode(http.NO_CONTENT) return b''
def test_getSubscriptionsForJid_current(self, sendMock): xml = """ <iq type='result' from='pubsub.shakespeare.lit' to='*****@*****.**' id='subscriptions1'> <pubsub xmlns='http://jabber.org/protocol/pubsub'> <subscriptions> <subscription node='node1' jid='*****@*****.**' subscription='subscribed'/> <subscription node='node2' jid='*****@*****.**' subscription='subscribed'/> <subscription node='node5' jid='*****@*****.**' subscription='unconfigured'/> <subscription node='node6' jid='*****@*****.**' subscription='subscribed' subid='123-abc'/> <subscription node='node6' jid='*****@*****.**' subscription='subscribed' subid='004-yyy'/> </subscriptions> </pubsub> </iq> """ el = parseXml(xml) sendMock.side_effect = utils.good_side_effect(el) xs = Mock() d = psaff.getSubscriptionsForJid(jid.JID('*****@*****.**'), xs) def cb(subs): actual = [a.toElement().toXml() for a in subs] expected = [ ps.Subscription( nodeIdentifier='node1', subscriber=jid.internJID('*****@*****.**').userhostJID(), state='subscribed'), ps.Subscription( nodeIdentifier='node2', subscriber=jid.internJID('*****@*****.**').userhostJID(), state='subscribed'), ps.Subscription( nodeIdentifier='node5', subscriber=jid.internJID('*****@*****.**').userhostJID(), state='unconfigured'), ps.Subscription( nodeIdentifier='node6', subscriber=jid.internJID('*****@*****.**').userhostJID(), state='subscribed', subscriptionIdentifier='123-abc'), ps.Subscription( nodeIdentifier='node6', subscriber=jid.internJID('*****@*****.**').userhostJID(), state='subscribed', subscriptionIdentifier='004-yyy'), ] self.assertEquals(len(actual), 5) for ex in expected: self.assertIn(ex.toElement().toXml(), actual) sendMock.assert_called_once_with(xs) d.addCallback(cb) return d
def test_getShadowCopyIQ(self): # User [email protected] joins self.protocol.mock_text['test-node'] = 'foo' xml = """<presence from='*****@*****.**' to='example.com'> <query xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </presence>""" self.stub.send(parseXml(xml)) # And requests the shadow copy of 'test-node' xml = """<iq from='*****@*****.**' to='example.com' type='get'> <shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </iq>""" self.stub.send(parseXml(xml)) response = self.stub.output[-1] self.assertEqual("<iq to='*****@*****.**' from='example.com' type='result'>" + "<shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'>foo</shadowcopy>" + "</iq>", response.toXml()) # Requesting the shadow copy of an non-existent node should result in Unauthorized error xml = """<iq from='*****@*****.**' to='example.com' type='get'> <shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='unknown-node'/> </iq>""" self.stub.send(parseXml(xml)) response = self.stub.output[-1] self.assertEqual("<iq to='*****@*****.**' from='example.com' type='error'>" + "<error xmlns='http://jarn.com/ns/collaborative-editing'>Unauthorized</error></iq>", response.toXml()) # User [email protected] who has not sent a presence to the component should not be able # to retrieve the text. xml = """<iq from='*****@*****.**' to='example.com' type='get'> <shadowcopy xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </iq>""" self.stub.send(parseXml(xml)) response = self.stub.output[-1] self.assertEqual("<iq to='*****@*****.**' from='example.com' type='error'>" + "<error xmlns='http://jarn.com/ns/collaborative-editing'>Unauthorized</error></iq>", response.toXml())
def test_onPingHandled(self): """ The ping handler should mark the stanza as handled. """ xml = """<iq from='*****@*****.**' to='example.com' type='get'> <ping xmlns='urn:xmpp:ping'/> </iq>""" iq = parseXml(xml) self.stub.send(iq) self.assertTrue(iq.handled)
def test_fromParentElementLegacy(self): """ A child element with legacy delay information is found and parsed. """ xml = parseXml(u""" <message> <x xmlns="jabber:x:delay" stamp="20020910T23:08:25"/> </message> """) stanza = DelayStanza.fromElement(xml) self.assertNotIdentical(None, stanza.delay)
def test_fromElementSender(self): """ The optional original sender address is parsed as a JID. """ xml = parseXml(u""" <delay xmlns="urn:xmpp:delay" stamp="2002-09-10T23:08:25Z" from="*****@*****.**"/> """) delay = Delay.fromElement(xml) self.assertEqual(JID(u'*****@*****.**'), delay.sender)
def formatPayload(src, xml): """ Hook up a newly created source to a feed and call format_payload. """ payload = parseXml(xml) feed = aggregator.Feed(handle=u'mediamatic', language=u'en') src.activate() src.feed = feed return src.format_payload(payload)
def test_fromParentElement(self): """ A child element with delay information is found and parsed. """ xml = parseXml(u""" <message> <delay xmlns="urn:xmpp:delay" stamp="2002-09-10T23:08:25Z"/> </message> """) stanza = DelayStanza.fromElement(xml) self.assertNotIdentical(None, stanza.delay)
def test_fromElementVersionEmpty(self): """ The ver attribute may be empty. """ xml = """ <iq type='get' to='[email protected]/Home' from='*****@*****.**'> <query xmlns='jabber:iq:roster' ver=''/> </iq> """ request = xmppim.RosterRequest.fromElement(parseXml(xml)) self.assertEqual('', request.version)
def test_fromElementSenderBad(self): """ An invalid original sender address results in C{None}. """ xml = parseXml(u""" <delay xmlns="urn:xmpp:delay" stamp="2002-09-10T23:08:25Z" from="user@@example.org"/> """) delay = Delay.fromElement(xml) self.assertIdentical(None, delay.sender)
def test_fromElementNode(self): """ Test creating L{disco.DiscoInfo} from L{domish.Element}, with node. """ xml = """<query xmlns='http://jabber.org/protocol/disco#info' node='test'> </query>""" element = parseXml(xml) info = disco.DiscoInfo.fromElement(element) self.assertEqual(u'test', info.nodeIdentifier)
def test_onPing(self): """ A ping should have a simple result response. """ xml = """<iq from='*****@*****.**' to='example.com' type='get'> <ping xmlns='urn:xmpp:ping'/> </iq>""" self.stub.send(parseXml(xml)) response = self.stub.output[-1] self.assertEquals('example.com', response.getAttribute('from')) self.assertEquals('*****@*****.**', response.getAttribute('to')) self.assertEquals('result', response.getAttribute('type'))
def _getItemsById(self, cursor, itemIdentifiers): self._checkNodeExists(cursor) items = [] for itemIdentifier in itemIdentifiers: cursor.execute( """SELECT data FROM nodes NATURAL JOIN items WHERE node=%s AND item=%s""", (self.nodeIdentifier, itemIdentifier)) result = cursor.fetchone() if result: items.append(parseXml(result[0])) return items
def _getItemsById(self, cursor, itemIdentifiers): self._checkNodeExists(cursor) items = [] for itemIdentifier in itemIdentifiers: cursor.execute("""SELECT data FROM nodes NATURAL JOIN items WHERE node=%s AND item=%s""", (self.nodeIdentifier, itemIdentifier)) result = cursor.fetchone() if result: items.append(parseXml(result[0])) return items
def test_onPatch(self): # 'foo' is the initial text. foo and bar present. self.protocol.mock_text['test-node'] = 'foo' xml = """<presence from='*****@*****.**' to='example.com'> <query xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </presence>""" self.stub.send(parseXml(xml)) xml = """<presence from='*****@*****.**' to='example.com'> <query xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'/> </presence>""" self.stub.send(parseXml(xml)) # bar sends a patch changing the text to 'foobar'. xml = """<iq from='*****@*****.**' to='example.com' id='id_1' type='set'> <patch xmlns='http://jarn.com/ns/collaborative-editing' node='test-node'>@@ -1,3 +1,6 @@\n foo\n+bar\n</patch> </iq>""" self.stub.send(parseXml(xml)) # He should have received a 'success' reply response = self.stub.output[-2] self.assertEqual( "<iq to='*****@*****.**' from='example.com' id='id_1' type='result'>" + "<success xmlns='http://jarn.com/ns/collaborative-editing'/></iq>", response.toXml()) # foo receives the same patch. iq = self.stub.output[-1] self.assertEqual( "<iq to='*****@*****.**' type='set' id='H_0'>" + "<patch xmlns='http://jarn.com/ns/collaborative-editing' " + "node='test-node' user='******'>@@ -1,3 +1,6 @@\n foo\n+bar\n</patch></iq>", iq.toXml()) # The shadow copy is 'foobar' self.assertEqual(u'foobar', self.protocol.shadow_copies['test-node'])
def test_fromElementLegacy(self): """ For legacy XEP-0091 support, the timestamp is assumed to be in UTC. """ xml = parseXml(u""" <x xmlns="jabber:x:delay" stamp="20020910T23:08:25"/> """) delay = Delay.fromElement(xml) self.assertEqual( datetime(2002, 9, 10, 23, 8, 25, tzinfo=dateutil.tz.tzutc()), delay.stamp) self.assertIdentical(None, delay.sender)
def test_fromElement(self): """ The timestamp is parsed with the proper timezone (UTC). """ xml = parseXml(u""" <delay xmlns="urn:xmpp:delay" stamp="2002-09-10T23:08:25Z"/> """) delay = Delay.fromElement(xml) self.assertEqual(datetime(2002, 9, 10, 23, 8, 25, tzinfo=dateutil.tz.tzutc()), delay.stamp) self.assertIdentical(None, delay.sender)
def test_fromParentElementBothLegacyFirst(self): """ The XEP-0203 format is used over earlier legacy XEP-0091 format. """ xml = parseXml(u""" <message> <x xmlns="jabber:x:delay" stamp="20010910T23:08:25"/> <delay xmlns="urn:xmpp:delay" stamp="2002-09-10T23:08:25Z"/> </message> """) stanza = DelayStanza.fromElement(xml) self.assertNotIdentical(None, stanza.delay) self.assertEqual(2002, stanza.delay.stamp.year)
def test_fromElementLegacy(self): """ For legacy XEP-0091 support, the timestamp is assumed to be in UTC. """ xml = parseXml(u""" <x xmlns="jabber:x:delay" stamp="20020910T23:08:25"/> """) delay = Delay.fromElement(xml) self.assertEqual(datetime(2002, 9, 10, 23, 8, 25, tzinfo=dateutil.tz.tzutc()), delay.stamp) self.assertIdentical(None, delay.sender)
def test_fromElementName(self): """ A roster item may have an optional name. """ xml = """ <item xmlns="jabber:iq:roster" jid="*****@*****.**" name="Test User"/> """ item = xmppim.RosterItem.fromElement(parseXml(xml)) self.assertEqual(u"Test User", item.name)
def test_fromElement(self): """ The timestamp is parsed with the proper timezone (UTC). """ xml = parseXml(u""" <delay xmlns="urn:xmpp:delay" stamp="2002-09-10T23:08:25Z"/> """) delay = Delay.fromElement(xml) self.assertEqual( datetime(2002, 9, 10, 23, 8, 25, tzinfo=dateutil.tz.tzutc()), delay.stamp) self.assertIdentical(None, delay.sender)
def test_fromElementSubscriptionRemove(self): """ Subscription 'remove' sets the remove attribute. """ xml = """ <item xmlns="jabber:iq:roster" jid="*****@*****.**" subscription="remove"/> """ item = xmppim.RosterItem.fromElement(parseXml(xml)) self.assertTrue(item.remove)
def test_fromElementVersion(self): """ If a ver attribute is present, put it in the request version. """ xml = """ <iq type='set' to='[email protected]/Home' from='*****@*****.**'> <query xmlns='jabber:iq:roster' ver='ver72'> <item jid='*****@*****.**'/> </query> </iq> """ request = xmppim.RosterRequest.fromElement(parseXml(xml)) self.assertEqual('ver72', request.version)
def test_fromElementApproved1(self): """ The approved attribute (1) signals a pre-approved subscription. """ xml = """ <item xmlns="jabber:iq:roster" jid="*****@*****.**" approved="1"/> """ item = xmppim.RosterItem.fromElement(parseXml(xml)) self.assertTrue(item.approved)
def test_fromElementPendingOut(self): """ The ask attribute, if set to 'subscription', means pending out. """ xml = """ <item xmlns="jabber:iq:roster" jid="*****@*****.**" ask="subscribe"/> """ item = xmppim.RosterItem.fromElement(parseXml(xml)) self.assertTrue(item.pendingOut)