Fix double roster entry issue with Unicode.

JIDs with Unicode values were being encoded by the JID class
instead of leaving them as just Unicode strings.

It may still be a good idea to use

    from __future__ import unicode_literals

pretty much everywhere though.

Fixes issue #88.
This commit is contained in:
Lance Stout 2011-05-20 16:48:13 -04:00
parent 6a07e7cbe3
commit 6b274a2543
3 changed files with 60 additions and 6 deletions

View file

@ -16,7 +16,8 @@ import sleekxmpp
from sleekxmpp import ClientXMPP, ComponentXMPP from sleekxmpp import ClientXMPP, ComponentXMPP
from sleekxmpp.stanza import Message, Iq, Presence from sleekxmpp.stanza import Message, Iq, Presence
from sleekxmpp.test import TestSocket, TestLiveSocket from sleekxmpp.test import TestSocket, TestLiveSocket
from sleekxmpp.xmlstream import StanzaBase, ET, register_stanza_plugin from sleekxmpp.xmlstream import ET, register_stanza_plugin
from sleekxmpp.xmlstream import ElementBase, StanzaBase
from sleekxmpp.xmlstream.tostring import tostring from sleekxmpp.xmlstream.tostring import tostring
from sleekxmpp.xmlstream.matcher import StanzaPath, MatcherId from sleekxmpp.xmlstream.matcher import StanzaPath, MatcherId
from sleekxmpp.xmlstream.matcher import MatchXMLMask, MatchXPath from sleekxmpp.xmlstream.matcher import MatchXMLMask, MatchXPath
@ -201,7 +202,7 @@ class SleekTest(unittest.TestCase):
"Stanza:\n%s" % str(stanza)) "Stanza:\n%s" % str(stanza))
else: else:
stanza_class = stanza.__class__ stanza_class = stanza.__class__
if isinstance(criteria, str): if not isinstance(criteria, ElementBase):
xml = self.parse_xml(criteria) xml = self.parse_xml(criteria)
else: else:
xml = criteria.xml xml = criteria.xml
@ -606,7 +607,7 @@ class SleekTest(unittest.TestCase):
self.fail("Stanza data was sent: %s" % sent) self.fail("Stanza data was sent: %s" % sent)
if sent is None: if sent is None:
self.fail("No stanza was sent.") self.fail("No stanza was sent.")
xml = self.parse_xml(sent) xml = self.parse_xml(sent)
self.fix_namespaces(xml, 'jabber:client') self.fix_namespaces(xml, 'jabber:client')
sent = self.xmpp._build_stanza(xml, 'jabber:client') sent = self.xmpp._build_stanza(xml, 'jabber:client')

View file

@ -6,6 +6,8 @@
See the file LICENSE for copying permission. See the file LICENSE for copying permission.
""" """
from __future__ import unicode_literals
class JID(object): class JID(object):
""" """
@ -42,7 +44,9 @@ class JID(object):
Arguments: Arguments:
jid - The new JID value. jid - The new JID value.
""" """
self._full = self._jid = str(jid) if isinstance(jid, JID):
jid = jid.full
self._full = self._jid = jid
self._domain = None self._domain = None
self._resource = None self._resource = None
self._user = None self._user = None
@ -123,10 +127,11 @@ class JID(object):
return self.full return self.full
def __repr__(self): def __repr__(self):
return str(self) return self.full
def __eq__(self, other): def __eq__(self, other):
""" """
Two JIDs are considered equal if they have the same full JID value. Two JIDs are considered equal if they have the same full JID value.
""" """
return str(other) == str(self) other = JID(other)
return self.full == other.full

View file

@ -1,3 +1,7 @@
# -*- encoding:utf-8 -*-
from __future__ import unicode_literals
from sleekxmpp.test import * from sleekxmpp.test import *
import time import time
import threading import threading
@ -162,6 +166,50 @@ class TestStreamRoster(SleekTest):
self.failUnless(events == ['roster_callback'], self.failUnless(events == ['roster_callback'],
"Roster timeout event not triggered: %s." % events) "Roster timeout event not triggered: %s." % events)
def testRosterUnicode(self):
"""Test that JIDs with Unicode values are handled properly."""
self.stream_start()
self.recv("""
<iq to="tester@localhost" type="set" id="1">
<query xmlns="jabber:iq:roster">
<item jid="andré@foo" subscription="both">
<group>Unicode</group>
</item>
</query>
</iq>
""")
# Give the event queue time to process.
time.sleep(.1)
roster = {'andré@foo': {
'name': '',
'subscription': 'both',
'groups': ['Unicode'],
'presence': {},
'in_roster': True}}
self.failUnless(self.xmpp.roster == roster,
"Unexpected roster values: %s" % self.xmpp.roster)
self.recv("""
<presence from="andré@foo/bar" />
""")
# Give the event queue time to process.
time.sleep(.1)
roster = {'andré@foo': {
'name': '',
'subscription': 'both',
'groups': ['Unicode'],
'presence': {
'bar':{'priority':0,
'status':'',
'show':'available'}},
'in_roster': True}}
self.failUnless(self.xmpp.roster == roster,
"Unexpected roster values: %s" % self.xmpp.roster)
suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamRoster) suite = unittest.TestLoader().loadTestsFromTestCase(TestStreamRoster)