Merge lp:~nataliabidart/ubuntu-sso-client/improve-gui into lp:ubuntu-sso-client

Proposed by Natalia Bidart
Status: Merged
Approved by: John Lenton
Approved revision: 554
Merged at revision: 550
Proposed branch: lp:~nataliabidart/ubuntu-sso-client/improve-gui
Merge into: lp:ubuntu-sso-client
Diff against target: 601 lines (+264/-74)
3 files modified
data/ui.glade (+122/-35)
ubuntu_sso/gui.py (+78/-23)
ubuntu_sso/tests/test_gui.py (+64/-16)
To merge this branch: bzr merge lp:~nataliabidart/ubuntu-sso-client/improve-gui
Reviewer Review Type Date Requested Status
John Lenton (community) Approve
Rodrigo Moya (community) Approve
Review via email: mp+31046@code.launchpad.net

Description of the change

More improvements:

* T&C opens a embedded webkit browser showing the T&C text.
* Password fields now shown a help text.
* Spinner + label for "captcha loading" are now centered and with a fixed size. Still can't set the background to white as requested in the spec, GTK is making me crazy.

Next branch: avoid using a warning dialog for errors. Integrate some mechanism of test the rest of the screens.

To post a comment you must log in.
Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :

This branch breaks the resizing of the dialog that you fixed in the previous branch. I guess you need to pass 'expand' and 'fill' arguments to the calls to the box's pack_start method.

Also, the text for the password help looks really bad, justified to the right. Is that intended?

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

> This branch breaks the resizing of the dialog that you fixed in the previous
> branch. I guess you need to pass 'expand' and 'fill' arguments to the calls to
> the box's pack_start method.
>
> Also, the text for the password help looks really bad, justified to the right.
> Is that intended?

All fixed. Sorry for the regression, I had to change the whole layout and forgot to set that back.

554. By Natalia Bidart

Email and password must not expand.

Revision history for this message
Rodrigo Moya (rodrigo-moya) wrote :

Looks good now.

About the white background, please don't do that. If the user changes to a theme that has white (or any other bright color) as the font color, text won't be seen. So, just leave it as the default, or use a color from the theme (the entry/text view default background color)

review: Approve
Revision history for this message
John Lenton (chipaca) wrote :

