Merge lp:~nataliabidart/ubuntu-sso-client/fix-933632 into lp:ubuntu-sso-client

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 884
Merged at revision: 880
Proposed branch: lp:~nataliabidart/ubuntu-sso-client/fix-933632
Merge into: lp:ubuntu-sso-client
Diff against target: 1225 lines (+294/-189)
21 files modified
setup.py (+0/-39)
ubuntu_sso/credentials.py (+3/-1)
ubuntu_sso/gtk/gui.py (+14/-16)
ubuntu_sso/gtk/tests/test_gui.py (+57/-53)
ubuntu_sso/keyring/tests/test_linux.py (+2/-3)
ubuntu_sso/main/__init__.py (+1/-1)
ubuntu_sso/main/tests/test_common.py (+15/-22)
ubuntu_sso/qt/__init__.py (+0/-10)
ubuntu_sso/qt/current_user_sign_in_page.py (+2/-4)
ubuntu_sso/qt/gui.py (+0/-2)
ubuntu_sso/qt/network_detection_page.py (+8/-8)
ubuntu_sso/qt/setup_account_page.py (+2/-3)
ubuntu_sso/qt/sign_in_page.py (+2/-4)
ubuntu_sso/qt/tests/test_setup_account.py (+2/-1)
ubuntu_sso/tests/__init__.py (+8/-8)
ubuntu_sso/utils/runner/glib.py (+11/-2)
ubuntu_sso/utils/runner/tests/test_glib.py (+132/-0)
ubuntu_sso/utils/runner/tests/test_qt.py (+9/-1)
ubuntu_sso/utils/runner/tests/test_runner.py (+9/-7)
ubuntu_sso/utils/runner/tx.py (+9/-1)
ubuntu_sso/utils/ui.py (+8/-3)
To merge this branch: bzr merge lp:~nataliabidart/ubuntu-sso-client/fix-933632
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Eric Casteleijn (community) Approve
Review via email: mp+93641@code.launchpad.net

Commit message

