Merge lp:~dobey/ubuntu-sso-client/update-4-0 into lp:ubuntu-sso-client/stable-4-0

Proposed by dobey on 2012-08-21
Status: Merged
Approved by: dobey on 2012-08-21
Approved revision: no longer in the source branch.
Merged at revision: 965
Proposed branch: lp:~dobey/ubuntu-sso-client/update-4-0
Merge into: lp:ubuntu-sso-client/stable-4-0
Diff against target: 2301 lines (+404/-525)
40 files modified
ubuntu_sso/account.py (+12/-10)
ubuntu_sso/credentials.py (+3/-3)
ubuntu_sso/keyring/__init__.py (+13/-8)
ubuntu_sso/keyring/tests/test_common.py (+11/-9)
ubuntu_sso/keyring/tests/test_linux.py (+3/-1)
ubuntu_sso/main/__init__.py (+2/-1)
ubuntu_sso/main/tests/test_common.py (+5/-3)
ubuntu_sso/qt/__init__.py (+5/-3)
ubuntu_sso/qt/common.py (+10/-7)
ubuntu_sso/qt/current_user_sign_in_page.py (+12/-9)
ubuntu_sso/qt/email_verification_page.py (+3/-2)
ubuntu_sso/qt/forgotten_password_page.py (+4/-3)
ubuntu_sso/qt/loadingoverlay.py (+3/-1)
ubuntu_sso/qt/main/__init__.py (+3/-3)
ubuntu_sso/qt/main/tests/test_main.py (+3/-2)
ubuntu_sso/qt/proxy_dialog.py (+5/-2)
ubuntu_sso/qt/reset_password_page.py (+12/-9)
ubuntu_sso/qt/setup_account_page.py (+35/-29)
ubuntu_sso/qt/tests/__init__.py (+13/-11)
ubuntu_sso/qt/tests/show_gui.py (+7/-5)
ubuntu_sso/qt/tests/test_common.py (+28/-25)
ubuntu_sso/qt/tests/test_current_user_sign_in_page.py (+15/-9)
ubuntu_sso/qt/tests/test_forgotten_password.py (+8/-5)
ubuntu_sso/qt/tests/test_reset_password.py (+6/-4)
ubuntu_sso/qt/tests/test_setup_account.py (+25/-11)
ubuntu_sso/qt/tests/test_ssl_dialog.py (+10/-8)
ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py (+2/-1)
ubuntu_sso/qt/ubuntu_sso_wizard.py (+2/-1)
ubuntu_sso/tests/__init__.py (+19/-17)
ubuntu_sso/tests/test_account.py (+31/-22)
ubuntu_sso/utils/__init__.py (+5/-107)
ubuntu_sso/utils/compat.py (+49/-0)
ubuntu_sso/utils/ipc.py (+8/-2)
ubuntu_sso/utils/runner/glib.py (+4/-3)
ubuntu_sso/utils/runner/tests/test_qt.py (+2/-2)
ubuntu_sso/utils/runner/tests/test_runner.py (+5/-3)
ubuntu_sso/utils/runner/tx.py (+6/-4)
ubuntu_sso/utils/tests/test_common.py (+7/-176)
ubuntu_sso/utils/tests/test_ipc.py (+3/-3)
ubuntu_sso/utils/ui.py (+5/-1)
To merge this branch: bzr merge lp:~dobey/ubuntu-sso-client/update-4-0
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve on 2012-08-21
Eric Casteleijn (community) 2012-08-21 Approve on 2012-08-21
Review via email: mp+120626@code.launchpad.net

Commit Message

[Brian Curtin]

    - Prepare codebase for transition to Python 3 with respect to Unicode usage.
    - Switch to Python 2 and 3 safe usage of a metaclass for IPC.
    - Remove SyncTimestampChecker as it is no longer used.
    - Unpack tuple function arguments in a Python 2 and 3 friendly way.
    - The second of three changes to prepare SSO for Python 3 Unicode usage.
    - The first of several changes to prepare sso for Python 3 Unicode usage.