I think this is great. I wait anxiously for improvements that are in the pipeline :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'data/ui.glade'
2--- data/ui.glade 2010-07-22 13:17:10 +0000
3+++ data/ui.glade 2010-07-27 14:29:41 +0000
4@@ -30,18 +30,10 @@
5 <placeholder/>
6 </child>
7 <child>
8- <object class="GtkTable" id="email_password_table">
9+ <object class="GtkHBox" id="emails_hbox">
10 <property name="visible">True</property>
11- <property name="n_rows">2</property>
12- <property name="n_columns">2</property>
13- <property name="column_spacing">5</property>
14- <property name="row_spacing">5</property>
15- <child>
16- <placeholder/>
17- </child>
18- <child>
19- <placeholder/>
20- </child>
21+ <property name="spacing">5</property>
22+ <property name="homogeneous">True</property>
23 <child>
24 <placeholder/>
25 </child>
26@@ -55,23 +47,63 @@
27 </packing>
28 </child>
29 <child>
30- <object class="GtkHBox" id="captcha_loading">
31- <property name="visible">True</property>
32- <child>
33- <object class="GtkLabel" id="captcha_loading_label">
34+ <placeholder/>
35+ </child>
36+ <child>
37+ <object class="GtkHBox" id="passwords_hbox">
38+ <property name="visible">True</property>
39+ <property name="spacing">5</property>
40+ <property name="homogeneous">True</property>
41+ <child>
42+ <placeholder/>
43+ </child>
44+ <child>
45+ <placeholder/>
46+ </child>
47+ </object>
48+ <packing>
49+ <property name="expand">False</property>
50+ <property name="position">3</property>
51+ </packing>
52+ </child>
53+ <child>
54+ <object class="GtkLabel" id="password_help_label">
55+ <property name="visible">True</property>
56+ <property name="wrap">True</property>
57+ </object>
58+ <packing>
59+ <property name="expand">False</property>
60+ <property name="position">4</property>
61+ </packing>
62+ </child>
63+ <child>
64+ <object class="GtkAlignment" id="captcha_loading">
65+ <property name="width_request">300</property>
66+ <property name="height_request">60</property>
67+ <property name="visible">True</property>
68+ <property name="xscale">0</property>
69+ <property name="yscale">0</property>
70+ <child>
71+ <object class="GtkHBox" id="captcha_loading_hbox">
72 <property name="visible">True</property>
73- <property name="xalign">1</property>
74+ <property name="spacing">5</property>
75+ <child>
76+ <placeholder/>
77+ </child>
78+ <child>
79+ <object class="GtkLabel" id="captcha_loading_label">
80+ <property name="visible">True</property>
81+ </object>
82+ <packing>
83+ <property name="expand">False</property>
84+ <property name="position">1</property>
85+ </packing>
86+ </child>
87 </object>
88- <packing>
89- <property name="position">0</property>
90- </packing>
91- </child>
92- <child>
93- <placeholder/>
94 </child>
95 </object>
96 <packing>
97- <property name="position">2</property>
98+ <property name="position">5</property>
99 </packing>
100 </child>
101 <child>
102@@ -79,7 +111,7 @@
103 <property name="stock">gtk-missing-image</property>
104 </object>
105 <packing>
106- <property name="position">3</property>
107+ <property name="position">6</property>
108 </packing>
109 </child>
110 <child>
111@@ -95,7 +127,7 @@
112 </object>
113 <packing>
114 <property name="expand">False</property>
115- <property name="position">5</property>
116+ <property name="position">8</property>
117 </packing>
118 </child>
119 <child>
120@@ -116,14 +148,22 @@
121 </packing>
122 </child>
123 <child>
124- <object class="GtkLinkButton" id="tc_button">
125- <property name="label" translatable="yes">test me!</property>
126+ <object class="GtkHButtonBox" id="hbuttonbox3">
127 <property name="visible">True</property>
128- <property name="can_focus">True</property>
129- <property name="receives_default">True</property>
130- <property name="has_tooltip">True</property>
131- <property name="relief">none</property>
132- <property name="xalign">0</property>
133+ <property name="layout_style">start</property>
134+ <child>
135+ <object class="GtkButton" id="tc_button">
136+ <property name="visible">True</property>
137+ <property name="can_focus">True</property>
138+ <property name="receives_default">True</property>
139+ <signal name="clicked" handler="on_tc_button_clicked"/>
140+ </object>
141+ <packing>
142+ <property name="expand">False</property>
143+ <property name="fill">False</property>
144+ <property name="position">0</property>
145+ </packing>
146+ </child>
147 </object>
148 <packing>
149 <property name="position">1</property>
150@@ -132,7 +172,7 @@
151 </object>
152 <packing>
153 <property name="expand">False</property>
154- <property name="position">6</property>
155+ <property name="position">9</property>
156 </packing>
157 </child>
158 <child>
159@@ -157,7 +197,7 @@
160 </child>
161 <child>
162 <object class="GtkButton" id="join_ok_button">
163- <property name="label">gtk-media-next</property>
164+ <property name="label">gtk-go-forward</property>
165 <property name="visible">True</property>
166 <property name="can_focus">True</property>
167 <property name="receives_default">True</property>
168@@ -173,7 +213,7 @@
169 </object>
170 <packing>
171 <property name="expand">False</property>
172- <property name="position">7</property>
173+ <property name="position">10</property>
174 </packing>
175 </child>
176 </object>
177@@ -247,6 +287,53 @@
178 <property name="position">4</property>
179 </packing>
180 </child>
181+ <child>
182+ <object class="GtkVBox" id="tc_browser_vbox">
183+ <property name="visible">True</property>
184+ <child>
185+ <object class="GtkScrolledWindow" id="tc_browser_window">
186+ <property name="visible">True</property>
187+ <property name="can_focus">True</property>
188+ <property name="hscrollbar_policy">never</property>
189+ <property name="vscrollbar_policy">automatic</property>
190+ <child>
191+ <placeholder/>
192+ </child>
193+ </object>
194+ <packing>
195+ <property name="position">0</property>
196+ </packing>
197+ </child>
198+ <child>
199+ <object class="GtkHButtonBox" id="hbuttonbox4">
200+ <property name="visible">True</property>
201+ <property name="layout_style">end</property>
202+ <child>
203+ <object class="GtkButton" id="tc_back_button">
204+ <property name="label">gtk-go-back</property>
205+ <property name="visible">True</property>
206+ <property name="can_focus">True</property>
207+ <property name="receives_default">True</property>
208+ <property name="use_stock">True</property>
209+ <signal name="clicked" handler="on_tc_back_button_clicked"/>
210+ </object>
211+ <packing>
212+ <property name="expand">False</property>
213+ <property name="fill">False</property>
214+ <property name="position">0</property>
215+ </packing>
216+ </child>
217+ </object>
218+ <packing>
219+ <property name="expand">False</property>
220+ <property name="position">1</property>
221+ </packing>
222+ </child>
223+ </object>
224+ <packing>
225+ <property name="position">5</property>
226+ </packing>
227+ </child>
228 </object>
229 </child>
230 </object>
231
232=== modified file 'ubuntu_sso/gui.py'
233--- ubuntu_sso/gui.py 2010-07-22 13:17:10 +0000
234+++ ubuntu_sso/gui.py 2010-07-27 14:29:41 +0000
235@@ -22,11 +22,13 @@
236
237 import gettext
238 import gtk
239+import webkit
240
241 _ = gettext.gettext
242
243
244 HELP_TEXT_COLOR = gtk.gdk.color_parse("#9c9a94")
245+TC_URI = 'http://one.ubuntu.com/terms/'
246
247
248 class LabeledEntry(gtk.Entry):
249@@ -79,8 +81,6 @@
250 class UserRegistrationGUI(object):
251 """User registration GUI."""
252
253- TC_URI = 'http://one.ubuntu.com/terms/'
254-
255 # Initial texts
256 JOIN_HEADER_LABEL = _('Join') + ' <b>Ubuntu One</b>'
257 NAME_ENTRY = _('Name')
258@@ -96,18 +96,18 @@
259 'and try entering them again.')
260 PASSWORD_MISMATCH = _('The passwords don\'t match, please double check '
261 'and try entering them again.')
262- PASSWORD_TOO_WEAK = _('The password must have at least 8 characters, one '
263- 'upper case and one number.')
264+ PASSWORD_HELP = _('The password must have a minimum of 8 characters '
265+ 'and include one uppercase character and one number.')
266 TC_NOT_ACCEPTED = _('Agreeing to the Ubuntu One Terms & Conditions is '
267 'required to subscribe')
268- CAPTCHA_LOADING = _('loading captcha image...')
269+ CAPTCHA_LOADING = _('Loading ...')
270 VERIFY_EMAIL_LABEL = _("""Enter verification code.
271
272-A four digit verification code has just been sent t your email address.
273+A four digit verification code has just been sent to your email address.
274 Please enter this code below.""")
275 EMAIL_TOKEN_ENTRY = _('Enter code verification here')
276
277- def __init__(self, backend=None, close_callback=None):
278+ def __init__(self, backend=None, close_callback=None, tc_uri=None):
279 """Create the GUI and initialize widgets."""
280
281 if backend is not None:
282@@ -115,6 +115,13 @@
283 self._captcha_filename = self._mktemp()
284 self.backend.generate_captcha(filename=self._captcha_filename)
285
286+ self.close_callback = close_callback
287+
288+ if tc_uri is None:
289+ self.tc_uri = TC_URI
290+ else:
291+ self.tc_uri = tc_uri
292+
293 ui_filename = os.path.abspath(os.path.join(os.path.dirname(__file__),
294 os.pardir, 'data', 'ui.glade'))
295 self.builder = gtk.Builder()
296@@ -124,13 +131,29 @@
297 self.text_widgets = ('name_entry', 'email1_entry', 'email2_entry',
298 'password1_entry', 'password2_entry',
299 'captcha_solution_entry', 'email_token_entry')
300- widgets = ('join_header_label', 'join_window', 'join_cancel_button',
301- 'join_ok_button', 'email_password_table', 'tc_button',
302- 'yes_to_updates_checkbutton', 'yes_to_tc_checkbutton',
303- 'enter_details_vbox', 'processing_vbox',
304- 'captcha_loading_label', 'captcha_image', 'captcha_loading',
305- 'verify_email_vbox', 'verify_email_label')
306- #+ self.text_widgets
307+ widgets = (
308+ 'captcha_image',
309+ 'captcha_loading',
310+ 'captcha_loading_label',
311+ 'captcha_loading_hbox',
312+ 'emails_hbox',
313+ 'enter_details_vbox',
314+ 'join_cancel_button',
315+ 'join_header_label',
316+ 'join_ok_button',
317+ 'join_window',
318+ 'password_help_label',
319+ 'passwords_hbox',
320+ 'processing_vbox',
321+ 'tc_back_button',
322+ 'tc_button',
323+ 'tc_browser_vbox',
324+ 'tc_browser_window',
325+ 'verify_email_label',
326+ 'verify_email_vbox',
327+ 'yes_to_tc_checkbutton',
328+ 'yes_to_updates_checkbutton',
329+ )
330 for name in widgets:
331 widget = self.builder.get_object(name)
332 assert widget is not None, '%s should be a valid object.' % name
333@@ -147,20 +170,24 @@
334
335 self.enter_details_vbox.pack_start(self.name_entry, expand=False)
336 self.enter_details_vbox.reorder_child(self.name_entry, 0)
337- self.email_password_table.attach(self.email1_entry, 0, 1, 0, 1)
338- self.email_password_table.attach(self.email2_entry, 1, 2, 0, 1)
339- self.email_password_table.attach(self.password1_entry, 0, 1, 1, 2)
340- self.email_password_table.attach(self.password2_entry, 1, 2, 1, 2)
341+ self.emails_hbox.pack_start(self.email1_entry)
342+ self.emails_hbox.pack_start(self.email2_entry)
343+ self.passwords_hbox.pack_start(self.password1_entry)
344+ self.passwords_hbox.pack_start(self.password2_entry)
345+ self.password_help_label.set_text(self.PASSWORD_HELP)
346+
347 self.enter_details_vbox.pack_start(self.captcha_solution_entry,
348 expand=False)
349- self.enter_details_vbox.reorder_child(self.captcha_solution_entry, 3)
350+ self.enter_details_vbox.reorder_child(self.captcha_solution_entry, 5)
351
352 self._set_captcha_loading()
353
354 self.yes_to_updates_checkbutton.set_label(self.YES_TO_UPDATES)
355 self.yes_to_tc_checkbutton.set_label(self.YES_TO_TC)
356+
357 self.tc_button.set_label(self.TC)
358- self.tc_button.set_uri(self.TC_URI)
359+ self.tc_browser = webkit.WebView()
360+ self.tc_browser_window.add(self.tc_browser)
361
362 self.verify_email_label.set_text(self.VERIFY_EMAIL_LABEL)
363 self.verify_email_vbox.pack_start(self.email_token_entry, expand=False)
364@@ -170,13 +197,14 @@
365 buttons=gtk.BUTTONS_CLOSE,
366 flags=gtk.DIALOG_MODAL)
367
368- self.close_callback = close_callback
369 # XXX: hack to not have the focus on the name entry
370 self.join_cancel_button.grab_focus()
371
372 self.enter_details_vbox.show()
373 self.processing_vbox.hide()
374 self.verify_email_vbox.hide()
375+ self.tc_browser_vbox.hide()
376+
377 self.join_window.show()
378
379 # hack until backend notifies the success of a registration
380@@ -185,10 +213,18 @@
381 def _set_captcha_loading(self):
382 """Present a spinner to the user while the captcha is downloaded."""
383 self.join_ok_button.set_sensitive(False)
384+
385 spinner = gtk.Spinner()
386 spinner.start()
387- self.captcha_loading.pack_start(spinner)
388+ self.captcha_loading_hbox.pack_start(spinner, expand=False)
389+ self.captcha_loading_hbox.reorder_child(spinner, 0)
390 self.captcha_loading_label.set_text(self.CAPTCHA_LOADING)
391+
392+ # XXX: currently not working :-/
393+ #white = gtk.gdk.Color('white')
394+ #self.captcha_loading.modify_fg(gtk.STATE_NORMAL, white)
395+ #self.captcha_loading.modify_base(gtk.STATE_NORMAL, white)
396+
397 self.captcha_loading.show_all()
398
399 def _set_processing_screen(self):
400@@ -238,7 +274,7 @@
401 if (len(password1) < 8 or
402 re.search('[A-Z]', password1) is None or
403 re.search('\d+', password1) is None):
404- self.warning_dialog.set_markup(self.PASSWORD_TOO_WEAK)
405+ self.warning_dialog.set_markup(self.PASSWORD_HELP)
406 self.warning_dialog.run()
407 self.warning_dialog.hide()
408 return
409@@ -254,6 +290,24 @@
410 self.verify_email_vbox.hide()
411 self._set_processing_screen()
412
413+ def on_tc_button_clicked(self, *args, **kwargs):
414+ """T & C button was clicked, show the browser with them."""
415+ self.tc_browser.open(self.tc_uri)
416+
417+ self.enter_details_vbox.hide()
418+ self.processing_vbox.hide()
419+ self.verify_email_vbox.hide()
420+ self.tc_browser_vbox.show_all()
421+
422+ def on_tc_back_button_clicked(self, *args, **kwargs):
423+ """T & C 'back' button was clicked, return to the previous screen."""
424+ self.enter_details_vbox.show()
425+ self.processing_vbox.hide()
426+ self.verify_email_vbox.hide()
427+ self.tc_browser_vbox.hide()
428+
429+ # backend callbacks
430+
431 def on_registration_successful(self):
432 """Registration can go on, user needs to verify email."""
433 self.enter_details_vbox.hide()
434@@ -262,6 +316,7 @@
435
436 def on_captcha_generated(self, captcha_id):
437 """Captcha image has been generated and is available to be shown."""
438+ self.captcha_loading.hide()
439 self.join_ok_button.set_sensitive(True)
440 self.captcha_image.show()
441 self.captcha_image.set_from_file(self._captcha_filename)
442
443=== modified file 'ubuntu_sso/tests/test_gui.py'
444--- ubuntu_sso/tests/test_gui.py 2010-07-21 16:03:44 +0000
445+++ ubuntu_sso/tests/test_gui.py 2010-07-27 14:29:41 +0000
446@@ -208,7 +208,9 @@
447 """Init."""
448 super(UserRegistrationGUITestCase, self).setUp()
449 self.backend = FakedSSOBackend()
450- self.ui = gui.UserRegistrationGUI(backend=self.backend)
451+ self.tc_uri = 'http://localhost'
452+ self.ui = gui.UserRegistrationGUI(backend=self.backend,
453+ tc_uri=self.tc_uri)
454 self.patch(self.ui.warning_dialog, 'run', NO_OP) # do not open dialogs
455
456 def tearDown(self):
457@@ -292,6 +294,8 @@
458 msg % ('processing_vbox', 'not '))
459 self.assertFalse(self.ui.verify_email_vbox.get_property('visible'),
460 msg % ('verify_email_vbox', 'not '))
461+ self.assertFalse(self.ui.tc_browser_vbox.get_property('visible'),
462+ msg % ('tc_browser_vbox', 'not '))
463
464 def test_join_ok_button_clicked(self):
465 """Clicking 'join_ok_button' presents the processing vbox."""
466@@ -304,6 +308,8 @@
467 msg % ('processing_vbox', ''))
468 self.assertFalse(self.ui.verify_email_vbox.get_property('visible'),
469 msg % ('verify_email_vbox', 'not '))
470+ self.assertFalse(self.ui.tc_browser_vbox.get_property('visible'),
471+ msg % ('tc_browser_vbox', 'not '))
472
473 def test_processing_vbox_displays_an_active_spinner(self):
474 """When processing the registration, an active spinner is shown."""
475@@ -329,12 +335,12 @@
476 self.assertTrue(self.ui.captcha_loading.get_property('visible'),
477 'the captcha_loading vbox should be visible.')
478
479- children = self.ui.captcha_loading.get_children()
480+ children = self.ui.captcha_loading_hbox.get_children()
481 self.assertEqual(2, len(children),
482 'captcha_loading must have two children.')
483- self.assertEqual(self.ui.captcha_loading_label, children[0],
484- 'captcha_loading must have a label as child.')
485- spinner = children[-1]
486+ self.assertIn(self.ui.captcha_loading_label, children,
487+ 'captcha_loading must have a label as child.')
488+ spinner = children[0]
489 self.assertIsInstance(spinner, gtk.Spinner)
490 self.assertTrue(self.ui.captcha_loading_label.get_property('visible'),
491 'the captcha_loading_label should be visible.')
492@@ -343,7 +349,7 @@
493 self.assertTrue(spinner.get_property('active'),
494 'the processing_spinner should be active.')
495
496- def test_veridy_email_label_display_correct_info(self):
497+ def test_verify_email_label_display_correct_info(self):
498 """The verify_email_label display VERIFY_EMAIL_LABEL."""
499 msg = 'verify_email_label must read "%s" (got "%s" instead).'
500 actual = self.ui.verify_email_label.get_text()
501@@ -360,18 +366,47 @@
502 msg % ('processing_vbox', 'not '))
503 self.assertTrue(self.ui.verify_email_vbox.get_property('visible'),
504 msg % ('verify_email_vbox', ''))
505-
506- def test_tc_button_is_a_link_button(self):
507- """Terms & Conditions is a link button."""
508- self.assertIsInstance(self.ui.tc_button, gtk.LinkButton)
509+ self.assertFalse(self.ui.tc_browser_vbox.get_property('visible'),
510+ msg % ('tc_browser_vbox', 'not '))
511+
512+ def test_tc_button_clicked_morphs_into_tc_browser_vbox(self):
513+ """Terms & Conditions morphs to a browser window."""
514+ self.ui.tc_button.clicked()
515+
516+ msg = '"%s" must %sbe visible after registration_successful.'
517+ self.assertFalse(self.ui.enter_details_vbox.get_property('visible'),
518+ msg % ('enter_details_vbox', 'not '))
519+ self.assertFalse(self.ui.processing_vbox.get_property('visible'),
520+ msg % ('processing_vbox', 'not '))
521+ self.assertFalse(self.ui.verify_email_vbox.get_property('visible'),
522+ msg % ('verify_email_vbox', 'not '))
523+ self.assertTrue(self.ui.tc_browser_vbox.get_property('visible'),
524+ msg % ('tc_browser_vbox', ''))
525+
526+ def test_tc_back_clicked_returns_to_previous_screen(self):
527+ """Terms & Conditions back button return to previous screen."""
528+ self.ui.tc_button.clicked()
529+ self.ui.tc_back_button.clicked()
530+
531+ msg = '"%s" must %sbe visible after registration_successful.'
532+ self.assertTrue(self.ui.enter_details_vbox.get_property('visible'),
533+ msg % ('enter_details_vbox', ''))
534+ self.assertFalse(self.ui.processing_vbox.get_property('visible'),
535+ msg % ('processing_vbox', 'not '))
536+ self.assertFalse(self.ui.verify_email_vbox.get_property('visible'),
537+ msg % ('verify_email_vbox', 'not '))
538+ self.assertFalse(self.ui.tc_browser_vbox.get_property('visible'),
539+ msg % ('tc_browser_vbox', 'not '))
540
541 def test_tc_button_has_the_proper_wording(self):
542- """Terms & Conditions is a link button."""
543+ """Terms & Conditions has the proper wording."""
544 self.assertEqual(self.ui.tc_button.get_label(), self.ui.TC)
545
546- def test_tc_button_has_the_proper_uri(self):
547- """Terms & Conditions is a link button."""
548- self.assertEqual(self.ui.tc_button.get_uri(), self.ui.TC_URI)
549+ def test_tc_browser_opens_the_proper_uri(self):
550+ """Terms & Conditions browser shows the proper uri."""
551+ self.patch(self.ui.tc_browser, 'open', self._set_called)
552+ self.ui.tc_button.clicked()
553+ self.assertEqual(self._called, ((self.tc_uri,), {}))
554
555 def test_join_ok_button_is_disabled_until_captcha_is_available(self):
556 """The join_ok_button is not sensitive until captcha is available."""
557@@ -382,6 +417,12 @@
558 self.ui.on_captcha_generated(captcha_id='something')
559 self.assertTrue(self.ui.join_ok_button.is_sensitive())
560
561+ def test_captcha_loading_is_hid_when_captcha_is_available(self):
562+ """The captcha_loading is hid when captcha is available."""
563+ self.ui.on_captcha_generated(captcha_id='something')
564+ self.assertFalse(self.ui.captcha_loading.get_property('visible'),
565+ 'captcha_loading is not visible.')
566+
567 def test_captcha_image_is_requested_as_startup(self):
568 """The captcha image is requested at startup."""
569 # assert generate_captcha was called
570@@ -435,6 +476,13 @@
571 self.assertEqual(self._dummy, self.ui.EMAIL_MISMATCH)
572 self.assertTrue(self._called, 'warning_dialog must be run.')
573
574+ def test_password_help_is_always_shown(self):
575+ """Password help text is correctly displayed."""
576+ self.assertTrue(self.ui.password_help_label.get_property('visible'),
577+ 'password help text is visible.')
578+ self.assertEqual(self.ui.password_help_label.get_text(),
579+ self.ui.PASSWORD_HELP)
580+
581 def test_warning_is_shown_if_password_mismatch(self):
582 """A warning message is shown if password doesn't match."""
583 # email will match
584@@ -455,7 +503,7 @@
585 self.ui.email1_entry.set_text(EMAIL)
586 self.ui.email2_entry.set_text(EMAIL)
587
588- msg = 'PASSWORD_TOO_WEAK should be set in warning_dialog for "%s".'
589+ msg = 'PASSWORD_HELP should be set in warning_dialog for "%s".'
590 # password will match but will be too weak
591 for w in ('', 'h3lloWo', PASSWORD.lower(), 'helloWorld'):
592 self.ui.password1_entry.set_text(w)
593@@ -463,7 +511,7 @@
594
595 self.ui.join_ok_button.clicked() # submit form
596
597- self.assertEqual(self._dummy, self.ui.PASSWORD_TOO_WEAK, msg % w)
598+ self.assertEqual(self._dummy, self.ui.PASSWORD_HELP, msg % w)
599 self.assertTrue(self._called, 'warning_dialog must be run.')
600
601 self._dummy = None

Subscribers

People subscribed via source and target branches