- Make gettext return unicode strings. Also, transform arguments passed to
  the GLib spawnner to bytes (LP: #933632).

To post a comment you must log in.
Revision history for this message
Eric Casteleijn (thisfred) wrote :

Looks good, great that the tests use unicode characters, nice incremental refactorings.

review: Approve
Revision history for this message
Roberto Alsina (ralsina) wrote :

Looks good to me!

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (72.3 KiB)

The attempt to merge lp:~nataliabidart/ubuntu-sso-client/fix-933632 into lp:ubuntu-sso-client failed. Below is the output from the failed tests.

*** Running GTK test suite for ubuntu_sso ***
twisted.trial.unittest
  TestCase
    runTest ... [OK]
ubuntu_sso.keyring.tests.test_common
  TestGetHostname
    test_get_hostname ... [OK]
    test_get_hostname_uses_filesystem_encoding ... [OK]
  TestTokenNameBuilder
    test_get_complex_token_name_for_app_name ... [OK]
    test_get_complex_token_name_for_hostname ... [OK]
    test_get_simple_token_name ... [OK]
    test_get_unicode_appname_token_name ... [OK]
    test_get_utf8_hostname_token_name ... [OK]
twisted.trial.unittest
  TestCase
    runTest ... [OK]
ubuntu_sso.keyring.tests.test_linux
  TestKeyring
    test_delete_credentials ... [OK]
    test_get_credentials ... [OK]
    test_get_credentials_migrating_token ... [OK]
    test_get_old_cred_found ... [OK]
    test_get_old_cred_found_but_not_asked_for ... [OK]
    test_get_old_cred_not_found ... [OK]
    test_set_credentials ... [OK]
ubuntu_sso.networkstate.tests.test_linux
  NetworkManagerStateErrorsTestCase
    test_dbus_problem ... [OK]
    test_nm_not_running ... [OK]
  NetworkManagerStateTestCase
    test_nm_connecting_then_offline ... [OK]
    test_nm_connecting_then_offline_old ... [OK]
    test_nm_connecting_then_online ... [OK]
    test_nm_connecting_then_online_old ... [OK]
    test_nm_offline ... [OK]
    test_nm_offline_local ... [OK]
    test_nm_offline_old ... [OK]
    test_nm_offline_site ... [OK]
    test_nm_online_global ... [OK]
    test_nm_online_old ... [OK]
ubuntu_sso.tests
  TestCase
    runTest ... [OK]
ubuntu_sso.networkstate.tests.test_linux
  TestConnection
    test_is_machine_connected_nm_state_connected_global ... [OK]
    test_is_machine_connected_nm_state_connected_old ... [OK]
    test_is_machine_defer_error ... [OK]
    test_is_machine_disconnected_nm_state_asleep ... ...

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (132.7 KiB)

The attempt to merge lp:~nataliabidart/ubuntu-sso-client/fix-933632 into lp:ubuntu-sso-client failed. Below is the output from the failed tests.

*** Running GTK test suite for ubuntu_sso ***
twisted.trial.unittest
  TestCase
    runTest ... [OK]
ubuntu_sso.keyring.tests.test_common
  TestGetHostname
    test_get_hostname ... [OK]
    test_get_hostname_uses_filesystem_encoding ... [OK]
  TestTokenNameBuilder
    test_get_complex_token_name_for_app_name ... [OK]
    test_get_complex_token_name_for_hostname ... [OK]
    test_get_simple_token_name ... [OK]
    test_get_unicode_appname_token_name ... [OK]
    test_get_utf8_hostname_token_name ... [OK]
twisted.trial.unittest
  TestCase
    runTest ... [OK]
ubuntu_sso.keyring.tests.test_linux
  TestKeyring
    test_delete_credentials ... [OK]
    test_get_credentials ... [OK]
    test_get_credentials_migrating_token ... [OK]
    test_get_old_cred_found ... [OK]
    test_get_old_cred_found_but_not_asked_for ... [OK]
    test_get_old_cred_not_found ... [OK]
    test_set_credentials ... [OK]
ubuntu_sso.networkstate.tests.test_linux
  NetworkManagerStateErrorsTestCase
    test_dbus_problem ... [OK]
    test_nm_not_running ... [OK]
  NetworkManagerStateTestCase
    test_nm_connecting_then_offline ... [OK]
    test_nm_connecting_then_offline_old ... [OK]
    test_nm_connecting_then_online ... [OK]
    test_nm_connecting_then_online_old ... [OK]
    test_nm_offline ... [OK]
    test_nm_offline_local ... [OK]
    test_nm_offline_old ... [OK]
    test_nm_offline_site ... [OK]
    test_nm_online_global ... [OK]
    test_nm_online_old ... [OK]
ubuntu_sso.tests
  TestCase
    runTest ... [OK]
ubuntu_sso.networkstate.tests.test_linux
  TestConnection
    test_is_machine_connected_nm_state_connected_global ... [OK]
    test_is_machine_connected_nm_state_connected_old ... [OK]
    test_is_machine_defer_error ... [OK]
    test_is_machine_disconnected_nm_state_asleep ... ...

884. By Natalia Bidart

Adapting mock so it works with LANG=C.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'setup.py'
2--- setup.py 2012-02-14 20:49:45 +0000
3+++ setup.py 2012-02-18 14:14:18 +0000
4@@ -153,11 +153,6 @@
5
6 def run(self):
7 """Execute the command."""
8- # pylint: disable=W0703
9- try:
10- self._wrapuic()
11- except Exception, e:
12- self.warn("Error wrapping uic to use gettext: %s" % e)
13 basepath = os.path.join('data', 'qt')
14 # TODO: build the resource files so that we can include them
15 #self.build_rc(os.path.join(basepath, 'icons_rc.py'),
16@@ -172,40 +167,6 @@
17
18 build_extra.build_extra.run(self)
19
20- # pylint: disable=E1002
21- _wrappeduic = False
22-
23- @classmethod
24- def _wrapuic(cls):
25- """Wrap uic to use gettext's _() in place of tr()"""
26- if cls._wrappeduic:
27- return
28-
29- from PyQt4.uic.Compiler import compiler, qtproxies, indenter
30-
31- # pylint: disable=C0103
32- class _UICompiler(compiler.UICompiler):
33- """Speciallized compiler for qt .ui files."""
34- def createToplevelWidget(self, classname, widgetname):
35- o = indenter.getIndenter()
36- o.level = 0
37- o.write('from gettext import gettext as _')
38- return super(_UICompiler, self).createToplevelWidget(classname,
39- widgetname)
40- compiler.UICompiler = _UICompiler
41-
42- class _i18n_string(qtproxies.i18n_string):
43- """Provide a translated text."""
44-
45- def __str__(self):
46- return "_('%s')" % self.string.encode('string-escape')
47-
48- qtproxies.i18n_string = _i18n_string
49-
50- cls._wrappeduic = True
51- # pylint: enable=C0103
52- # pylint: enable=E1002
53-
54
55 class SSOClean(DistUtilsExtra.auto.clean_build_tree):
56 """Class to clean up after the build."""
57
58=== modified file 'ubuntu_sso/credentials.py'
59--- ubuntu_sso/credentials.py 2012-02-11 19:25:01 +0000
60+++ ubuntu_sso/credentials.py 2012-02-18 14:14:18 +0000
61@@ -148,7 +148,9 @@
62 value = getattr(self, arg)
63 if value:
64 args.append('--%s' % arg)
65- args.append("%s" % str(value))
66+ if not isinstance(value, basestring):
67+ value = str(value)
68+ args.append(value)
69
70 if login_only:
71 args.append('--login_only')
72
73=== modified file 'ubuntu_sso/gtk/gui.py'
74--- ubuntu_sso/gtk/gui.py 2012-02-11 19:25:01 +0000
75+++ ubuntu_sso/gtk/gui.py 2012-02-18 14:14:18 +0000
76@@ -111,6 +111,7 @@
77 # To be replaced by values from the theme (LP: #616526)
78 HELP_TEXT_COLOR = parse_color("#bfbfbf")
79 WARNING_TEXT_COLOR = parse_color("red")
80+LARGE_MARKUP = u'<span size="x-large">%s</span>'
81
82
83 def log_call(f):
84@@ -173,9 +174,9 @@
85
86 def get_text(self):
87 """Get text only if it's not the label nor empty."""
88- result = super(LabeledEntry, self).get_text()
89+ result = super(LabeledEntry, self).get_text().decode('utf8')
90 if result == self.label or result.isspace():
91- result = ''
92+ result = u''
93 return result
94
95 def set_warning(self, warning_msg):
96@@ -209,10 +210,10 @@
97 self._done = False # whether the whole process was completed or not
98
99 self.app_name = app_name
100- self.app_label = '<b>%s</b>' % self.app_name
101- self.ping_url = kwargs.get('ping_url', '')
102- self.tc_url = kwargs.get('tc_url', '')
103- self.help_text = kwargs.get('help_text', '')
104+ self.app_label = u'<b>%s</b>' % self.app_name
105+ self.ping_url = kwargs.get('ping_url', u'')
106+ self.tc_url = kwargs.get('tc_url', u'')
107+ self.help_text = kwargs.get('help_text', u'')
108 self.login_only = kwargs.get('login_only', False)
109 window_id = kwargs.get('window_id', 0)
110 self.close_callback = kwargs.get('close_callback', NO_OP)
111@@ -338,15 +339,14 @@
112 def success_vbox(self):
113 """The success page."""
114 message = SUCCESS % {'app_name': self.app_name}
115- message = '<span size="x-large">%s</span>' % message
116+ message = LARGE_MARKUP % message
117 self.finish_vbox.label.set_markup(message)
118 return self.finish_vbox
119
120 @property
121 def error_vbox(self):
122 """The error page."""
123- self.finish_vbox.label.set_markup('<span size="x-large">%s</span>' %
124- ERROR)
125+ self.finish_vbox.label.set_markup(LARGE_MARKUP % ERROR)
126 return self.finish_vbox
127
128 # helpers
129@@ -362,7 +362,7 @@
130 result = f(app_name, *args, **kwargs)
131 else:
132 logger.info('%s: ignoring call since received app_name '\
133- '"%s" (expected "%s")',
134+ '%r (expected %r)',
135 f.__name__, app_name, self.app_name)
136 return result
137
138@@ -459,8 +459,7 @@
139
140 def _set_header(self, header):
141 """Set 'header' as the window title and header."""
142- markup = '<span size="x-large">%s</span>'
143- self.header_label.set_markup(markup % header)
144+ self.header_label.set_markup(LARGE_MARKUP % header)
145 self.window.set_title(self.header_label.get_text()) # avoid markup
146
147 def _set_current_page(self, current_page, warning_text=None):
148@@ -792,9 +791,8 @@
149 f = self.backend.register_user
150 error_handler = partial(self._handle_error, f,
151 self.on_user_registration_error)
152- f(unicode(self.app_name), email1.decode('utf8'),
153- password1.decode('utf8'), name.decode('utf8'),
154- unicode(self._captcha_id), captcha_solution.decode('utf8'),
155+ f(self.app_name, self.user_email, self.user_password, name,
156+ self._captcha_id, captcha_solution,
157 reply_handler=NO_OP, error_handler=error_handler)
158
159 def on_verify_token_button_clicked(self, *args, **kwargs):
160@@ -1035,7 +1033,7 @@
161 """Captcha image has been generated and is available to be shown."""
162 if captcha_id is None:
163 logger.warning('on_captcha_generated: captcha_id is None for '
164- 'app_name "%s".', app_name)
165+ 'app_name %r.', app_name)
166 self._captcha_id = captcha_id
167 self._set_captcha_image()
168
169
170=== modified file 'ubuntu_sso/gtk/tests/test_gui.py'
171--- ubuntu_sso/gtk/tests/test_gui.py 2012-02-11 01:51:57 +0000
172+++ ubuntu_sso/gtk/tests/test_gui.py 2012-02-18 14:14:18 +0000
173@@ -165,7 +165,7 @@
174 tmp = Gdk.RGBA()
175 assert tmp.parse(gdk_color.to_string())
176
177- msg = 'Text color must be "%s" (got "%s" instead).'
178+ msg = 'Text color must be %r (got %r instead).'
179 self.assertEqual(rgba_color, tmp, msg % (rgba_color, tmp))
180
181 def assert_backend_called(self, method, *args, **kwargs):
182@@ -211,7 +211,7 @@
183 def assert_correct_label(self):
184 """Check that the entry has the correct label."""
185 # text content is correct
186- msg = 'Text content must be "%s" (got "%s" instead).'
187+ msg = 'Text content must be %r (got %r instead).'
188 expected = self.label
189 actual = super(gui.LabeledEntry, self.entry).get_text()
190 self.assertEqual(expected, actual, msg % (expected, actual))
191@@ -231,7 +231,7 @@
192
193 def test_tooltip(self):
194 """Entry have the correct tooltip."""
195- msg = 'Tooltip must be "%s" (got "%s" instead).'
196+ msg = 'Tooltip must be %r (got %r instead).'
197 expected = self.label
198 actual = self.entry.get_tooltip_text()
199 # tooltip is correct
200@@ -404,7 +404,7 @@
201
202 def assert_entries_are_packed_to_ui(self, container_name, entries):
203 """Every entry is properly packed in the ui 'container_name'."""
204- msg = 'Entry "%s" must be packed in "%s" but is not.'
205+ msg = 'Entry %r must be packed in %r but is not.'
206 container = getattr(self.ui, container_name)
207 for kind in entries:
208 name = '%s_entry' % kind
209@@ -414,7 +414,7 @@
210
211 def assert_warnings_visibility(self, visible=False):
212 """Every warning label should be 'visible'."""
213- msg = '"%s" should have %sempty content.'
214+ msg = '%r should have %sempty content.'
215 for name in self.ui.widgets:
216 widget = getattr(self.ui, name)
217 if 'warning' in name:
218@@ -429,7 +429,7 @@
219 self.assertTrue(label.get_property('visible'))
220
221 # warning content is correct
222- actual = label.get_text()
223+ actual = label.get_text().decode('utf-8')
224 self.assertEqual(actual, message)
225
226 # content color is correct
227@@ -547,7 +547,7 @@
228
229 def test_initial_text_for_entries(self):
230 """Entries have the correct text at startup."""
231- msg = 'Text for "%s" must be "%s" (got "%s" instead).'
232+ msg = 'Text for %r must be %r (got %r instead).'
233 for name in self.ui.entries:
234 entry = getattr(self.ui, name)
235 expected = getattr(gui.utils.ui, name.upper())
236@@ -557,14 +557,14 @@
237
238 def test_entries_activates_default(self):
239 """Entries have the activates default prop set."""
240- msg = '"%s" must have activates_default set to True.'
241+ msg = '%r must have activates_default set to True.'
242 for name in self.ui.entries:
243 entry = getattr(self.ui, name)
244 self.assertTrue(entry.get_activates_default(), msg % (name,))
245
246 def test_password_fields_are_password(self):
247 """Password fields have the is_password flag set."""
248- msg = '"%s" should be a password LabeledEntry instance.'
249+ msg = '%r should be a password LabeledEntry instance.'
250 passwords = filter(lambda name: 'password' in name,
251 self.ui.entries)
252 for name in passwords:
253@@ -578,7 +578,7 @@
254 def test_cancel_buttons_close_window(self):
255 """Every cancel button should close the window when clicked."""
256 self.patch(self.ui.backend, 'disconnect_from_signal', lambda *a: None)
257- msg = '"%s" should close the window when clicked.'
258+ msg = '%r should close the window when clicked.'
259 buttons = filter(lambda name: 'cancel_button' in name or
260 'close_button' in name, self.ui.widgets)
261 for name in buttons:
262@@ -597,15 +597,16 @@
263 self.ui.finish_success()
264 self.assert_pages_visibility(finish=True)
265 self.assertEqual(gui.SUCCESS % {'app_name': APP_NAME},
266- self.ui.finish_vbox.label.get_text())
267- result = self.ui.finish_vbox.label.get_text()
268+ self.ui.finish_vbox.label.get_text().decode('utf8'))
269+ result = self.ui.finish_vbox.label.get_text().decode('utf8')
270 self.assertTrue(self.ui.app_name in result)
271
272 def test_finish_error_shows_error_page(self):
273 """When calling 'finish_error' the error page is shown."""
274 self.ui.finish_error()
275 self.assert_pages_visibility(finish=True)
276- self.assertEqual(gui.ERROR, self.ui.finish_vbox.label.get_text())
277+ self.assertEqual(gui.ERROR,
278+ self.ui.finish_vbox.label.get_text().decode('utf8'))
279
280
281 class SetTransientForTestCase(UbuntuSSOClientTestCase):
282@@ -649,9 +650,9 @@
283
284 def test_initial_text_for_header_label(self):
285 """The header must have the correct text at startup."""
286- msg = 'Text for the header must be "%s" (got "%s" instead).'
287+ msg = 'Text for the header must be %r (got %r instead).'
288 expected = gui.JOIN_HEADER_LABEL % {'app_name': APP_NAME}
289- actual = self.ui.header_label.get_text()
290+ actual = self.ui.header_label.get_text().decode('utf8')
291 # text content is correct
292 self.assertEqual(expected, actual, msg % (expected, actual))
293
294@@ -670,26 +671,26 @@
295
296 def test_initial_texts_for_checkbuttons(self):
297 """Check buttons have the correct text at startup."""
298- msg = 'Text for "%s" must be "%s" (got "%s" instead).'
299+ msg = 'Text for %r must be %r (got %r instead).'
300 expected = gui.YES_TO_UPDATES % {'app_name': APP_NAME}
301- actual = self.ui.yes_to_updates_checkbutton.get_label()
302+ actual = self.ui.yes_to_updates_checkbutton.get_label().decode('utf8')
303 self.assertEqual(expected, actual, msg % ('yes_to_updates_checkbutton',
304 expected, actual))
305 expected = gui.YES_TO_TC % {'app_name': APP_NAME}
306- actual = self.ui.yes_to_tc_checkbutton.get_label()
307+ actual = self.ui.yes_to_tc_checkbutton.get_label().decode('utf8')
308 self.assertEqual(expected, actual,
309 msg % ('yes_to_tc_checkbutton', expected, actual))
310
311 def test_checkbutton_is_checked_at_startup(self):
312 """Checkbuttons are checked by default."""
313- msg = '"%s" is checked by default.'
314+ msg = '%r is checked by default.'
315 name = 'yes_to_updates_checkbutton'
316 widget = getattr(self.ui, name)
317 self.assertTrue(widget.get_active(), msg % name)
318
319 def test_checkbutton_isnt_checked_at_startup(self):
320 """Checkbuttons are checked by default."""
321- msg = '"%s" is checked by default.'
322+ msg = '%r is checked by default.'
323 name = 'yes_to_tc_checkbutton'
324 widget = getattr(self.ui, name)
325 self.assertFalse(widget.get_active(), msg % name)
326@@ -732,7 +733,8 @@
327 'the processing spinner should be active.')
328 self.assertTrue(label.get_property('visible'),
329 'the processing label should be visible.')
330- self.assertEqual(label.get_text(), gui.ONE_MOMENT_PLEASE,
331+ self.assertEqual(label.get_text().decode('utf8'),
332+ gui.ONE_MOMENT_PLEASE,
333 'the processing label text must be correct.')
334
335 def test_captcha_image_is_not_visible_at_startup(self):
336@@ -775,7 +777,7 @@
337 'the captcha_loading spinner should be active.')
338 self.assertTrue(label.get_property('visible'),
339 'the captcha_loading label should be visible.')
340- self.assertEqual(label.get_text(), gui.LOADING,
341+ self.assertEqual(label.get_text().decode('utf8'), gui.LOADING,
342 'the captcha_loading label text must be correct.')
343
344 def test_join_ok_button_is_disabled_until_captcha_is_available(self):
345@@ -814,7 +816,7 @@
346 def test_on_captcha_generated_logs_captcha_id_when_none(self):
347 """If the captcha id is None, a warning is logged."""
348 self.ui.on_captcha_generated(app_name=APP_NAME, captcha_id=None)
349- self.assertTrue(self.memento.check(logging.WARNING, APP_NAME))
350+ self.assertTrue(self.memento.check(logging.WARNING, repr(APP_NAME)))
351 self.assertTrue(self.memento.check(logging.WARNING,
352 'captcha_id is None'))
353
354@@ -837,7 +839,7 @@
355
356 def test_login_button_has_correct_wording(self):
357 """The sign in button has the proper wording."""
358- actual = self.ui.login_button.get_label()
359+ actual = self.ui.login_button.get_label().decode('utf8')
360 self.assertEqual(gui.LOGIN_BUTTON_LABEL, actual)
361
362 def test_join_ok_button_does_nothing_if_clicked_but_disabled(self):
363@@ -870,7 +872,7 @@
364 """When captcha was retrieved after error, the warning is removed."""
365 self.ui.on_captcha_generation_error(APP_NAME, error=self.error)
366 self.ui.on_captcha_generated(app_name=APP_NAME, captcha_id=CAPTCHA_ID)
367- self.assertEqual(self.ui.warning_label.get_text(), '')
368+ self.assertEqual(self.ui.warning_label.get_text().decode('utf8'), '')
369
370
371 class NoTermsAndConditionsTestCase(UbuntuSSOClientTestCase):
372@@ -953,12 +955,13 @@
373
374 def test_tc_button_has_the_proper_wording(self):
375 """Terms & Conditions has the proper wording."""
376- self.assertEqual(self.ui.tc_button.get_label(), gui.TC_BUTTON)
377+ self.assertEqual(self.ui.tc_button.get_label().decode('utf8'),
378+ gui.TC_BUTTON)
379
380 def test_tc_has_no_help_text(self):
381 """The help text is removed."""
382 self.ui.on_tc_browser_notify_load_status(self.browser)
383- self.assertEqual('', self.ui.help_label.get_text())
384+ self.assertEqual('', self.ui.help_label.get_text().decode('utf8'))
385
386 def test_tc_browser_opens_the_proper_url(self):
387 """Terms & Conditions browser shows the proper uri."""
388@@ -1115,8 +1118,8 @@
389
390 def test_help_label_display_correct_wording(self):
391 """The help_label display VERIFY_EMAIL_LABEL."""
392- msg = 'help_label must read "%s" (got "%s" instead).'
393- actual = self.ui.help_label.get_label()
394+ msg = 'help_label must read %r (got %r instead).'
395+ actual = self.ui.help_label.get_label().decode('utf8')
396 expected = gui.VERIFY_EMAIL_LABEL % {'app_name': APP_NAME,
397 'email': EMAIL}
398 self.assertEqual(expected, actual, msg % (expected, actual))
399@@ -1160,7 +1163,7 @@
400 """On email validated the help text is not removed."""
401 self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL)
402 self.assertEqual(self.ui.verify_email_vbox.help_text,
403- self.ui.help_label.get_label())
404+ self.ui.help_label.get_label().decode('utf8'))
405
406 def test_on_email_validation_error_verify_email_is_shown(self):
407 """On email validation error, the verify_email page is shown."""
408@@ -1186,16 +1189,16 @@
409 def test_success_label_is_correct(self):
410 """The success message is correct."""
411 self.assertEqual(gui.SUCCESS % {'app_name': APP_NAME},
412- self.ui.success_vbox.label.get_text())
413- markup = self.ui.success_vbox.label.get_label()
414+ self.ui.success_vbox.label.get_text().decode('utf8'))
415+ markup = self.ui.success_vbox.label.get_label().decode('utf8')
416 self.assertTrue('<span size="x-large">' in markup)
417 self.assertTrue(self.ui.app_name in markup)
418
419 def test_error_label_is_correct(self):
420 """The error message is correct."""
421 self.assertEqual(gui.ERROR,
422- self.ui.error_vbox.label.get_text())
423- markup = self.ui.error_vbox.label.get_label()
424+ self.ui.error_vbox.label.get_text().decode('utf8'))
425+ markup = self.ui.error_vbox.label.get_label().decode('utf8')
426 self.assertTrue('<span size="x-large">' in markup)
427
428 def test_on_finish_close_button_clicked_closes_window(self):
429@@ -1346,7 +1349,7 @@
430 """Password help text is correctly displayed."""
431 self.assertTrue(self.ui.password_help_label.get_property('visible'),
432 'password help text is visible.')
433- self.assertEqual(self.ui.password_help_label.get_text(),
434+ self.assertEqual(self.ui.password_help_label.get_text().decode('utf8'),
435 gui.PASSWORD_HELP)
436 self.assertNotIn('register_user', self.ui.backend._called)
437
438@@ -1436,16 +1439,16 @@
439
440 def test_initial_text_for_header_label(self):
441 """The header must have the correct text when logging in."""
442- msg = 'Text for the header must be "%s" (got "%s" instead).'
443+ msg = 'Text for the header must be %r (got %r instead).'
444 expected = gui.LOGIN_HEADER_LABEL % {'app_name': APP_NAME}
445- actual = self.ui.header_label.get_text()
446+ actual = self.ui.header_label.get_text().decode('utf8')
447 self.assertEqual(expected, actual, msg % (expected, actual))
448
449 def test_initial_text_for_help_label(self):
450 """The help must have the correct text at startup."""
451- msg = 'Text for the help must be "%s" (got "%s" instead).'
452+ msg = 'Text for the help must be %r (got %r instead).'
453 expected = gui.CONNECT_HELP_LABEL % {'app_name': APP_NAME}
454- actual = self.ui.help_label.get_text()
455+ actual = self.ui.help_label.get_text().decode('utf8')
456 self.assertEqual(expected, actual, msg % (expected, actual))
457
458 def test_entries_are_packed_to_ui_for_login(self):
459@@ -1628,23 +1631,23 @@
460
461 def test_forgotten_password_button_has_the_proper_wording(self):
462 """The forgotten_password_button has the proper wording."""
463- self.assertEqual(self.ui.forgotten_password_button.get_label(),
464- gui.FORGOTTEN_PASSWORD_BUTTON)
465+ actual = self.ui.forgotten_password_button.get_label()
466+ self.assertEqual(actual.decode('utf8'), gui.FORGOTTEN_PASSWORD_BUTTON)
467
468 def test_on_forgotten_password_button_clicked_help_text(self):
469 """Clicking forgotten_password_button the help is properly changed."""
470 wanted = gui.REQUEST_PASSWORD_TOKEN_LABEL % {'app_name': APP_NAME}
471- self.assertEqual(self.ui.help_label.get_text(), wanted)
472+ self.assertEqual(self.ui.help_label.get_text().decode('utf8'), wanted)
473
474 def test_on_forgotten_password_button_clicked_header_label(self):
475 """Clicking forgotten_password_button the title is properly changed."""
476- self.assertEqual(self.ui.header_label.get_text(),
477+ self.assertEqual(self.ui.header_label.get_text().decode('utf8'),
478 gui.RESET_PASSWORD)
479
480 def test_on_forgotten_password_button_clicked_ok_button(self):
481 """Clicking forgotten_password_button the ok button reads 'Next'."""
482- self.assertEqual(self.ui.request_password_token_ok_button.get_label(),
483- gui.NEXT)
484+ actual = self.ui.request_password_token_ok_button.get_label()
485+ self.assertEqual(actual.decode('utf8'), gui.NEXT)
486
487 def test_on_forgotten_password_button_clicked_morphs_window(self):
488 """Clicking forgotten_password_button the proper page is shown."""
489@@ -1691,7 +1694,7 @@
490 self.click_request_password_token_with_valid_data()
491 self.ui.on_password_reset_token_sent(app_name=APP_NAME, email=EMAIL)
492
493- self.assertEqual(self.ui.help_label.get_text(),
494+ self.assertEqual(self.ui.help_label.get_text().decode('utf8'),
495 gui.SET_NEW_PASSWORD_LABEL % {'email': EMAIL})
496
497 def test_on_password_reset_token_sent_ok_button(self):
498@@ -1699,8 +1702,8 @@
499 self.click_request_password_token_with_valid_data()
500 self.ui.on_password_reset_token_sent(app_name=APP_NAME, email=EMAIL)
501
502- self.assertEqual(self.ui.set_new_password_ok_button.get_label(),
503- gui.RESET_PASSWORD)
504+ actual = self.ui.set_new_password_ok_button.get_label()
505+ self.assertEqual(actual.decode('utf8'), gui.RESET_PASSWORD)
506
507 def test_on_password_reset_error_shows_login_page(self):
508 """When reset token wasn't successfuly sent the login page is shown."""
509@@ -1872,8 +1875,8 @@
510 """Password help text is correctly displayed."""
511 visible = self.ui.reset_password_help_label.get_property('visible')
512 self.assertTrue(visible, 'password help text is visible.')
513- self.assertEqual(self.ui.reset_password_help_label.get_text(),
514- gui.PASSWORD_HELP)
515+ actual = self.ui.reset_password_help_label.get_text()
516+ self.assertEqual(actual.decode('utf8'), gui.PASSWORD_HELP)
517 self.assertNotIn('set_new_password', self.ui.backend._called)
518
519 def test_warning_is_shown_if_password_mismatch(self):
520@@ -1951,7 +1954,7 @@
521 """Callbacks do nothing but logging when app_name doesn't match."""
522 mismatch_app_name = self.ui.app_name * 2
523 for method in self.ui._signals.itervalues():
524- msgs = ('ignoring', method.__name__, mismatch_app_name)
525+ msgs = ('ignoring', method.__name__, repr(mismatch_app_name))
526 method(mismatch_app_name, 'dummy')
527 self.assertTrue(self.memento.check(logging.INFO, *msgs))
528 self.memento.records = []
529@@ -2068,7 +2071,8 @@
530
531 def test_help_text_is_used(self):
532 """The passed help_text is used."""
533- self.assertEqual(self.ui.help_label.get_text(), HELP_TEXT)
534+ self.assertEqual(self.ui.help_label.get_text().decode('utf8'),
535+ HELP_TEXT)
536
537
538 class ReturnCodeTestCase(UbuntuSSOClientTestCase):
539@@ -2087,7 +2091,7 @@
540 def test_every_cancel_calls_proper_callback(self):
541 """When any cancel button is clicked, USER_CANCELLATION is called."""
542 self.patch(self.ui.backend, 'disconnect_from_signal', lambda *a: None)
543- msg = 'USER_CANCELLATION should be returned when "%s" is clicked.'
544+ msg = 'USER_CANCELLATION should be returned when %r is clicked.'
545 buttons = filter(lambda name: 'cancel_button' in name, self.ui.widgets)
546 for name in buttons:
547 widget = getattr(self.ui, name)
548
549=== modified file 'ubuntu_sso/keyring/tests/test_linux.py'
550--- ubuntu_sso/keyring/tests/test_linux.py 2012-01-26 15:34:16 +0000
551+++ ubuntu_sso/keyring/tests/test_linux.py 2012-02-18 14:14:18 +0000
552@@ -26,7 +26,6 @@
553
554 from ubuntu_sso import keyring as common_keyring
555 from ubuntu_sso.keyring import linux as keyring
556-from ubuntu_sso.tests import APP_NAME
557
558
559 class MockItem(object):
560@@ -168,9 +167,9 @@
561 sample_creds = {"name": "sample creds name"}
562 kr = keyring.Keyring()
563 self.patch(keyring, "get_token_name", keyring.get_old_token_name)
564- yield kr.set_credentials(APP_NAME, sample_creds)
565+ yield kr.set_credentials("app name", sample_creds)
566
567- result = yield kr.get_credentials(APP_NAME)
568+ result = yield kr.get_credentials("app name")
569 self.assertEqual(result, sample_creds)
570
571 @inlineCallbacks
572
573=== modified file 'ubuntu_sso/main/__init__.py'
574--- ubuntu_sso/main/__init__.py 2012-02-11 01:51:57 +0000
575+++ ubuntu_sso/main/__init__.py 2012-02-18 14:14:18 +0000
576@@ -318,7 +318,7 @@
577 def CredentialsFound(self, app_name, credentials):
578 """Signal thrown when the credentials are found."""
579 self.ref_count -= 1
580- logger.info('%s: emitting CredentialsFound with app_name "%s".',
581+ logger.info('%s: emitting CredentialsFound with app_name %r.',
582 self.__class__.__name__, app_name)
583 self.proxy.CredentialsFound(app_name, credentials)
584
585
586=== modified file 'ubuntu_sso/main/tests/test_common.py'
587--- ubuntu_sso/main/tests/test_common.py 2012-02-10 17:18:22 +0000
588+++ ubuntu_sso/main/tests/test_common.py 2012-02-18 14:14:18 +0000
589@@ -919,7 +919,8 @@
590 @defer.inlineCallbacks
591 def setUp(self):
592 yield super(CredentialsManagementOpsTestCase, self).setUp()
593- self.args = dict((k, str(v)) for k, v in self.base_args.iteritems())
594+ self.args = dict(self.base_args)
595+ self.args[WINDOW_ID_KEY] = str(self.args[WINDOW_ID_KEY])
596 self.cred_args = self.base_args.copy()
597
598 def test_register(self):
599@@ -955,12 +956,16 @@
600 class CredentialsManagementSignalsTestCase(CredentialsManagementTestCase):
601 """Tests for the CredentialsManagement DBus signals."""
602
603+ def assert_signal_logged(self, signal, *args):
604+ """Check that signal info was properly logged."""
605+ signal(APP_NAME, *args)
606+ msgs = [self.obj.__class__.__name__,
607+ signal.__name__, repr(APP_NAME)]
608+ self.assertTrue(self.memento.check_info(*msgs))
609+
610 def test_credentials_found(self):
611 """The CredentialsFound signal."""
612- self.obj.CredentialsFound(APP_NAME, TOKEN)
613- msgs = (self.obj.__class__.__name__,
614- self.obj.CredentialsFound.__name__, APP_NAME)
615- self.assertTrue(self.memento.check_info(*msgs))
616+ self.assert_signal_logged(self.obj.CredentialsFound, TOKEN)
617
618 msg = 'credentials must not be logged (found %r in log).'
619 for val in TOKEN.itervalues():
620@@ -968,24 +973,15 @@
621
622 def test_credentials_not_found(self):
623 """The CredentialsNotFound signal."""
624- self.obj.CredentialsNotFound(APP_NAME)
625- msgs = (self.obj.__class__.__name__,
626- self.obj.CredentialsNotFound.__name__, APP_NAME)
627- self.assertTrue(self.memento.check_info(*msgs))
628+ self.assert_signal_logged(self.obj.CredentialsNotFound)
629
630 def test_credentials_cleared(self):
631 """The CredentialsCleared signal."""
632- self.obj.CredentialsCleared(APP_NAME)
633- msgs = (self.obj.__class__.__name__,
634- self.obj.CredentialsCleared.__name__, APP_NAME)
635- self.assertTrue(self.memento.check_info(*msgs))
636+ self.assert_signal_logged(self.obj.CredentialsCleared)
637
638 def test_credentials_stored(self):
639 """The CredentialsStored signal."""
640- self.obj.CredentialsStored(APP_NAME)
641- msgs = (self.obj.__class__.__name__,
642- self.obj.CredentialsStored.__name__, APP_NAME)
643- self.assertTrue(self.memento.check_info(*msgs))
644+ self.assert_signal_logged(self.obj.CredentialsStored)
645
646 def test_credentials_error(self):
647 """The CredentialsError signal."""
648@@ -993,15 +989,12 @@
649 self.obj.CredentialsError(APP_NAME, error)
650 msgs = (self.obj.__class__.__name__,
651 self.obj.CredentialsError.__name__,
652- APP_NAME, str(error))
653+ repr(APP_NAME), repr(error))
654 self.assertTrue(self.memento.check_error(*msgs))
655
656 def test_authorization_denied(self):
657 """The AuthorizationDenied signal."""
658- self.obj.AuthorizationDenied(APP_NAME)
659- msgs = (self.obj.__class__.__name__,
660- self.obj.AuthorizationDenied.__name__, APP_NAME)
661- self.assertTrue(self.memento.check_info(*msgs))
662+ self.assert_signal_logged(self.obj.AuthorizationDenied)
663
664
665 class UbuntuSSOServiceTestCase(BaseTestCase):
666
667=== modified file 'ubuntu_sso/qt/__init__.py'
668--- ubuntu_sso/qt/__init__.py 2012-02-09 18:28:40 +0000
669+++ ubuntu_sso/qt/__init__.py 2012-02-18 14:14:18 +0000
670@@ -16,21 +16,11 @@
671
672 """The Qt graphical interface for the Ubuntu Single Sign On Client."""
673
674-import gettext
675 import collections
676
677
678-_ = gettext.gettext
679-
680 ERROR_ALL = '__all__'
681 ERROR_MESSAGE = 'message'
682-LOCAL_FOLDERS_TITLE = _("Syncing your computer with the cloud")
683-LOCAL_FOLDERS_SPACE_HEADER = _("Space (%s)")
684-LOCAL_FOLDERS_OFFER_LABEL = _("The folders you have selected to sync "
685- "take over your %(quota)s space. You can remove some folders or add "
686- "some extra space")
687-LOCAL_FOLDERS_CALCULATING = _("Calculating")
688-NEXT = _("Next")
689
690
691 # Based on the gtk implementation
692
693=== modified file 'ubuntu_sso/qt/current_user_sign_in_page.py'
694--- ubuntu_sso/qt/current_user_sign_in_page.py 2012-02-14 14:38:23 +0000
695+++ ubuntu_sso/qt/current_user_sign_in_page.py 2012-02-18 14:14:18 +0000
696@@ -16,7 +16,6 @@
697
698 """Page to allow the user to login into Ubuntu Single Sign On."""
699
700-import gettext
701 from functools import partial
702
703 from PyQt4 import QtGui, QtCore
704@@ -27,6 +26,7 @@
705 from ubuntu_sso.qt.gui import SSOWizardPage
706 from ubuntu_sso.logger import setup_logging
707 from ubuntu_sso.utils.ui import (
708+ CANCEL_BUTTON,
709 EMAIL_LABEL,
710 FORGOTTEN_PASSWORD_BUTTON,
711 is_correct_email,
712@@ -38,7 +38,6 @@
713 FORGOTTEN_PASSWORD_LINK_STYLE = '<a href="#">{forgotten_text}</a>'
714
715
716-_ = gettext.gettext
717 logger = setup_logging('ubuntu_sso.current_user_sign_in_page')
718
719
720@@ -87,8 +86,7 @@
721
722 def initializePage(self):
723 """Setup UI details."""
724- self.setButtonText(QtGui.QWizard.CancelButton,
725- _("Cancel"))
726+ self.setButtonText(QtGui.QWizard.CancelButton, CANCEL_BUTTON)
727 # Layout without custom button 1,
728 # without finish button
729 self.wizard().setButtonLayout([
730
731=== modified file 'ubuntu_sso/qt/gui.py'
732--- ubuntu_sso/qt/gui.py 2012-02-14 14:38:23 +0000
733+++ ubuntu_sso/qt/gui.py 2012-02-18 14:14:18 +0000
734@@ -15,7 +15,6 @@
735 # with this program. If not, see <http://www.gnu.org/licenses/>.
736 """Qt implementation of the UI."""
737
738-import gettext
739 from functools import wraps
740
741 # pylint: disable=F0401,E0611
742@@ -40,7 +39,6 @@
743 from ubuntu_sso.utils.ui import GENERIC_BACKEND_ERROR
744
745
746-_ = gettext.gettext
747 logger = setup_logging('ubuntu_sso.gui')
748
749
750
751=== modified file 'ubuntu_sso/qt/network_detection_page.py'
752--- ubuntu_sso/qt/network_detection_page.py 2012-02-13 20:27:48 +0000
753+++ ubuntu_sso/qt/network_detection_page.py 2012-02-18 14:14:18 +0000
754@@ -16,17 +16,17 @@
755
756 """Pages from SSO."""
757
758-
759-import gettext
760-
761 from twisted.internet import defer
762 from PyQt4 import QtGui
763
764 from ubuntu_sso import networkstate
765
766 from ubuntu_sso.qt.ui import network_detection_ui
767-
768-_ = gettext.gettext
769+from ubuntu_sso.utils.ui import (
770+ CLOSE_AND_SETUP_LATER,
771+ NETWORK_DETECTION_TITLE,
772+ TRY_AGAIN_BUTTON,
773+)
774
775
776 class NetworkDetectionPage(QtGui.QWizardPage):
777@@ -35,7 +35,7 @@
778
779 def __init__(self, banner_pixmap=None, parent=None):
780 super(NetworkDetectionPage, self).__init__(parent)
781- self.setTitle(_("Network detection"))
782+ self.setTitle(NETWORK_DETECTION_TITLE)
783 self.ui = network_detection_ui.Ui_Form()
784 self.ui.setupUi(self)
785 if banner_pixmap is not None:
786@@ -47,9 +47,9 @@
787 """Set UI details."""
788 self.wizard()._next_id = None
789
790- self.setButtonText(QtGui.QWizard.CustomButton1, _("Try again"))
791+ self.setButtonText(QtGui.QWizard.CustomButton1, TRY_AGAIN_BUTTON)
792 self.setButtonText(QtGui.QWizard.CancelButton,
793- _("Close window and set up later"))
794+ CLOSE_AND_SETUP_LATER)
795 self.wizard().setButtonLayout([
796 QtGui.QWizard.Stretch,
797 QtGui.QWizard.CustomButton1,
798
799=== modified file 'ubuntu_sso/qt/setup_account_page.py'
800--- ubuntu_sso/qt/setup_account_page.py 2012-02-15 17:33:40 +0000
801+++ ubuntu_sso/qt/setup_account_page.py 2012-02-18 14:14:18 +0000
802@@ -55,7 +55,6 @@
803 is_min_required_password,
804 is_correct_email,
805 JOIN_HEADER_LABEL,
806- NAME,
807 NAME_ENTRY,
808 NAME_INVALID,
809 PASSWORD,
810@@ -177,7 +176,7 @@
811 self.set_up_button.clicked.connect(self.set_next_validation)
812 self.set_up_button.setEnabled(False)
813
814- self.ui.name_label.setText(NAME)
815+ self.ui.name_label.setText(NAME_ENTRY)
816 self.ui.email_label.setText(EMAIL)
817 self.ui.confirm_email_label.setText(RETYPE_EMAIL)
818 self.ui.password_label.setText(PASSWORD)
819@@ -200,7 +199,7 @@
820 #pylint: enable=C0103
821
822 def _set_translated_strings(self):
823- """Set the different gettext translated strings."""
824+ """Set the strings."""
825 logger.debug('SetUpAccountPage._set_translated_strings')
826 # set the translated string
827 self.ui.name_label.setText(NAME_ENTRY)
828
829=== modified file 'ubuntu_sso/qt/sign_in_page.py'
830--- ubuntu_sso/qt/sign_in_page.py 2012-02-13 20:27:48 +0000
831+++ ubuntu_sso/qt/sign_in_page.py 2012-02-18 14:14:18 +0000
832@@ -16,19 +16,17 @@
833
834 """Page to allow the user to sign in."""
835
836-import gettext
837-
838 from PyQt4 import QtGui, QtCore
839
840 from ubuntu_sso.qt.gui import SSOWizardPage
841 from ubuntu_sso.logger import setup_logging
842 from ubuntu_sso.utils.ui import (
843+ CLOSE_AND_SETUP_LATER,
844 EXISTING_ACCOUNT_CHOICE_BUTTON,
845 SET_UP_ACCOUNT_CHOICE_BUTTON,
846 )
847
848
849-_ = gettext.gettext
850 logger = setup_logging('ubuntu_sso.sing_in_page')
851
852
853@@ -76,7 +74,7 @@
854
855 def initializePage(self):
856 """Setup UI details."""
857- self.ui.cancel_button.setText(_("Close window and setup later"))
858+ self.ui.cancel_button.setText(CLOSE_AND_SETUP_LATER)
859 self.ui.cancel_button.clicked.connect(self.singInCanceled.emit)
860 # Layout without custom button 1,
861 # without finish button
862
863=== modified file 'ubuntu_sso/qt/tests/test_setup_account.py'
864--- ubuntu_sso/qt/tests/test_setup_account.py 2012-02-16 14:37:19 +0000
865+++ ubuntu_sso/qt/tests/test_setup_account.py 2012-02-18 14:14:18 +0000
866@@ -232,7 +232,8 @@
867 self.assertFalse(self.ui.captcha_received)
868
869 # labels
870- self.assertEqual(self.ui.ui.name_label.text(), setup_account_page.NAME)
871+ self.assertEqual(self.ui.ui.name_label.text(),
872+ setup_account_page.NAME_ENTRY)
873 self.assertEqual(self.ui.ui.email_label.text(),
874 setup_account_page.EMAIL)
875 self.assertEqual(self.ui.ui.confirm_email_label.text(),
876
877=== modified file 'ubuntu_sso/tests/__init__.py'
878--- ubuntu_sso/tests/__init__.py 2012-02-10 17:18:22 +0000
879+++ ubuntu_sso/tests/__init__.py 2012-02-18 14:14:18 +0000
880@@ -26,20 +26,20 @@
881
882 from ubuntu_sso.keyring import get_token_name
883
884-APP_NAME = u'The Super App!'
885+APP_NAME = u'I ♥ Ubuntu'
886 CAPTCHA_ID = u'test ñiña'
887 CAPTCHA_PATH = os.path.abspath(os.path.join(os.curdir, 'ubuntu_sso', 'tests',
888 'files', 'captcha.png'))
889 CAPTCHA_SOLUTION = u'william Byrd ñandú'
890 EMAIL = u'test@example.com'
891-EMAIL_TOKEN = u'B2Pgtf'
892+EMAIL_TOKEN = u'B2P☺ gtf'
893 GTK_GUI_EXE = 'ubuntu-sso-login-gtk'
894-HELP_TEXT = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed
895-lorem nibh. Suspendisse gravida nulla non nunc suscipit pulvinar tempus ut
896-augue. Morbi consequat, ligula a elementum pretium, dolor nulla tempus metus,
897-sed viverra nisi risus non velit."""
898-NAME = u'Juanito Pérez'
899-PASSWORD = u'h3lloWorld'
900+HELP_TEXT = u'☛ Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' \
901+'Nam sed lorem nibh. Suspendisse gravida nulla non nunc suscipit pulvinar ' \
902+'tempus ut augue. Morbi consequat, ligula a elementum pretium, ' \
903+'dolor nulla tempus metus, sed viverra nisi risus non velit.'
904+NAME = u'Juanito ☀ Pérez'
905+PASSWORD = u'h3lloWorld☑ '
906 PING_URL = u'http://localhost/ping-me/'
907 POLICY_URL = u'http://localhost/policy/'
908 RESET_PASSWORD_TOKEN = u'8G5Wtq'
909
910=== modified file 'ubuntu_sso/utils/runner/glib.py'
911--- ubuntu_sso/utils/runner/glib.py 2012-02-10 17:03:56 +0000
912+++ ubuntu_sso/utils/runner/glib.py 2012-02-18 14:14:18 +0000
913@@ -27,7 +27,7 @@
914 logger = setup_logging("ubuntu_sso.utils.runner.glib")
915
916
917-NO_SUCH_FILE_OR_DIR = '(No such file or directory)'
918+NO_SUCH_FILE_OR_DIR = 'No such file or directory'
919
920
921 def spawn_program(args, reply_handler, error_handler):
922@@ -66,8 +66,17 @@
923 GLib.SpawnFlags.STDOUT_TO_DEV_NULL | \
924 GLib.SpawnFlags.STDERR_TO_DEV_NULL
925 pid = None
926+
927+ bytes_args = []
928+ for arg in args:
929+ if isinstance(arg, unicode):
930+ arg = arg.encode('utf-8')
931+ if not isinstance(arg, basestring):
932+ arg = str(arg)
933+ bytes_args.append(arg)
934+
935 try:
936- pid, _, _, _ = GLib.spawn_async(argv=args, flags=flags)
937+ pid, _, _, _ = GLib.spawn_async(argv=bytes_args, flags=flags)
938 except GLib.GError, e:
939 handle_error(e)
940 else:
941
942=== added file 'ubuntu_sso/utils/runner/tests/test_glib.py'
943--- ubuntu_sso/utils/runner/tests/test_glib.py 1970-01-01 00:00:00 +0000
944+++ ubuntu_sso/utils/runner/tests/test_glib.py 2012-02-18 14:14:18 +0000
945@@ -0,0 +1,132 @@
946+# -*- coding: utf-8 -*-
947+#
948+# Copyright 2012 Canonical Ltd.
949+#
950+# This program is free software: you can redistribute it and/or modify it
951+# under the terms of the GNU General Public License version 3, as published
952+# by the Free Software Foundation.
953+#
954+# This program is distributed in the hope that it will be useful, but
955+# WITHOUT ANY WARRANTY; without even the implied warranties of
956+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
957+# PURPOSE. See the GNU General Public License for more details.
958+#
959+# You should have received a copy of the GNU General Public License along
960+# with this program. If not, see <http://www.gnu.org/licenses/>.
961+
962+"""Tests for the glib runner helper module."""
963+
964+import subprocess
965+
966+# pylint: disable=E0611
967+from gi.repository import GLib
968+# pylint: enable=E0611
969+from twisted.internet import defer
970+
971+from ubuntu_sso.utils import runner
972+from ubuntu_sso.utils.runner import glib
973+from ubuntu_sso.utils.runner.tests.test_runner import SpawnProgramTestCase
974+
975+
976+class FakedSignal(object):
977+ """Fake a glib signal."""
978+
979+ def __init__(self, name):
980+ self.name = name
981+ self._handlers = []
982+
983+ def connect(self, handler):
984+ """Connect 'handler' with this signal."""
985+ self._handlers.append(handler)
986+
987+ def emit(self, *args, **kwargs):
988+ """Emit this signal."""
989+ for handler in self._handlers:
990+ handler(*args, **kwargs)
991+
992+
993+class FakedProcess(object):
994+ """Fake a glib Process."""
995+
996+ _argv = _flags = None
997+ _pid = 123456
998+ _pids = []
999+ _status_code = 0
1000+
1001+ SpawnFlags = GLib.SpawnFlags
1002+ GError = GLib.GError
1003+
1004+ def __init__(self):
1005+ self.pid = lambda: self._pid
1006+ self.started = FakedSignal('started')
1007+ self.finished = FakedSignal('finished')
1008+ self.error = FakedSignal('error')
1009+
1010+ def spawn_async(self, argv, flags):
1011+ """Spwan a process."""
1012+ if 'None' in argv:
1013+ exc = GLib.GError()
1014+ exc.message = str('Can not handle None')
1015+ exc.code = 24
1016+ raise exc
1017+
1018+ self._argv = argv
1019+ self._flags = flags
1020+
1021+ try:
1022+ subprocess.call(argv)
1023+ except Exception, e:
1024+ exc = GLib.GError()
1025+ exc.message = str(e)
1026+ exc.code = 42
1027+ raise exc
1028+
1029+ self._pids.append(self._pid)
1030+ return (self._pid, None, None, None)
1031+
1032+ def child_watch_add(self, pid, child_watch):
1033+ """Addd a child watch."""
1034+ if pid in self._pids:
1035+ child_watch(pid, self._status_code)
1036+
1037+ def spawn_close_pid(self, pid):
1038+ """Close the 'pid'."""
1039+ self._pids.remove(pid)
1040+
1041+
1042+class GLibSpawnProgramTestCase(SpawnProgramTestCase):
1043+ """The test suite for the spawn_program method (using GLib)."""
1044+
1045+ use_reactor = False
1046+
1047+ @defer.inlineCallbacks
1048+ def setUp(self):
1049+ yield super(GLibSpawnProgramTestCase, self).setUp()
1050+ # Since we can't mix plan glib runner and the gireactor, we patch
1051+ # GLib.spawn_async and fake the conditions so the glib runner is chosen
1052+ self.process = FakedProcess()
1053+ self.patch(glib, 'GLib', self.process)
1054+ self.patch(runner, 'is_twisted_reactor_installed', lambda: False)
1055+ self.patch(runner, 'is_qt4_main_loop_installed', lambda: False)
1056+
1057+ # Access to a protected member _flags, _argv of a client class
1058+ # pylint: disable=W0212
1059+
1060+ @defer.inlineCallbacks
1061+ def test_flags_are_correct(self):
1062+ """The flags are the correct ones."""
1063+ yield self.spawn_fn(self.args)
1064+
1065+ flags = GLib.SpawnFlags.DO_NOT_REAP_CHILD | \
1066+ GLib.SpawnFlags.SEARCH_PATH | \
1067+ GLib.SpawnFlags.STDOUT_TO_DEV_NULL | \
1068+ GLib.SpawnFlags.STDERR_TO_DEV_NULL
1069+ self.assertEqual(self.process._flags, flags)
1070+
1071+ @defer.inlineCallbacks
1072+ def test_argv_is_bytes(self):
1073+ """The argv parameter is converted to bytes."""
1074+ yield self.spawn_fn(self.args)
1075+
1076+ bytes_args = [a.encode('utf-8') for a in self.args]
1077+ self.assertEqual(self.process._argv, bytes_args)
1078
1079=== modified file 'ubuntu_sso/utils/runner/tests/test_qt.py'
1080--- ubuntu_sso/utils/runner/tests/test_qt.py 2012-02-10 15:44:28 +0000
1081+++ ubuntu_sso/utils/runner/tests/test_qt.py 2012-02-18 14:14:18 +0000
1082@@ -64,8 +64,16 @@
1083 self.started.emit()
1084
1085 args = (program,) + tuple(arguments)
1086+
1087+ # subprocess expects bytes
1088+ bytes_args = []
1089+ for arg in args:
1090+ if isinstance(arg, unicode):
1091+ arg = arg.encode('utf-8')
1092+ bytes_args.append(arg)
1093+
1094 try:
1095- subprocess.call(args)
1096+ subprocess.call(bytes_args)
1097 except OSError, e:
1098 if e.errno == 2:
1099 self.error.emit(self.FailedToStart)
1100
1101=== modified file 'ubuntu_sso/utils/runner/tests/test_runner.py'
1102--- ubuntu_sso/utils/runner/tests/test_runner.py 2012-02-08 02:13:03 +0000
1103+++ ubuntu_sso/utils/runner/tests/test_runner.py 2012-02-18 14:14:18 +0000
1104@@ -24,21 +24,23 @@
1105 from ubuntu_sso.utils import runner
1106
1107
1108-TEST_ME_DIR = 'test-me'
1109+TEST_ME_DIR = u'test-me-more-♥'
1110+TEST_ME_DIR_BYTES = TEST_ME_DIR.encode('utf-8')
1111
1112
1113 class SpawnProgramTestCase(TestCase):
1114 """The test suite for the spawn_program method."""
1115
1116 timeout = 3
1117- args = ('python', '-c', 'import os; os.system("mkdir %s")' % TEST_ME_DIR)
1118+ args = (u'python', u'-c',
1119+ u'import os; os.system("mkdir %s")' % TEST_ME_DIR)
1120
1121 @defer.inlineCallbacks
1122 def setUp(self):
1123 yield super(SpawnProgramTestCase, self).setUp()
1124- assert not os.path.exists(TEST_ME_DIR)
1125- self.addCleanup(lambda: os.path.exists(TEST_ME_DIR) and
1126- os.rmdir(TEST_ME_DIR))
1127+ assert not os.path.exists(TEST_ME_DIR_BYTES)
1128+ self.addCleanup(lambda: os.path.exists(TEST_ME_DIR_BYTES) and
1129+ os.rmdir(TEST_ME_DIR_BYTES))
1130
1131 def spawn_fn(self, args):
1132 """The target function to test."""
1133@@ -46,8 +48,8 @@
1134
1135 def assert_command_was_run(self):
1136 """The spawnned commnad was correctly run."""
1137- self.assertTrue(os.path.exists(TEST_ME_DIR))
1138- self.assertTrue(os.path.isdir(TEST_ME_DIR))
1139+ self.assertTrue(os.path.exists(TEST_ME_DIR_BYTES))
1140+ self.assertTrue(os.path.isdir(TEST_ME_DIR_BYTES))
1141
1142 @defer.inlineCallbacks
1143 def test_program_is_spawned(self):
1144
1145=== modified file 'ubuntu_sso/utils/runner/tx.py'
1146--- ubuntu_sso/utils/runner/tx.py 2012-02-08 18:29:39 +0000
1147+++ ubuntu_sso/utils/runner/tx.py 2012-02-18 14:14:18 +0000
1148@@ -68,6 +68,14 @@
1149 program = args[0]
1150 argv = args[1:]
1151
1152+ bytes_args = []
1153+ for arg in argv:
1154+ if isinstance(arg, unicode):
1155+ arg = arg.encode('utf-8')
1156+ if not isinstance(arg, basestring):
1157+ arg = str(arg)
1158+ bytes_args.append(arg)
1159+
1160 if program and not os.access(program, os.X_OK):
1161 # handle searching the executable in the PATH, since
1162 # twisted will not solve that for us :-/
1163@@ -81,7 +89,7 @@
1164 break
1165
1166 try:
1167- d = utils.getProcessOutputAndValue(program, argv, env=os.environ)
1168+ d = utils.getProcessOutputAndValue(program, bytes_args, env=os.environ)
1169 except OSError, e:
1170 error_handler(msg=e, failed_to_start=True)
1171 except Exception, e:
1172
1173=== modified file 'ubuntu_sso/utils/ui.py'
1174--- ubuntu_sso/utils/ui.py 2012-02-13 20:27:48 +0000
1175+++ ubuntu_sso/utils/ui.py 2012-02-18 14:14:18 +0000
1176@@ -21,11 +21,12 @@
1177
1178 from ubuntu_sso.logger import setup_logging
1179
1180+
1181+gettext.install('ubuntu-sso-client', unicode=True)
1182 logger = setup_logging('ubuntu_sso.utils.ui')
1183
1184
1185-gettext.textdomain('ubuntu-sso-client')
1186-_ = gettext.gettext
1187+# Undefined variable '_', pylint: disable=E0602
1188
1189 # all the text that is used in the gui
1190 AGREE_TO_PRIVACY_POLICY = _('By signing up to {app_name} you agree to '
1191@@ -33,11 +34,13 @@
1192 AGREE_TO_TERMS = _('By signing up to {app_name} you agree to '
1193 'our {terms_and_conditions}')
1194 AGREE_TO_TERMS_AND_PRIVACY_POLICY = AGREE_TO_TERMS + _(' and {privacy_policy}')
1195+CANCEL_BUTTON = _('Cancel')
1196 CAPTCHA_SOLUTION_ENTRY = _('Type the characters above')
1197 CAPTCHA_LOAD_ERROR = _('There was a problem getting the captcha, '
1198 'reloading...')
1199 CAPTCHA_RELOAD_TOOLTIP = _('Reload')
1200 CAPTCHA_REQUIRED_ERROR = _('The captcha is a required field')
1201+CLOSE_AND_SETUP_LATER = _('Close window and setup later')
1202 CONGRATULATIONS = _("Congratulations, {app_name} is installed!")
1203 PROXY_CREDS_DIALOG_TITLE = _('Add proxy settings')
1204 PROXY_CREDS_HEADER = _('You are connecting through a proxy.')
1205@@ -76,10 +79,10 @@
1206 LOGIN_HEADER_LABEL = _('Connect to %(app_name)s')
1207 LOGIN_PASSWORD_ENTRY = _('Password')
1208 LOGIN_PASSWORD_LABEL = LOGIN_PASSWORD_ENTRY
1209-NAME = _("Name")
1210 NAME_ENTRY = _('Name')
1211 NAME_INVALID = _('The name must not be empty.')
1212 NEXT = _('Next')
1213+NETWORK_DETECTION_TITLE = _('Network detection')
1214 ONE_MOMENT_PLEASE = _('One moment please...')
1215 PASSWORD = _("Create a password")
1216 PASSWORD_CHANGED = _('Your password was successfully changed.')
1217@@ -140,6 +143,8 @@
1218 YES_TO_TC = _('I agree with the %(app_name)s terms and conditions')
1219 YES_TO_UPDATES = _('Yes! Email me %(app_name)s tips and updates.')
1220
1221+# pylint: enable=E0602
1222+
1223
1224 def get_password_strength(password):
1225 """Return the strength of the password.

Subscribers

People subscribed via source and target branches