[Mike McCracken]

    - Fix hang on captcha generation due to PIL exception. (LP: #1031437)

To post a comment you must log in.
Eric Casteleijn (thisfred) :
review: Approve
Roberto Alsina (ralsina) :
review: Approve
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (109.6 KiB)

The attempt to merge lp:~dobey/ubuntu-sso-client/update-4-0 into lp:ubuntu-sso-client/stable-4-0 failed. Below is the output from the failed tests.

*** Running QT test suite for ubuntu_sso ***
running build
Compiled data/qt/proxy_credentials_dialog.ui into ubuntu_sso/qt/ui/proxy_credentials_dialog_ui.py
Compiled data/qt/email_verification.ui into ubuntu_sso/qt/ui/email_verification_ui.py
Compiled data/qt/reset_password.ui into ubuntu_sso/qt/ui/reset_password_ui.py
Compiled data/qt/forgotten_password.ui into ubuntu_sso/qt/ui/forgotten_password_ui.py
Compiled data/qt/current_user_sign_in.ui into ubuntu_sso/qt/ui/current_user_sign_in_ui.py
Compiled data/qt/error_message.ui into ubuntu_sso/qt/ui/error_message_ui.py
Compiled data/qt/network_detection.ui into ubuntu_sso/qt/ui/network_detection_ui.py
Compiled data/qt/ssl_dialog.ui into ubuntu_sso/qt/ui/ssl_dialog_ui.py
Compiled data/qt/setup_account.ui into ubuntu_sso/qt/ui/setup_account_ui.py
Compiled data/qt/loadingoverlay.ui into ubuntu_sso/qt/ui/loadingoverlay_ui.py
compiled data/qt/resources.qrc into ubuntu_sso/qt/ui/resources_rc.py
Compiled data/qt/success_message.ui into ubuntu_sso/qt/ui/success_message_ui.py
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/ubuntu_sso
copying ubuntu_sso/credentials.py -> build/lib.linux-x86_64-2.7/ubuntu_sso
copying ubuntu_sso/logger.py -> build/lib.linux-x86_64-2.7/ubuntu_sso
copying ubuntu_sso/__init__.py -> build/lib.linux-x86_64-2.7/ubuntu_sso
copying ubuntu_sso/account.py -> build/lib.linux-x86_64-2.7/ubuntu_sso
creating build/lib.linux-x86_64-2.7/ubuntu_sso/tests
copying ubuntu_sso/tests/test_credentials.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/tests
copying ubuntu_sso/tests/test_account.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/tests
copying ubuntu_sso/tests/__init__.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/tests
copying ubuntu_sso/tests/linux.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/tests
creating build/lib.linux-x86_64-2.7/ubuntu_sso/keyring
copying ubuntu_sso/keyring/pykeyring.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/keyring
copying ubuntu_sso/keyring/__init__.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/keyring
copying ubuntu_sso/keyring/linux.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/keyring
creating build/lib.linux-x86_64-2.7/ubuntu_sso/keyring/tests
copying ubuntu_sso/keyring/tests/test_linux.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/keyring/tests
copying ubuntu_sso/keyring/tests/test_common.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/keyring/tests
copying ubuntu_sso/keyring/tests/test_pykeyring.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/keyring/tests
copying ubuntu_sso/keyring/tests/__init__.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/keyring/tests
creating build/lib.linux-x86_64-2.7/ubuntu_sso/main
copying ubuntu_sso/main/qt.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/main
copying ubuntu_sso/main/darwin.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/main
copying ubuntu_sso/main/perspective_broker.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/main
copying ubuntu_sso/main/glib.py -> build/lib.linux-x86_64-2.7/ubuntu_sso/main
copying ubuntu_sso/main/__init__.py -> build/lib.linu...

965. By Brian Curtin on 2012-08-21

[Brian Curtin]

    - Prepare codebase for transition to Python 3 with respect to Unicode usage.
    - Switch to Python 2 and 3 safe usage of a metaclass for IPC.
    - Remove SyncTimestampChecker as it is no longer used.
    - Unpack tuple function arguments in a Python 2 and 3 friendly way.
    - The second of three changes to prepare SSO for Python 3 Unicode usage.
    - The first of several changes to prepare sso for Python 3 Unicode usage.

[Mike McCracken]

    - Fix hang on captcha generation due to PIL exception. (LP: #1031437)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntu_sso/account.py'
2--- ubuntu_sso/account.py 2012-06-22 21:04:49 +0000
3+++ ubuntu_sso/account.py 2012-08-21 18:02:19 +0000
4@@ -35,19 +35,21 @@
5
6 """
7
8+from __future__ import unicode_literals
9+
10 import os
11 import re
12
13 from twisted.internet import defer
14
15 from ubuntu_sso.logger import setup_logging
16-from ubuntu_sso.utils import webclient
17+from ubuntu_sso.utils import compat, webclient
18 from ubuntu_sso.utils.webclient import restful
19 from ubuntu_sso.utils.webclient.common import WebClientError
20
21
22 logger = setup_logging("ubuntu_sso.account")
23-SERVICE_URL = u"https://login.ubuntu.com/api/1.0/"
24+SERVICE_URL = "https://login.ubuntu.com/api/1.0/"
25 SSO_STATUS_OK = 'ok'
26 SSO_STATUS_ERROR = 'error'
27
28@@ -112,7 +114,7 @@
29 result = {}
30 for key, val in errdict.items():
31 # workaround until bug #624955 is solved
32- if isinstance(val, basestring):
33+ if isinstance(val, compat.basestring):
34 result[key] = val
35 else:
36 result[key] = "\n".join(val)
37@@ -125,7 +127,7 @@
38 filename)
39 restful_client = restful.RestfulClient(self.service_url)
40 try:
41- captcha = yield restful_client.restcall(u"captchas.new")
42+ captcha = yield restful_client.restcall("captchas.new")
43 finally:
44 restful_client.shutdown()
45
46@@ -162,7 +164,7 @@
47 logger.error('register_user: InvalidPasswordError')
48 raise InvalidPasswordError()
49
50- result = yield restful_client.restcall(u"registration.register",
51+ result = yield restful_client.restcall("registration.register",
52 email=email, password=password,
53 displayname=displayname,
54 captcha_id=captcha_id,
55@@ -189,7 +191,7 @@
56 password=password)
57 try:
58 credentials = yield restful_client.restcall(
59- u"authentications.authenticate",
60+ "authentications.authenticate",
61 token_name=token_name)
62 except WebClientError:
63 logger.exception('login failed with:')
64@@ -208,7 +210,7 @@
65 restful_client = restful.RestfulClient(self.service_url,
66 oauth_credentials=token)
67 try:
68- me_info = yield restful_client.restcall(u"accounts.me")
69+ me_info = yield restful_client.restcall("accounts.me")
70 finally:
71 restful_client.shutdown()
72 key = 'preferred_email'
73@@ -229,7 +231,7 @@
74 restful_client = restful.RestfulClient(self.service_url,
75 oauth_credentials=credentials)
76 try:
77- result = yield restful_client.restcall(u"accounts.validate_email",
78+ result = yield restful_client.restcall("accounts.validate_email",
79 email_token=email_token)
80 finally:
81 restful_client.shutdown()
82@@ -247,7 +249,7 @@
83 """Request a token to reset the password for the account 'email'."""
84 restful_client = restful.RestfulClient(self.service_url)
85 try:
86- operation = u"registration.request_password_reset_token"
87+ operation = "registration.request_password_reset_token"
88 result = yield restful_client.restcall(operation, email=email)
89 except WebClientError as e:
90 logger.exception('request_password_reset_token failed with:')
91@@ -272,7 +274,7 @@
92 restful_client = restful.RestfulClient(self.service_url)
93 try:
94 result = yield restful_client.restcall(
95- u"registration.set_new_password",
96+ "registration.set_new_password",
97 email=email, token=token,
98 new_password=new_password)
99 except WebClientError as e:
100
101=== modified file 'ubuntu_sso/credentials.py'
102--- ubuntu_sso/credentials.py 2012-07-13 21:07:38 +0000
103+++ ubuntu_sso/credentials.py 2012-08-21 18:02:19 +0000
104@@ -54,7 +54,7 @@
105 )
106 from ubuntu_sso.keyring import Keyring
107 from ubuntu_sso.logger import setup_logging
108-from ubuntu_sso.utils import get_bin_cmd, runner
109+from ubuntu_sso.utils import compat, get_bin_cmd, runner
110
111
112 logger = setup_logging('ubuntu_sso.credentials')
113@@ -189,8 +189,8 @@
114 value = getattr(self, arg)
115 if value:
116 args.append('--%s' % arg)
117- if not isinstance(value, basestring):
118- value = str(value)
119+ if not isinstance(value, compat.basestring):
120+ value = compat.text_type(value)
121 args.append(value)
122
123 if login_only:
124
125=== modified file 'ubuntu_sso/keyring/__init__.py'
126--- ubuntu_sso/keyring/__init__.py 2012-06-27 20:41:19 +0000
127+++ ubuntu_sso/keyring/__init__.py 2012-08-21 18:02:19 +0000
128@@ -28,6 +28,8 @@
129 # files in the program, then also delete it here.
130 """Implementations of different keyrings."""
131
132+from __future__ import unicode_literals
133+
134 import socket
135 import sys
136
137@@ -41,11 +43,12 @@
138 from twisted.internet.defer import inlineCallbacks, returnValue
139
140 from ubuntu_sso.logger import setup_logging
141+from ubuntu_sso.utils import compat
142
143 logger = setup_logging("ubuntu_sso.keyring")
144
145-TOKEN_SEPARATOR = u' @ '
146-SEPARATOR_REPLACEMENT = u' AT '
147+TOKEN_SEPARATOR = ' @ '
148+SEPARATOR_REPLACEMENT = ' AT '
149
150 U1_APP_NAME = "Ubuntu One"
151 U1_KEY_NAME = "UbuntuOne token for https://ubuntuone.com"
152@@ -58,7 +61,9 @@
153 def gethostname():
154 """Get the hostname, return the name as unicode."""
155 sys_encoding = sys.getfilesystemencoding()
156- hostname = socket.gethostname().decode(sys_encoding)
157+ hostname = socket.gethostname()
158+ if isinstance(hostname, compat.binary_type):
159+ return hostname.decode(sys_encoding)
160 return hostname
161
162
163@@ -68,10 +73,10 @@
164 computer_name = gethostname()
165 quoted_computer_name = quote(computer_name)
166
167- assert isinstance(computer_name, unicode)
168- assert isinstance(quoted_computer_name, unicode)
169+ assert isinstance(computer_name, compat.text_type)
170+ assert isinstance(quoted_computer_name, compat.text_type)
171
172- return u"%s - %s" % (quoted_app_name, quoted_computer_name)
173+ return "%s - %s" % (quoted_app_name, quoted_computer_name)
174
175
176 def get_token_name(app_name):
177@@ -80,8 +85,8 @@
178 computer_name = computer_name.replace(TOKEN_SEPARATOR,
179 SEPARATOR_REPLACEMENT)
180
181- assert isinstance(computer_name, unicode)
182- assert isinstance(computer_name, unicode)
183+ assert isinstance(computer_name, compat.text_type)
184+ assert isinstance(computer_name, compat.text_type)
185
186 return TOKEN_SEPARATOR.join((app_name, computer_name))
187
188
189=== modified file 'ubuntu_sso/keyring/tests/test_common.py'
190--- ubuntu_sso/keyring/tests/test_common.py 2012-04-09 17:38:24 +0000
191+++ ubuntu_sso/keyring/tests/test_common.py 2012-08-21 18:02:19 +0000
192@@ -33,6 +33,8 @@
193 # files in the program, then also delete it here.
194 """Tests for the keyring common module."""
195
196+from __future__ import unicode_literals
197+
198 from twisted.trial.unittest import TestCase
199
200 from ubuntu_sso import keyring
201@@ -49,7 +51,7 @@
202
203 def test_get_hostname_uses_filesystem_encoding(self):
204 """The fs encoding is used to decode the name returned by socket."""
205- fake_hostname = u"Привет-ПК"
206+ fake_hostname = "Привет-ПК"
207 hostname_koi8r = fake_hostname.encode("koi8-r")
208 self.patch(keyring.socket, "gethostname", lambda: hostname_koi8r)
209 self.patch(keyring.sys, "getfilesystemencoding", lambda: "koi8-r")
210@@ -67,35 +69,35 @@
211
212 def test_get_simple_token_name(self):
213 """A simple token name is built right."""
214- sample_app_name = u"UbuntuTwo"
215+ sample_app_name = "UbuntuTwo"
216 sample_hostname = "Darkstar"
217 expected_result = "UbuntuTwo @ Darkstar"
218 self.check_build(sample_app_name, sample_hostname, expected_result)
219
220 def test_get_complex_token_name_for_app_name(self):
221 """A complex token name is built right too."""
222- sample_app_name = u"Ubuntu @ Eleven"
223+ sample_app_name = "Ubuntu @ Eleven"
224 sample_hostname = "Mate+Cocido"
225 expected_result = "Ubuntu @ Eleven @ Mate+Cocido"
226 self.check_build(sample_app_name, sample_hostname, expected_result)
227
228 def test_get_complex_token_name_for_hostname(self):
229 """A complex token name is built right too."""
230- sample_app_name = u"Ubuntu Eleven"
231+ sample_app_name = "Ubuntu Eleven"
232 sample_hostname = "Mate @ Cocido"
233 expected_result = "Ubuntu Eleven @ Mate AT Cocido"
234 self.check_build(sample_app_name, sample_hostname, expected_result)
235
236 def test_get_unicode_appname_token_name(self):
237 """A token name with unicode in the app name."""
238- sample_app_name = u"Ubuntu 四百六十九"
239+ sample_app_name = "Ubuntu 四百六十九"
240 sample_hostname = "Darkstar"
241- expected_result = u"Ubuntu 四百六十九 @ Darkstar"
242+ expected_result = "Ubuntu 四百六十九 @ Darkstar"
243 self.check_build(sample_app_name, sample_hostname, expected_result)
244
245 def test_get_utf8_hostname_token_name(self):
246 """A token name with utf8 in the host name."""
247- sample_app_name = u"Ubuntu Eleven"
248- sample_hostname = u"Привет-ПК"
249- expected_result = u"Ubuntu Eleven @ Привет-ПК"
250+ sample_app_name = "Ubuntu Eleven"
251+ sample_hostname = "Привет-ПК"
252+ expected_result = "Ubuntu Eleven @ Привет-ПК"
253 self.check_build(sample_app_name, sample_hostname, expected_result)
254
255=== modified file 'ubuntu_sso/keyring/tests/test_linux.py'
256--- ubuntu_sso/keyring/tests/test_linux.py 2012-06-22 16:55:35 +0000
257+++ ubuntu_sso/keyring/tests/test_linux.py 2012-08-21 18:02:19 +0000
258@@ -33,6 +33,8 @@
259 # files in the program, then also delete it here.
260 """Tests for the keyring.py module."""
261
262+from __future__ import unicode_literals
263+
264 from twisted.internet import defer
265 from twisted.internet.defer import inlineCallbacks
266 from twisted.trial.unittest import TestCase
267@@ -133,7 +135,7 @@
268 self.mock_service = None
269 self.service = self.patch(keyring, "SecretService",
270 self.get_mock_service)
271- self.patch(common_keyring, "gethostname", lambda: u"darkstar")
272+ self.patch(common_keyring, "gethostname", lambda: "darkstar")
273
274 def get_mock_service(self):
275 """Create only one instance of the mock service per test."""
276
277=== modified file 'ubuntu_sso/main/__init__.py'
278--- ubuntu_sso/main/__init__.py 2012-07-12 15:54:13 +0000
279+++ ubuntu_sso/main/__init__.py 2012-08-21 18:02:19 +0000
280@@ -52,6 +52,7 @@
281 )
282 from ubuntu_sso.keyring import get_token_name, Keyring
283 from ubuntu_sso.logger import setup_logging, log_call
284+from ubuntu_sso.utils import compat
285
286
287 logger = setup_logging("ubuntu_sso.main")
288@@ -109,7 +110,7 @@
289 result["message"] = e.__class__.__doc__
290 elif isinstance(e.args[0], dict):
291 result.update(e.args[0])
292- elif isinstance(e.args[0], basestring):
293+ elif isinstance(e.args[0], compat.basestring):
294 result["message"] = e.args[0]
295
296 return result
297
298=== modified file 'ubuntu_sso/main/tests/test_common.py'
299--- ubuntu_sso/main/tests/test_common.py 2012-04-09 17:38:24 +0000
300+++ ubuntu_sso/main/tests/test_common.py 2012-08-21 18:02:19 +0000
301@@ -28,6 +28,8 @@
302 # files in the program, then also delete it here.
303 """Tests for the main SSO client code."""
304
305+from __future__ import unicode_literals
306+
307 import logging
308
309 from functools import partial
310@@ -137,7 +139,7 @@
311 class MyException(Exception):
312 """Custom Exception."""
313
314- message = u'My custom error for ♥ Ubuntu'
315+ message = 'My custom error for ♥ Ubuntu'
316 my_exc = MyException(message)
317 result = except_to_errdict(my_exc)
318 self.assertEqual(result["errtype"], my_exc.__class__.__name__)
319@@ -145,7 +147,7 @@
320
321 def test_first_arg_is_unicode(self):
322 """If the first arg is a unicode, use it as the message."""
323- sample_string = u"a sample string"
324+ sample_string = "a sample string"
325 e = TestExceptToErrdictException(sample_string)
326 result = except_to_errdict(e)
327 self.assertEqual(result["errtype"], e.__class__.__name__)
328@@ -160,7 +162,7 @@
329
330 def test_some_other_thing_as_first_arg(self):
331 """If first arg is not basestring nor dict, then repr all args."""
332- sample_args = (None, u"unicode2\ufffd", "errorcode3")
333+ sample_args = (None, "unicode2\ufffd", "errorcode3")
334 e = TestExceptToErrdictException(*sample_args)
335 result = except_to_errdict(e)
336 self.assertEqual(result["errtype"], e.__class__.__name__)
337
338=== modified file 'ubuntu_sso/qt/__init__.py'
339--- ubuntu_sso/qt/__init__.py 2012-06-27 19:03:44 +0000
340+++ ubuntu_sso/qt/__init__.py 2012-08-21 18:02:19 +0000
341@@ -28,6 +28,8 @@
342 # files in the program, then also delete it here.
343 """The Qt graphical interface for the Ubuntu Single Sign On Client."""
344
345+from __future__ import unicode_literals
346+
347 import sys
348 import collections
349
350@@ -38,13 +40,13 @@
351
352 logger = setup_gui_logging('ubuntu_sso.qt')
353
354-LINK_STYLE = (u'<a href="{link_url}">'
355+LINK_STYLE = ('<a href="{link_url}">'
356 '<span style="color:#df2d1f;">{link_text}</span></a>')
357 ERROR_ALL = '__all__'
358-ERROR_STYLE = u'<font color="#df2d1f" style="font-size:small"><b>%s</b></font>'
359+ERROR_STYLE = '<font color="#df2d1f" style="font-size:small"><b>%s</b></font>'
360 ERROR_MESSAGE = 'message'
361 PREFERED_UI_SIZE = {'width': 550, 'height': 525}
362-TITLE_STYLE = u'<span style="font-size:xx-large;font-weight:bold;">%s</span>'
363+TITLE_STYLE = '<span style="font-size:xx-large;font-weight:bold;">%s</span>'
364 WINDOW_TITLE = 'Ubuntu Single Sign On'
365
366 # TODO: There is a pixel discrepancy between Qt on Linux and Windows
367
368=== modified file 'ubuntu_sso/qt/common.py'
369--- ubuntu_sso/qt/common.py 2012-04-09 17:38:24 +0000
370+++ ubuntu_sso/qt/common.py 2012-08-21 18:02:19 +0000
371@@ -30,8 +30,11 @@
372 # files in the program, then also delete it here.
373 """Common functionality used by the UI modules."""
374
375+from __future__ import unicode_literals
376+
377 import re
378
379+from ubuntu_sso.utils import compat
380 from ubuntu_sso.utils.ui import (
381 PASSWORD_DIGIT,
382 PASSWORD_LENGTH,
383@@ -41,14 +44,14 @@
384 )
385
386 # all the text + styles that are used in the gui
387-BAD = u'<img src=":/password_hint_warning.png" /><small> %s </small>'
388-GOOD = u'<img src=":/password_hint_ok.png" /><small> %s </small>'
389-NORMAL = u'<small> %s </small>'
390+BAD = '<img src=":/password_hint_warning.png" /><small> %s </small>'
391+GOOD = '<img src=":/password_hint_ok.png" /><small> %s </small>'
392+NORMAL = '<small> %s </small>'
393
394
395 def password_assistance(line_edit, assistance, icon_type=BAD):
396 """Show help for the password field."""
397- text1 = unicode(line_edit.text())
398+ text1 = compat.text_type(line_edit.text())
399 label_text = ["<b>%s</b>" % PASSWORD_MUST_CONTAIN, ]
400
401 if len(text1) < 8:
402@@ -75,9 +78,9 @@
403 def password_check_match(line_edit, line_edit_confirm, assistance):
404 """Check if passwords match, otherwise show a message."""
405 password_assistance(line_edit, assistance)
406- label_text = unicode(assistance.text())
407- text1 = unicode(line_edit.text())
408- text2 = unicode(line_edit_confirm.text())
409+ label_text = compat.text_type(assistance.text())
410+ text1 = compat.text_type(line_edit.text())
411+ text2 = compat.text_type(line_edit_confirm.text())
412 if text1 != text2:
413 label_text += "<br>" + BAD % PASSWORD_MATCH
414 assistance.setText(label_text)
415
416=== modified file 'ubuntu_sso/qt/current_user_sign_in_page.py'
417--- ubuntu_sso/qt/current_user_sign_in_page.py 2012-06-08 13:33:39 +0000
418+++ ubuntu_sso/qt/current_user_sign_in_page.py 2012-08-21 18:02:19 +0000
419@@ -37,6 +37,7 @@
420 from ubuntu_sso.qt import LINK_STYLE, build_general_error_message
421 from ubuntu_sso.qt.sso_wizard_page import SSOWizardPage
422 from ubuntu_sso.qt.ui.current_user_sign_in_ui import Ui_CurrentUserSignInPage
423+from ubuntu_sso.utils import compat
424 from ubuntu_sso.utils.ui import (
425 CANCEL_BUTTON,
426 EMAIL_LABEL,
427@@ -56,9 +57,9 @@
428 """Wizard Page that lets a current user Sign into Ubuntu Single Sign On."""
429
430 ui_class = Ui_CurrentUserSignInPage
431- userLoggedIn = QtCore.pyqtSignal(unicode)
432+ userLoggedIn = QtCore.pyqtSignal(compat.text_type)
433 passwordForgotten = QtCore.pyqtSignal()
434- userNotValidated = QtCore.pyqtSignal(unicode)
435+ userNotValidated = QtCore.pyqtSignal(compat.text_type)
436
437 @property
438 def _signals(self):
439@@ -76,12 +77,12 @@
440 @property
441 def password(self):
442 """Return the content of the password edit."""
443- return unicode(self.ui.password_edit.text())
444+ return compat.text_type(self.ui.password_edit.text())
445
446 def on_user_not_validated(self, app_name, email):
447 """Show the validate email page."""
448 self.hide_overlay()
449- email = unicode(self.ui.email_edit.text())
450+ email = compat.text_type(self.ui.email_edit.text())
451 self.userNotValidated.emit(email)
452
453 # Invalid names of Qt-inherited methods
454@@ -129,17 +130,19 @@
455
456 def _validate(self):
457 """Perform input validation."""
458- correct_mail = is_correct_email(unicode(self.ui.email_edit.text()))
459- correct_password = len(unicode(self.ui.password_edit.text())) > 0
460+ correct_mail = is_correct_email(
461+ compat.text_type(self.ui.email_edit.text()))
462+ correct_password = len(
463+ compat.text_type(self.ui.password_edit.text())) > 0
464 enabled = correct_mail and correct_password
465 self.ui.sign_in_button.setEnabled(enabled)
466
467 def login(self):
468 """Perform the login using the self.backend."""
469 # grab the data from the view and call the backend
470- email = unicode(self.ui.email_edit.text())
471+ email = compat.text_type(self.ui.email_edit.text())
472 logger.info('CurrentUserSignInPage.login for: %s', email)
473- password = unicode(self.ui.password_edit.text())
474+ password = compat.text_type(self.ui.password_edit.text())
475 args = (self.app_name, email, password)
476 if self.ping_url:
477 f = self.backend.login_and_ping
478@@ -163,7 +166,7 @@
479 """We managed to log in."""
480 logger.info('Logged in for %s', app_name)
481 self.hide_overlay()
482- email = unicode(self.ui.email_edit.text())
483+ email = compat.text_type(self.ui.email_edit.text())
484 logger.debug('About to emit userLoggedIn signal with: (%s).', email)
485 self.userLoggedIn.emit(email)
486
487
488=== modified file 'ubuntu_sso/qt/email_verification_page.py'
489--- ubuntu_sso/qt/email_verification_page.py 2012-04-09 17:38:24 +0000
490+++ ubuntu_sso/qt/email_verification_page.py 2012-08-21 18:02:19 +0000
491@@ -37,6 +37,7 @@
492 from ubuntu_sso.qt import build_general_error_message
493 from ubuntu_sso.qt.sso_wizard_page import SSOWizardPage
494 from ubuntu_sso.qt.ui.email_verification_ui import Ui_EmailVerificationPage
495+from ubuntu_sso.utils import compat
496 from ubuntu_sso.utils.ui import (
497 ERROR_EMAIL_TOKEN,
498 NEXT,
499@@ -53,7 +54,7 @@
500 """Widget used to input the email verification code."""
501
502 ui_class = Ui_EmailVerificationPage
503- registrationSuccess = QtCore.pyqtSignal(unicode)
504+ registrationSuccess = QtCore.pyqtSignal(compat.text_type)
505
506 def __init__(self, *args, **kwargs):
507 self.email = ''
508@@ -115,7 +116,7 @@
509 """Call the next action."""
510 logger.debug('EmailVerificationController.validate_email for: %s',
511 self.email)
512- code = unicode(self.ui.verification_code_edit.text())
513+ code = compat.text_type(self.ui.verification_code_edit.text())
514 args = (self.app_name, self.email, self.password, code)
515 self.hide_error()
516 self.show_overlay()
517
518=== modified file 'ubuntu_sso/qt/forgotten_password_page.py'
519--- ubuntu_sso/qt/forgotten_password_page.py 2012-04-09 17:38:24 +0000
520+++ ubuntu_sso/qt/forgotten_password_page.py 2012-08-21 18:02:19 +0000
521@@ -36,6 +36,7 @@
522 from ubuntu_sso.logger import setup_gui_logging, log_call
523 from ubuntu_sso.qt.sso_wizard_page import SSOWizardEnhancedEditPage
524 from ubuntu_sso.qt.ui.forgotten_password_ui import Ui_ForgottenPasswordPage
525+from ubuntu_sso.utils import compat
526 from ubuntu_sso.utils.ui import (
527 EMAIL_LABEL,
528 FORGOTTEN_PASSWORD_TITLE,
529@@ -53,7 +54,7 @@
530 """Widget used to deal with users that forgot the password."""
531
532 ui_class = Ui_ForgottenPasswordPage
533- passwordResetTokenSent = QtCore.pyqtSignal(unicode)
534+ passwordResetTokenSent = QtCore.pyqtSignal(compat.text_type)
535
536 @property
537 def _signals(self):
538@@ -69,7 +70,7 @@
539 @property
540 def email_address(self):
541 """Return the email address provided by the user."""
542- return unicode(self.ui.email_line_edit.text())
543+ return compat.text_type(self.ui.email_line_edit.text())
544
545 #pylint: disable=C0103
546
547@@ -122,7 +123,7 @@
548
549 def _validate(self):
550 """Validate that we have an email."""
551- email = unicode(self.ui.email_line_edit.text())
552+ email = compat.text_type(self.ui.email_line_edit.text())
553 self.ui.send_button.setEnabled(is_correct_email(email))
554
555 def on_password_reset_token_sent(self, app_name, email):
556
557=== modified file 'ubuntu_sso/qt/loadingoverlay.py'
558--- ubuntu_sso/qt/loadingoverlay.py 2012-06-22 22:34:43 +0000
559+++ ubuntu_sso/qt/loadingoverlay.py 2012-08-21 18:02:19 +0000
560@@ -28,12 +28,14 @@
561 # files in the program, then also delete it here.
562 """Loading animation over a widget."""
563
564+from __future__ import unicode_literals
565+
566 from PyQt4 import QtGui, QtCore
567
568 from ubuntu_sso.qt.ui import loadingoverlay_ui
569 from ubuntu_sso.utils.ui import LOADING_OVERLAY
570
571-LOADING_STYLE = u'<span style="font-size:x-large;">{0}</span>'
572+LOADING_STYLE = '<span style="font-size:x-large;">{0}</span>'
573
574
575 class LoadingOverlay(QtGui.QFrame):
576
577=== modified file 'ubuntu_sso/qt/main/__init__.py'
578--- ubuntu_sso/qt/main/__init__.py 2012-06-13 21:26:02 +0000
579+++ ubuntu_sso/qt/main/__init__.py 2012-08-21 18:02:19 +0000
580@@ -38,7 +38,7 @@
581 from ubuntu_sso.qt.ui import resources_rc
582 # pylint: enable=W0611
583 from ubuntu_sso.qt.ubuntu_sso_wizard import UbuntuSSOClientGUI
584-from ubuntu_sso.utils import PLATFORM_QSS
585+from ubuntu_sso.utils import compat, PLATFORM_QSS
586
587
588 # Invalid name "source", pylint: disable=C0103
589@@ -63,13 +63,13 @@
590 data = []
591 for qss_name in (PLATFORM_QSS, ":/stylesheet.qss"):
592 qss = QtCore.QResource(qss_name)
593- data.append(unicode(qss.data()))
594+ data.append(compat.text_type(qss.data()))
595 app.setStyleSheet('\n'.join(data))
596
597 # Fix the string that contains unicode chars.
598 for key in kwargs:
599 value = kwargs[key]
600- if isinstance(value, str):
601+ if isinstance(value, compat.binary_type):
602 kwargs[key] = value.decode('utf-8')
603
604 # Unused variable 'ui', pylint: disable=W0612
605
606=== modified file 'ubuntu_sso/qt/main/tests/test_main.py'
607--- ubuntu_sso/qt/main/tests/test_main.py 2012-06-13 21:52:42 +0000
608+++ ubuntu_sso/qt/main/tests/test_main.py 2012-08-21 18:02:19 +0000
609@@ -37,6 +37,7 @@
610 from twisted.trial.unittest import TestCase
611
612 from ubuntu_sso.qt import main
613+from ubuntu_sso.utils import compat
614 from ubuntu_sso import tests
615
616
617@@ -205,7 +206,7 @@
618 data = []
619 for qss_name in (main.PLATFORM_QSS, ":/stylesheet.qss"):
620 qss = QtCore.QResource(qss_name)
621- data.append(unicode(qss.data()))
622+ data.append(compat.text_type(qss.data()))
623 self.assertEqual(
624- unicode(main.QtGui.QApplication.instance().styleSheet()),
625+ compat.text_type(main.QtGui.QApplication.instance().styleSheet()),
626 '\n'.join(data))
627
628=== modified file 'ubuntu_sso/qt/proxy_dialog.py'
629--- ubuntu_sso/qt/proxy_dialog.py 2012-06-22 16:12:03 +0000
630+++ ubuntu_sso/qt/proxy_dialog.py 2012-08-21 18:02:19 +0000
631@@ -38,6 +38,7 @@
632 from ubuntu_sso.logger import setup_gui_logging
633 from ubuntu_sso.keyring import Keyring
634 from ubuntu_sso.qt.ui.proxy_credentials_dialog_ui import Ui_ProxyCredsDialog
635+from ubuntu_sso.utils import compat
636 from ubuntu_sso.utils.ui import (
637 CANCEL_BUTTON,
638 PROXY_CREDS_DIALOG_TITLE,
639@@ -109,8 +110,10 @@
640 @defer.inlineCallbacks
641 def _on_save_clicked(self, *args):
642 """Save the new credentials."""
643- username = unicode(self.ui.username_entry.text()).encode('utf8')
644- password = unicode(self.ui.password_entry.text()).encode('utf8')
645+ username = compat.text_type(
646+ self.ui.username_entry.text()).encode('utf8')
647+ password = compat.text_type(
648+ self.ui.password_entry.text()).encode('utf8')
649 creds = dict(username=username, password=password)
650 # pylint: disable=W0703, W0612
651 try:
652
653=== modified file 'ubuntu_sso/qt/reset_password_page.py'
654--- ubuntu_sso/qt/reset_password_page.py 2012-04-09 17:38:24 +0000
655+++ ubuntu_sso/qt/reset_password_page.py 2012-08-21 18:02:19 +0000
656@@ -38,6 +38,7 @@
657 from ubuntu_sso.qt import build_general_error_message, common
658 from ubuntu_sso.qt.sso_wizard_page import SSOWizardEnhancedEditPage
659 from ubuntu_sso.qt.ui.reset_password_ui import Ui_ResetPasswordPage
660+from ubuntu_sso.utils import compat
661 from ubuntu_sso.utils.ui import (
662 is_min_required_password,
663 PASSWORD1_ENTRY,
664@@ -57,7 +58,7 @@
665 """Widget used to allow the user change his password."""
666
667 ui_class = Ui_ResetPasswordPage
668- passwordChanged = pyqtSignal(unicode)
669+ passwordChanged = pyqtSignal(compat.text_type)
670
671 @property
672 def _signals(self):
673@@ -146,9 +147,9 @@
674 def _validate(self):
675 """Enable the submit button if data is valid."""
676 enabled = True
677- code = unicode(self.ui.reset_code_line_edit.text())
678- password = unicode(self.ui.password_line_edit.text())
679- confirm_password = unicode(
680+ code = compat.text_type(self.ui.reset_code_line_edit.text())
681+ password = compat.text_type(self.ui.password_line_edit.text())
682+ confirm_password = compat.text_type(
683 self.ui.confirm_password_line_edit.text())
684 if not is_min_required_password(password):
685 enabled = False
686@@ -175,7 +176,8 @@
687 logger.info('ResetPasswordPage.on_password_changed for %s, email: %s',
688 app_name, email)
689 self.hide_overlay()
690- email = unicode(self.wizard().forgotten.ui.email_line_edit.text())
691+ email = compat.text_type(
692+ self.wizard().forgotten.ui.email_line_edit.text())
693 self.passwordChanged.emit(email)
694
695 def on_password_change_error(self, app_name, error):
696@@ -187,9 +189,10 @@
697 def set_new_password(self):
698 """Request a new password to be set."""
699 self.hide_error()
700- email = unicode(self.wizard().forgotten.ui.email_line_edit.text())
701- code = unicode(self.ui.reset_code_line_edit.text())
702- password = unicode(self.ui.password_line_edit.text())
703+ email = compat.text_type(
704+ self.wizard().forgotten.ui.email_line_edit.text())
705+ code = compat.text_type(self.ui.reset_code_line_edit.text())
706+ password = compat.text_type(self.ui.password_line_edit.text())
707 logger.info('Setting new password for %r and email %r with code %r',
708 self.app_name, email, code)
709 args = (self.app_name, email, code, password)
710@@ -201,4 +204,4 @@
711
712 def is_correct_password_confirmation(self, password):
713 """Return if the password is correct."""
714- return unicode(self.ui.password_line_edit.text()) == password
715+ return compat.text_type(self.ui.password_line_edit.text()) == password
716
717=== modified file 'ubuntu_sso/qt/setup_account_page.py'
718--- ubuntu_sso/qt/setup_account_page.py 2012-07-03 21:30:33 +0000
719+++ ubuntu_sso/qt/setup_account_page.py 2012-08-21 18:02:19 +0000
720@@ -30,7 +30,7 @@
721
722 import tempfile
723 import os
724-from io import StringIO
725+from io import BytesIO
726 from functools import partial
727
728 # pylint: disable=F0401
729@@ -53,6 +53,7 @@
730 )
731 from ubuntu_sso.qt.sso_wizard_page import SSOWizardEnhancedEditPage
732 from ubuntu_sso.qt.ui.setup_account_ui import Ui_SetUpAccountPage
733+from ubuntu_sso.utils import compat
734 from ubuntu_sso.utils.ui import (
735 AGREE_TO_PRIVACY_POLICY,
736 AGREE_TO_TERMS,
737@@ -99,7 +100,7 @@
738 """Customized Setup Account page for SSO."""
739
740 ui_class = Ui_SetUpAccountPage
741- userRegistered = QtCore.pyqtSignal(unicode)
742+ userRegistered = QtCore.pyqtSignal(compat.text_type)
743
744 def __init__(self, *args, **kwargs):
745 self.captcha_file = None
746@@ -127,7 +128,7 @@
747 @property
748 def password(self):
749 """Return the content of the password edit."""
750- return unicode(self.ui.password_edit.text())
751+ return compat.text_type(self.ui.password_edit.text())
752
753 # Invalid name "initializePage"
754 # pylint: disable=C0103
755@@ -263,12 +264,14 @@
756
757 def _enable_setup_button(self):
758 """Only enable the setup button if the form is valid."""
759- name = unicode(self.ui.name_edit.text()).strip()
760- email = unicode(self.ui.email_edit.text())
761- confirm_email = unicode(self.ui.confirm_email_edit.text())
762- password = unicode(self.ui.password_edit.text())
763- confirm_password = unicode(self.ui.confirm_password_edit.text())
764- captcha_solution = unicode(self.ui.captcha_solution_edit.text())
765+ name = compat.text_type(self.ui.name_edit.text()).strip()
766+ email = compat.text_type(self.ui.email_edit.text())
767+ confirm_email = compat.text_type(self.ui.confirm_email_edit.text())
768+ password = compat.text_type(self.ui.password_edit.text())
769+ confirm_password = compat.text_type(
770+ self.ui.confirm_password_edit.text())
771+ captcha_solution = compat.text_type(
772+ self.ui.captcha_solution_edit.text())
773
774 # Check for len(name) > 0 to ensure that a bool is assigned to enabled
775 if not self.terms_checkbox.isVisible():
776@@ -326,10 +329,10 @@
777 # done either by a setParent or something within the qtreactor, PIL
778 # in this case does solve the issue. Sorry :(
779 pil_image = Image.open(self.captcha_file)
780- string_io = StringIO()
781- pil_image.save(string_io, format='png')
782+ bytes_io = BytesIO()
783+ pil_image.save(bytes_io, format='png')
784 pixmap_image = QtGui.QPixmap()
785- pixmap_image.loadFromData(string_io.getvalue())
786+ pixmap_image.loadFromData(bytes_io.getvalue())
787 self.captcha_image = pixmap_image
788 self.on_captcha_refresh_complete()
789
790@@ -355,18 +358,20 @@
791 def on_user_registered(self, app_name, email):
792 """Execute when the user did register."""
793 self.hide_overlay()
794- email = unicode(self.ui.email_edit.text())
795+ email = compat.text_type(self.ui.email_edit.text())
796 self.userRegistered.emit(email)
797
798 def validate_form(self):
799 """Validate the info of the form and return an error."""
800 logger.debug('SetUpAccountPage.validate_form')
801- name = unicode(self.ui.name_edit.text()).strip()
802- email = unicode(self.ui.email_edit.text())
803- confirm_email = unicode(self.ui.confirm_email_edit.text())
804- password = unicode(self.ui.password_edit.text())
805- confirm_password = unicode(self.ui.confirm_password_edit.text())
806- captcha_solution = unicode(self.ui.captcha_solution_edit.text())
807+ name = compat.text_type(self.ui.name_edit.text()).strip()
808+ email = compat.text_type(self.ui.email_edit.text())
809+ confirm_email = compat.text_type(self.ui.confirm_email_edit.text())
810+ password = compat.text_type(self.ui.password_edit.text())
811+ confirm_password = compat.text_type(
812+ self.ui.confirm_password_edit.text())
813+ captcha_solution = compat.text_type(
814+ self.ui.captcha_solution_edit.text())
815 condition = True
816 messages = []
817 if not name:
818@@ -395,11 +400,12 @@
819 def set_next_validation(self):
820 """Set the validation as the next page."""
821 logger.debug('SetUpAccountPage.set_next_validation')
822- email = unicode(self.ui.email_edit.text())
823- password = unicode(self.ui.password_edit.text())
824- name = unicode(self.ui.name_edit.text())
825+ email = compat.text_type(self.ui.email_edit.text())
826+ password = compat.text_type(self.ui.password_edit.text())
827+ name = compat.text_type(self.ui.name_edit.text())
828 captcha_id = self.captcha_id
829- captcha_solution = unicode(self.ui.captcha_solution_edit.text())
830+ captcha_solution = compat.text_type(
831+ self.ui.captcha_solution_edit.text())
832 # validate the current info of the form, try to perform the action
833 # to register the user, and then move foward
834 if self.validate_form():
835@@ -418,11 +424,11 @@
836
837 def is_correct_email_confirmation(self, email_address):
838 """Return that the email is the same."""
839- return unicode(self.ui.email_edit.text()) == email_address
840+ return compat.text_type(self.ui.email_edit.text()) == email_address
841
842 def is_correct_password_confirmation(self, password):
843 """Return that the passwords are correct."""
844- return unicode(self.ui.password_edit.text()) == password
845+ return compat.text_type(self.ui.password_edit.text()) == password
846
847 def focus_changed(self, old, now):
848 """Check who has the focus to activate password popups if necessary."""
849@@ -441,7 +447,7 @@
850
851 def name_assistance(self):
852 """Show help for the name field."""
853- text = unicode(self.ui.name_edit.text())
854+ text = compat.text_type(self.ui.name_edit.text())
855 if not text.strip():
856 self.set_error_message(self.ui.name_assistance,
857 EMPTY_NAME)
858@@ -452,7 +458,7 @@
859
860 def email_assistance(self):
861 """Show help for the email field."""
862- text = unicode(self.ui.email_edit.text())
863+ text = compat.text_type(self.ui.email_edit.text())
864 if not is_correct_email(text):
865 self.set_error_message(self.ui.email_assistance,
866 INVALID_EMAIL)
867@@ -463,8 +469,8 @@
868
869 def confirm_email_assistance(self):
870 """Show help for the confirm email field."""
871- text1 = unicode(self.ui.email_edit.text())
872- text2 = unicode(self.ui.confirm_email_edit.text())
873+ text1 = compat.text_type(self.ui.email_edit.text())
874+ text2 = compat.text_type(self.ui.confirm_email_edit.text())
875 if text1 != text2:
876 self.set_error_message(self.ui.confirm_email_assistance,
877 EMAIL_MATCH)
878
879=== modified file 'ubuntu_sso/qt/tests/__init__.py'
880--- ubuntu_sso/qt/tests/__init__.py 2012-04-09 17:38:24 +0000
881+++ ubuntu_sso/qt/tests/__init__.py 2012-08-21 18:02:19 +0000
882@@ -42,6 +42,7 @@
883 TC_URL,
884 WINDOW_ID,
885 )
886+from ubuntu_sso.utils import compat
887
888 KWARGS = dict(app_name=APP_NAME, help_text=HELP_TEXT, ping_url=PING_URL,
889 policy_url=POLICY_URL, tc_url=TC_URL, window_id=WINDOW_ID)
890@@ -498,10 +499,10 @@
891 label = QtGui.QLabel()
892 maybe_elide_text(label, expected, max_width)
893
894- self.assertEqual(TITLE_STYLE % unicode(label.text()),
895- unicode(title_label.text()))
896- self.assertEqual(unicode(label.toolTip()),
897- unicode(title_label.toolTip()))
898+ self.assertEqual(TITLE_STYLE % compat.text_type(label.text()),
899+ compat.text_type(title_label.text()))
900+ self.assertEqual(compat.text_type(label.toolTip()),
901+ compat.text_type(title_label.toolTip()))
902 self.assertTrue(title_label.isVisible())
903
904 def assert_subtitle_correct(self, subtitle_label, expected, max_width):
905@@ -509,9 +510,10 @@
906 label = QtGui.QLabel()
907 maybe_elide_text(label, expected, max_width)
908
909- self.assertEqual(unicode(label.text()), unicode(subtitle_label.text()))
910- self.assertEqual(unicode(label.toolTip()),
911- unicode(subtitle_label.toolTip()))
912+ self.assertEqual(compat.text_type(label.text()),
913+ compat.text_type(subtitle_label.text()))
914+ self.assertEqual(compat.text_type(label.toolTip()),
915+ compat.text_type(subtitle_label.toolTip()))
916 self.assertTrue(subtitle_label.isVisible())
917
918 def assert_error_correct(self, error_label, expected, max_width):
919@@ -519,10 +521,10 @@
920 label = QtGui.QLabel()
921 maybe_elide_text(label, expected, max_width)
922
923- self.assertEqual(ERROR_STYLE % unicode(label.text()),
924- unicode(error_label.text()))
925- self.assertEqual(unicode(label.toolTip()),
926- unicode(error_label.toolTip()))
927+ self.assertEqual(ERROR_STYLE % compat.text_type(label.text()),
928+ compat.text_type(error_label.text()))
929+ self.assertEqual(compat.text_type(label.toolTip()),
930+ compat.text_type(error_label.toolTip()))
931 self.assertTrue(error_label.isVisible())
932
933 def get_pixmap_data(self, pixmap):
934
935=== modified file 'ubuntu_sso/qt/tests/show_gui.py'
936--- ubuntu_sso/qt/tests/show_gui.py 2012-06-27 19:03:44 +0000
937+++ ubuntu_sso/qt/tests/show_gui.py 2012-08-21 18:02:19 +0000
938@@ -28,6 +28,8 @@
939 # files in the program, then also delete it here.
940 """Script that shows the qt gui."""
941
942+from __future__ import unicode_literals
943+
944 import sys
945
946 # pylint: disable=E1101,F0401,E0611
947@@ -65,12 +67,12 @@
948 client.cred_manager.connect_to_signal('AuthorizationDenied', found)
949 client.cred_manager.connect_to_signal('CredentialsError', found)
950
951- yield client.cred_manager.login(u'Ubuntu Two',
952+ yield client.cred_manager.login('Ubuntu Two',
953 {
954- HELP_TEXT_KEY: u'This is a test help text.',
955- PING_URL_KEY: u'http://www.wikipedia.com/',
956- POLICY_URL_KEY: u'http://one.ubuntu.com/',
957- TC_URL_KEY: u'http://www.google.com/',
958+ HELP_TEXT_KEY: 'This is a test help text.',
959+ PING_URL_KEY: 'http://www.wikipedia.com/',
960+ POLICY_URL_KEY: 'http://one.ubuntu.com/',
961+ TC_URL_KEY: 'http://www.google.com/',
962 })
963 yield d
964
965
966=== modified file 'ubuntu_sso/qt/tests/test_common.py'
967--- ubuntu_sso/qt/tests/test_common.py 2012-06-22 20:52:26 +0000
968+++ ubuntu_sso/qt/tests/test_common.py 2012-08-21 18:02:19 +0000
969@@ -29,10 +29,13 @@
970 # files in the program, then also delete it here.
971 """Test the common functions."""
972
973+from __future__ import unicode_literals
974+
975 from PyQt4 import QtGui
976 from twisted.internet import defer
977 from twisted.trial.unittest import TestCase
978
979+from ubuntu_sso.utils import compat
980 from ubuntu_sso.qt import (
981 build_general_error_message,
982 maybe_elide_text,
983@@ -74,7 +77,7 @@
984 password_assistance(self.line_edit, self.label_assistance)
985 self.assertIn(
986 BAD % PASSWORD_LENGTH,
987- unicode(self.label_assistance.text()),
988+ compat.text_type(self.label_assistance.text()),
989 )
990
991 def test_long_password(self):
992@@ -86,7 +89,7 @@
993 password_assistance(self.line_edit, self.label_assistance)
994 self.assertIn(
995 GOOD % PASSWORD_LENGTH,
996- unicode(self.label_assistance.text()),
997+ compat.text_type(self.label_assistance.text()),
998 )
999
1000 def test_no_number_password(self):
1001@@ -98,7 +101,7 @@
1002 password_assistance(self.line_edit, self.label_assistance)
1003 self.assertIn(
1004 BAD % PASSWORD_DIGIT,
1005- unicode(self.label_assistance.text()),
1006+ compat.text_type(self.label_assistance.text()),
1007 )
1008
1009 def test_number_password(self):
1010@@ -110,7 +113,7 @@
1011 password_assistance(self.line_edit, self.label_assistance)
1012 self.assertIn(
1013 GOOD % PASSWORD_DIGIT,
1014- unicode(self.label_assistance.text()),
1015+ compat.text_type(self.label_assistance.text()),
1016 )
1017
1018 def test_no_uppercase_password(self):
1019@@ -122,7 +125,7 @@
1020 password_assistance(self.line_edit, self.label_assistance)
1021 self.assertIn(
1022 BAD % PASSWORD_UPPER,
1023- unicode(self.label_assistance.text()),
1024+ compat.text_type(self.label_assistance.text()),
1025 )
1026
1027 def test_upper_password(self):
1028@@ -134,7 +137,7 @@
1029 password_assistance(self.line_edit, self.label_assistance)
1030 self.assertIn(
1031 GOOD % PASSWORD_UPPER,
1032- unicode(self.label_assistance.text()),
1033+ compat.text_type(self.label_assistance.text()),
1034 )
1035
1036 def test_matching_passwords(self):
1037@@ -148,7 +151,7 @@
1038 self.line_edit_confirm, self.label_assistance)
1039 self.assertNotIn(
1040 BAD % PASSWORD_MATCH,
1041- unicode(self.label_assistance.text()))
1042+ compat.text_type(self.label_assistance.text()))
1043
1044 def test_not_matching_passwords(self):
1045 """Status when the passwords not match.
1046@@ -161,7 +164,7 @@
1047 self.line_edit_confirm, self.label_assistance)
1048 self.assertIn(
1049 BAD % PASSWORD_MATCH,
1050- unicode(self.label_assistance.text()),
1051+ compat.text_type(self.label_assistance.text()),
1052 )
1053
1054 def test_password_assistance_in_focus_length_correct(self):
1055@@ -171,15 +174,15 @@
1056 password_assistance(self.line_edit, self.label_assistance, NORMAL)
1057 self.assertIn(
1058 GOOD % PASSWORD_LENGTH,
1059- unicode(self.label_assistance.text()),
1060+ compat.text_type(self.label_assistance.text()),
1061 )
1062 self.assertIn(
1063 NORMAL % PASSWORD_UPPER,
1064- unicode(self.label_assistance.text()),
1065+ compat.text_type(self.label_assistance.text()),
1066 )
1067 self.assertIn(
1068 NORMAL % PASSWORD_DIGIT,
1069- unicode(self.label_assistance.text()),
1070+ compat.text_type(self.label_assistance.text()),
1071 )
1072
1073 def test_password_assistance_in_focus_with_upper(self):
1074@@ -189,15 +192,15 @@
1075 password_assistance(self.line_edit, self.label_assistance, NORMAL)
1076 self.assertIn(
1077 NORMAL % PASSWORD_LENGTH,
1078- unicode(self.label_assistance.text()),
1079+ compat.text_type(self.label_assistance.text()),
1080 )
1081 self.assertIn(
1082 GOOD % PASSWORD_UPPER,
1083- unicode(self.label_assistance.text()),
1084+ compat.text_type(self.label_assistance.text()),
1085 )
1086 self.assertIn(
1087 NORMAL % PASSWORD_DIGIT,
1088- unicode(self.label_assistance.text()),
1089+ compat.text_type(self.label_assistance.text()),
1090 )
1091
1092 def test_password_assistance_in_focus_with_number(self):
1093@@ -207,15 +210,15 @@
1094 password_assistance(self.line_edit, self.label_assistance, NORMAL)
1095 self.assertIn(
1096 NORMAL % PASSWORD_LENGTH,
1097- unicode(self.label_assistance.text()),
1098+ compat.text_type(self.label_assistance.text()),
1099 )
1100 self.assertIn(
1101 NORMAL % PASSWORD_UPPER,
1102- unicode(self.label_assistance.text()),
1103+ compat.text_type(self.label_assistance.text()),
1104 )
1105 self.assertIn(
1106 GOOD % PASSWORD_DIGIT,
1107- unicode(self.label_assistance.text()),
1108+ compat.text_type(self.label_assistance.text()),
1109 )
1110
1111 def test_password_assistance_in_focus_all_ok(self):
1112@@ -225,19 +228,19 @@
1113 password_assistance(self.line_edit, self.label_assistance, NORMAL)
1114 self.assertIn(
1115 GOOD % PASSWORD_LENGTH,
1116- unicode(self.label_assistance.text()),
1117+ compat.text_type(self.label_assistance.text()),
1118 )
1119 self.assertIn(
1120 GOOD % PASSWORD_UPPER,
1121- unicode(self.label_assistance.text()),
1122+ compat.text_type(self.label_assistance.text()),
1123 )
1124 self.assertIn(
1125 GOOD % PASSWORD_DIGIT,
1126- unicode(self.label_assistance.text()),
1127+ compat.text_type(self.label_assistance.text()),
1128 )
1129 self.assertNotIn(
1130 NORMAL % PASSWORD_MATCH,
1131- unicode(self.label_assistance.text()),
1132+ compat.text_type(self.label_assistance.text()),
1133 )
1134
1135
1136@@ -276,7 +279,7 @@
1137
1138 self.assertEqual(self.ui.toolTip(), '')
1139 self.assertEqual(self.ui.text(), text)
1140- self.assertNotIn(u'\u2026', self.ui.text())
1141+ self.assertNotIn('\u2026', self.ui.text())
1142
1143 def test_text_not_elided_if_equals_max_width(self):
1144 """If text is equal than max_width, do not elide."""
1145@@ -286,7 +289,7 @@
1146
1147 self.assertEqual(self.ui.toolTip(), '')
1148 self.assertEqual(self.ui.text(), text)
1149- self.assertNotIn(u'\u2026', self.ui.text())
1150+ self.assertNotIn('\u2026', self.ui.text())
1151
1152 def test_text_elided_if_bigger_than_max_width(self):
1153 """If text is equal than max_width, do not elide."""
1154@@ -295,8 +298,8 @@
1155 maybe_elide_text(self.ui, text, self.max_width)
1156
1157 self.assertEqual(self.ui.toolTip(), text)
1158- expected = unicode(self.ui.text())
1159- self.assertTrue(expected.endswith(u'\u2026'))
1160+ expected = compat.text_type(self.ui.text())
1161+ self.assertTrue(expected.endswith('\u2026'))
1162 self.assertTrue(text.startswith(expected[:-1]))
1163
1164
1165
1166=== modified file 'ubuntu_sso/qt/tests/test_current_user_sign_in_page.py'
1167--- ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-06-08 15:10:34 +0000
1168+++ ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-08-21 18:02:19 +0000
1169@@ -28,8 +28,11 @@
1170 # files in the program, then also delete it here.
1171 """Tests for the Setup Account page Qt UI."""
1172
1173+from __future__ import unicode_literals
1174+
1175 from PyQt4 import QtGui, QtCore
1176
1177+from ubuntu_sso.utils import compat
1178 from ubuntu_sso.qt import current_user_sign_in_page as gui
1179 from ubuntu_sso.qt.tests import (
1180 PageBaseTestCase,
1181@@ -66,13 +69,14 @@
1182
1183 def test_unicode_in_forgotten_password_link(self):
1184 """Ensure that this label supports unicode."""
1185- forgot_fr = u"J'ai oublié mon mot de passe"
1186+ forgot_fr = "J'ai oublié mon mot de passe"
1187 self.patch(gui, "FORGOTTEN_PASSWORD_BUTTON", forgot_fr)
1188 forgotten_text = gui.LINK_STYLE.format(link_url='#',
1189 link_text=forgot_fr)
1190 self.ui._set_translated_strings()
1191- self.assertEqual(unicode(self.ui.ui.forgot_password_label.text()),
1192- forgotten_text)
1193+ self.assertEqual(
1194+ compat.text_type(self.ui.ui.forgot_password_label.text()),
1195+ forgotten_text)
1196
1197 def test_set_translated_strings(self):
1198 """Test the translated string method."""
1199@@ -80,16 +84,18 @@
1200 self.assert_title_correct(expected)
1201 expected = gui.LOGIN_SUBTITLE % dict(app_name=self.app_name)
1202 self.assert_subtitle_correct(expected)
1203- self.assertEqual(unicode(self.ui.ui.email_label.text()),
1204+ self.assertEqual(compat.text_type(self.ui.ui.email_label.text()),
1205 gui.EMAIL_LABEL)
1206- self.assertEqual(unicode(self.ui.ui.password_label.text()),
1207+ self.assertEqual(compat.text_type(self.ui.ui.password_label.text()),
1208 gui.LOGIN_PASSWORD_LABEL)
1209 text = gui.LINK_STYLE.format(link_url='#',
1210 link_text=gui.FORGOTTEN_PASSWORD_BUTTON)
1211- self.assertEqual(unicode(self.ui.ui.forgot_password_label.text()),
1212- text)
1213- self.assertEqual(unicode(self.ui.ui.sign_in_button.text()),
1214- gui.SIGN_IN_BUTTON)
1215+ self.assertEqual(
1216+ compat.text_type(self.ui.ui.forgot_password_label.text()),
1217+ text)
1218+ self.assertEqual(
1219+ compat.text_type(self.ui.ui.sign_in_button.text()),
1220+ gui.SIGN_IN_BUTTON)
1221
1222 def test_connect_ui(self):
1223 """Test the connect ui method."""
1224
1225=== modified file 'ubuntu_sso/qt/tests/test_forgotten_password.py'
1226--- ubuntu_sso/qt/tests/test_forgotten_password.py 2012-04-09 17:38:24 +0000
1227+++ ubuntu_sso/qt/tests/test_forgotten_password.py 2012-08-21 18:02:19 +0000
1228@@ -30,6 +30,7 @@
1229
1230 from PyQt4 import QtCore
1231
1232+from ubuntu_sso.utils import compat
1233 from ubuntu_sso.qt import forgotten_password_page as gui
1234 from ubuntu_sso.qt.tests import (
1235 PageBaseTestCase,
1236@@ -60,8 +61,9 @@
1237 def test_email_address(self):
1238 """Test the email_address property."""
1239 value = self.ui.email_address
1240- self.assertEqual(value, unicode(self.ui.ui.email_line_edit.text()))
1241- self.assertTrue(isinstance(value, unicode))
1242+ self.assertEqual(value,
1243+ compat.text_type(self.ui.ui.email_line_edit.text()))
1244+ self.assertTrue(isinstance(value, compat.text_type))
1245
1246 def test_send_button_clicked(self):
1247 """Test the send_button property."""
1248@@ -87,9 +89,10 @@
1249 subtitle = gui.FORGOTTEN_PASSWORD_SUBTITLE
1250 self.assert_subtitle_correct(subtitle.format(app_name=self.app_name))
1251
1252- self.assertEqual(unicode(self.ui.ui.email_address_label.text()),
1253- gui.EMAIL_LABEL)
1254- self.assertEqual(unicode(self.ui.ui.send_button.text()),
1255+ self.assertEqual(
1256+ compat.text_type(self.ui.ui.email_address_label.text()),
1257+ gui.EMAIL_LABEL)
1258+ self.assertEqual(compat.text_type(self.ui.ui.send_button.text()),
1259 gui.RESET_PASSWORD)
1260
1261 def test_connect_ui(self):
1262
1263=== modified file 'ubuntu_sso/qt/tests/test_reset_password.py'
1264--- ubuntu_sso/qt/tests/test_reset_password.py 2012-04-09 17:38:24 +0000
1265+++ ubuntu_sso/qt/tests/test_reset_password.py 2012-08-21 18:02:19 +0000
1266@@ -32,6 +32,7 @@
1267
1268 from PyQt4 import QtGui, QtCore
1269
1270+from ubuntu_sso.utils import compat
1271 from ubuntu_sso.utils.ui import (
1272 PASSWORD1_ENTRY,
1273 PASSWORD2_ENTRY,
1274@@ -86,11 +87,12 @@
1275 self.ui.initializePage()
1276 self.assert_title_correct(RESET_TITLE)
1277 self.assert_subtitle_correct(RESET_SUBTITLE)
1278- self.assertEqual(unicode(self.ui.ui.password_label.text()),
1279+ self.assertEqual(compat.text_type(self.ui.ui.password_label.text()),
1280 PASSWORD1_ENTRY)
1281- self.assertEqual(unicode(self.ui.ui.confirm_password_label.text()),
1282- PASSWORD2_ENTRY)
1283- self.assertEqual(unicode(self.ui.ui.reset_code.text()),
1284+ self.assertEqual(
1285+ compat.text_type(self.ui.ui.confirm_password_label.text()),
1286+ PASSWORD2_ENTRY)
1287+ self.assertEqual(compat.text_type(self.ui.ui.reset_code.text()),
1288 RESET_CODE_ENTRY)
1289
1290 def test_focus_changed_password_visibility(self):
1291
1292=== modified file 'ubuntu_sso/qt/tests/test_setup_account.py'
1293--- ubuntu_sso/qt/tests/test_setup_account.py 2012-06-08 15:10:34 +0000
1294+++ ubuntu_sso/qt/tests/test_setup_account.py 2012-08-21 18:02:19 +0000
1295@@ -30,6 +30,9 @@
1296
1297 from PyQt4 import QtGui, QtCore
1298
1299+from ubuntu_sso.utils import compat
1300+from ubuntu_sso.tests import CAPTCHA_PATH
1301+
1302 from ubuntu_sso.qt import common, setup_account_page as gui
1303 from ubuntu_sso.qt.tests import PageBaseTestCase
1304
1305@@ -67,7 +70,7 @@
1306
1307 self.ui.ui.refresh_label.linkActivated.emit('error')
1308
1309- message = unicode(self.ui.form_errors_label.text())
1310+ message = compat.text_type(self.ui.form_errors_label.text())
1311 self.assertEqual(message, ' ')
1312
1313 def test_enable_setup_button_with_visible_check(self):
1314@@ -116,15 +119,15 @@
1315 self.ui.focus_changed(None, self.ui.ui.password_edit)
1316 self.assertIn(
1317 common.NORMAL % common.PASSWORD_LENGTH,
1318- unicode(self.ui.ui.password_assistance.text()),
1319+ compat.text_type(self.ui.ui.password_assistance.text()),
1320 )
1321 self.assertIn(
1322 common.NORMAL % common.PASSWORD_UPPER,
1323- unicode(self.ui.ui.password_assistance.text()),
1324+ compat.text_type(self.ui.ui.password_assistance.text()),
1325 )
1326 self.assertIn(
1327 common.NORMAL % common.PASSWORD_DIGIT,
1328- unicode(self.ui.ui.password_assistance.text()),
1329+ compat.text_type(self.ui.ui.password_assistance.text()),
1330 )
1331
1332 def test_password_focus_gain(self):
1333@@ -219,16 +222,18 @@
1334 self.assertFalse(self.ui.captcha_received)
1335
1336 # labels
1337- self.assertEqual(unicode(self.ui.ui.name_label.text()),
1338+ self.assertEqual(compat.text_type(self.ui.ui.name_label.text()),
1339 gui.NAME_ENTRY)
1340- self.assertEqual(unicode(self.ui.ui.email_label.text()),
1341+ self.assertEqual(compat.text_type(self.ui.ui.email_label.text()),
1342 gui.EMAIL)
1343- self.assertEqual(unicode(self.ui.ui.confirm_email_label.text()),
1344- gui.RETYPE_EMAIL)
1345- self.assertEqual(unicode(self.ui.ui.password_label.text()),
1346+ self.assertEqual(
1347+ compat.text_type(self.ui.ui.confirm_email_label.text()),
1348+ gui.RETYPE_EMAIL)
1349+ self.assertEqual(compat.text_type(self.ui.ui.password_label.text()),
1350 gui.PASSWORD)
1351- self.assertEqual(unicode(self.ui.ui.confirm_password_label.text()),
1352- gui.RETYPE_PASSWORD)
1353+ self.assertEqual(
1354+ compat.text_type(self.ui.ui.confirm_password_label.text()),
1355+ gui.RETYPE_PASSWORD)
1356
1357 # assistants
1358 self.assertFalse(self.ui.ui.name_assistance.isVisible())
1359@@ -337,6 +342,15 @@
1360 self.ui.showEvent(QtGui.QShowEvent())
1361 self.ui.hideEvent(QtGui.QHideEvent())
1362
1363+ def test_on_captcha_generated(self):
1364+ """Check that the captcha image is handled correctly."""
1365+
1366+ self.ui.captcha_file = CAPTCHA_PATH
1367+ self.ui.on_captcha_generated(u"fake app name",
1368+ "fake id")
1369+ pixmap_empty = self.ui.captcha_image.size().isEmpty()
1370+ self.assertEqual(pixmap_empty, False)
1371+
1372 def test_on_captcha_refreshing_visible(self):
1373 """Check the state of the overlay on captcha refreshing."""
1374 self.ui.hide_overlay()
1375
1376=== modified file 'ubuntu_sso/qt/tests/test_ssl_dialog.py'
1377--- ubuntu_sso/qt/tests/test_ssl_dialog.py 2012-04-09 17:38:24 +0000
1378+++ ubuntu_sso/qt/tests/test_ssl_dialog.py 2012-08-21 18:02:19 +0000
1379@@ -34,6 +34,7 @@
1380
1381 from ubuntu_sso import USER_CANCELLATION, USER_SUCCESS
1382 from ubuntu_sso.qt import ssl_dialog
1383+from ubuntu_sso.utils import compat
1384 from ubuntu_sso.utils.ui import (
1385 CANCEL_BUTTON,
1386 SSL_APPNAME_HELP,
1387@@ -94,17 +95,18 @@
1388 def test_set_labels(self):
1389 """Test that the labels contain the correct info."""
1390 self.assertEqual(SSL_HEADER,
1391- unicode(self.dialog.ui.title_label.text()))
1392+ compat.text_type(self.dialog.ui.title_label.text()))
1393 explanation = SSL_EXPLANATION % dict(domain=self.domain)
1394 intro = ssl_dialog.REASONS_TEMPLATE % dict(explanation=explanation,
1395 first_reason=SSL_FIRST_REASON,
1396 second_reason=SSL_SECOND_REASON,
1397 third_reason=SSL_THIRD_REASON)
1398- self.assertEqual(intro, unicode(self.dialog.ui.intro_label.text()))
1399+ self.assertEqual(intro,
1400+ compat.text_type(self.dialog.ui.intro_label.text()))
1401 self.assertEqual(SSL_NOT_SURE % dict(app_name=self.appname),
1402- unicode(self.dialog.ui.not_sure_label.text()))
1403+ compat.text_type(self.dialog.ui.not_sure_label.text()))
1404 self.assertEqual(SSL_REMEMBER_DECISION,
1405- unicode(self.dialog.ui.remember_checkbox.text()))
1406+ compat.text_type(self.dialog.ui.remember_checkbox.text()))
1407
1408 def test_on_cancel_clicked(self):
1409 """Test the cancelation action."""
1410@@ -146,16 +148,16 @@
1411 self.assertIn('_on_cancel_clicked', called)
1412
1413 self.assertEqual(CANCEL_BUTTON,
1414- unicode(dialog.ui.cancel_button.text()))
1415+ compat.text_type(dialog.ui.cancel_button.text()))
1416 self.assertEqual(SSL_CONNECT_BUTTON,
1417- unicode(dialog.ui.connect_button.text()))
1418+ compat.text_type(dialog.ui.connect_button.text()))
1419 self.assertEqual(SSL_HELP_BUTTON,
1420- unicode(dialog.ui.help_button.text()))
1421+ compat.text_type(dialog.ui.help_button.text()))
1422
1423 def test_set_expander(self):
1424 """Test that the expander is correctly set."""
1425 self.assertEqual(SSL_CERT_DETAILS,
1426- unicode(self.dialog.expander.text()))
1427+ compat.text_type(self.dialog.expander.text()))
1428 self.assertNotEqual(None, self.dialog.expander.content)
1429 self.assertEqual(2, self.dialog.ui.expander_layout.indexOf(
1430 self.dialog.expander))
1431
1432=== modified file 'ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py'
1433--- ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py 2012-05-11 18:32:40 +0000
1434+++ ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py 2012-08-21 18:02:19 +0000
1435@@ -41,6 +41,7 @@
1436 BaseTestCase,
1437 FakeOverlay,
1438 )
1439+from ubuntu_sso.utils import compat
1440
1441
1442 # is ok to access private method/attrs in tests
1443@@ -107,7 +108,7 @@
1444
1445 def test_window_title(self):
1446 """Check the window title for the application."""
1447- title = unicode(self.ui.windowTitle())
1448+ title = compat.text_type(self.ui.windowTitle())
1449 self.assertEqual(title, ubuntu_sso_wizard.WINDOW_TITLE)
1450
1451
1452
1453=== modified file 'ubuntu_sso/qt/ubuntu_sso_wizard.py'
1454--- ubuntu_sso/qt/ubuntu_sso_wizard.py 2012-05-25 13:51:31 +0000
1455+++ ubuntu_sso/qt/ubuntu_sso_wizard.py 2012-08-21 18:02:19 +0000
1456@@ -44,6 +44,7 @@
1457 USER_SUCCESS,
1458 )
1459 from ubuntu_sso.logger import setup_gui_logging
1460+from ubuntu_sso.utils import compat
1461 from ubuntu_sso.qt import PREFERED_UI_SIZE, WINDOW_TITLE
1462 from ubuntu_sso.qt.current_user_sign_in_page import CurrentUserSignInPage
1463 from ubuntu_sso.qt.email_verification_page import EmailVerificationPage
1464@@ -203,7 +204,7 @@
1465 logger.debug('Moving to EmailVerificationPage from: %s',
1466 self.currentPage())
1467 self._next_id = self.email_verification_page_id
1468- self.email_verification.email = unicode(email)
1469+ self.email_verification.email = compat.text_type(email)
1470 self.email_verification.password = self.currentPage().password
1471 self.next()
1472 self._next_id = -1
1473
1474=== modified file 'ubuntu_sso/tests/__init__.py'
1475--- ubuntu_sso/tests/__init__.py 2012-06-27 19:03:44 +0000
1476+++ ubuntu_sso/tests/__init__.py 2012-08-21 18:02:19 +0000
1477@@ -28,6 +28,8 @@
1478 # files in the program, then also delete it here.
1479 """Tests for the Ubuntu SSO library."""
1480
1481+from __future__ import unicode_literals
1482+
1483 import os
1484
1485 from collections import defaultdict
1486@@ -38,30 +40,30 @@
1487
1488 from ubuntu_sso.keyring import get_token_name
1489
1490-APP_NAME = u'I ♥ Ubuntu'
1491-CAPTCHA_ID = u'test ñiña'
1492+APP_NAME = 'I ♥ Ubuntu'
1493+CAPTCHA_ID = 'test ñiña'
1494 CAPTCHA_PATH = os.path.abspath(os.path.join(os.curdir, 'ubuntu_sso', 'tests',
1495 'files', 'captcha.png'))
1496-CAPTCHA_SOLUTION = u'william Byrd ñandú'
1497-EMAIL = u'test@example.com'
1498-EMAIL_TOKEN = u'B2P☺ gtf'
1499+CAPTCHA_SOLUTION = 'william Byrd ñandú'
1500+EMAIL = 'test@example.com'
1501+EMAIL_TOKEN = 'B2P☺ gtf'
1502 GUI_EXE = 'ubuntu-sso-login-qt'
1503-HELP_TEXT = u'☛ Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' \
1504+HELP_TEXT = '☛ Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' \
1505 'Nam sed lorem nibh. Suspendisse gravida nulla non nunc suscipit pulvinar ' \
1506 'tempus ut augue. Morbi consequat, ligula a elementum pretium, ' \
1507 'dolor nulla tempus metus, sed viverra nisi risus non velit.'
1508-NAME = u'Juanito ☀ Pérez'
1509-PASSWORD = u'h3lloWorld☑ '
1510-PING_URL = u'http://localhost/ping-me/'
1511-POLICY_URL = u'http://localhost/policy/'
1512-RESET_PASSWORD_TOKEN = u'8G5Wtq'
1513-TOKEN = {u'consumer_key': u'xQ7xDAz',
1514- u'consumer_secret': u'KzCJWCTNbbntwfyCKKjomJDzlgqxLy',
1515- u'token_name': u'test',
1516- u'token': u'GkInOfSMGwTXAUoVQwLUoPxElEEUdhsLVNTPhxHJDUIeHCPNEo',
1517- u'token_secret': u'qFYImEtlczPbsCnYyuwLoPDlPEnvNcIktZphPQklAWrvyfFMV'}
1518+NAME = 'Juanito ☀ Pérez'
1519+PASSWORD = 'h3lloWorld☑ '
1520+PING_URL = 'http://localhost/ping-me/'
1521+POLICY_URL = 'http://localhost/policy/'
1522+RESET_PASSWORD_TOKEN = '8G5Wtq'
1523+TOKEN = {'consumer_key': 'xQ7xDAz',
1524+ 'consumer_secret': 'KzCJWCTNbbntwfyCKKjomJDzlgqxLy',
1525+ 'token_name': 'test',
1526+ 'token': 'GkInOfSMGwTXAUoVQwLUoPxElEEUdhsLVNTPhxHJDUIeHCPNEo',
1527+ 'token_secret': 'qFYImEtlczPbsCnYyuwLoPDlPEnvNcIktZphPQklAWrvyfFMV'}
1528 TOKEN_NAME = get_token_name(APP_NAME)
1529-TC_URL = u'http://localhost/'
1530+TC_URL = 'http://localhost/'
1531 WINDOW_ID = 5
1532
1533
1534
1535=== modified file 'ubuntu_sso/tests/test_account.py'
1536--- ubuntu_sso/tests/test_account.py 2012-07-03 21:04:09 +0000
1537+++ ubuntu_sso/tests/test_account.py 2012-08-21 18:02:19 +0000
1538@@ -31,13 +31,21 @@
1539 # files in the program, then also delete it here.
1540 """Tests for the SSO account code."""
1541
1542+from __future__ import unicode_literals
1543+
1544 import os
1545
1546+# pylint: disable=W0621,F0401,E0611
1547+try:
1548+ import urllib.request as url_lib
1549+except ImportError:
1550+ import urllib2 as url_lib
1551+# pylint: enable=W0621,F0401,E0611
1552+
1553 from twisted.trial.unittest import TestCase
1554 from twisted.internet import defer
1555
1556 from ubuntu_sso import account
1557-from ubuntu_sso import utils
1558 from ubuntu_sso.account import (
1559 Account,
1560 AuthenticationError,
1561@@ -64,12 +72,13 @@
1562 TOKEN,
1563 TOKEN_NAME,
1564 )
1565+from ubuntu_sso.utils import compat
1566
1567
1568 CANT_RESET_PASSWORD_CONTENT = "CanNotResetPassowrdError: " \
1569 "Can't reset password for this account"
1570 RESET_TOKEN_INVALID_CONTENT = "AuthToken matching query does not exist."
1571-EMAIL_ALREADY_REGISTERED = u'a@example.com'
1572+EMAIL_ALREADY_REGISTERED = 'a@example.com'
1573 STATUS_UNKNOWN = {'status': 'yadda-yadda'}
1574 STATUS_ERROR = {'status': SSO_STATUS_ERROR,
1575 'errors': {'something': ['Bla', 'Ble']}}
1576@@ -79,7 +88,7 @@
1577 STATUS_EMAIL_OK = {'email': EMAIL}
1578
1579 FAKE_NEW_CAPTCHA = {
1580- 'image_url': "file://" + unicode(CAPTCHA_PATH),
1581+ 'image_url': "file://" + compat.text_type(CAPTCHA_PATH),
1582 'captcha_id': CAPTCHA_ID,
1583 }
1584
1585@@ -177,17 +186,17 @@
1586
1587 def fake_accounts_me(self):
1588 """Fake the 'me' information."""
1589- return {u'username': u'Wh46bKY',
1590- u'preferred_email': self.preferred_email,
1591- u'displayname': u'',
1592- u'unverified_emails': [u'aaaaaa@example.com'],
1593- u'verified_emails': [],
1594- u'openid_identifier': u'Wh46bKY'}
1595+ return {'username': 'Wh46bKY',
1596+ 'preferred_email': self.preferred_email,
1597+ 'displayname': '',
1598+ 'unverified_emails': ['aaaaaa@example.com'],
1599+ 'verified_emails': [],
1600+ 'openid_identifier': 'Wh46bKY'}
1601
1602 def check_all_kwargs_unicode(self, **kwargs):
1603 """Check that the values of all keyword arguments are unicode."""
1604 for (key, value) in kwargs.items():
1605- if isinstance(value, str):
1606+ if isinstance(value, compat.binary_type):
1607 raise AssertionError("Error: kwarg '%s' is non-unicode." % key)
1608
1609 def restcall(self, method_name, **kwargs):
1610@@ -215,7 +224,7 @@
1611 self.addCleanup(f.close)
1612 return f
1613
1614- self.patch(utils, 'urlopen', fake_urlopen) # fd to the path
1615+ self.patch(url_lib, 'urlopen', fake_urlopen) # fd to the path
1616 self.processor = Account()
1617 self.register_kwargs = dict(email=EMAIL, password=PASSWORD,
1618 displayname=NAME,
1619@@ -254,27 +263,27 @@
1620 @defer.inlineCallbacks
1621 def test_register_user_checks_valid_email(self):
1622 """Email is validated."""
1623- self.register_kwargs['email'] = u'notavalidemail'
1624+ self.register_kwargs['email'] = 'notavalidemail'
1625 d = self.processor.register_user(**self.register_kwargs)
1626 yield self.assertFailure(d, InvalidEmailError)
1627
1628 @defer.inlineCallbacks
1629 def test_register_user_checks_valid_password(self):
1630 """Password is validated."""
1631- self.register_kwargs['password'] = u''
1632+ self.register_kwargs['password'] = ''
1633 d = self.processor.register_user(**self.register_kwargs)
1634 yield self.assertFailure(d, InvalidPasswordError)
1635
1636 # 7 chars, one less than expected
1637- self.register_kwargs['password'] = u'tesT3it'
1638- d = self.processor.register_user(**self.register_kwargs)
1639- yield self.assertFailure(d, InvalidPasswordError)
1640-
1641- self.register_kwargs['password'] = u'test3it!' # no upper case
1642- d = self.processor.register_user(**self.register_kwargs)
1643- yield self.assertFailure(d, InvalidPasswordError)
1644-
1645- self.register_kwargs['password'] = u'testIt!!' # no number
1646+ self.register_kwargs['password'] = 'tesT3it'
1647+ d = self.processor.register_user(**self.register_kwargs)
1648+ yield self.assertFailure(d, InvalidPasswordError)
1649+
1650+ self.register_kwargs['password'] = 'test3it!' # no upper case
1651+ d = self.processor.register_user(**self.register_kwargs)
1652+ yield self.assertFailure(d, InvalidPasswordError)
1653+
1654+ self.register_kwargs['password'] = 'testIt!!' # no number
1655 d = self.processor.register_user(**self.register_kwargs)
1656 yield self.assertFailure(d, InvalidPasswordError)
1657
1658
1659=== modified file 'ubuntu_sso/utils/__init__.py'
1660--- ubuntu_sso/utils/__init__.py 2012-07-13 20:45:14 +0000
1661+++ ubuntu_sso/utils/__init__.py 2012-08-21 18:02:19 +0000
1662@@ -28,22 +28,12 @@
1663 # files in the program, then also delete it here.
1664 """Utility modules that may find use outside ubuntu_sso."""
1665
1666-import cgi
1667+from __future__ import unicode_literals
1668+
1669 import os
1670 import sys
1671-import time
1672
1673 from dirspec.utils import get_program_path
1674-from oauth import oauth
1675-
1676-try:
1677- # pylint: disable=E0611,F0401
1678- from urllib.parse import urlparse
1679- from urllib.request import Request, urlopen
1680- # pylint: enable=E0611,F0401
1681-except ImportError:
1682- from urlparse import urlparse
1683- from urllib2 import Request, urlopen
1684
1685 from twisted.internet import defer
1686
1687@@ -52,7 +42,7 @@
1688 UI_PROXY_CREDS_DIALOG,
1689 UI_SSL_DIALOG)
1690 from ubuntu_sso.logger import setup_logging
1691-from ubuntu_sso.utils import webclient
1692+from ubuntu_sso.utils import compat, webclient
1693
1694
1695 logger = setup_logging("ubuntu_sso.utils")
1696@@ -150,98 +140,6 @@
1697 return cmd_args
1698
1699
1700-class RequestHead(Request):
1701- """A request with the method set to HEAD."""
1702-
1703- _request_method = "HEAD"
1704-
1705- def get_method(self):
1706- """Return the desired method."""
1707- return self._request_method
1708-
1709-
1710-class SyncTimestampChecker(object):
1711- """A timestamp that's regularly checked with a server."""
1712-
1713- CHECKING_INTERVAL = 60 * 60 # in seconds
1714- ERROR_INTERVAL = 30 # in seconds
1715- SERVER_URL = "http://one.ubuntu.com/api/time"
1716-
1717- def __init__(self):
1718- """Initialize this instance."""
1719- self.next_check = time.time()
1720- self.skew = 0
1721-
1722- def get_server_time(self):
1723- """Get the time at the server."""
1724- headers = {"Cache-Control": "no-cache"}
1725- request = RequestHead(self.SERVER_URL, headers=headers)
1726- response = urlopen(request)
1727- date_string = response.info()["Date"]
1728- # delay import, otherwise a default reactor gets installed
1729- from twisted.web import http
1730- timestamp = http.stringToDatetime(date_string)
1731- return timestamp
1732-
1733- def get_faithful_time(self):
1734- """Get an accurate timestamp."""
1735- local_time = time.time()
1736- if local_time >= self.next_check:
1737- try:
1738- server_time = self.get_server_time()
1739- self.next_check = local_time + self.CHECKING_INTERVAL
1740- self.skew = server_time - local_time
1741- logger.debug("Calculated server-local time skew: %r",
1742- self.skew)
1743- #pylint: disable=W0703
1744- except Exception as server_error:
1745- logger.debug("Error while verifying the server time skew: %r",
1746- server_error)
1747- self.next_check = local_time + self.ERROR_INTERVAL
1748-
1749- # delay import, otherwise a default reactor gets installed
1750- from twisted.web import http
1751- logger.debug("Using corrected timestamp: %r",
1752- http.datetimeToString(local_time + self.skew))
1753- return int(local_time + self.skew)
1754-
1755-
1756-# pylint: disable=C0103
1757-timestamp_checker = SyncTimestampChecker()
1758-# pylint: enable=C0103
1759-
1760-
1761-def oauth_headers(url, credentials, http_method='GET'):
1762- """Sign 'url' using 'credentials'.
1763-
1764- * 'url' must be a valid unicode url.
1765- * 'credentials' must be a valid OAuth token.
1766-
1767- Return oauth headers that can be pass to any Request like object.
1768-
1769- """
1770- assert isinstance(url, unicode)
1771- url = url.encode('utf-8')
1772- _, _, _, _, query, _ = urlparse(url)
1773- parameters = dict(cgi.parse_qsl(query))
1774- parameters["oauth_timestamp"] = timestamp_checker.get_faithful_time()
1775-
1776- consumer = oauth.OAuthConsumer(credentials['consumer_key'],
1777- credentials['consumer_secret'])
1778- token = oauth.OAuthToken(credentials['token'],
1779- credentials['token_secret'])
1780- kwargs = dict(oauth_consumer=consumer, token=token,
1781- http_method=http_method, http_url=url,
1782- parameters=parameters)
1783- get_request = oauth.OAuthRequest.from_consumer_and_token
1784- oauth_req = get_request(**kwargs)
1785- hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1()
1786- oauth_req.sign_request(hmac_sha1, consumer, token)
1787- headers = oauth_req.to_header()
1788-
1789- return headers
1790-
1791-
1792 @defer.inlineCallbacks
1793 def ping_url(url, email, credentials):
1794 """Ping the 'url' with the 'email' attached to it.
1795@@ -251,7 +149,7 @@
1796 """
1797 logger.info('Pinging server using url: %r, email: %r.',
1798 url, email)
1799- assert isinstance(url, unicode), 'Url %r must be unicode' % url
1800+ assert isinstance(url, compat.text_type), 'Url %r must be unicode' % url
1801
1802 target_url = url
1803 try:
1804@@ -262,7 +160,7 @@
1805 if target_url == url:
1806 logger.debug('Original url (%r) could not be formatted, '
1807 'appending email (%r).', url, email)
1808- assert url.endswith(u'/'), 'Url %r must end with /.' % url
1809+ assert url.endswith('/'), 'Url %r must end with /.' % url
1810 target_url = url + email
1811
1812 wc = webclient.webclient_factory()
1813
1814=== added file 'ubuntu_sso/utils/compat.py'
1815--- ubuntu_sso/utils/compat.py 1970-01-01 00:00:00 +0000
1816+++ ubuntu_sso/utils/compat.py 2012-08-21 18:02:19 +0000
1817@@ -0,0 +1,49 @@
1818+# -*- coding: utf-8 -*-
1819+#
1820+# Copyright 2012 Canonical Ltd.
1821+#
1822+# This program is free software: you can redistribute it and/or modify it
1823+# under the terms of the GNU General Public License version 3, as published
1824+# by the Free Software Foundation.
1825+#
1826+# This program is distributed in the hope that it will be useful, but
1827+# WITHOUT ANY WARRANTY; without even the implied warranties of
1828+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1829+# PURPOSE. See the GNU General Public License for more details.
1830+#
1831+# You should have received a copy of the GNU General Public License along
1832+# with this program. If not, see <http://www.gnu.org/licenses/>.
1833+#
1834+# In addition, as a special exception, the copyright holders give
1835+# permission to link the code of portions of this program with the
1836+# OpenSSL library under certain conditions as described in each
1837+# individual source file, and distribute linked combinations
1838+# including the two.
1839+# You must obey the GNU General Public License in all respects
1840+# for all of the code used other than OpenSSL. If you modify
1841+# file(s) with this exception, you may extend this exception to your
1842+# version of the file(s), but you are not obligated to do so. If you
1843+# do not wish to do so, delete this exception statement from your
1844+# version. If you delete this exception statement from all source
1845+# files in the program, then also delete it here.
1846+"""Python 2 and 3 compatibility."""
1847+
1848+from __future__ import unicode_literals
1849+
1850+# The following approach was outlined in Lennart Regebro's
1851+# "Porting to Python 3" book.
1852+# http://python3porting.com/noconv.html#more-bytes-strings-and-unicode
1853+
1854+import sys
1855+
1856+# Disable redefined builtin, invalid name warning
1857+# pylint: disable=W0622,C0103
1858+
1859+if sys.version_info < (3,):
1860+ text_type = unicode
1861+ binary_type = str
1862+ basestring = basestring
1863+else:
1864+ text_type = str
1865+ binary_type = bytes
1866+ basestring = str
1867
1868=== modified file 'ubuntu_sso/utils/ipc.py'
1869--- ubuntu_sso/utils/ipc.py 2012-06-22 16:51:06 +0000
1870+++ ubuntu_sso/utils/ipc.py 2012-08-21 18:02:19 +0000
1871@@ -172,10 +172,16 @@
1872 return super(RemoteMeta, mcs).__new__(mcs, name, bases, attrs)
1873
1874
1875-class RemoteService(Referenceable, SignalBroadcaster):
1876+def meta_base(meta):
1877+ """A function to return a metaclass which is called directly.
1878+ This is safe for both Python 2 and 3."""
1879+ return meta("MetaBase", (object,), {})
1880+
1881+
1882+class RemoteService(meta_base(RemoteMeta),
1883+ Referenceable, SignalBroadcaster):
1884 """A remote service that provides the methods listed in remote_calls."""
1885
1886- __metaclass__ = RemoteMeta
1887 remote_calls = []
1888
1889
1890
1891=== modified file 'ubuntu_sso/utils/runner/glib.py'
1892--- ubuntu_sso/utils/runner/glib.py 2012-06-22 16:12:03 +0000
1893+++ ubuntu_sso/utils/runner/glib.py 2012-08-21 18:02:19 +0000
1894@@ -35,6 +35,7 @@
1895 # pylint: enable=E0611,F0401
1896
1897 from ubuntu_sso.logger import setup_logging
1898+from ubuntu_sso.utils import compat
1899
1900 logger = setup_logging("ubuntu_sso.utils.runner.glib")
1901
1902@@ -81,10 +82,10 @@
1903
1904 bytes_args = []
1905 for arg in args:
1906- if isinstance(arg, unicode):
1907+ if isinstance(arg, compat.text_type):
1908 arg = arg.encode('utf-8')
1909- if not isinstance(arg, basestring):
1910- arg = str(arg)
1911+ if not isinstance(arg, compat.basestring):
1912+ arg = compat.binary_type(arg)
1913 bytes_args.append(arg)
1914
1915 try:
1916
1917=== modified file 'ubuntu_sso/utils/runner/tests/test_qt.py'
1918--- ubuntu_sso/utils/runner/tests/test_qt.py 2012-06-22 16:12:03 +0000
1919+++ ubuntu_sso/utils/runner/tests/test_qt.py 2012-08-21 18:02:19 +0000
1920@@ -33,7 +33,7 @@
1921 from PyQt4 import QtCore
1922 from twisted.internet import defer
1923
1924-from ubuntu_sso.utils import runner
1925+from ubuntu_sso.utils import compat, runner
1926 from ubuntu_sso.utils.runner import qt
1927 from ubuntu_sso.utils.runner.tests.test_runner import SpawnProgramTestCase
1928
1929@@ -80,7 +80,7 @@
1930 # subprocess expects bytes
1931 bytes_args = []
1932 for arg in args:
1933- if isinstance(arg, unicode):
1934+ if isinstance(arg, compat.text_type):
1935 arg = arg.encode('utf-8')
1936 bytes_args.append(arg)
1937
1938
1939=== modified file 'ubuntu_sso/utils/runner/tests/test_runner.py'
1940--- ubuntu_sso/utils/runner/tests/test_runner.py 2012-04-09 17:38:24 +0000
1941+++ ubuntu_sso/utils/runner/tests/test_runner.py 2012-08-21 18:02:19 +0000
1942@@ -28,6 +28,8 @@
1943 # files in the program, then also delete it here.
1944 """Tests for the runner helper module."""
1945
1946+from __future__ import unicode_literals
1947+
1948 import os
1949
1950 from twisted.internet import defer
1951@@ -36,15 +38,15 @@
1952 from ubuntu_sso.utils import runner
1953
1954
1955-TEST_ME_DIR = u'test-me-more-♥'
1956+TEST_ME_DIR = 'test-me-more-♥'
1957 TEST_ME_DIR_BYTES = TEST_ME_DIR.encode('utf-8')
1958
1959
1960 class SpawnProgramTestCase(TestCase):
1961 """The test suite for the spawn_program method."""
1962
1963- args = (u'python', u'-c',
1964- u'import os; os.system("mkdir %s")' % TEST_ME_DIR)
1965+ args = ('python', '-c',
1966+ 'import os; os.system("mkdir %s")' % TEST_ME_DIR)
1967 use_reactor = True
1968 timeout = 3
1969
1970
1971=== modified file 'ubuntu_sso/utils/runner/tx.py'
1972--- ubuntu_sso/utils/runner/tx.py 2012-06-22 16:12:03 +0000
1973+++ ubuntu_sso/utils/runner/tx.py 2012-08-21 18:02:19 +0000
1974@@ -34,6 +34,7 @@
1975 from twisted.internet import utils
1976
1977 from ubuntu_sso.logger import setup_logging
1978+from ubuntu_sso.utils import compat
1979
1980
1981 logger = setup_logging("ubuntu_sso.utils.runner.tx")
1982@@ -57,8 +58,9 @@
1983
1984 """
1985
1986- def child_watch((stdout, stderr, exit_code)):
1987+ def child_watch(args):
1988 """Handle child termination."""
1989+ stdout, stderr, exit_code = args
1990 if stdout:
1991 logger.debug('Returned stdout is (exit code was %r): %r',
1992 exit_code, stdout)
1993@@ -82,10 +84,10 @@
1994
1995 bytes_args = []
1996 for arg in argv:
1997- if isinstance(arg, unicode):
1998+ if isinstance(arg, compat.text_type):
1999 arg = arg.encode('utf-8')
2000- if not isinstance(arg, basestring):
2001- arg = str(arg)
2002+ if not isinstance(arg, compat.basestring):
2003+ arg = compat.binary_type(arg)
2004 bytes_args.append(arg)
2005
2006 if program and not os.access(program, os.X_OK):
2007
2008=== modified file 'ubuntu_sso/utils/tests/test_common.py'
2009--- ubuntu_sso/utils/tests/test_common.py 2012-07-12 15:54:13 +0000
2010+++ ubuntu_sso/utils/tests/test_common.py 2012-08-21 18:02:19 +0000
2011@@ -28,23 +28,18 @@
2012 # files in the program, then also delete it here.
2013 """Tests for the oauth_headers helper function."""
2014
2015+from __future__ import unicode_literals
2016+
2017 import logging
2018 import sys
2019-import time
2020
2021 from twisted.internet import defer
2022-from twisted.internet.threads import deferToThread
2023 from twisted.web import resource
2024 from ubuntuone.devtools.handlers import MementoHandler
2025 from ubuntuone.devtools.testing.txwebserver import HTTPWebServer
2026
2027 from ubuntu_sso import utils
2028 from ubuntu_sso.tests import TestCase, EMAIL, TOKEN
2029-from ubuntu_sso.utils import (
2030- oauth,
2031- oauth_headers,
2032- SyncTimestampChecker,
2033-)
2034
2035 CONSTANTS_MODULE = 'ubuntu_sso.constants'
2036 NOT_DEFINED = object()
2037@@ -188,97 +183,6 @@
2038 self.assertEqual(expected, result)
2039
2040
2041-class SignWithCredentialsTestCase(TestCase):
2042- """Test suite for the oauth_headers method."""
2043-
2044- url = u'http://example.com'
2045- fake_timestamp_value = 1
2046-
2047- @defer.inlineCallbacks
2048- def setUp(self):
2049- """Initialize this test suite."""
2050- yield super(SignWithCredentialsTestCase, self).setUp()
2051- self.timestamp_called = False
2052-
2053- def fake_timestamp():
2054- """A fake timestamp that records the call."""
2055- self.timestamp_called = True
2056- return self.fake_timestamp_value
2057-
2058- self.patch(utils.timestamp_checker, "get_faithful_time",
2059- fake_timestamp)
2060-
2061- def build_header(self, url, http_method='GET'):
2062- """Build an Oauth header for comparison."""
2063- consumer = oauth.OAuthConsumer(TOKEN['consumer_key'],
2064- TOKEN['consumer_secret'])
2065- token = oauth.OAuthToken(TOKEN['token'],
2066- TOKEN['token_secret'])
2067- get_request = oauth.OAuthRequest.from_consumer_and_token
2068- oauth_req = get_request(oauth_consumer=consumer, token=token,
2069- http_method=http_method, http_url=url)
2070- oauth_req.sign_request(oauth.OAuthSignatureMethod_HMAC_SHA1(),
2071- consumer, token)
2072- return oauth_req.to_header()
2073-
2074- def dictify_header(self, header):
2075- """Convert an OAuth header into a dict."""
2076- result = {}
2077- fields = header.split(', ')
2078- for field in fields:
2079- key, value = field.split('=')
2080- result[key] = value.strip('"')
2081-
2082- return result
2083-
2084- def assert_header_equal(self, expected, actual):
2085- """Is 'expected' equals to 'actual'?"""
2086- expected = self.dictify_header(expected['Authorization'])
2087- actual = self.dictify_header(actual['Authorization'])
2088- for header in (expected, actual):
2089- header.pop('oauth_nonce')
2090- header.pop('oauth_timestamp')
2091- header.pop('oauth_signature')
2092-
2093- self.assertEqual(expected, actual)
2094-
2095- def assert_method_called(self, path, query_str='', http_method='GET'):
2096- """Assert that the url build by joining 'paths' was called."""
2097- expected = (self.url, path, query_str)
2098- expected = ''.join(expected).encode('utf8')
2099- expected = self.build_header(expected, http_method=http_method)
2100- actual = oauth_headers(url=self.url + path, credentials=TOKEN)
2101- self.assert_header_equal(expected, actual)
2102-
2103- def test_call(self):
2104- """Calling 'get' triggers an OAuth signed GET request."""
2105- path = u'/test/'
2106- self.assert_method_called(path)
2107-
2108- def test_quotes_path(self):
2109- """Calling 'get' quotes the path."""
2110- path = u'/test me more, sí!/'
2111- self.assert_method_called(path)
2112-
2113- def test_adds_parameters_to_oauth_request(self):
2114- """The query string from the path is used in the oauth request."""
2115- self.patch(oauth, 'OAuthRequest', FakedOAuthRequest)
2116-
2117- path = u'/test/something?foo=bar'
2118- oauth_headers(url=self.url + path, credentials=TOKEN)
2119-
2120- self.assertIn('parameters', FakedOAuthRequest.params)
2121- params = FakedOAuthRequest.params['parameters']
2122- del(params["oauth_timestamp"])
2123- self.assertEqual(params, {'foo': 'bar'})
2124-
2125- def test_oauth_headers_uses_timestamp_checker(self):
2126- """The oauth_headers function uses the timestamp_checker."""
2127- oauth_headers(u"http://protocultura.net", TOKEN)
2128- self.assertTrue(self.timestamp_called,
2129- "the timestamp MUST be requested.")
2130-
2131-
2132 class RootResource(resource.Resource):
2133 """A root resource that logs the number of calls."""
2134
2135@@ -312,86 +216,13 @@
2136 """A mock, test, sample, and fake exception."""
2137
2138
2139-class TimestampCheckerTestCase(TestCase):
2140- """Tests for the timestamp checker."""
2141-
2142- @defer.inlineCallbacks
2143- def setUp(self):
2144- """Initialize a fake webserver."""
2145- yield super(TimestampCheckerTestCase, self).setUp()
2146- self.ws = MockWebServer()
2147- self.ws.start()
2148- self.addCleanup(self.ws.stop)
2149- self.patch(SyncTimestampChecker, "SERVER_URL", self.ws.get_iri())
2150-
2151- @defer.inlineCallbacks
2152- def test_returned_value_is_int(self):
2153- """The returned value is an integer."""
2154- checker = SyncTimestampChecker()
2155- timestamp = yield deferToThread(checker.get_faithful_time)
2156- self.assertEqual(type(timestamp), int)
2157-
2158- @defer.inlineCallbacks
2159- def test_first_call_does_head(self):
2160- """The first call gets the clock from our web."""
2161- checker = SyncTimestampChecker()
2162- yield deferToThread(checker.get_faithful_time)
2163- self.assertEqual(self.ws.root.count, 1)
2164-
2165- @defer.inlineCallbacks
2166- def test_second_call_is_cached(self):
2167- """For the second call, the time is cached."""
2168- checker = SyncTimestampChecker()
2169- yield deferToThread(checker.get_faithful_time)
2170- yield deferToThread(checker.get_faithful_time)
2171- self.assertEqual(self.ws.root.count, 1)
2172-
2173- @defer.inlineCallbacks
2174- def test_after_timeout_cache_expires(self):
2175- """After some time, the cache expires."""
2176- fake_timestamp = 1
2177- self.patch(time, "time", lambda: fake_timestamp)
2178- checker = SyncTimestampChecker()
2179- yield deferToThread(checker.get_faithful_time)
2180- fake_timestamp += SyncTimestampChecker.CHECKING_INTERVAL
2181- yield deferToThread(checker.get_faithful_time)
2182- self.assertEqual(self.ws.root.count, 2)
2183-
2184- @defer.inlineCallbacks
2185- def test_server_date_sends_nocache_headers(self):
2186- """Getting the server date sends the no-cache headers."""
2187- checker = SyncTimestampChecker()
2188- yield deferToThread(checker.get_server_time)
2189- assert len(self.ws.root.request_headers) == 1
2190- headers = self.ws.root.request_headers[0]
2191- result = headers.getRawHeaders("Cache-Control")
2192- self.assertEqual(result, ["no-cache"])
2193-
2194- @defer.inlineCallbacks
2195- def test_server_error_means_skew_not_updated(self):
2196- """When server can't be reached, the skew is not updated."""
2197- fake_timestamp = 1
2198- self.patch(time, "time", lambda: fake_timestamp)
2199- checker = SyncTimestampChecker()
2200-
2201- def failing_get_server_time():
2202- """Let's fail while retrieving the server time."""
2203- raise FakedError()
2204-
2205- self.patch(checker, "get_server_time", failing_get_server_time)
2206- yield deferToThread(checker.get_faithful_time)
2207- self.assertEqual(checker.skew, 0)
2208- self.assertEqual(checker.next_check,
2209- fake_timestamp + SyncTimestampChecker.ERROR_INTERVAL)
2210-
2211-
2212 class PingUrlTestCase(TestCase):
2213 """Test suite for the URL pinging."""
2214
2215 @defer.inlineCallbacks
2216 def setUp(self):
2217 yield super(PingUrlTestCase, self).setUp()
2218- self.url = u'http://example.com/'
2219+ self.url = 'http://example.com/'
2220 self.wc = FakeWebclient()
2221 self.patch(utils.webclient, "webclient_factory",
2222 lambda *args: self.wc)
2223@@ -422,7 +253,7 @@
2224 @defer.inlineCallbacks
2225 def test_ping_url_formatting(self):
2226 """The email is added as the first formatting argument."""
2227- self.url = u'http://example.com/{email}/something/else'
2228+ self.url = 'http://example.com/{email}/something/else'
2229 yield utils.ping_url(url=self.url, email=EMAIL, credentials=TOKEN)
2230
2231 expected = self.url.format(email=EMAIL)
2232@@ -433,7 +264,7 @@
2233 @defer.inlineCallbacks
2234 def test_ping_url_formatting_with_query_params(self):
2235 """The email is added as the first formatting argument."""
2236- self.url = u'http://example.com/{email}?something=else'
2237+ self.url = 'http://example.com/{email}?something=else'
2238 yield utils.ping_url(url=self.url, email=EMAIL, credentials=TOKEN)
2239
2240 expected = self.url.format(email=EMAIL)
2241@@ -444,7 +275,7 @@
2242 @defer.inlineCallbacks
2243 def test_ping_url_formatting_no_email_kwarg(self):
2244 """The email is added as the first formatting argument."""
2245- self.url = u'http://example.com/{0}/yadda/?something=else'
2246+ self.url = 'http://example.com/{0}/yadda/?something=else'
2247 yield utils.ping_url(url=self.url, email=EMAIL, credentials=TOKEN)
2248
2249 expected = self.url.format(EMAIL)
2250@@ -455,7 +286,7 @@
2251 @defer.inlineCallbacks
2252 def test_ping_url_formatting_no_format(self):
2253 """The email is appended if formatting could not be accomplished."""
2254- self.url = u'http://example.com/yadda/'
2255+ self.url = 'http://example.com/yadda/'
2256 yield utils.ping_url(url=self.url, email=EMAIL, credentials=TOKEN)
2257
2258 expected = self.url + EMAIL
2259
2260=== modified file 'ubuntu_sso/utils/tests/test_ipc.py'
2261--- ubuntu_sso/utils/tests/test_ipc.py 2012-04-30 16:15:46 +0000
2262+++ ubuntu_sso/utils/tests/test_ipc.py 2012-08-21 18:02:19 +0000
2263@@ -505,16 +505,16 @@
2264 """The remote_calls are renamed."""
2265 test_token = object()
2266
2267- class TestClass(object):
2268+ # pylint: disable=W0232
2269+ class TestClass(ipc.meta_base(ipc.RemoteMeta)):
2270 """A class for testing."""
2271
2272- __metaclass__ = ipc.RemoteMeta
2273-
2274 remote_calls = ['test_method']
2275
2276 def test_method(self):
2277 """Fake call."""
2278 return test_token
2279+ # pylint: enable=W0232
2280
2281 tc = TestClass()
2282 self.assertEquals(tc.test_method(), test_token)
2283
2284=== modified file 'ubuntu_sso/utils/ui.py'
2285--- ubuntu_sso/utils/ui.py 2012-04-09 17:38:24 +0000
2286+++ ubuntu_sso/utils/ui.py 2012-08-21 18:02:19 +0000
2287@@ -31,11 +31,15 @@
2288 import argparse
2289 import re
2290 import gettext
2291+import sys
2292
2293 from ubuntu_sso.logger import setup_logging
2294
2295+INSTALL_KWARGS = {}
2296+if sys.version_info < (3,):
2297+ INSTALL_KWARGS["unicode"] = True
2298
2299-gettext.install('ubuntu-sso-client', unicode=True)
2300+gettext.install('ubuntu-sso-client', **INSTALL_KWARGS)
2301 logger = setup_logging('ubuntu_sso.utils.ui')
2302
2303

Subscribers

People subscribed via source and target branches

to all changes: