Merge lp:~nataliabidart/ubuntu-sso-client/gtk-gi into lp:ubuntu-sso-client

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 862
Merged at revision: 843
Proposed branch: lp:~nataliabidart/ubuntu-sso-client/gtk-gi
Merge into: lp:ubuntu-sso-client
Prerequisite: lp:~alecu/ubuntu-sso-client/use-restful-client
Diff against target: 2630 lines (+720/-500)
32 files modified
data/gtk/ui.glade (+314/-180)
run-tests (+13/-15)
ubuntu_sso/account.py (+7/-3)
ubuntu_sso/gtk/__init__.py (+1/-3)
ubuntu_sso/gtk/gui.py (+90/-60)
ubuntu_sso/gtk/main.py (+5/-3)
ubuntu_sso/gtk/tests/__init__.py (+1/-3)
ubuntu_sso/gtk/tests/test_gui.py (+76/-56)
ubuntu_sso/gtk/tests/test_main.py (+4/-4)
ubuntu_sso/keyring/__init__.py (+17/-9)
ubuntu_sso/keyring/tests/test_common.py (+4/-5)
ubuntu_sso/keyring/tests/test_linux.py (+1/-1)
ubuntu_sso/logger.py (+20/-4)
ubuntu_sso/main/__init__.py (+2/-2)
ubuntu_sso/main/glib.py (+45/-0)
ubuntu_sso/main/linux.py (+27/-22)
ubuntu_sso/main/qt.py (+49/-0)
ubuntu_sso/main/windows.py (+1/-1)
ubuntu_sso/qt/gui.py (+2/-1)
ubuntu_sso/qt/tests/login_u_p.py (+16/-5)
ubuntu_sso/qt/tests/show_gui.py (+5/-6)
ubuntu_sso/qt/tests/test_controllers.py (+4/-3)
ubuntu_sso/qt/tests/test_enchanced_line_edit.py (+3/-2)
ubuntu_sso/qt/tests/test_reset_password.py (+2/-1)
ubuntu_sso/tests/__init__.py (+2/-2)
ubuntu_sso/tests/bin/show_gui (+0/-58)
ubuntu_sso/tests/bin/show_nm_state (+0/-41)
ubuntu_sso/tests/test_account.py (+1/-1)
ubuntu_sso/utils/tests/test_txsecrets.py (+3/-0)
ubuntu_sso/utils/webclient/__init__.py (+2/-4)
ubuntu_sso/utils/webclient/qtnetwork.py (+2/-0)
ubuntu_sso/utils/webclient/tests/test_webclient.py (+1/-5)
To merge this branch: bzr merge lp:~nataliabidart/ubuntu-sso-client/gtk-gi
Reviewer Review Type Date Requested Status
dobey (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+90134@code.launchpad.net

Commit message

- Added a dedicated logger for the gui module.
- Migrated the GTK UI to use GI bindings (LP: #801111).
- Enabled libsoup backend for webclient so the GTK UI will work.
- Enabled the running of all the tests using the single command ./run-tests.
- Added an initial version of GLib and Qt mainloop integration (needed to run all the tests).

Description of the change

You need to be running latest Ubuntu One nightlies in order this branch to work.

Also, if testing IRL, please note that the captcha image will not load because of bug #921822 (the rest of the remote calls works perfectly).

Another thing to note is that the change in the .glade file is caused by the upgrade of the syntax to latest Glade version (the changes were the result of opening the file in Glade @ precise, adding the activate-link signal handler to the 2 LinkButton we have, saving, and closing the file).

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) wrote :

+1

review: Approve
Revision history for this message
dobey (dobey) wrote :

I'm seeing a lot of the following error, in the GTK+ tests, though the tests still pass:

Gtk-WARNING **: Unable to show 'foo': Operation not supported

Do you know why this is happening?

Revision history for this message
dobey (dobey) wrote :

There also seem to be some differences from the currently shipped version, in terms of size/layout. Is there a way to test all of the pieces without actually creating a new account? I'm not really sure how to test this IRL, beyond the simple "i already have an account" piece, without making real accounts.

review: Needs Information
Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> I'm seeing a lot of the following error, in the GTK+ tests, though the tests
> still pass:
>
> Gtk-WARNING **: Unable to show 'foo': Operation not supported
>
> Do you know why this is happening?

Yes. In the UI we have a couple of LinkButton's that are not meant to open any link in any browser. I added a dummy callback (on_activate_link) and I connected it with those buttons to the activate-link signal. According to the doc, if I define a handler for the activate-signal and return True, http://developer.gnome.org/gtk3/stable/GtkLinkButton.html#GtkLinkButton-activate-link, the default handler gtk_show_uri will not be called, but in practice it's called. I would guess this is a bug... the warning complains about the "uri" property being invalid (which is intended, since we don't want any link to be opened in any browser).

Revision history for this message
Natalia Bidart (nataliabidart) wrote :

> There also seem to be some differences from the currently shipped version, in
> terms of size/layout. Is there a way to test all of the pieces without
> actually creating a new account? I'm not really sure how to test this IRL,
> beyond the simple "i already have an account" piece, without making real
> accounts.

Yes, there are some size differences, but shouldn't be layout differences.

The way of test is actually creating SSO accounts... but you can do it for dummy applications and not for Ubuntu One (so your U1 metadata does not get messed up). To do so:

* in a terminal pointing to this branch run:

DEBUG=True PYTHONPATH=. bin/ubuntu-sso-login

* open d-feet and connect to the session bus, look for the com.ubuntu.sso service, and go to the CredentialsManagement interface. Choose the "login" or "register" method, and pass arguments like:

'Foo', {}

or:

'Foo Bar', {'help_text': 'something for test here'}

When you execute one of the methods above, you should get a GTK window with the login or register screen in it, and you should be able to login or create a kinda dummy account.

Revision history for this message
dobey (dobey) wrote :

https://launchpadlibrarian.net/91640946/sso-gtk3-nowrap.png shows what I meant about layout. It looks like the description label is not getting wrapped. I don't know if this is due to a change in this branch to the glade data, or if it's introduced by changes in gtk3 itself. I suspect the latter though.

Revision history for this message
dobey (dobey) wrote :

Looks OK to me. I think we'll need a bug against python-gi for breaking ^C. I'll file it shortly. I have filed bug #925042 against ubuntu-sso-client for the label wrapping issue.

review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

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

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

*** Running test suite for ubuntu_sso ***
ubuntu_sso.tests.test_account
  AccountTestCase
    test_generate_captcha ... [OK]
    test_is_not_validated ... [OK]
    test_is_not_validated_empty_result ... [OK]
    test_is_validated ... [OK]
    test_login_if_http_error ... [OK]
    test_login_if_no_error ... [OK]
    test_register_user_checks_valid_email ... [OK]
    test_register_user_checks_valid_password ... [OK]
    test_register_user_if_status_error ... [OK]
    test_register_user_if_status_error_with_string_message ... [OK]
    test_register_user_if_status_ok ... [OK]
    test_register_user_if_status_unknown ... [OK]
    test_request_password_reset_token_if_http_error ... [OK]
    test_request_password_reset_token_if_status_ok ... [OK]
    test_request_password_reset_token_if_status_unknown ... [OK]
    test_set_new_password_if_http_error ... [OK]
    test_set_new_password_if_status_ok ... [OK]
    test_set_new_password_if_status_unknown ... [OK]
    test_validate_email_if_status_error ... [OK]
    test_validate_email_if_status_error_with_string_message ... [OK]
    test_validate_email_if_status_ok ... [OK]
    test_validate_email_if_status_unknown ... [OK]
  EnvironOverridesTestCase
    test_no_override_service_url ... [OK]
    test_override_service_url ... [OK]
    test_service_url_as_parameter ... [OK]
twisted.trial.unittest
  TestCase
    runTest ... [OK]
ubuntu_sso.tests.test_account
  TimestampedAuthorizerTestCase
    test_authorize_request_includes_timestamp ... [OK]
ubuntu_sso.tests.test_credentials
  BasicTestCase
    runTest ... [OK]
  ClearCredentialsTestCase
    test_clear_credentials ... [OK]
    test_keyring_failure ... [OK]
  CredentialsAuthDeniedTestCase
    test_auth_denial_cb ... [OK]
  CredentialsCallbacksTestCase
    test_callbacks_are_stored ... [OK]
    test_callbacks_default_to_no_op ... [OK]
    test_creation_parameters_are_stored ... ...

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

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

*** Running test suite for ubuntu_sso ***
ubuntu_sso.tests.test_account
  AccountTestCase
    test_generate_captcha ... [OK]
    test_is_not_validated ... [OK]
    test_is_not_validated_empty_result ... [OK]
    test_is_validated ... [OK]
    test_login_if_http_error ... [OK]
    test_login_if_no_error ... [OK]
    test_register_user_checks_valid_email ... [OK]
    test_register_user_checks_valid_password ... [OK]
    test_register_user_if_status_error ... [OK]
    test_register_user_if_status_error_with_string_message ... [OK]
    test_register_user_if_status_ok ... [OK]
    test_register_user_if_status_unknown ... [OK]
    test_request_password_reset_token_if_http_error ... [OK]
    test_request_password_reset_token_if_status_ok ... [OK]
    test_request_password_reset_token_if_status_unknown ... [OK]
    test_set_new_password_if_http_error ... [OK]
    test_set_new_password_if_status_ok ... [OK]
    test_set_new_password_if_status_unknown ... [OK]
    test_validate_email_if_status_error ... [OK]
    test_validate_email_if_status_error_with_string_message ... [OK]
    test_validate_email_if_status_ok ... [OK]
    test_validate_email_if_status_unknown ... [OK]
  EnvironOverridesTestCase
    test_no_override_service_url ... [OK]
    test_override_service_url ... [OK]
    test_service_url_as_parameter ... [OK]
twisted.trial.unittest
  TestCase
    runTest ... [OK]
ubuntu_sso.tests.test_account
  TimestampedAuthorizerTestCase
    test_authorize_request_includes_timestamp ... [OK]
ubuntu_sso.tests.test_credentials
  BasicTestCase
    runTest ... [OK]
  ClearCredentialsTestCase
    test_clear_credentials ... [OK]
    test_keyring_failure ... [OK]
  CredentialsAuthDeniedTestCase
    test_auth_denial_cb ... [OK]
  CredentialsCallbacksTestCase
    test_callbacks_are_stored ... [OK]
    test_callbacks_default_to_no_op ... [OK]
    test_creation_parameters_are_stored ... ...

Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

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

*** Running test suite for ubuntu_sso ***

xvfb-run: error: Xvfb failed to start

859. By Natalia Bidart

- Adding proper cleanup for GTK windows created during tests.

860. By Natalia Bidart

- Add cleanups calls to every created UI.

861. By Natalia Bidart

Attaching new bug number.

862. By Natalia Bidart

Merged trunk in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/gtk/ui.glade'
2--- data/gtk/ui.glade 2011-09-19 13:09:46 +0000
3+++ data/gtk/ui.glade 2012-02-02 18:14:19 +0000
4@@ -1,72 +1,14 @@
5 <?xml version="1.0" encoding="UTF-8"?>
6 <interface>
7 <requires lib="gtk+" version="2.16"/>
8- <!-- interface-naming-policy project-wide -->
9- <object class="GtkWindow" id="window">
10- <property name="border_width">10</property>
11- <property name="window_position">center</property>
12- <signal name="delete_event" handler="on_close_clicked"/>
13- <child>
14- <object class="GtkVBox" id="window_vbox">
15- <property name="visible">True</property>
16- <property name="spacing">5</property>
17- <child>
18- <object class="GtkLabel" id="header_label">
19- <property name="visible">True</property>
20- <property name="xalign">0</property>
21- <property name="label" translatable="yes">Header Label </property>
22- <property name="wrap">True</property>
23- </object>
24- <packing>
25- <property name="expand">False</property>
26- <property name="padding">5</property>
27- <property name="position">0</property>
28- </packing>
29- </child>
30- <child>
31- <object class="GtkLabel" id="help_label">
32- <property name="visible">True</property>
33- <property name="xalign">0</property>
34- <property name="label" translatable="yes">help label</property>
35- <property name="wrap">True</property>
36- </object>
37- <packing>
38- <property name="expand">False</property>
39- <property name="position">1</property>
40- </packing>
41- </child>
42- <child>
43- <object class="GtkLabel" id="warning_label">
44- <property name="visible">True</property>
45- <property name="xalign">0</property>
46- <property name="label" translatable="yes">warning label</property>
47- <property name="wrap">True</property>
48- </object>
49- <packing>
50- <property name="expand">False</property>
51- <property name="position">2</property>
52- </packing>
53- </child>
54- <child>
55- <object class="GtkNotebook" id="content">
56- <property name="visible">True</property>
57- <property name="can_focus">True</property>
58- <property name="show_tabs">False</property>
59- <property name="show_border">False</property>
60- </object>
61- <packing>
62- <property name="position">3</property>
63- </packing>
64- </child>
65- </object>
66- </child>
67- </object>
68 <object class="GtkVBox" id="enter_details_vbox">
69 <property name="visible">True</property>
70+ <property name="can_focus">False</property>
71 <property name="spacing">5</property>
72 <child>
73 <object class="GtkHBox" id="emails_hbox">
74 <property name="visible">True</property>
75+ <property name="can_focus">False</property>
76 <property name="spacing">5</property>
77 <property name="homogeneous">True</property>
78 <child>
79@@ -78,12 +20,14 @@
80 </object>
81 <packing>
82 <property name="expand">False</property>
83+ <property name="fill">True</property>
84 <property name="position">0</property>
85 </packing>
86 </child>
87 <child>
88 <object class="GtkHBox" id="passwords_hbox">
89 <property name="visible">True</property>
90+ <property name="can_focus">False</property>
91 <property name="spacing">5</property>
92 <property name="homogeneous">True</property>
93 <child>
94@@ -95,38 +39,45 @@
95 </object>
96 <packing>
97 <property name="expand">False</property>
98+ <property name="fill">True</property>
99 <property name="position">1</property>
100 </packing>
101 </child>
102 <child>
103 <object class="GtkLabel" id="password_help_label">
104 <property name="visible">True</property>
105+ <property name="can_focus">False</property>
106 <property name="label">password help</property>
107 <property name="wrap">True</property>
108 </object>
109 <packing>
110 <property name="expand">False</property>
111+ <property name="fill">True</property>
112 <property name="position">2</property>
113 </packing>
114 </child>
115 <child>
116 <object class="GtkAlignment" id="alignment5">
117 <property name="visible">True</property>
118+ <property name="can_focus">False</property>
119 <property name="xscale">0</property>
120 <property name="yscale">0</property>
121 <child>
122 <object class="GtkHBox" id="hbox1">
123 <property name="visible">True</property>
124+ <property name="can_focus">False</property>
125 <child>
126 <object class="GtkVBox" id="captcha_vbox">
127 <property name="width_request">300</property>
128 <property name="height_request">60</property>
129 <property name="visible">True</property>
130+ <property name="can_focus">False</property>
131 <child>
132 <object class="GtkEventBox" id="captcha_loading">
133 <property name="width_request">300</property>
134 <property name="height_request">60</property>
135 <property name="visible">True</property>
136+ <property name="can_focus">False</property>
137 <child>
138 <placeholder/>
139 </child>
140@@ -141,9 +92,12 @@
141 <object class="GtkImage" id="captcha_image">
142 <property name="width_request">300</property>
143 <property name="visible">True</property>
144+ <property name="can_focus">False</property>
145 <property name="stock">gtk-missing-image</property>
146 </object>
147 <packing>
148+ <property name="expand">True</property>
149+ <property name="fill">True</property>
150 <property name="position">1</property>
151 </packing>
152 </child>
153@@ -157,23 +111,28 @@
154 <child>
155 <object class="GtkVBox" id="vbox1">
156 <property name="visible">True</property>
157+ <property name="can_focus">False</property>
158 <child>
159 <object class="GtkButton" id="captcha_reload_button">
160+ <property name="use_action_appearance">False</property>
161 <property name="visible">True</property>
162 <property name="can_focus">True</property>
163 <property name="receives_default">True</property>
164+ <property name="use_action_appearance">False</property>
165 <property name="relief">none</property>
166 <property name="focus_on_click">False</property>
167- <signal name="clicked" handler="on_captcha_reload_button_clicked"/>
168+ <signal name="clicked" handler="on_captcha_reload_button_clicked" swapped="no"/>
169 <child>
170 <object class="GtkImage" id="image1">
171 <property name="visible">True</property>
172+ <property name="can_focus">False</property>
173 <property name="icon_name">reload</property>
174 </object>
175 </child>
176 </object>
177 <packing>
178 <property name="expand">False</property>
179+ <property name="fill">True</property>
180 <property name="position">0</property>
181 </packing>
182 </child>
183@@ -186,6 +145,7 @@
184 </object>
185 <packing>
186 <property name="expand">False</property>
187+ <property name="fill">True</property>
188 <property name="position">1</property>
189 </packing>
190 </child>
191@@ -194,64 +154,76 @@
192 </object>
193 <packing>
194 <property name="expand">False</property>
195+ <property name="fill">True</property>
196 <property name="position">3</property>
197 </packing>
198 </child>
199 <child>
200 <object class="GtkVBox" id="captcha_solution_vbox">
201 <property name="visible">True</property>
202+ <property name="can_focus">False</property>
203 <child>
204 <placeholder/>
205 </child>
206 </object>
207 <packing>
208 <property name="expand">False</property>
209+ <property name="fill">True</property>
210 <property name="position">4</property>
211 </packing>
212 </child>
213 <child>
214 <object class="GtkCheckButton" id="yes_to_updates_checkbutton">
215 <property name="label" translatable="yes">yes to updates</property>
216+ <property name="use_action_appearance">False</property>
217 <property name="visible">True</property>
218 <property name="can_focus">True</property>
219 <property name="receives_default">False</property>
220+ <property name="use_action_appearance">False</property>
221 <property name="active">True</property>
222 <property name="draw_indicator">True</property>
223 </object>
224 <packing>
225 <property name="expand">False</property>
226+ <property name="fill">True</property>
227 <property name="position">5</property>
228 </packing>
229 </child>
230 <child>
231 <object class="GtkVBox" id="tc_vbox">
232 <property name="visible">True</property>
233+ <property name="can_focus">False</property>
234 <property name="spacing">5</property>
235 <child>
236 <object class="GtkCheckButton" id="yes_to_tc_checkbutton">
237 <property name="label" translatable="yes">yes to tc</property>
238+ <property name="use_action_appearance">False</property>
239 <property name="visible">True</property>
240 <property name="can_focus">True</property>
241 <property name="receives_default">False</property>
242- <property name="active">False</property>
243+ <property name="use_action_appearance">False</property>
244 <property name="draw_indicator">True</property>
245 </object>
246 <packing>
247 <property name="expand">False</property>
248+ <property name="fill">True</property>
249 <property name="position">0</property>
250 </packing>
251 </child>
252 <child>
253 <object class="GtkHButtonBox" id="hbuttonbox3">
254 <property name="visible">True</property>
255+ <property name="can_focus">False</property>
256 <property name="layout_style">start</property>
257 <child>
258 <object class="GtkButton" id="tc_button">
259 <property name="label">show tc</property>
260+ <property name="use_action_appearance">False</property>
261 <property name="visible">True</property>
262 <property name="can_focus">True</property>
263 <property name="receives_default">True</property>
264- <signal name="clicked" handler="on_tc_button_clicked"/>
265+ <property name="use_action_appearance">False</property>
266+ <signal name="clicked" handler="on_tc_button_clicked" swapped="no"/>
267 </object>
268 <packing>
269 <property name="expand">False</property>
270@@ -262,42 +234,53 @@
271 </object>
272 <packing>
273 <property name="expand">False</property>
274+ <property name="fill">True</property>
275 <property name="position">1</property>
276 </packing>
277 </child>
278 <child>
279 <object class="GtkLabel" id="tc_warning_label">
280 <property name="visible">True</property>
281+ <property name="can_focus">False</property>
282 <property name="xalign">0</property>
283 <property name="label">tc warning</property>
284 <property name="wrap">True</property>
285 </object>
286 <packing>
287+ <property name="expand">True</property>
288+ <property name="fill">True</property>
289 <property name="position">2</property>
290 </packing>
291 </child>
292 </object>
293 <packing>
294 <property name="expand">False</property>
295+ <property name="fill">True</property>
296 <property name="position">6</property>
297 </packing>
298 </child>
299 <child>
300 <object class="GtkHBox" id="hbox2">
301 <property name="visible">True</property>
302+ <property name="can_focus">False</property>
303 <property name="spacing">5</property>
304 <child>
305 <object class="GtkHButtonBox" id="hbuttonbox9">
306 <property name="visible">True</property>
307+ <property name="can_focus">False</property>
308 <property name="layout_style">start</property>
309 <child>
310 <object class="GtkLinkButton" id="login_button">
311 <property name="label">login button</property>
312+ <property name="use_action_appearance">False</property>
313 <property name="visible">True</property>
314 <property name="can_focus">True</property>
315 <property name="receives_default">True</property>
316+ <property name="use_action_appearance">False</property>
317 <property name="relief">none</property>
318- <signal name="clicked" handler="on_sign_in_button_clicked"/>
319+ <property name="uri">foo</property>
320+ <signal name="activate-link" handler="on_activate_link" swapped="no"/>
321+ <signal name="clicked" handler="on_sign_in_button_clicked" swapped="no"/>
322 </object>
323 <packing>
324 <property name="expand">False</property>
325@@ -308,20 +291,24 @@
326 </object>
327 <packing>
328 <property name="expand">False</property>
329+ <property name="fill">True</property>
330 <property name="position">0</property>
331 </packing>
332 </child>
333 <child>
334 <object class="GtkHButtonBox" id="hbuttonbox1">
335 <property name="visible">True</property>
336+ <property name="can_focus">False</property>
337 <property name="spacing">5</property>
338 <property name="layout_style">end</property>
339 <child>
340 <object class="GtkButton" id="join_cancel_button">
341 <property name="label">gtk-cancel</property>
342+ <property name="use_action_appearance">False</property>
343 <property name="visible">True</property>
344 <property name="can_focus">True</property>
345 <property name="receives_default">True</property>
346+ <property name="use_action_appearance">False</property>
347 <property name="use_stock">True</property>
348 </object>
349 <packing>
350@@ -333,11 +320,13 @@
351 <child>
352 <object class="GtkButton" id="join_ok_button">
353 <property name="label">gtk-go-forward</property>
354+ <property name="use_action_appearance">False</property>
355 <property name="visible">True</property>
356 <property name="can_focus">True</property>
357 <property name="receives_default">True</property>
358+ <property name="use_action_appearance">False</property>
359 <property name="use_stock">True</property>
360- <signal name="clicked" handler="on_join_ok_button_clicked"/>
361+ <signal name="clicked" handler="on_join_ok_button_clicked" swapped="no"/>
362 </object>
363 <packing>
364 <property name="expand">False</property>
365@@ -348,6 +337,7 @@
366 </object>
367 <packing>
368 <property name="expand">False</property>
369+ <property name="fill">True</property>
370 <property name="pack_type">end</property>
371 <property name="position">1</property>
372 </packing>
373@@ -355,122 +345,72 @@
374 </object>
375 <packing>
376 <property name="expand">False</property>
377+ <property name="fill">True</property>
378 <property name="pack_type">end</property>
379 <property name="position">7</property>
380 </packing>
381 </child>
382 </object>
383- <object class="GtkVBox" id="processing_vbox">
384- <property name="visible">True</property>
385- <property name="spacing">10</property>
386- <child>
387- <placeholder/>
388- </child>
389- </object>
390- <object class="GtkVBox" id="verify_email_vbox">
391- <property name="visible">True</property>
392- <property name="spacing">10</property>
393- <child>
394- <object class="GtkAlignment" id="alignment4">
395- <property name="visible">True</property>
396- <property name="xscale">0</property>
397- <property name="yscale">0</property>
398- <child>
399- <object class="GtkVBox" id="verify_email_details_vbox">
400- <property name="visible">True</property>
401- <child>
402- <placeholder/>
403- </child>
404- </object>
405- </child>
406- </object>
407- <packing>
408- <property name="position">0</property>
409- </packing>
410- </child>
411- <child>
412- <object class="GtkHButtonBox" id="hbuttonbox2">
413- <property name="visible">True</property>
414- <property name="spacing">5</property>
415- <property name="layout_style">end</property>
416- <child>
417- <object class="GtkButton" id="verify_token_button">
418- <property name="label">gtk-ok</property>
419- <property name="visible">True</property>
420- <property name="can_focus">True</property>
421- <property name="receives_default">True</property>
422- <property name="use_stock">True</property>
423- <signal name="clicked" handler="on_verify_token_button_clicked"/>
424- </object>
425- <packing>
426- <property name="expand">False</property>
427- <property name="fill">False</property>
428- <property name="position">0</property>
429- </packing>
430- </child>
431- </object>
432- <packing>
433- <property name="expand">False</property>
434- <property name="position">1</property>
435- </packing>
436- </child>
437- </object>
438- <object class="GtkVBox" id="tc_browser_vbox">
439- <property name="visible">True</property>
440- <signal name="hide" handler="on_tc_browser_vbox_hide"/>
441- <child>
442- <object class="GtkScrolledWindow" id="tc_browser_window">
443- <property name="visible">True</property>
444- <property name="can_focus">True</property>
445- <property name="border_width">10</property>
446- <property name="hscrollbar_policy">never</property>
447- <property name="vscrollbar_policy">automatic</property>
448- <property name="shadow_type">in</property>
449- <child>
450- <placeholder/>
451- </child>
452- </object>
453- <packing>
454- <property name="position">0</property>
455- </packing>
456- </child>
457- <child>
458- <object class="GtkHButtonBox" id="hbuttonbox4">
459- <property name="visible">True</property>
460- <property name="layout_style">end</property>
461- <child>
462- <object class="GtkButton" id="tc_back_button">
463- <property name="label">gtk-go-back</property>
464- <property name="visible">True</property>
465- <property name="can_focus">True</property>
466- <property name="receives_default">True</property>
467- <property name="use_stock">True</property>
468- <signal name="clicked" handler="on_tc_back_button_clicked"/>
469- </object>
470- <packing>
471- <property name="expand">False</property>
472- <property name="fill">False</property>
473- <property name="position">0</property>
474- </packing>
475- </child>
476- </object>
477- <packing>
478- <property name="expand">False</property>
479+ <object class="GtkVBox" id="finish_vbox">
480+ <property name="visible">True</property>
481+ <property name="can_focus">False</property>
482+ <property name="spacing">10</property>
483+ <child>
484+ <object class="GtkLabel" id="finish_label">
485+ <property name="visible">True</property>
486+ <property name="can_focus">False</property>
487+ <property name="wrap">True</property>
488+ </object>
489+ <packing>
490+ <property name="expand">True</property>
491+ <property name="fill">True</property>
492+ <property name="position">0</property>
493+ </packing>
494+ </child>
495+ <child>
496+ <object class="GtkHButtonBox" id="hbuttonbox8">
497+ <property name="visible">True</property>
498+ <property name="can_focus">False</property>
499+ <property name="layout_style">end</property>
500+ <child>
501+ <object class="GtkButton" id="finish_close_button">
502+ <property name="label">gtk-close</property>
503+ <property name="use_action_appearance">False</property>
504+ <property name="visible">True</property>
505+ <property name="can_focus">True</property>
506+ <property name="receives_default">True</property>
507+ <property name="use_action_appearance">False</property>
508+ <property name="use_stock">True</property>
509+ <signal name="clicked" handler="on_close_clicked" swapped="no"/>
510+ </object>
511+ <packing>
512+ <property name="expand">False</property>
513+ <property name="fill">False</property>
514+ <property name="position">0</property>
515+ </packing>
516+ </child>
517+ </object>
518+ <packing>
519+ <property name="expand">False</property>
520+ <property name="fill">True</property>
521 <property name="position">1</property>
522 </packing>
523 </child>
524 </object>
525 <object class="GtkVBox" id="login_vbox">
526 <property name="visible">True</property>
527+ <property name="can_focus">False</property>
528 <property name="spacing">10</property>
529 <child>
530 <object class="GtkAlignment" id="alignment3">
531 <property name="visible">True</property>
532+ <property name="can_focus">False</property>
533 <property name="xscale">0</property>
534 <property name="yscale">0</property>
535 <child>
536 <object class="GtkVBox" id="login_details_vbox">
537 <property name="visible">True</property>
538+ <property name="can_focus">False</property>
539 <property name="spacing">5</property>
540 <child>
541 <placeholder/>
542@@ -482,26 +422,34 @@
543 </child>
544 </object>
545 <packing>
546+ <property name="expand">True</property>
547+ <property name="fill">True</property>
548 <property name="position">0</property>
549 </packing>
550 </child>
551 <child>
552 <object class="GtkHBox" id="hbox3">
553 <property name="visible">True</property>
554+ <property name="can_focus">False</property>
555 <property name="spacing">5</property>
556 <child>
557 <object class="GtkHButtonBox" id="hbuttonbox10">
558 <property name="visible">True</property>
559+ <property name="can_focus">False</property>
560 <property name="layout_style">start</property>
561 <child>
562 <object class="GtkLinkButton" id="forgotten_password_button">
563- <property name="label" translatable="yes">button</property>
564+ <property name="label" translatable="yes">forgot password button</property>
565+ <property name="use_action_appearance">False</property>
566 <property name="visible">True</property>
567 <property name="can_focus">True</property>
568 <property name="receives_default">True</property>
569 <property name="has_tooltip">True</property>
570+ <property name="use_action_appearance">False</property>
571 <property name="relief">none</property>
572- <signal name="clicked" handler="on_forgotten_password_button_clicked"/>
573+ <property name="uri">foo</property>
574+ <signal name="activate-link" handler="on_activate_link" swapped="no"/>
575+ <signal name="clicked" handler="on_forgotten_password_button_clicked" swapped="no"/>
576 </object>
577 <packing>
578 <property name="expand">False</property>
579@@ -513,20 +461,24 @@
580 </object>
581 <packing>
582 <property name="expand">False</property>
583+ <property name="fill">True</property>
584 <property name="position">0</property>
585 </packing>
586 </child>
587 <child>
588 <object class="GtkHButtonBox" id="hbuttonbox5">
589 <property name="visible">True</property>
590+ <property name="can_focus">False</property>
591 <property name="spacing">5</property>
592 <property name="layout_style">end</property>
593 <child>
594 <object class="GtkButton" id="login_cancel_button">
595 <property name="label">gtk-cancel</property>
596+ <property name="use_action_appearance">False</property>
597 <property name="visible">True</property>
598 <property name="can_focus">True</property>
599 <property name="receives_default">True</property>
600+ <property name="use_action_appearance">False</property>
601 <property name="use_stock">True</property>
602 </object>
603 <packing>
604@@ -538,11 +490,13 @@
605 <child>
606 <object class="GtkButton" id="login_back_button">
607 <property name="label">gtk-go-back</property>
608+ <property name="use_action_appearance">False</property>
609 <property name="visible">True</property>
610 <property name="can_focus">True</property>
611 <property name="receives_default">True</property>
612+ <property name="use_action_appearance">False</property>
613 <property name="use_stock">True</property>
614- <signal name="clicked" handler="on_login_back_button_clicked"/>
615+ <signal name="clicked" handler="on_login_back_button_clicked" swapped="no"/>
616 </object>
617 <packing>
618 <property name="expand">False</property>
619@@ -553,11 +507,13 @@
620 <child>
621 <object class="GtkButton" id="login_ok_button">
622 <property name="label">gtk-connect</property>
623+ <property name="use_action_appearance">False</property>
624 <property name="visible">True</property>
625 <property name="can_focus">True</property>
626 <property name="receives_default">True</property>
627+ <property name="use_action_appearance">False</property>
628 <property name="use_stock">True</property>
629- <signal name="clicked" handler="on_login_connect_button_clicked"/>
630+ <signal name="clicked" handler="on_login_connect_button_clicked" swapped="no"/>
631 </object>
632 <packing>
633 <property name="expand">False</property>
634@@ -568,6 +524,7 @@
635 </object>
636 <packing>
637 <property name="expand">False</property>
638+ <property name="fill">True</property>
639 <property name="pack_type">end</property>
640 <property name="position">1</property>
641 </packing>
642@@ -575,21 +532,33 @@
643 </object>
644 <packing>
645 <property name="expand">False</property>
646+ <property name="fill">True</property>
647 <property name="position">1</property>
648 </packing>
649 </child>
650 </object>
651+ <object class="GtkVBox" id="processing_vbox">
652+ <property name="visible">True</property>
653+ <property name="can_focus">False</property>
654+ <property name="spacing">10</property>
655+ <child>
656+ <placeholder/>
657+ </child>
658+ </object>
659 <object class="GtkVBox" id="request_password_token_vbox">
660 <property name="visible">True</property>
661+ <property name="can_focus">False</property>
662 <property name="spacing">10</property>
663 <child>
664 <object class="GtkAlignment" id="alignment2">
665 <property name="visible">True</property>
666+ <property name="can_focus">False</property>
667 <property name="xscale">0</property>
668 <property name="yscale">0</property>
669 <child>
670 <object class="GtkVBox" id="request_password_token_details_vbox">
671 <property name="visible">True</property>
672+ <property name="can_focus">False</property>
673 <property name="spacing">5</property>
674 <child>
675 <placeholder/>
676@@ -598,20 +567,25 @@
677 </child>
678 </object>
679 <packing>
680+ <property name="expand">True</property>
681+ <property name="fill">True</property>
682 <property name="position">0</property>
683 </packing>
684 </child>
685 <child>
686 <object class="GtkHButtonBox" id="hbuttonbox7">
687 <property name="visible">True</property>
688+ <property name="can_focus">False</property>
689 <property name="spacing">5</property>
690 <property name="layout_style">end</property>
691 <child>
692 <object class="GtkButton" id="request_password_token_cancel_button">
693 <property name="label">gtk-cancel</property>
694+ <property name="use_action_appearance">False</property>
695 <property name="visible">True</property>
696 <property name="can_focus">True</property>
697 <property name="receives_default">True</property>
698+ <property name="use_action_appearance">False</property>
699 <property name="use_stock">True</property>
700 </object>
701 <packing>
702@@ -623,11 +597,13 @@
703 <child>
704 <object class="GtkButton" id="request_password_token_back_button">
705 <property name="label">gtk-go-back</property>
706+ <property name="use_action_appearance">False</property>
707 <property name="visible">True</property>
708 <property name="can_focus">True</property>
709 <property name="receives_default">True</property>
710+ <property name="use_action_appearance">False</property>
711 <property name="use_stock">True</property>
712- <signal name="clicked" handler="on_request_password_token_back_button_clicked"/>
713+ <signal name="clicked" handler="on_request_password_token_back_button_clicked" swapped="no"/>
714 </object>
715 <packing>
716 <property name="expand">False</property>
717@@ -638,11 +614,13 @@
718 <child>
719 <object class="GtkButton" id="request_password_token_ok_button">
720 <property name="label">gtk-ok</property>
721+ <property name="use_action_appearance">False</property>
722 <property name="visible">True</property>
723 <property name="can_focus">True</property>
724 <property name="receives_default">True</property>
725+ <property name="use_action_appearance">False</property>
726 <property name="use_stock">True</property>
727- <signal name="clicked" handler="on_request_password_token_ok_button_clicked"/>
728+ <signal name="clicked" handler="on_request_password_token_ok_button_clicked" swapped="no"/>
729 </object>
730 <packing>
731 <property name="expand">False</property>
732@@ -653,35 +631,42 @@
733 </object>
734 <packing>
735 <property name="expand">False</property>
736+ <property name="fill">True</property>
737 <property name="position">1</property>
738 </packing>
739 </child>
740 </object>
741 <object class="GtkVBox" id="set_new_password_vbox">
742 <property name="visible">True</property>
743+ <property name="can_focus">False</property>
744 <property name="spacing">10</property>
745 <child>
746 <object class="GtkVBox" id="vbox2">
747 <property name="visible">True</property>
748+ <property name="can_focus">False</property>
749 <child>
750 <object class="GtkLabel" id="reset_password_help_label">
751 <property name="visible">True</property>
752+ <property name="can_focus">False</property>
753 <property name="label">label</property>
754 <property name="wrap">True</property>
755 </object>
756 <packing>
757 <property name="expand">False</property>
758+ <property name="fill">True</property>
759 <property name="position">0</property>
760 </packing>
761 </child>
762 <child>
763 <object class="GtkAlignment" id="alignment1">
764 <property name="visible">True</property>
765+ <property name="can_focus">False</property>
766 <property name="xscale">0</property>
767 <property name="yscale">0</property>
768 <child>
769 <object class="GtkVBox" id="set_new_password_details_vbox">
770 <property name="visible">True</property>
771+ <property name="can_focus">False</property>
772 <property name="spacing">5</property>
773 <child>
774 <placeholder/>
775@@ -696,25 +681,32 @@
776 </child>
777 </object>
778 <packing>
779+ <property name="expand">True</property>
780+ <property name="fill">True</property>
781 <property name="position">1</property>
782 </packing>
783 </child>
784 </object>
785 <packing>
786+ <property name="expand">True</property>
787+ <property name="fill">True</property>
788 <property name="position">0</property>
789 </packing>
790 </child>
791 <child>
792 <object class="GtkHButtonBox" id="hbuttonbox6">
793 <property name="visible">True</property>
794+ <property name="can_focus">False</property>
795 <property name="spacing">5</property>
796 <property name="layout_style">end</property>
797 <child>
798 <object class="GtkButton" id="set_new_password_cancel_button">
799 <property name="label">gtk-cancel</property>
800+ <property name="use_action_appearance">False</property>
801 <property name="visible">True</property>
802 <property name="can_focus">True</property>
803 <property name="receives_default">True</property>
804+ <property name="use_action_appearance">False</property>
805 <property name="use_stock">True</property>
806 </object>
807 <packing>
808@@ -726,11 +718,13 @@
809 <child>
810 <object class="GtkButton" id="set_new_password_ok_button">
811 <property name="label">gtk-ok</property>
812+ <property name="use_action_appearance">False</property>
813 <property name="visible">True</property>
814 <property name="can_focus">True</property>
815 <property name="receives_default">True</property>
816+ <property name="use_action_appearance">False</property>
817 <property name="use_stock">True</property>
818- <signal name="clicked" handler="on_set_new_password_ok_button_clicked"/>
819+ <signal name="clicked" handler="on_set_new_password_ok_button_clicked" swapped="no"/>
820 </object>
821 <packing>
822 <property name="expand">False</property>
823@@ -741,34 +735,104 @@
824 </object>
825 <packing>
826 <property name="expand">False</property>
827- <property name="position">1</property>
828- </packing>
829- </child>
830- </object>
831- <object class="GtkVBox" id="finish_vbox">
832- <property name="visible">True</property>
833+ <property name="fill">True</property>
834+ <property name="position">1</property>
835+ </packing>
836+ </child>
837+ </object>
838+ <object class="GtkVBox" id="tc_browser_vbox">
839+ <property name="visible">True</property>
840+ <property name="can_focus">False</property>
841+ <signal name="hide" handler="on_tc_browser_vbox_hide" swapped="no"/>
842+ <child>
843+ <object class="GtkScrolledWindow" id="tc_browser_window">
844+ <property name="visible">True</property>
845+ <property name="can_focus">True</property>
846+ <property name="border_width">10</property>
847+ <property name="hscrollbar_policy">never</property>
848+ <property name="shadow_type">in</property>
849+ <child>
850+ <placeholder/>
851+ </child>
852+ </object>
853+ <packing>
854+ <property name="expand">True</property>
855+ <property name="fill">True</property>
856+ <property name="position">0</property>
857+ </packing>
858+ </child>
859+ <child>
860+ <object class="GtkHButtonBox" id="hbuttonbox4">
861+ <property name="visible">True</property>
862+ <property name="can_focus">False</property>
863+ <property name="layout_style">end</property>
864+ <child>
865+ <object class="GtkButton" id="tc_back_button">
866+ <property name="label">gtk-go-back</property>
867+ <property name="use_action_appearance">False</property>
868+ <property name="visible">True</property>
869+ <property name="can_focus">True</property>
870+ <property name="receives_default">True</property>
871+ <property name="use_action_appearance">False</property>
872+ <property name="use_stock">True</property>
873+ <signal name="clicked" handler="on_tc_back_button_clicked" swapped="no"/>
874+ </object>
875+ <packing>
876+ <property name="expand">False</property>
877+ <property name="fill">False</property>
878+ <property name="position">0</property>
879+ </packing>
880+ </child>
881+ </object>
882+ <packing>
883+ <property name="expand">False</property>
884+ <property name="fill">True</property>
885+ <property name="position">1</property>
886+ </packing>
887+ </child>
888+ </object>
889+ <object class="GtkVBox" id="verify_email_vbox">
890+ <property name="visible">True</property>
891+ <property name="can_focus">False</property>
892 <property name="spacing">10</property>
893 <child>
894- <object class="GtkLabel" id="finish_label">
895+ <object class="GtkAlignment" id="alignment4">
896 <property name="visible">True</property>
897- <property name="wrap">True</property>
898+ <property name="can_focus">False</property>
899+ <property name="xscale">0</property>
900+ <property name="yscale">0</property>
901+ <child>
902+ <object class="GtkVBox" id="verify_email_details_vbox">
903+ <property name="visible">True</property>
904+ <property name="can_focus">False</property>
905+ <child>
906+ <placeholder/>
907+ </child>
908+ </object>
909+ </child>
910 </object>
911 <packing>
912+ <property name="expand">True</property>
913+ <property name="fill">True</property>
914 <property name="position">0</property>
915 </packing>
916 </child>
917 <child>
918- <object class="GtkHButtonBox" id="hbuttonbox8">
919+ <object class="GtkHButtonBox" id="hbuttonbox2">
920 <property name="visible">True</property>
921+ <property name="can_focus">False</property>
922+ <property name="spacing">5</property>
923 <property name="layout_style">end</property>
924 <child>
925- <object class="GtkButton" id="finish_close_button">
926- <property name="label">gtk-close</property>
927+ <object class="GtkButton" id="verify_token_button">
928+ <property name="label">gtk-ok</property>
929+ <property name="use_action_appearance">False</property>
930 <property name="visible">True</property>
931 <property name="can_focus">True</property>
932 <property name="receives_default">True</property>
933+ <property name="use_action_appearance">False</property>
934 <property name="use_stock">True</property>
935- <signal name="clicked" handler="on_close_clicked"/>
936+ <signal name="clicked" handler="on_verify_token_button_clicked" swapped="no"/>
937 </object>
938 <packing>
939 <property name="expand">False</property>
940@@ -779,8 +843,78 @@
941 </object>
942 <packing>
943 <property name="expand">False</property>
944+ <property name="fill">True</property>
945 <property name="position">1</property>
946 </packing>
947 </child>
948 </object>
949+ <object class="GtkWindow" id="window">
950+ <property name="can_focus">False</property>
951+ <property name="border_width">10</property>
952+ <property name="window_position">center</property>
953+ <signal name="delete-event" handler="on_close_clicked" swapped="no"/>
954+ <child>
955+ <object class="GtkVBox" id="window_vbox">
956+ <property name="visible">True</property>
957+ <property name="can_focus">False</property>
958+ <property name="spacing">5</property>
959+ <child>
960+ <object class="GtkLabel" id="header_label">
961+ <property name="visible">True</property>
962+ <property name="can_focus">False</property>
963+ <property name="xalign">0</property>
964+ <property name="label" translatable="yes">Header Label </property>
965+ <property name="wrap">True</property>
966+ </object>
967+ <packing>
968+ <property name="expand">False</property>
969+ <property name="fill">True</property>
970+ <property name="padding">5</property>
971+ <property name="position">0</property>
972+ </packing>
973+ </child>
974+ <child>
975+ <object class="GtkLabel" id="help_label">
976+ <property name="visible">True</property>
977+ <property name="can_focus">False</property>
978+ <property name="xalign">0</property>
979+ <property name="label" translatable="yes">help label</property>
980+ <property name="wrap">True</property>
981+ </object>
982+ <packing>
983+ <property name="expand">False</property>
984+ <property name="fill">True</property>
985+ <property name="position">1</property>
986+ </packing>
987+ </child>
988+ <child>
989+ <object class="GtkLabel" id="warning_label">
990+ <property name="visible">True</property>
991+ <property name="can_focus">False</property>
992+ <property name="xalign">0</property>
993+ <property name="label" translatable="yes">warning label</property>
994+ <property name="wrap">True</property>
995+ </object>
996+ <packing>
997+ <property name="expand">False</property>
998+ <property name="fill">True</property>
999+ <property name="position">2</property>
1000+ </packing>
1001+ </child>
1002+ <child>
1003+ <object class="GtkNotebook" id="content">
1004+ <property name="visible">True</property>
1005+ <property name="can_focus">True</property>
1006+ <property name="show_tabs">False</property>
1007+ <property name="show_border">False</property>
1008+ </object>
1009+ <packing>
1010+ <property name="expand">True</property>
1011+ <property name="fill">True</property>
1012+ <property name="position">3</property>
1013+ </packing>
1014+ </child>
1015+ </object>
1016+ </child>
1017+ </object>
1018 </interface>
1019
1020=== modified file 'run-tests'
1021--- run-tests 2012-02-01 19:19:32 +0000
1022+++ run-tests 2012-02-02 18:14:19 +0000
1023@@ -22,13 +22,6 @@
1024
1025 set -e
1026
1027-if [ "$1" == "-qt" ]; then
1028- USE_QT=1
1029- shift
1030-else
1031- USE_QT=0
1032-fi
1033-
1034 if [ $# -ne 0 ]; then
1035 # run specific module given by the caller
1036 MODULE="$@"
1037@@ -48,13 +41,18 @@
1038
1039 unset GTK_MODULES
1040
1041+echo "*** Running test suite for ""$MODULE"" ***"
1042+`which xvfb-run` u1trial --reactor=gi -p "$QT_TESTS_PATH, $GTK_TESTS_PATH" -i "test_windows.py" "$MODULE"
1043+rm -rf _trial_temp
1044+
1045+echo "*** Running GTK test suite ***"
1046+`which xvfb-run` u1trial --reactor=gi --gui "$GTK_TESTS_PATH"
1047+rm -rf _trial_temp
1048+
1049+echo "*** Running QT test suite ***"
1050 ./setup.py build
1051-echo "Running test suite for ""$MODULE"
1052-if [ "$USE_QT" -eq 0 ]; then
1053- `which xvfb-run` u1trial --ignore-paths "$QT_TESTS_PATH" -i "$WINDOWS_TESTS" "$MODULE"
1054-else
1055- `which xvfb-run` u1trial --ignore-paths "$GTK_TESTS_PATH" -i "$WINDOWS_TESTS" --reactor=qt4 --gui "$MODULE"
1056-fi
1057+USE_QT_MAINLOOP=True `which xvfb-run` u1trial --reactor=qt4 --gui "$QT_TESTS_PATH"
1058+rm -rf _trial_temp
1059+rm -rf build
1060+
1061 style_check
1062-rm -rf _trial_temp
1063-rm -rf build
1064
1065=== modified file 'ubuntu_sso/account.py'
1066--- ubuntu_sso/account.py 2012-01-26 13:25:13 +0000
1067+++ ubuntu_sso/account.py 2012-02-02 18:14:19 +0000
1068@@ -16,7 +16,11 @@
1069 #
1070 # You should have received a copy of the GNU General Public License along
1071 # with this program. If not, see <http://www.gnu.org/licenses/>.
1072-"""Single Sign On account management."""
1073+"""Single Sign On account management.
1074+
1075+All the methods in Account expect unicode as parameters.
1076+
1077+"""
1078
1079 import os
1080 import re
1081@@ -188,7 +192,7 @@
1082 try:
1083 credentials = yield restful_client.restcall(
1084 u"authentications.authenticate",
1085- token_name=token_name.decode("utf-8"))
1086+ token_name=token_name)
1087 except WebClientError:
1088 logger.exception('login failed with:')
1089 raise AuthenticationError()
1090@@ -218,7 +222,7 @@
1091 'email_token: %r, token_name: %r.',
1092 email, email_token, token_name)
1093 credentials = yield self.login(email=email, password=password,
1094- token_name=token_name.decode("utf-8"))
1095+ token_name=token_name)
1096 restful_client = restful.RestfulClient(self.service_url,
1097 oauth_credentials=credentials)
1098 result = yield restful_client.restcall(u"accounts.validate_email",
1099
1100=== modified file 'ubuntu_sso/gtk/__init__.py'
1101--- ubuntu_sso/gtk/__init__.py 2010-11-19 19:53:22 +0000
1102+++ ubuntu_sso/gtk/__init__.py 2012-02-02 18:14:19 +0000
1103@@ -1,8 +1,6 @@
1104 # -*- coding: utf-8 -*-
1105 #
1106-# Author: Natalia Bidart <natalia.bidart@canonical.com>
1107-#
1108-# Copyright 2009-2010 Canonical Ltd.
1109+# Copyright 2009-2012 Canonical Ltd.
1110 #
1111 # This program is free software: you can redistribute it and/or modify it
1112 # under the terms of the GNU General Public License version 3, as published
1113
1114=== modified file 'ubuntu_sso/gtk/gui.py'
1115--- ubuntu_sso/gtk/gui.py 2012-01-17 21:18:24 +0000
1116+++ ubuntu_sso/gtk/gui.py 2012-02-02 18:14:19 +0000
1117@@ -1,6 +1,6 @@
1118 # -*- coding: utf-8 -*-
1119 #
1120-# Copyright 2010 Canonical Ltd.
1121+# Copyright 2010-2012 Canonical Ltd.
1122 #
1123 # This program is free software: you can redistribute it and/or modify it
1124 # under the terms of the GNU General Public License version 3, as published
1125@@ -24,8 +24,10 @@
1126
1127 from functools import wraps
1128
1129-import gtk
1130-
1131+# pylint: disable=E0611,F0401
1132+from gi.repository import Gdk, Gtk
1133+from gi.repository.GdkX11 import X11Window
1134+# pylint: enable=E0611,F0401
1135 from twisted.internet import defer
1136
1137 from ubuntu_sso import (
1138@@ -33,7 +35,7 @@
1139 NO_OP,
1140 utils,
1141 )
1142-from ubuntu_sso.logger import setup_logging
1143+from ubuntu_sso.logger import setup_gui_logging
1144 from ubuntu_sso.utils.ui import (
1145 CAPTCHA_LOAD_ERROR,
1146 CAPTCHA_RELOAD_TOOLTIP,
1147@@ -72,7 +74,19 @@
1148 # pylint: disable=E1101
1149
1150
1151-logger = setup_logging('ubuntu_sso.gui')
1152+logger = setup_gui_logging('ubuntu_sso.gui.gtk')
1153+
1154+
1155+# pylint: disable=C0103
1156+def parse_color(color):
1157+ """Parse a string color into Gdk.Color."""
1158+ c = Gdk.RGBA()
1159+ result = c.parse(color)
1160+ if not result:
1161+ logger.warning('Could not parse color %r.', color)
1162+ return c
1163+# pylint: enable=C0103
1164+
1165
1166 # To be removed when Python bindings provide these constants
1167 # as per http://code.google.com/p/pywebkitgtk/issues/detail?id=44
1168@@ -92,8 +106,8 @@
1169
1170 DEFAULT_WIDTH = 30
1171 # To be replaced by values from the theme (LP: #616526)
1172-HELP_TEXT_COLOR = gtk.gdk.Color("#bfbfbf")
1173-WARNING_TEXT_COLOR = gtk.gdk.Color("red")
1174+HELP_TEXT_COLOR = parse_color("#bfbfbf")
1175+WARNING_TEXT_COLOR = parse_color("red")
1176
1177 USER_CANCELLATION = 10
1178 LOGIN_SUCCESS = REGISTRATION_SUCCESS = 0
1179@@ -111,9 +125,12 @@
1180 return inner
1181
1182
1183-class LabeledEntry(gtk.Entry):
1184+class LabeledEntry(Gtk.Entry):
1185 """An entry that displays the label within itself ina grey color."""
1186
1187+ # Use of super on an old style class
1188+ # pylint: disable=E1002
1189+
1190 def __init__(self, label, is_password=False, *args, **kwargs):
1191 self.label = label
1192 self.is_password = is_password
1193@@ -133,7 +150,8 @@
1194 """Clear text and restore text color."""
1195 self.set_text(self.get_text())
1196
1197- self.modify_text(gtk.STATE_NORMAL, None) # restore to theme's default
1198+ # restore to theme's default
1199+ self.override_color(Gtk.StateFlags.NORMAL, None)
1200
1201 if self.is_password:
1202 self.set_visibility(False)
1203@@ -146,7 +164,7 @@
1204 return
1205
1206 self.set_text(self.label)
1207- self.modify_text(gtk.STATE_NORMAL, HELP_TEXT_COLOR)
1208+ self.override_color(Gtk.StateFlags.NORMAL, HELP_TEXT_COLOR)
1209
1210 if self.is_password:
1211 self.set_visibility(True)
1212@@ -163,7 +181,7 @@
1213 def set_warning(self, warning_msg):
1214 """Display warning as secondary icon, set 'warning_msg' as tooltip."""
1215 self.warning = warning_msg
1216- self.set_property('secondary-icon-stock', gtk.STOCK_DIALOG_WARNING)
1217+ self.set_property('secondary-icon-stock', Gtk.STOCK_DIALOG_WARNING)
1218 self.set_property('secondary-icon-sensitive', True)
1219 self.set_property('secondary-icon-activatable', False)
1220 self.set_property('secondary-icon-tooltip-text', warning_msg)
1221@@ -185,8 +203,6 @@
1222 logger.debug('UbuntuSSOClientGUI: app_name %r, kwargs %r.',
1223 app_name, kwargs)
1224
1225- gtk.link_button_set_uri_hook(NO_OP)
1226-
1227 self._captcha_filename = tempfile.mktemp()
1228 self._captcha_id = None
1229 self._signals_receivers = {}
1230@@ -211,19 +227,18 @@
1231 self.user_password = None
1232
1233 ui_filename = get_data_file('gtk', 'ui.glade')
1234- builder = gtk.Builder()
1235+ builder = Gtk.Builder()
1236 builder.add_from_file(ui_filename)
1237 builder.connect_signals(self)
1238
1239 self.widgets = []
1240 self.warnings = []
1241 self.cancels = []
1242- self.labels = []
1243 for obj in builder.get_objects():
1244 name = getattr(obj, 'name', None)
1245- if name is None and isinstance(obj, gtk.Buildable):
1246+ if name is None and isinstance(obj, Gtk.Buildable):
1247 # work around bug lp:507739
1248- name = gtk.Buildable.get_name(obj)
1249+ name = Gtk.Buildable.get_name(obj)
1250 if name is None:
1251 logging.warn("%s has no name (??)", obj)
1252 else:
1253@@ -235,9 +250,6 @@
1254 if 'cancel_button' in name:
1255 obj.connect('clicked', self.on_close_clicked)
1256 self.cancels.append(obj)
1257- if 'label' in name:
1258- obj.connect('size-allocate', self.on_size_allocate)
1259- self.labels.append(obj)
1260
1261 self.entries = (u'name_entry', u'email1_entry', u'email2_entry',
1262 u'password1_entry', u'password2_entry',
1263@@ -297,7 +309,10 @@
1264 # still do everything as a standalone window. Also,
1265 # window_foreign_new may return None breaking set_transient_for.
1266 try:
1267- win = gtk.gdk.window_foreign_new(window_id)
1268+ display = Gdk.Display.get_default()
1269+ # this is not working, we need to create a XLib.window
1270+ # as a second parameter to foreign_new_for_display
1271+ win = X11Window.foreign_new_for_display(display, None)
1272 self.window.realize()
1273 self.window.window.set_transient_for(win)
1274 except: # pylint: disable=W0702
1275@@ -366,20 +381,21 @@
1276
1277 def _add_spinner_to_container(self, container, legend=None):
1278 """Add a spinner to 'container'."""
1279- spinner = gtk.Spinner()
1280+ spinner = Gtk.Spinner()
1281 spinner.start()
1282
1283- label = gtk.Label()
1284+ label = Gtk.Label()
1285 if legend:
1286 label.set_text(legend)
1287 else:
1288 label.set_text(LOADING)
1289
1290- hbox = gtk.HBox(spacing=5)
1291- hbox.pack_start(spinner, expand=False)
1292- hbox.pack_start(label, expand=False)
1293+ hbox = Gtk.HBox(spacing=5)
1294+ hbox.pack_start(spinner, expand=False, fill=True, padding=0)
1295+ hbox.pack_start(label, expand=False, fill=True, padding=0)
1296
1297- alignment = gtk.Alignment(xalign=0.5, yalign=0.5)
1298+ alignment = Gtk.Alignment(xalign=0.5, yalign=0.5,
1299+ xscale=0, yscale=0)
1300 alignment.add(hbox)
1301 alignment.show_all()
1302
1303@@ -394,7 +410,7 @@
1304 def _set_warning_message(self, widget, message):
1305 """Set 'message' as text for 'widget'."""
1306 widget.set_text(message)
1307- widget.modify_fg(gtk.STATE_NORMAL, WARNING_TEXT_COLOR)
1308+ widget.override_color(Gtk.StateFlags.NORMAL, WARNING_TEXT_COLOR)
1309 widget.show()
1310
1311 def _clear_warnings(self):
1312@@ -433,7 +449,7 @@
1313
1314 def _append_page(self, page):
1315 """Append 'page' to the 'window'."""
1316- self.content.append_page(page)
1317+ self.content.append_page(page, None)
1318
1319 def _set_header(self, header):
1320 """Set 'header' as the window title and header."""
1321@@ -472,8 +488,8 @@
1322 """Present a spinner to the user while the captcha is downloaded."""
1323 self.captcha_image.hide()
1324 self._add_spinner_to_container(self.captcha_loading)
1325- white = gtk.gdk.Color('white')
1326- self.captcha_loading.modify_bg(gtk.STATE_NORMAL, white)
1327+ self.captcha_loading.override_background_color(Gtk.StateFlags.NORMAL,
1328+ parse_color('white'))
1329 self.captcha_loading.show_all()
1330 self.join_ok_button.set_sensitive(False)
1331
1332@@ -490,20 +506,26 @@
1333 self.enter_details_vbox.header = JOIN_HEADER_LABEL % d
1334 self.enter_details_vbox.help_text = self.help_text
1335 self.enter_details_vbox.default_widget = self.join_ok_button
1336- self.join_ok_button.set_flags(gtk.CAN_DEFAULT)
1337+ self.join_ok_button.set_can_default(True)
1338
1339- self.enter_details_vbox.pack_start(self.name_entry, expand=False)
1340+ self.enter_details_vbox.pack_start(self.name_entry,
1341+ expand=False, fill=True, padding=0)
1342 self.enter_details_vbox.reorder_child(self.name_entry, 0)
1343 entry = self.captcha_solution_entry
1344- self.captcha_solution_vbox.pack_start(entry, expand=False)
1345+ self.captcha_solution_vbox.pack_start(entry,
1346+ expand=False, fill=True, padding=0)
1347 msg = CAPTCHA_RELOAD_TOOLTIP
1348 self.captcha_reload_button.set_tooltip_text(msg)
1349
1350- self.emails_hbox.pack_start(self.email1_entry, expand=False)
1351- self.emails_hbox.pack_start(self.email2_entry, expand=False)
1352+ self.emails_hbox.pack_start(self.email1_entry,
1353+ expand=False, fill=True, padding=0)
1354+ self.emails_hbox.pack_start(self.email2_entry,
1355+ expand=False, fill=True, padding=0)
1356
1357- self.passwords_hbox.pack_start(self.password1_entry, expand=False)
1358- self.passwords_hbox.pack_start(self.password2_entry, expand=False)
1359+ self.passwords_hbox.pack_start(self.password1_entry,
1360+ expand=False, fill=True, padding=0)
1361+ self.passwords_hbox.pack_start(self.password2_entry,
1362+ expand=False, fill=True, padding=0)
1363 help_msg = '<small>%s</small>' % PASSWORD_HELP
1364 self.password_help_label.set_markup(help_msg)
1365
1366@@ -519,7 +541,7 @@
1367 self.yes_to_tc_checkbutton.set_label(msg)
1368 self.tc_button.set_label(TC_BUTTON)
1369 else:
1370- self.tc_vbox.hide_all()
1371+ self.tc_vbox.hide()
1372 self.login_button.set_label(LOGIN_BUTTON_LABEL)
1373
1374 return self.enter_details_vbox
1375@@ -528,7 +550,7 @@
1376 """Build the Terms & Conditions page."""
1377 self.tc_browser_vbox.help_text = ''
1378 self.tc_browser_vbox.default_widget = self.tc_back_button
1379- self.tc_browser_vbox.default_widget.set_flags(gtk.CAN_DEFAULT)
1380+ self.tc_browser_vbox.default_widget.set_can_default(True)
1381 return self.tc_browser_vbox
1382
1383 def _build_processing_page(self):
1384@@ -541,17 +563,16 @@
1385 def _build_verify_email_page(self):
1386 """Build the verify email page."""
1387 self.verify_email_vbox.default_widget = self.verify_token_button
1388- self.verify_email_vbox.default_widget.set_flags(gtk.CAN_DEFAULT)
1389+ self.verify_email_vbox.default_widget.set_can_default(True)
1390
1391 self.verify_email_details_vbox.pack_start(self.email_token_entry,
1392- expand=False)
1393-
1394+ expand=False, fill=True, padding=0)
1395 return self.verify_email_vbox
1396
1397 def _build_finish_page(self):
1398 """Build the success page."""
1399 self.finish_vbox.default_widget = self.finish_close_button
1400- self.finish_vbox.default_widget.set_flags(gtk.CAN_DEFAULT)
1401+ self.finish_vbox.default_widget.set_can_default(True)
1402 self.finish_vbox.label = self.finish_label
1403 return self.finish_vbox
1404
1405@@ -561,11 +582,13 @@
1406 self.login_vbox.header = LOGIN_HEADER_LABEL % d
1407 self.login_vbox.help_text = CONNECT_HELP_LABEL % d
1408 self.login_vbox.default_widget = self.login_ok_button
1409- self.login_vbox.default_widget.set_flags(gtk.CAN_DEFAULT)
1410+ self.login_vbox.default_widget.set_can_default(True)
1411
1412- self.login_details_vbox.pack_start(self.login_email_entry)
1413+ self.login_details_vbox.pack_start(self.login_email_entry,
1414+ expand=True, fill=True, padding=0)
1415 self.login_details_vbox.reorder_child(self.login_email_entry, 0)
1416- self.login_details_vbox.pack_start(self.login_password_entry)
1417+ self.login_details_vbox.pack_start(self.login_password_entry,
1418+ expand=True, fill=True, padding=0)
1419 self.login_details_vbox.reorder_child(self.login_password_entry, 1)
1420
1421 msg = FORGOTTEN_PASSWORD_BUTTON
1422@@ -580,12 +603,12 @@
1423 text = REQUEST_PASSWORD_TOKEN_LABEL % {'app_name': self.app_label}
1424 self.request_password_token_vbox.help_text = text
1425 btn = self.request_password_token_ok_button
1426- btn.set_flags(gtk.CAN_DEFAULT)
1427+ btn.set_can_default(True)
1428 self.request_password_token_vbox.default_widget = btn
1429
1430 entry = self.reset_email_entry
1431 self.request_password_token_details_vbox.pack_start(entry,
1432- expand=False)
1433+ expand=False, fill=True, padding=0)
1434 cb = self.on_reset_email_entry_changed
1435 self.reset_email_entry.connect('changed', cb)
1436 self.request_password_token_ok_button.set_label(NEXT)
1437@@ -598,13 +621,14 @@
1438 self.set_new_password_vbox.header = RESET_PASSWORD
1439 self.set_new_password_vbox.help_text = SET_NEW_PASSWORD_LABEL
1440 btn = self.set_new_password_ok_button
1441- btn.set_flags(gtk.CAN_DEFAULT)
1442+ btn.set_can_default(True)
1443 self.set_new_password_vbox.default_widget = btn
1444
1445 for entry in (self.reset_code_entry,
1446 self.reset_password1_entry,
1447 self.reset_password2_entry):
1448- self.set_new_password_details_vbox.pack_start(entry, expand=False)
1449+ self.set_new_password_details_vbox.pack_start(entry,
1450+ expand=False, fill=True, padding=0)
1451
1452 cb = self.on_set_new_password_entries_changed
1453 self.reset_code_entry.connect('changed', cb)
1454@@ -645,6 +669,11 @@
1455
1456 # GTK callbacks
1457
1458+ def destroy(self):
1459+ """Destroy this UI."""
1460+ self.window.hide()
1461+ self.window.destroy()
1462+
1463 def connect(self, signal_name, handler, *args, **kwargs):
1464 """Connect 'signal_name' with 'handler'."""
1465 logger.debug('connect: signal %r, handler %r, args %r, kwargs, %r',
1466@@ -661,9 +690,9 @@
1467 self._done = True
1468 self._set_current_page(self.error_vbox)
1469
1470- def on_size_allocate(self, widget, allocation):
1471- """The widget can re rezised, embrase it!."""
1472- widget.set_size_request(allocation.width - 2, -1)
1473+ def on_activate_link(self, button):
1474+ """Do nothing, used for LinkButtons that are used as regular ones."""
1475+ return True
1476
1477 def on_close_clicked(self, *args, **kwargs):
1478 """Call self.close_callback if defined."""
1479@@ -678,8 +707,8 @@
1480 self.window.hide()
1481
1482 # process any pending events before callbacking with result
1483- while gtk.events_pending():
1484- gtk.main_iteration()
1485+ while Gtk.events_pending():
1486+ Gtk.main_iteration()
1487
1488 return_code = LOGIN_SUCCESS
1489 if not self._done:
1490@@ -751,8 +780,9 @@
1491 ' name %r, captcha_id %r and captcha_solution %r.', email1,
1492 name, self._captcha_id, captcha_solution)
1493 f = self.backend.register_user
1494- f(self.app_name, email1, password1, name,
1495- self._captcha_id, captcha_solution,
1496+ f(unicode(self.app_name), email1.decode('utf8'),
1497+ password1.decode('utf8'), name.decode('utf8'),
1498+ unicode(self._captcha_id), captcha_solution.decode('utf8'),
1499 reply_handler=NO_OP, error_handler=NO_OP)
1500
1501 def on_verify_token_button_clicked(self, *args, **kwargs):
1502@@ -902,8 +932,8 @@
1503 def on_tc_button_clicked(self, *args, **kwargs):
1504 """The T&C button was clicked, create the browser and load terms."""
1505 # delay the import of webkit to be able to build without it
1506- import webkit
1507- browser = webkit.WebView()
1508+ from gi.repository import WebKit # pylint: disable=E0611
1509+ browser = WebKit.WebView()
1510
1511 # The signal WebKitWebView::load-finished is deprecated and should not
1512 # be used in newly-written code. Use the "load-status" property
1513
1514=== modified file 'ubuntu_sso/gtk/main.py'
1515--- ubuntu_sso/gtk/main.py 2012-01-16 21:10:12 +0000
1516+++ ubuntu_sso/gtk/main.py 2012-02-02 18:14:19 +0000
1517@@ -18,7 +18,9 @@
1518
1519 import argparse
1520
1521-import gtk
1522+# pylint: disable=E0611
1523+from gi.repository import Gtk
1524+# pylint: enable=E0611
1525
1526 from ubuntu_sso.gtk.gui import UbuntuSSOClientGUI
1527
1528@@ -45,5 +47,5 @@
1529
1530 def main(**kwargs):
1531 """Start the GTK mainloop and open the main window."""
1532- UbuntuSSOClientGUI(close_callback=gtk.main_quit, **kwargs)
1533- gtk.main()
1534+ UbuntuSSOClientGUI(close_callback=Gtk.main_quit, **kwargs)
1535+ Gtk.main()
1536
1537=== modified file 'ubuntu_sso/gtk/tests/__init__.py'
1538--- ubuntu_sso/gtk/tests/__init__.py 2010-11-19 19:53:22 +0000
1539+++ ubuntu_sso/gtk/tests/__init__.py 2012-02-02 18:14:19 +0000
1540@@ -1,8 +1,6 @@
1541 # -*- coding: utf-8 -*-
1542 #
1543-# Author: Natalia Bidart <natalia.bidart@canonical.com>
1544-#
1545-# Copyright 2009 Canonical Ltd.
1546+# Copyright 2009-2012 Canonical Ltd.
1547 #
1548 # This program is free software: you can redistribute it and/or modify it
1549 # under the terms of the GNU General Public License version 3, as published
1550
1551=== modified file 'ubuntu_sso/gtk/tests/test_gui.py'
1552--- ubuntu_sso/gtk/tests/test_gui.py 2012-01-17 21:18:24 +0000
1553+++ ubuntu_sso/gtk/tests/test_gui.py 2012-02-02 18:14:19 +0000
1554@@ -21,8 +21,9 @@
1555
1556 from collections import defaultdict
1557
1558-import gtk
1559-import webkit
1560+# pylint: disable=E0611
1561+from gi.repository import Gdk, Gtk, WebKit
1562+# pylint: enable=E0611
1563
1564 from twisted.internet import defer
1565 from twisted.trial.unittest import TestCase
1566@@ -42,6 +43,9 @@
1567 # Instance of 'UbuntuSSOClientGUI' has no 'yyy' member
1568 # pylint: disable=E1101,E1103
1569
1570+# Use of super on an old style class
1571+# pylint: disable=E1002
1572+
1573
1574 class FakedSSOBackend(object):
1575 """Fake a SSO Backend."""
1576@@ -99,7 +103,7 @@
1577 self[prop_name] = newval
1578
1579
1580-class FakedEmbeddedBrowser(gtk.TextView):
1581+class FakedEmbeddedBrowser(Gtk.TextView):
1582 """Faked an embedded browser."""
1583
1584 def __init__(self):
1585@@ -156,6 +160,14 @@
1586 """Set _called to True."""
1587 self._called = (args, kwargs)
1588
1589+ def assert_color_equal(self, rgba_color, gdk_color):
1590+ """Check that 'rgba_color' is the same as 'gdk_color'."""
1591+ tmp = Gdk.RGBA()
1592+ assert tmp.parse(gdk_color.to_string())
1593+
1594+ msg = 'Text color must be "%s" (got "%s" instead).'
1595+ self.assertEqual(rgba_color, tmp, msg % (rgba_color, tmp))
1596+
1597
1598 class LabeledEntryTestCase(BasicTestCase):
1599 """Test suite for the labeled entry."""
1600@@ -168,9 +180,11 @@
1601 self.entry = gui.LabeledEntry(label=self.label)
1602
1603 # we need a window to be able to realize ourselves
1604- window = gtk.Window()
1605+ window = Gtk.Window()
1606 window.add(self.entry)
1607 window.show_all()
1608+ self.addCleanup(window.hide)
1609+ self.addCleanup(window.destroy)
1610
1611 def grab_focus(self, focus_in=True):
1612 """Grab focus on widget, if None use self.entry."""
1613@@ -188,10 +202,9 @@
1614 self.assertEqual(expected, actual, msg % (expected, actual))
1615
1616 # text color is correct
1617- msg = 'Text color must be "%s" (got "%s" instead).'
1618 expected = gui.HELP_TEXT_COLOR
1619- actual = self.entry.style.text[gtk.STATE_NORMAL]
1620- self.assertEqual(expected, actual, msg % (expected, actual))
1621+ actual = self.entry.get_style().text[Gtk.StateFlags.NORMAL]
1622+ self.assert_color_equal(expected, actual)
1623
1624 def test_initial_text(self):
1625 """Entry have the correct text at startup."""
1626@@ -218,11 +231,11 @@
1627
1628 def test_text_defaults_to_theme_color_when_focus_in(self):
1629 """Entry restore its text color when focused in."""
1630- self.patch(self.entry, 'modify_text', self._set_called)
1631+ self.patch(self.entry, 'override_color', self._set_called)
1632
1633 self.grab_focus()
1634
1635- self.assertEqual(((gtk.STATE_NORMAL, None), {}), self._called,
1636+ self.assertEqual(((Gtk.StateFlags.NORMAL, None), {}), self._called,
1637 'Entry text color must be restore on focus in.')
1638
1639 def test_refill_entry_on_focus_out_if_no_input(self):
1640@@ -305,7 +318,7 @@
1641 self.entry.set_warning(msg)
1642 self.assertEqual(self.entry.warning, msg)
1643 self.assertEqual(self.entry.get_property('secondary-icon-stock'),
1644- gtk.STOCK_DIALOG_WARNING)
1645+ Gtk.STOCK_DIALOG_WARNING)
1646 self.assertEqual(self.entry.get_property('secondary-icon-sensitive'),
1647 True)
1648 self.assertEqual(self.entry.get_property('secondary-icon-activatable'),
1649@@ -371,6 +384,7 @@
1650 'tc_browser', 'login', 'request_password_token',
1651 'set_new_password')
1652 self.ui = self.gui_class(**self.kwargs)
1653+ self.addCleanup(self.ui.destroy)
1654 self.error = {'message': UNKNOWN_ERROR}
1655
1656 def assert_entries_are_packed_to_ui(self, container_name, entries):
1657@@ -405,8 +419,8 @@
1658
1659 # content color is correct
1660 expected = gui.WARNING_TEXT_COLOR
1661- actual = label.style.fg[gtk.STATE_NORMAL]
1662- self.assertEqual(expected, actual) # until realized this will fail
1663+ actual = label.get_style().fg[Gtk.StateFlags.NORMAL]
1664+ self.assert_color_equal(expected, actual)
1665
1666 def assert_correct_entry_warning(self, entry, message):
1667 """Check that a warning is shown displaying 'message'."""
1668@@ -533,16 +547,6 @@
1669 entry = getattr(self.ui, name)
1670 self.assertTrue(entry.get_activates_default(), msg % (name,))
1671
1672- def test_label_size_allocated_is_connected(self):
1673- """Labels have the size-allocate signal connected."""
1674- msg = 'Label %r must have size-allocate connected.'
1675- labels = [i for i in self.ui.widgets if 'label' in i]
1676- for label in labels:
1677- widget = getattr(self.ui, label)
1678- widget.emit('size-allocate', gtk.gdk.Rectangle(1, 2, 3, 4))
1679- self.assertEqual(widget.get_size_request(), (3 - 2, -1),
1680- msg % (label,))
1681-
1682 def test_password_fields_are_password(self):
1683 """Password fields have the is_password flag set."""
1684 msg = '"%s" should be a password LabeledEntry instance.'
1685@@ -573,28 +577,6 @@
1686 """Main window has the proper icon."""
1687 self.assertEqual('ubuntu-logo', self.ui.window.get_icon_name())
1688
1689- def test_transient_window_is_none_if_window_id_is_zero(self):
1690- """The transient window is correct."""
1691- self.patch(gtk.gdk, 'window_foreign_new', self._set_called)
1692- self.gui_class(window_id=0, **self.kwargs)
1693- self.assertFalse(self._called, 'set_transient_for must not be called.')
1694-
1695- def test_transient_window_is_correct(self):
1696- """The transient window is correct."""
1697- xid = 5
1698- self.patch(gtk.gdk, 'window_foreign_new', self._set_called)
1699- self.gui_class(window_id=xid, **self.kwargs)
1700- self.assertTrue(self.memento.check(logging.ERROR, 'set_transient_for'))
1701- self.assertTrue(self.memento.check(logging.ERROR, str(xid)))
1702- self.assertEqual(self._called, ((xid,), {}))
1703-
1704- def test_transient_window_accepts_negative_id(self):
1705- """The transient window accepts a negative window id."""
1706- xid = -5
1707- self.patch(gtk.gdk, 'window_foreign_new', self._set_called)
1708- self.gui_class(window_id=xid, **self.kwargs)
1709- self.assertEqual(self._called, ((xid,), {}))
1710-
1711 def test_finish_success_shows_success_page(self):
1712 """When calling 'finish_success' the success page is shown."""
1713 self.ui.finish_success()
1714@@ -611,6 +593,42 @@
1715 self.assertEqual(gui.ERROR, self.ui.finish_vbox.label.get_text())
1716
1717
1718+class SetTransientForTestCase(UbuntuSSOClientTestCase):
1719+ """Test suite for setting the window as transient for another one."""
1720+
1721+ def test_transient_window_is_none_if_window_id_is_zero(self):
1722+ """The transient window is correct."""
1723+ self.patch(gui.X11Window, 'foreign_new_for_display', self._set_called)
1724+ ui = self.gui_class(window_id=0, **self.kwargs)
1725+ self.addCleanup(ui.destroy)
1726+
1727+ self.assertFalse(self._called, 'set_transient_for must not be called.')
1728+
1729+ def test_transient_window_is_correct(self):
1730+ """The transient window is correct."""
1731+ xid = 5
1732+ self.patch(gui.X11Window, 'foreign_new_for_display', self._set_called)
1733+ ui = self.gui_class(window_id=xid, **self.kwargs)
1734+ self.addCleanup(ui.destroy)
1735+
1736+ self.assertTrue(self.memento.check(logging.ERROR, 'set_transient_for'))
1737+ self.assertTrue(self.memento.check(logging.ERROR, str(xid)))
1738+ self.assertEqual(self._called, ((xid,), {}))
1739+
1740+ def test_transient_window_accepts_negative_id(self):
1741+ """The transient window accepts a negative window id."""
1742+ xid = -5
1743+ self.patch(gui.X11Window, 'foreign_new_for_display', self._set_called)
1744+ ui = self.gui_class(window_id=xid, **self.kwargs)
1745+ self.addCleanup(ui.destroy)
1746+
1747+ self.assertEqual(self._called, ((xid,), {}))
1748+
1749+
1750+SetTransientForTestCase.skip = "Apparently, so far we can't use XLib " \
1751+"dynamic bindings to complete the call to X11Window.foreign_new_for_display."
1752+
1753+
1754 class EnterDetailsTestCase(UbuntuSSOClientTestCase):
1755 """Test suite for the user registration (enter details page)."""
1756
1757@@ -695,8 +713,8 @@
1758 'processing_vbox must have two children.')
1759
1760 spinner, label = box.get_children()
1761- self.assertIsInstance(spinner, gtk.Spinner)
1762- self.assertIsInstance(label, gtk.Label)
1763+ self.assertIsInstance(spinner, Gtk.Spinner)
1764+ self.assertIsInstance(label, Gtk.Label)
1765
1766 self.assertTrue(spinner.get_property('visible'),
1767 'the processing spinner should be visible.')
1768@@ -715,6 +733,8 @@
1769 def test_captcha_filename_is_different_each_time(self):
1770 """The captcha image is different each time."""
1771 ui = self.gui_class(**self.kwargs)
1772+ self.addCleanup(ui.destroy)
1773+
1774 self.assertNotEqual(self.ui._captcha_filename, ui._captcha_filename)
1775
1776 def test_captcha_image_is_removed_when_exiting(self):
1777@@ -736,8 +756,8 @@
1778 'captcha_loading must have two children.')
1779
1780 spinner, label = box.get_children()
1781- self.assertIsInstance(spinner, gtk.Spinner)
1782- self.assertIsInstance(label, gtk.Label)
1783+ self.assertIsInstance(spinner, Gtk.Spinner)
1784+ self.assertIsInstance(label, Gtk.Label)
1785
1786 self.assertTrue(spinner.get_property('visible'),
1787 'the captcha_loading spinner should be visible.')
1788@@ -872,7 +892,7 @@
1789 @defer.inlineCallbacks
1790 def setUp(self):
1791 yield super(TermsAndConditionsBrowserTestCase, self).setUp()
1792- self.patch(webkit, 'WebView', FakedEmbeddedBrowser)
1793+ self.patch(WebKit, 'WebView', FakedEmbeddedBrowser)
1794
1795 self.ui.tc_button.clicked()
1796 self.addCleanup(self.ui.tc_browser_vbox.hide)
1797@@ -968,10 +988,10 @@
1798
1799 def test_navigation_requested_succeeds_for_no_clicking(self):
1800 """The navigation request succeeds when user hasn't clicked a link."""
1801- action = webkit.WebNavigationAction()
1802+ action = WebKit.WebNavigationAction()
1803 action.set_reason(gui.WEBKIT_WEB_NAVIGATION_REASON_OTHER)
1804
1805- decision = webkit.WebPolicyDecision()
1806+ decision = WebKit.WebPolicyDecision()
1807 decision.use = self._set_called
1808
1809 kwargs = dict(browser=self.browser, frame=None, request=None,
1810@@ -981,10 +1001,10 @@
1811
1812 def test_navigation_requested_ignores_clicked_links(self):
1813 """The navigation request is ignored if a link was clicked."""
1814- action = webkit.WebNavigationAction()
1815+ action = WebKit.WebNavigationAction()
1816 action.set_reason(gui.WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED)
1817
1818- decision = webkit.WebPolicyDecision()
1819+ decision = WebKit.WebPolicyDecision()
1820 decision.ignore = self._set_called
1821
1822 self.patch(gui.webbrowser, 'open', lambda *args, **kwargs: None)
1823@@ -1007,11 +1027,11 @@
1824
1825 """
1826 url = 'http://something.com/yadda'
1827- action = webkit.WebNavigationAction()
1828+ action = WebKit.WebNavigationAction()
1829 action.set_reason(gui.WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED)
1830 action.set_original_uri(url)
1831
1832- decision = webkit.WebPolicyDecision()
1833+ decision = WebKit.WebPolicyDecision()
1834 decision.ignore = gui.NO_OP
1835
1836 self.patch(gui.webbrowser, 'open', self._set_called)
1837@@ -2081,7 +2101,7 @@
1838
1839 def test_closing_main_window(self):
1840 """When closing the main window, USER_CANCELLATION is called."""
1841- self.ui.window.emit('delete-event', gtk.gdk.Event(gtk.gdk.DELETE))
1842+ self.ui.window.emit('delete-event', Gdk.Event())
1843 self.assertEqual(self._called, ((gui.USER_CANCELLATION,), {}))
1844
1845 def test_every_cancel_calls_proper_callback(self):
1846
1847=== modified file 'ubuntu_sso/gtk/tests/test_main.py'
1848--- ubuntu_sso/gtk/tests/test_main.py 2012-01-18 12:37:00 +0000
1849+++ ubuntu_sso/gtk/tests/test_main.py 2012-02-02 18:14:19 +0000
1850@@ -73,14 +73,14 @@
1851 called = []
1852 self.patch(main, 'UbuntuSSOClientGUI',
1853 lambda **kw: called.append(('GUI', kw)))
1854- self.patch(main.gtk, 'main',
1855- lambda: called.append('gtk.main'))
1856+ self.patch(main.Gtk, 'main',
1857+ lambda: called.append('main'))
1858
1859 kwargs = dict(foo='foo', bar='bar', baz='yadda', yadda=0)
1860 main.main(**kwargs)
1861
1862- kwargs['close_callback'] = main.gtk.main_quit
1863- self.assertEqual(called, [('GUI', kwargs), 'gtk.main'])
1864+ kwargs['close_callback'] = main.Gtk.main_quit
1865+ self.assertEqual(called, [('GUI', kwargs), 'main'])
1866
1867 def test_parse_args_app_name_is_required(self):
1868 """If no app_name, show help and exit."""
1869
1870=== modified file 'ubuntu_sso/keyring/__init__.py'
1871--- ubuntu_sso/keyring/__init__.py 2011-10-17 18:24:55 +0000
1872+++ ubuntu_sso/keyring/__init__.py 2012-02-02 18:14:19 +0000
1873@@ -29,8 +29,8 @@
1874
1875 logger = setup_logging("ubuntu_sso.keyring")
1876
1877-TOKEN_SEPARATOR = ' @ '
1878-SEPARATOR_REPLACEMENT = ' AT '
1879+TOKEN_SEPARATOR = u' @ '
1880+SEPARATOR_REPLACEMENT = u' AT '
1881
1882 U1_APP_NAME = "Ubuntu One"
1883 U1_KEY_NAME = "UbuntuOne token for https://ubuntuone.com"
1884@@ -41,26 +41,34 @@
1885
1886
1887 def gethostname():
1888- """Get the hostname, encoded in utf-8."""
1889+ """Get the hostname, return the name as unicode."""
1890 sys_encoding = sys.getfilesystemencoding()
1891 hostname = socket.gethostname().decode(sys_encoding)
1892- return hostname.encode("utf-8")
1893+ return hostname
1894
1895
1896 def get_old_token_name(app_name):
1897- """Build the token name (old style)."""
1898+ """Build the token name (old style). Return an unicode."""
1899 quoted_app_name = urllib.quote(app_name)
1900 computer_name = gethostname()
1901 quoted_computer_name = urllib.quote(computer_name)
1902- return "%s - %s" % (quoted_app_name, quoted_computer_name)
1903+
1904+ assert isinstance(computer_name, unicode)
1905+ assert isinstance(quoted_computer_name, unicode)
1906+
1907+ return u"%s - %s" % (quoted_app_name, quoted_computer_name)
1908
1909
1910 def get_token_name(app_name):
1911- """Build the token name."""
1912- computer_name = gethostname().decode("utf-8")
1913+ """Build the token name.. Return an unicode."""
1914+ computer_name = gethostname()
1915 computer_name = computer_name.replace(TOKEN_SEPARATOR,
1916 SEPARATOR_REPLACEMENT)
1917- return TOKEN_SEPARATOR.join((app_name, computer_name)).encode("utf-8")
1918+
1919+ assert isinstance(computer_name, unicode)
1920+ assert isinstance(computer_name, unicode)
1921+
1922+ return TOKEN_SEPARATOR.join((app_name, computer_name))
1923
1924
1925 @inlineCallbacks
1926
1927=== modified file 'ubuntu_sso/keyring/tests/test_common.py'
1928--- ubuntu_sso/keyring/tests/test_common.py 2011-10-28 10:41:18 +0000
1929+++ ubuntu_sso/keyring/tests/test_common.py 2012-02-02 18:14:19 +0000
1930@@ -38,10 +38,9 @@
1931 """The fs encoding is used to decode the name returned by socket."""
1932 fake_hostname = u"Привет-ПК"
1933 hostname_koi8r = fake_hostname.encode("koi8-r")
1934- hostname_utf8 = fake_hostname.encode("utf-8")
1935 self.patch(keyring.socket, "gethostname", lambda: hostname_koi8r)
1936 self.patch(keyring.sys, "getfilesystemencoding", lambda: "koi8-r")
1937- self.assertEqual(keyring.gethostname(), hostname_utf8)
1938+ self.assertEqual(keyring.gethostname(), fake_hostname)
1939
1940
1941 class TestTokenNameBuilder(TestCase):
1942@@ -78,12 +77,12 @@
1943 """A token name with unicode in the app name."""
1944 sample_app_name = u"Ubuntu 四百六十九"
1945 sample_hostname = "Darkstar"
1946- expected_result = u"Ubuntu 四百六十九 @ Darkstar".encode("utf-8")
1947+ expected_result = u"Ubuntu 四百六十九 @ Darkstar"
1948 self.check_build(sample_app_name, sample_hostname, expected_result)
1949
1950 def test_get_utf8_hostname_token_name(self):
1951 """A token name with utf8 in the host name."""
1952 sample_app_name = u"Ubuntu Eleven"
1953- sample_hostname = u"Привет-ПК".encode("utf-8")
1954- expected_result = u"Ubuntu Eleven @ Привет-ПК".encode("utf-8")
1955+ sample_hostname = u"Привет-ПК"
1956+ expected_result = u"Ubuntu Eleven @ Привет-ПК"
1957 self.check_build(sample_app_name, sample_hostname, expected_result)
1958
1959=== modified file 'ubuntu_sso/keyring/tests/test_linux.py'
1960--- ubuntu_sso/keyring/tests/test_linux.py 2011-10-28 10:41:18 +0000
1961+++ ubuntu_sso/keyring/tests/test_linux.py 2012-02-02 18:14:19 +0000
1962@@ -121,7 +121,7 @@
1963 self.mock_service = None
1964 self.service = self.patch(keyring, "SecretService",
1965 self.get_mock_service)
1966- self.patch(common_keyring, "gethostname", lambda: "darkstar")
1967+ self.patch(common_keyring, "gethostname", lambda: u"darkstar")
1968
1969 def get_mock_service(self):
1970 """Create only one instance of the mock service per test."""
1971
1972=== modified file 'ubuntu_sso/logger.py'
1973--- ubuntu_sso/logger.py 2012-01-10 18:25:01 +0000
1974+++ ubuntu_sso/logger.py 2012-02-02 18:14:19 +0000
1975@@ -42,20 +42,31 @@
1976 LOG_LEVEL = logging.INFO
1977
1978 LOG_PATH = os.path.join(LOGFOLDER, 'sso-client.log')
1979+FMT = "%(asctime)s:%(msecs)s - %(name)s - %(levelname)s - %(message)s"
1980+
1981 MAIN_HANDLER = RotatingFileHandler(unicode_path(LOG_PATH),
1982 maxBytes=1048576,
1983 backupCount=5)
1984 MAIN_HANDLER.setLevel(LOG_LEVEL)
1985-FMT = "%(asctime)s:%(msecs)s - %(name)s - %(levelname)s - %(message)s"
1986 MAIN_HANDLER.setFormatter(logging.Formatter(fmt=FMT))
1987
1988-
1989-def setup_logging(log_domain):
1990+GUI_LOG_PATH = os.path.join(LOGFOLDER, 'sso-client-gui.log')
1991+GUI_HANDLER = RotatingFileHandler(unicode_path(GUI_LOG_PATH),
1992+ maxBytes=1048576,
1993+ backupCount=5)
1994+GUI_HANDLER.setLevel(LOG_LEVEL)
1995+GUI_HANDLER.setFormatter(logging.Formatter(fmt=FMT))
1996+
1997+
1998+def setup_logging(log_domain, handler=None):
1999 """Create basic logger to set filename."""
2000+ if handler is None:
2001+ handler = MAIN_HANDLER
2002+
2003 logger = logging.getLogger(log_domain)
2004 logger.propagate = False
2005 logger.setLevel(LOG_LEVEL)
2006- logger.addHandler(MAIN_HANDLER)
2007+ logger.addHandler(handler)
2008 if os.environ.get('DEBUG'):
2009 debug_handler = logging.StreamHandler(sys.stderr)
2010 debug_handler.setFormatter(logging.Formatter(fmt=FMT))
2011@@ -64,6 +75,11 @@
2012 return logger
2013
2014
2015+def setup_gui_logging(log_domain):
2016+ """Create basic logger to set filename."""
2017+ return setup_logging(log_domain, GUI_HANDLER)
2018+
2019+
2020 def log_call(log_func):
2021 """Decorator to log, using 'log_func', calls to functions."""
2022
2023
2024=== modified file 'ubuntu_sso/main/__init__.py'
2025--- ubuntu_sso/main/__init__.py 2012-01-20 18:08:04 +0000
2026+++ ubuntu_sso/main/__init__.py 2012-02-02 18:14:19 +0000
2027@@ -486,8 +486,8 @@
2028 def main():
2029 """Run the backend service."""
2030 logger.info('Setting up Ubuntu SSO service.')
2031- source.start_setup()
2032+ loop = source.start_setup()
2033 service = UbuntuSSOService()
2034 d = service.start()
2035- d.addBoth(source.finish_setup)
2036+ d.addBoth(source.finish_setup, loop)
2037 source.main()
2038
2039=== added file 'ubuntu_sso/main/glib.py'
2040--- ubuntu_sso/main/glib.py 1970-01-01 00:00:00 +0000
2041+++ ubuntu_sso/main/glib.py 2012-02-02 18:14:19 +0000
2042@@ -0,0 +1,45 @@
2043+# -*- coding: utf-8 -*-
2044+#
2045+# Copyright 2012 Canonical Ltd.
2046+#
2047+# This program is free software: you can redistribute it and/or modify it
2048+# under the terms of the GNU General Public License version 3, as published
2049+# by the Free Software Foundation.
2050+#
2051+# This program is distributed in the hope that it will be useful, but
2052+# WITHOUT ANY WARRANTY; without even the implied warranties of
2053+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2054+# PURPOSE. See the GNU General Public License for more details.
2055+#
2056+# You should have received a copy of the GNU General Public License along
2057+# with this program. If not, see <http://www.gnu.org/licenses/>.
2058+
2059+"""GLib main loop runner."""
2060+
2061+# pylint: disable=E0611,F0401
2062+
2063+from gi.repository import GLib, Gdk, Gtk
2064+
2065+
2066+def timeout_func(*a, **kw):
2067+ """Delay import of dynamic bindings to avoid crashes."""
2068+ return GLib.timeout_add(*a, **kw)
2069+
2070+
2071+def shutdown_func(*a, **kw):
2072+ """Delay import of dynamic bindings to avoid crashes."""
2073+ Gtk.main_quit()
2074+
2075+
2076+def run_func(loop):
2077+ """Delay import of dynamic bindings to avoid crashes."""
2078+ Gtk.main()
2079+
2080+
2081+def start_setup():
2082+ """Setup the env to run the service."""
2083+ import dbus.mainloop.glib # pylint: disable=W0621
2084+
2085+ dbus.mainloop.glib.threads_init()
2086+ Gdk.threads_init()
2087+ dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
2088
2089=== modified file 'ubuntu_sso/main/linux.py'
2090--- ubuntu_sso/main/linux.py 2012-01-26 17:21:32 +0000
2091+++ ubuntu_sso/main/linux.py 2012-02-02 18:14:19 +0000
2092@@ -25,12 +25,12 @@
2093
2094 """
2095
2096+import os
2097+import signal
2098 import threading
2099-import signal
2100
2101-import dbus.mainloop.glib
2102+import dbus
2103 import dbus.service
2104-import gtk
2105
2106 from twisted.internet import defer
2107
2108@@ -68,8 +68,8 @@
2109 class SSOLoginProxy(dbus.service.Object):
2110 """Login thru the Single Sign On service."""
2111
2112- # Operator not preceded by a space (fails with dbus decorators)
2113- # pylint: disable=C0322
2114+ # Use of super on an old style class
2115+ # pylint: disable=E1002
2116
2117 def __init__(self, root, *args, **kwargs):
2118 """Initiate the Login object."""
2119@@ -77,6 +77,9 @@
2120 super(SSOLoginProxy, self).__init__(*args, **kwargs)
2121 self.root = root
2122
2123+ # Operator not preceded by a space (fails with dbus decorators)
2124+ # pylint: disable=C0322
2125+
2126 # generate_capcha signals
2127 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
2128 def CaptchaGenerated(self, app_name, result):
2129@@ -202,6 +205,9 @@
2130
2131 """
2132
2133+ # Use of super on an old style class
2134+ # pylint: disable=E1002
2135+
2136 def __init__(self, root, *args, **kwargs):
2137 # pylint: disable=E1002
2138 super(CredentialsManagementProxy, self).__init__(*args, **kwargs)
2139@@ -433,39 +439,38 @@
2140 return defer.succeed(result)
2141
2142
2143+if os.environ.get('USE_QT_MAINLOOP'):
2144+ from ubuntu_sso.main import qt
2145+ source = qt
2146+else:
2147+ from ubuntu_sso.main import glib
2148+ source = glib
2149+
2150+
2151+timeout_func = source.timeout_func
2152+shutdown_func = source.shutdown_func
2153+start_setup = source.start_setup
2154+
2155+
2156 def sighup_handler(*a, **kw):
2157 """Stop the service."""
2158 # This handler may be called in any thread, so is not thread safe.
2159 # See the link below for info:
2160 # www.listware.net/201004/gtk-devel-list/115067-unix-signals-in-glib.html
2161- #
2162- # gtk.main_quit and the logger methods are safe to be called from any
2163- # thread. Just don't call other random stuff here.
2164 logger.info("Stoping Ubuntu SSO service since SIGHUP was received.")
2165- gtk.main_quit()
2166+ shutdown_func()
2167
2168
2169 class AlreadyStartedError(Exception):
2170 """The backend service has already been started."""
2171
2172
2173-timeout_func = gtk.timeout_add
2174-shutdown_func = gtk.main_quit
2175-
2176-
2177-def start_setup():
2178- """Setup the env to run the service."""
2179- dbus.mainloop.glib.threads_init()
2180- gtk.gdk.threads_init()
2181- dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
2182-
2183-
2184-def finish_setup(result):
2185+def finish_setup(result, loop):
2186 """Run the specific mainloop only if no failure ocurred."""
2187 if result is None: # no failure ocurred, start the service
2188 logger.debug("Hooking up SIGHUP with handler %r.", sighup_handler)
2189 signal.signal(signal.SIGHUP, sighup_handler)
2190- gtk.main()
2191+ source.run_func(loop)
2192
2193
2194 def main():
2195
2196=== added file 'ubuntu_sso/main/qt.py'
2197--- ubuntu_sso/main/qt.py 1970-01-01 00:00:00 +0000
2198+++ ubuntu_sso/main/qt.py 2012-02-02 18:14:19 +0000
2199@@ -0,0 +1,49 @@
2200+# -*- coding: utf-8 -*-
2201+#
2202+# Copyright 2012 Canonical Ltd.
2203+#
2204+# This program is free software: you can redistribute it and/or modify it
2205+# under the terms of the GNU General Public License version 3, as published
2206+# by the Free Software Foundation.
2207+#
2208+# This program is distributed in the hope that it will be useful, but
2209+# WITHOUT ANY WARRANTY; without even the implied warranties of
2210+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2211+# PURPOSE. See the GNU General Public License for more details.
2212+#
2213+# You should have received a copy of the GNU General Public License along
2214+# with this program. If not, see <http://www.gnu.org/licenses/>.
2215+
2216+"""Qt main loop runner."""
2217+
2218+# pylint: disable=E0611,F0401
2219+
2220+import sys
2221+
2222+from PyQt4 import QtCore
2223+
2224+
2225+def timeout_func(*a, **kw):
2226+ """Delay import of dynamic bindings to avoid crashes."""
2227+ # use a QTimer to simulate a looping call
2228+
2229+
2230+def shutdown_func(*a, **kw):
2231+ """Delay import of dynamic bindings to avoid crashes."""
2232+ QtCore.QCoreApplication.instance().exit()
2233+
2234+
2235+def start_setup():
2236+ """Setup the env to run the service."""
2237+ import dbus.mainloop.qt # pylint: disable=W0621
2238+
2239+ # this has to be created before calling dbus.mainloop.qt.DBusQtMainLoop
2240+ loop = QtCore.QCoreApplication(sys.argv)
2241+ dbus.mainloop.qt.DBusQtMainLoop(set_as_default=True)
2242+
2243+ return loop
2244+
2245+
2246+def run_func(loop):
2247+ """Delay import of dynamic bindings to avoid crashes."""
2248+ loop.exec_()
2249
2250=== modified file 'ubuntu_sso/main/windows.py'
2251--- ubuntu_sso/main/windows.py 2012-01-10 20:47:06 +0000
2252+++ ubuntu_sso/main/windows.py 2012-02-02 18:14:19 +0000
2253@@ -411,7 +411,7 @@
2254 # pylint: disable=E1101
2255
2256
2257-def finish_setup(result):
2258+def finish_setup(result, loop):
2259 """Stop the reactor if a failure ocurred."""
2260 if isinstance(result, Failure):
2261 reactor.stop()
2262
2263=== modified file 'ubuntu_sso/qt/gui.py'
2264--- ubuntu_sso/qt/gui.py 2012-02-01 19:19:32 +0000
2265+++ ubuntu_sso/qt/gui.py 2012-02-02 18:14:19 +0000
2266@@ -1,5 +1,4 @@
2267 # -*- coding: utf-8 -*-
2268-# Author: Manuel de la Pena <manuel@canonical.com>
2269 #
2270 # Copyright 2011 Canonical Ltd.
2271 #
2272@@ -18,6 +17,8 @@
2273
2274 import gettext
2275
2276+# pylint: disable=F0401,E0611
2277+
2278 from PyQt4.QtCore import pyqtSignal, Qt, SIGNAL
2279 from PyQt4.QtGui import (
2280 QApplication,
2281
2282=== modified file 'ubuntu_sso/qt/tests/login_u_p.py'
2283--- ubuntu_sso/qt/tests/login_u_p.py 2012-01-10 18:14:09 +0000
2284+++ ubuntu_sso/qt/tests/login_u_p.py 2012-02-02 18:14:19 +0000
2285@@ -17,10 +17,11 @@
2286
2287 import sys
2288
2289+# pylint: disable=E1101,F0401,E0611
2290+
2291 if sys.platform != 'win32':
2292- # pylint: disable=F0401
2293- from twisted.internet import glib2reactor
2294- glib2reactor.install()
2295+ from twisted.internet import gireactor
2296+ gireactor.install()
2297
2298 from dbus.mainloop.glib import DBusGMainLoop
2299 DBusGMainLoop(set_as_default=True)
2300@@ -29,8 +30,6 @@
2301
2302 from ubuntu_sso.main import get_sso_client
2303
2304-# pylint: disable=E1101
2305-
2306
2307 @defer.inlineCallbacks
2308 def main():
2309@@ -48,7 +47,19 @@
2310 client.cred_manager.connect_to_signal('AuthorizationDenied', found)
2311 client.cred_manager.connect_to_signal('CredentialsError', found)
2312
2313+ # use the following to trigger a CredentialsError (AuthenticationError)
2314 args = dict(email='xyz@canonical.com', password='ABC')
2315+
2316+ # use the following to trigger a CredentialsError (UserNotValidated)
2317+ args = dict(email='a@example.com', password='1234567U')
2318+
2319+ # remove prior credentials
2320+ cleared = defer.Deferred()
2321+ client.cred_manager.connect_to_signal('CredentialsCleared',
2322+ cleared.callback)
2323+ yield client.cred_manager.clear_credentials('SUPER', {})
2324+ yield cleared
2325+
2326 yield client.cred_manager.login_email_password('SUPER', args)
2327 print "called ok"
2328 yield d
2329
2330=== modified file 'ubuntu_sso/qt/tests/show_gui.py'
2331--- ubuntu_sso/qt/tests/show_gui.py 2012-01-10 18:14:09 +0000
2332+++ ubuntu_sso/qt/tests/show_gui.py 2012-02-02 18:14:19 +0000
2333@@ -17,10 +17,11 @@
2334
2335 import sys
2336
2337+# pylint: disable=E1101,F0401,E0611
2338+
2339 if sys.platform != 'win32':
2340- # pylint: disable=F0401
2341- from twisted.internet import glib2reactor
2342- glib2reactor.install()
2343+ from twisted.internet import gireactor
2344+ gireactor.install()
2345
2346 from dbus.mainloop.glib import DBusGMainLoop
2347 DBusGMainLoop(set_as_default=True)
2348@@ -35,8 +36,6 @@
2349 UI_MODULE_KEY,
2350 )
2351
2352-# pylint: disable=E1101
2353-
2354
2355 @defer.inlineCallbacks
2356 def main():
2357@@ -54,7 +53,7 @@
2358 client.cred_manager.connect_to_signal('AuthorizationDenied', found)
2359 client.cred_manager.connect_to_signal('CredentialsError', found)
2360
2361- yield client.cred_manager.login('Ubuntu One',
2362+ yield client.cred_manager.login('Ubuntu Two',
2363 {
2364 TC_URL_KEY: 'http://www.google.com',
2365 HELP_TEXT_KEY: 'This is a test.',
2366
2367=== modified file 'ubuntu_sso/qt/tests/test_controllers.py'
2368--- ubuntu_sso/qt/tests/test_controllers.py 2012-02-01 19:19:32 +0000
2369+++ ubuntu_sso/qt/tests/test_controllers.py 2012-02-02 18:14:19 +0000
2370@@ -23,15 +23,16 @@
2371
2372 from twisted.internet import defer
2373
2374+# pylint: disable=F0401,E0611
2375+
2376+from PyQt4.QtCore import QString, SIGNAL
2377 from PyQt4.QtGui import QCheckBox, QLabel, QLineEdit, QWizard
2378-from PyQt4.QtCore import QString, SIGNAL
2379
2380-# pylint: disable=F0401
2381 try:
2382 from PIL import Image
2383 except ImportError:
2384 import Image
2385-# pylint: enable=F0401
2386+# pylint: enable=F0401,E0611
2387
2388 from ubuntu_sso.qt.controllers import (
2389 BackendController,
2390
2391=== modified file 'ubuntu_sso/qt/tests/test_enchanced_line_edit.py'
2392--- ubuntu_sso/qt/tests/test_enchanced_line_edit.py 2011-10-28 10:41:18 +0000
2393+++ ubuntu_sso/qt/tests/test_enchanced_line_edit.py 2012-02-02 18:14:19 +0000
2394@@ -20,8 +20,9 @@
2395
2396 from twisted.trial.unittest import TestCase
2397
2398-from PyQt4 import QtGui
2399-from PyQt4 import QtCore
2400+# pylint: disable=E1101
2401+
2402+from PyQt4 import QtGui, QtCore
2403
2404 from ubuntu_sso.qt.gui import EnhancedLineEdit
2405
2406
2407=== modified file 'ubuntu_sso/qt/tests/test_reset_password.py'
2408--- ubuntu_sso/qt/tests/test_reset_password.py 2012-02-01 19:19:32 +0000
2409+++ ubuntu_sso/qt/tests/test_reset_password.py 2012-02-02 18:14:19 +0000
2410@@ -1,5 +1,4 @@
2411 # -*- coding: utf-8 -*-
2412-# Author: Manuel de la Pena <manuel@canonical.com>
2413 #
2414 # Copyright 2011 Canonical Ltd.
2415 #
2416@@ -16,6 +15,8 @@
2417 # with this program. If not, see <http://www.gnu.org/licenses/>.
2418 """Test the Reset Password Page."""
2419
2420+# pylint: disable=F0401,E0611,E1101
2421+
2422 from PyQt4 import QtGui, QtCore
2423 from twisted.internet import defer
2424 from twisted.trial.unittest import TestCase
2425
2426=== modified file 'ubuntu_sso/tests/__init__.py'
2427--- ubuntu_sso/tests/__init__.py 2012-01-10 18:14:09 +0000
2428+++ ubuntu_sso/tests/__init__.py 2012-02-02 18:14:19 +0000
2429@@ -27,10 +27,10 @@
2430 from ubuntu_sso.keyring import get_token_name
2431
2432 APP_NAME = u'The Super App!'
2433-CAPTCHA_ID = u'test'
2434+CAPTCHA_ID = u'test ñiña'
2435 CAPTCHA_PATH = os.path.abspath(os.path.join(os.curdir, 'ubuntu_sso', 'tests',
2436 'files', 'captcha.png'))
2437-CAPTCHA_SOLUTION = u'william Byrd'
2438+CAPTCHA_SOLUTION = u'william Byrd ñandú'
2439 EMAIL = u'test@example.com'
2440 EMAIL_TOKEN = u'B2Pgtf'
2441 GTK_GUI_CLASS = 'UbuntuSSOClientGUI'
2442
2443=== removed directory 'ubuntu_sso/tests/bin'
2444=== removed file 'ubuntu_sso/tests/bin/show_gui'
2445--- ubuntu_sso/tests/bin/show_gui 2010-12-20 14:29:18 +0000
2446+++ ubuntu_sso/tests/bin/show_gui 1970-01-01 00:00:00 +0000
2447@@ -1,58 +0,0 @@
2448-#!/usr/bin/python
2449-
2450-# ubuntu-sso-login-gui - GUI for registration and login for Ubuntu SSO
2451-#
2452-# Author: Natalia Bidart <natalia.bidart@canonical.com>
2453-#
2454-# Copyright 2010 Canonical Ltd.
2455-#
2456-# This program is free software: you can redistribute it and/or modify it
2457-# under the terms of the GNU General Public License version 3, as published
2458-# by the Free Software Foundation.
2459-#
2460-# This program is distributed in the hope that it will be useful, but
2461-# WITHOUT ANY WARRANTY; without even the implied warranties of
2462-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2463-# PURPOSE. See the GNU General Public License for more details.
2464-#
2465-# You should have received a copy of the GNU General Public License along
2466-# with this program. If not, see <http://www.gnu.org/licenses/>.
2467-"""Script to run the Ubuntu SSO client GUI."""
2468-
2469-import gtk
2470-import sys
2471-
2472-from ubuntu_sso.gtk.gui import UbuntuSSOClientGUI
2473-
2474-
2475-APP_NAME = 'Ubuntu'
2476-TC_URL = 'http://one.ubuntu.com/terms'
2477-HELP_TEXT = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' \
2478- 'Nam sed lorem nibh. Suspendisse gravida nulla non nunc suscipit' \
2479- ' pulvinar tempus ut augue.'
2480-
2481-
2482-if __name__ == '__main__':
2483-
2484- # pylint: disable=C0103, E1101
2485-
2486- tc_url = TC_URL
2487- login_only = False
2488- xid = 0
2489-
2490- if '--login' in sys.argv:
2491- login_only = True
2492- tc_url = None
2493-
2494- if '--with-parent-window' in sys.argv:
2495- win = gtk.Window()
2496- win.set_title(APP_NAME)
2497- win.set_position(gtk.WIN_POS_CENTER)
2498- win.set_size_request(800, 600)
2499- win.show()
2500- xid = win.window.xid
2501-
2502- UbuntuSSOClientGUI(close_callback=lambda *args, **kwargs: gtk.main_quit(),
2503- app_name=APP_NAME, tc_url=tc_url, help_text=HELP_TEXT,
2504- window_id=xid, login_only=login_only)
2505- gtk.main()
2506
2507=== removed file 'ubuntu_sso/tests/bin/show_nm_state'
2508--- ubuntu_sso/tests/bin/show_nm_state 2011-02-24 02:46:19 +0000
2509+++ ubuntu_sso/tests/bin/show_nm_state 1970-01-01 00:00:00 +0000
2510@@ -1,41 +0,0 @@
2511-#!/usr/bin/python
2512-
2513-# show_nm_state - Show the state of the NetworkManager daemon
2514-#
2515-# Author: Alejandro J. Cura <alecu@canonical.com>
2516-#
2517-# Copyright 2010 Canonical Ltd.
2518-#
2519-# This program is free software: you can redistribute it and/or modify it
2520-# under the terms of the GNU General Public License version 3, as published
2521-# by the Free Software Foundation.
2522-#
2523-# This program is distributed in the hope that it will be useful, but
2524-# WITHOUT ANY WARRANTY; without even the implied warranties of
2525-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2526-# PURPOSE. See the GNU General Public License for more details.
2527-#
2528-# You should have received a copy of the GNU General Public License along
2529-# with this program. If not, see <http://www.gnu.org/licenses/>.
2530-"""A test program that just shows the network state."""
2531-
2532-import gobject
2533-
2534-from dbus.mainloop.glib import DBusGMainLoop
2535-
2536-from ubuntu_sso.networkstate.linux import NetworkManagerState, NM_STATE_NAMES
2537-
2538-DBusGMainLoop(set_as_default=True)
2539-
2540-
2541-def got_state(state):
2542- """Called when the network state is found."""
2543- try:
2544- print NM_STATE_NAMES[state]
2545- finally:
2546- gobject.MainLoop().quit()
2547-
2548-# pylint: disable=C0103
2549-nms = NetworkManagerState(got_state)
2550-nms.find_online_state()
2551-gobject.MainLoop().run()
2552
2553=== modified file 'ubuntu_sso/tests/test_account.py'
2554--- ubuntu_sso/tests/test_account.py 2012-01-26 13:25:13 +0000
2555+++ ubuntu_sso/tests/test_account.py 2012-02-02 18:14:19 +0000
2556@@ -325,7 +325,7 @@
2557 def test_login_if_http_error(self):
2558 """Proper error is raised if authentication fails."""
2559 # use an invalid token name
2560- self.login_kwargs['token_name'] = (APP_NAME * 2).encode("utf-8")
2561+ self.login_kwargs['token_name'] = APP_NAME * 2
2562 d = self.processor.login(**self.login_kwargs)
2563 yield self.assertFailure(d, AuthenticationError)
2564
2565
2566=== modified file 'ubuntu_sso/utils/tests/test_txsecrets.py'
2567--- ubuntu_sso/utils/tests/test_txsecrets.py 2012-01-26 17:21:32 +0000
2568+++ ubuntu_sso/utils/tests/test_txsecrets.py 2012-02-02 18:14:19 +0000
2569@@ -36,6 +36,9 @@
2570 # pylint complains when things are a little too dynamic
2571 # pylint: disable=E1101
2572
2573+# Use of super on an old style class
2574+# pylint: disable=E1002
2575+
2576
2577 ERROR_CREATE_BUT_LOCKED = "Cannot create an item in a locked collection"
2578 PROMPT_BASE_PATH = "/org/freedesktop/secrets/prompt"
2579
2580=== modified file 'ubuntu_sso/utils/webclient/__init__.py'
2581--- ubuntu_sso/utils/webclient/__init__.py 2012-01-19 21:41:43 +0000
2582+++ ubuntu_sso/utils/webclient/__init__.py 2012-02-02 18:14:19 +0000
2583@@ -35,10 +35,8 @@
2584 if is_qt4reactor_installed():
2585 from ubuntu_sso.utils.webclient import qtnetwork as web_module
2586 else:
2587- # the libsoup backend depends on the twisted + GI bug
2588- # meanwhile, use the txweb sample client
2589- #from ubuntu_sso.utils.webclient import libsoup as web_module
2590- from ubuntu_sso.utils.webclient import txweb as web_module
2591+ from ubuntu_sso.utils.webclient import libsoup as web_module
2592+ #from ubuntu_sso.utils.webclient import txweb as web_module
2593 return web_module
2594
2595
2596
2597=== modified file 'ubuntu_sso/utils/webclient/qtnetwork.py'
2598--- ubuntu_sso/utils/webclient/qtnetwork.py 2012-01-25 15:02:50 +0000
2599+++ ubuntu_sso/utils/webclient/qtnetwork.py 2012-02-02 18:14:19 +0000
2600@@ -17,11 +17,13 @@
2601
2602 import sys
2603
2604+# pylint: disable=E0611
2605 from PyQt4.QtCore import (
2606 QBuffer,
2607 QCoreApplication,
2608 QUrl,
2609 )
2610+# pylint: enable=E0611
2611 from PyQt4.QtNetwork import (
2612 QNetworkAccessManager,
2613 QNetworkProxy,
2614
2615=== modified file 'ubuntu_sso/utils/webclient/tests/test_webclient.py'
2616--- ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-01-27 20:12:10 +0000
2617+++ ubuntu_sso/utils/webclient/tests/test_webclient.py 2012-02-02 18:14:19 +0000
2618@@ -255,11 +255,7 @@
2619 """Test the module name for the libsoup case."""
2620 self.patch(webclient, "is_qt4reactor_installed", lambda: False)
2621 module = webclient.webclient_module()
2622- # pylint: disable=W0511
2623- # TODO: the libsoup backend depends on the twisted + GI bug
2624- # meanwhile, use the test txweb client
2625- #self.assert_module_name(module, "libsoup")
2626- self.assert_module_name(module, "txweb")
2627+ self.assert_module_name(module, "libsoup")
2628
2629
2630 class WebClientTestCase(TestCase):

Subscribers

People subscribed via source and target branches