From 6b274a2543744f9b94823f5bd2a6c23ec8cc3f75 Mon Sep 17 00:00:00 2001
From: Lance Stout <lancestout@gmail.com>
Date: Fri, 20 May 2011 16:48:13 -0400
Subject: 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.
---
 sleekxmpp/test/sleektest.py |  7 ++++---
 sleekxmpp/xmlstream/jid.py  | 11 ++++++++---
 tests/test_stream_roster.py | 48 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/sleekxmpp/test/sleektest.py b/sleekxmpp/test/sleektest.py
index fd47a87e..24af1e7a 100644
--- a/sleekxmpp/test/sleektest.py
+++ b/sleekxmpp/test/sleektest.py
@@ -16,7 +16,8 @@ import sleekxmpp
 from sleekxmpp import ClientXMPP, ComponentXMPP
 from sleekxmpp.stanza import Message, Iq, Presence
 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.matcher import StanzaPath, MatcherId
 from sleekxmpp.xmlstream.matcher import MatchXMLMask, MatchXPath
@@ -201,7 +202,7 @@ class SleekTest(unittest.TestCase):
                     "Stanza:\n%s" % str(stanza))
         else:
             stanza_class = stanza.__class__
-            if isinstance(criteria, str):
+            if not isinstance(criteria, ElementBase):
                 xml = self.parse_xml(criteria)
             else:
                 xml = criteria.xml
@@ -606,7 +607,7 @@ class SleekTest(unittest.TestCase):
             self.fail("Stanza data was sent: %s" % sent)
         if sent is None:
             self.fail("No stanza was sent.")
-        
+
         xml = self.parse_xml(sent)
         self.fix_namespaces(xml, 'jabber:client')
         sent = self.xmpp._build_stanza(xml, 'jabber:client')
diff --git a/sleekxmpp/xmlstream/jid.py b/sleekxmpp/xmlstream/jid.py
index 5019a25e..36b33056 100644
--- a/sleekxmpp/xmlstream/jid.py
+++ b/sleekxmpp/xmlstream/jid.py
@@ -6,6 +6,8 @@
     See the file LICENSE for copying permission.
 """
 
+from __future__ import unicode_literals
+
 
 class JID(object):
     """
@@ -42,7 +44,9 @@ class JID(object):
         Arguments:
             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._resource = None
         self._user = None
@@ -123,10 +127,11 @@ class JID(object):
         return self.full
 
     def __repr__(self):
-        return str(self)
+        return self.full
 
     def __eq__(self, other):
         """
         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
diff --git a/tests/test_stream_roster.py b/tests/test_stream_roster.py
index 731d1145..d86ff955 100644
--- a/tests/test_stream_roster.py
+++ b/tests/test_stream_roster.py
@@ -1,3 +1,7 @@
+# -*- encoding:utf-8 -*-
+
+from __future__ import unicode_literals
+
 from sleekxmpp.test import *
 import time
 import threading
@@ -162,6 +166,50 @@ class TestStreamRoster(SleekTest):
         self.failUnless(events == ['roster_callback'],
                  "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)
-- 
cgit v1.2.3


From 4bb226147a0faa3b0c92934f64585357bb197f68 Mon Sep 17 00:00:00 2001
From: Lance Stout <lancestout@gmail.com>
Date: Fri, 20 May 2011 21:15:57 -0400
Subject: Make roster test a little more robust.

---
 tests/test_stream_roster.py | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tests/test_stream_roster.py b/tests/test_stream_roster.py
index d86ff955..15b8683a 100644
--- a/tests/test_stream_roster.py
+++ b/tests/test_stream_roster.py
@@ -192,7 +192,10 @@ class TestStreamRoster(SleekTest):
                 "Unexpected roster values: %s" % self.xmpp.roster)
 
         self.recv("""
-          <presence from="andré@foo/bar" />
+          <presence to="tester@localhost" from="andré@foo/bar">
+            <show>away</show>
+            <status>Testing</status>
+          </presence>
         """)
 
         # Give the event queue time to process.
@@ -204,8 +207,8 @@ class TestStreamRoster(SleekTest):
                     'groups': ['Unicode'],
                     'presence': {
                         'bar':{'priority':0,
-                               'status':'',
-                               'show':'available'}},
+                               'status':'Testing',
+                               'show':'away'}},
                     'in_roster': True}}
         self.failUnless(self.xmpp.roster == roster,
                 "Unexpected roster values: %s" % self.xmpp.roster)
-- 
cgit v1.2.3


From 7152d93dd05346fdb7dbe1893bff6395f83a79a9 Mon Sep 17 00:00:00 2001
From: Lance Stout <lancestout@gmail.com>
Date: Fri, 20 May 2011 21:38:10 -0400
Subject: Fix test timeout issue.

A better method than using time.sleep is needed.
Maybe use queue.task_done to detect when event processing
has ended? Research time!
---
 tests/test_stream_handlers.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tests/test_stream_handlers.py b/tests/test_stream_handlers.py
index a475b36c..dae4456d 100644
--- a/tests/test_stream_handlers.py
+++ b/tests/test_stream_handlers.py
@@ -104,6 +104,9 @@ class TestHandlers(SleekTest):
         iq['query'] = 'test2'
         self.send(iq)
 
+        # Give the event queue time to process.
+        time.sleep(0.1)
+
         # Check that the waiter is no longer registered
         waiter_exists = self.xmpp.removeHandler('IqWait_test2')
 
-- 
cgit v1.2.3