Merge lp:~nataliabidart/ubuntu-sso-client/stable-3-0-update-2.99.5 into lp:ubuntu-sso-client/stable-3-0
- stable-3-0-update-2.99.5
- Merge into stable-3-0
Status: | Merged | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Approved by: | Natalia Bidart | ||||||||||||||||||||||||||||
Approved revision: | 827 | ||||||||||||||||||||||||||||
Merged at revision: | 826 | ||||||||||||||||||||||||||||
Proposed branch: | lp:~nataliabidart/ubuntu-sso-client/stable-3-0-update-2.99.5 | ||||||||||||||||||||||||||||
Merge into: | lp:ubuntu-sso-client/stable-3-0 | ||||||||||||||||||||||||||||
Diff against target: |
2716 lines (+888/-321) 46 files modified
data/qt/resources.qrc (+10/-0) data/qt/setup_account.ui (+35/-2) data/qt/stylesheet.qss (+119/-0) run-tests (+1/-1) setup.py (+0/-39) ubuntu_sso/credentials.py (+3/-1) ubuntu_sso/gtk/gui.py (+14/-16) ubuntu_sso/gtk/tests/test_gui.py (+57/-53) ubuntu_sso/keyring/tests/test_linux.py (+2/-3) ubuntu_sso/main/__init__.py (+1/-1) ubuntu_sso/main/linux.py (+2/-3) ubuntu_sso/main/qt.py (+23/-3) ubuntu_sso/main/tests/test_common.py (+15/-22) ubuntu_sso/main/tests/test_qt.py (+69/-0) ubuntu_sso/qt/__init__.py (+0/-10) ubuntu_sso/qt/common.py (+1/-0) ubuntu_sso/qt/current_user_sign_in_page.py (+18/-8) ubuntu_sso/qt/email_verification_page.py (+6/-1) ubuntu_sso/qt/enhanced_check_box.py (+5/-2) ubuntu_sso/qt/forgotten_password_page.py (+18/-4) ubuntu_sso/qt/gui.py (+13/-7) ubuntu_sso/qt/main.py (+13/-1) ubuntu_sso/qt/network_detection_page.py (+8/-8) ubuntu_sso/qt/reset_password_page.py (+11/-2) ubuntu_sso/qt/setup_account_page.py (+18/-10) ubuntu_sso/qt/sign_in_page.py (+2/-4) ubuntu_sso/qt/tests/__init__.py (+22/-2) ubuntu_sso/qt/tests/test_current_user_sign_in_page.py (+32/-22) ubuntu_sso/qt/tests/test_email_verification.py (+9/-11) ubuntu_sso/qt/tests/test_enhanced_check_box.py (+0/-7) ubuntu_sso/qt/tests/test_forgotten_password.py (+31/-9) ubuntu_sso/qt/tests/test_network_detection.py (+2/-4) ubuntu_sso/qt/tests/test_reset_password.py (+77/-31) ubuntu_sso/qt/tests/test_setup_account.py (+50/-3) ubuntu_sso/qt/tests/test_sign_in_page.py (+2/-2) ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py (+2/-2) ubuntu_sso/qt/ubuntu_sso_wizard.py (+1/-0) ubuntu_sso/tests/__init__.py (+8/-8) ubuntu_sso/utils/__init__.py (+9/-3) ubuntu_sso/utils/runner/glib.py (+11/-2) ubuntu_sso/utils/runner/tests/test_glib.py (+132/-0) ubuntu_sso/utils/runner/tests/test_qt.py (+9/-1) ubuntu_sso/utils/runner/tests/test_runner.py (+9/-7) ubuntu_sso/utils/runner/tx.py (+9/-1) ubuntu_sso/utils/tests/test_common.py (+1/-2) ubuntu_sso/utils/ui.py (+8/-3) |
||||||||||||||||||||||||||||
To merge this branch: | bzr merge lp:~nataliabidart/ubuntu-sso-client/stable-3-0-update-2.99.5 | ||||||||||||||||||||||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Review via email: mp+94066@code.launchpad.net |
Commit message
- Updating from trunk up to revno 882:
[ Diego Sarmentero <email address hidden> ]
- Fixed: Captcha is failing for the Qt UI (LP: #933679).
- Add stylesheets for the Qt UI.
- Fixed: Qt UI: must call the backend passing reply_handler
and error_handler (LP: #931452).
[ Natalia B. Bidart <email address hidden> ]
- Make gettext return unicode strings. Also, transform arguments passed to
the GLib spawnner to bytes (LP: #933632).
- Fix lint issue on nightlies build (LP: #934488).
- Try to load the qt main/ implementation when possible, if not default
to the glib (LP: #933534).
- Make the bin_dir discoverable when running from the system installation
(LP: #933039).
[ Roberto Alsina <email address hidden> ]
- Implement timeout_func for the Qt frontend (LP: #933758).
Description of the change
Ubuntu One Auto Pilot (otto-pilot) wrote : | # |
The attempt to merge lp:~nataliabidart/ubuntu-sso-client/stable-3-0-update-2.99.5 into lp:ubuntu-sso-client/stable-3-0 failed. Below is the output from the failed tests.
*** Running GTK test suite for ubuntu_sso ***
twisted.
TestCase
runTest ... [OK]
ubuntu_
TestGetHostname
test_
test_
TestTokenName
test_
test_
test_
test_
test_
twisted.
TestCase
runTest ... [OK]
ubuntu_
TestKeyring
test_
test_
test_
test_
test_
test_
test_
ubuntu_
NetworkManage
test_
test_
NetworkManage
test_
test_
test_
test_
test_nm_offline ... [OK]
test_
test_
test_
test_
test_
ubuntu_sso.tests
TestCase
runTest ... [OK]
ubuntu_
TestConnection
test_
test_
test_
test_
Preview Diff
1 | === added file 'data/Ubuntu-B.ttf' |
2 | Binary files data/Ubuntu-B.ttf 1970-01-01 00:00:00 +0000 and data/Ubuntu-B.ttf 2012-02-21 23:01:20 +0000 differ |
3 | === added file 'data/Ubuntu-R.ttf' |
4 | Binary files data/Ubuntu-R.ttf 1970-01-01 00:00:00 +0000 and data/Ubuntu-R.ttf 2012-02-21 23:01:20 +0000 differ |
5 | === added file 'data/balloon_shape.png' |
6 | Binary files data/balloon_shape.png 1970-01-01 00:00:00 +0000 and data/balloon_shape.png 2012-02-21 23:01:20 +0000 differ |
7 | === added file 'data/password_hint_ok.png' |
8 | Binary files data/password_hint_ok.png 1970-01-01 00:00:00 +0000 and data/password_hint_ok.png 2012-02-21 23:01:20 +0000 differ |
9 | === added file 'data/password_hint_warning.png' |
10 | Binary files data/password_hint_warning.png 1970-01-01 00:00:00 +0000 and data/password_hint_warning.png 2012-02-21 23:01:20 +0000 differ |
11 | === added file 'data/qt/resources.qrc' |
12 | --- data/qt/resources.qrc 1970-01-01 00:00:00 +0000 |
13 | +++ data/qt/resources.qrc 2012-02-21 23:01:20 +0000 |
14 | @@ -0,0 +1,10 @@ |
15 | +<RCC> |
16 | + <qresource prefix="/"> |
17 | + <file>../password_hint_ok.png</file> |
18 | + <file>../password_hint_warning.png</file> |
19 | + <file>../Ubuntu-R.ttf</file> |
20 | + <file>../Ubuntu-B.ttf</file> |
21 | + <file>../balloon_shape.png</file> |
22 | + <file>stylesheet.qss</file> |
23 | + </qresource> |
24 | +</RCC> |
25 | |
26 | === modified file 'data/qt/setup_account.ui' |
27 | --- data/qt/setup_account.ui 2012-02-02 15:44:18 +0000 |
28 | +++ data/qt/setup_account.ui 2012-02-21 23:01:20 +0000 |
29 | @@ -221,6 +221,22 @@ |
30 | <number>3</number> |
31 | </property> |
32 | <item> |
33 | + <spacer name="verticalSpacer_4"> |
34 | + <property name="orientation"> |
35 | + <enum>Qt::Vertical</enum> |
36 | + </property> |
37 | + <property name="sizeType"> |
38 | + <enum>QSizePolicy::Fixed</enum> |
39 | + </property> |
40 | + <property name="sizeHint" stdset="0"> |
41 | + <size> |
42 | + <width>20</width> |
43 | + <height>10</height> |
44 | + </size> |
45 | + </property> |
46 | + </spacer> |
47 | + </item> |
48 | + <item> |
49 | <widget class="QLabel" name="password_label"> |
50 | <property name="font"> |
51 | <font> |
52 | @@ -283,6 +299,22 @@ |
53 | <number>3</number> |
54 | </property> |
55 | <item> |
56 | + <spacer name="verticalSpacer_5"> |
57 | + <property name="orientation"> |
58 | + <enum>Qt::Vertical</enum> |
59 | + </property> |
60 | + <property name="sizeType"> |
61 | + <enum>QSizePolicy::Fixed</enum> |
62 | + </property> |
63 | + <property name="sizeHint" stdset="0"> |
64 | + <size> |
65 | + <width>20</width> |
66 | + <height>10</height> |
67 | + </size> |
68 | + </property> |
69 | + </spacer> |
70 | + </item> |
71 | + <item> |
72 | <widget class="QLabel" name="confirm_password_label"> |
73 | <property name="font"> |
74 | <font> |
75 | @@ -576,7 +608,7 @@ |
76 | <item row="6" column="1" rowspan="2"> |
77 | <widget class="QLabel" name="password_assistance"> |
78 | <property name="sizePolicy"> |
79 | - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> |
80 | + <sizepolicy hsizetype="Maximum" vsizetype="Minimum"> |
81 | <horstretch>0</horstretch> |
82 | <verstretch>0</verstretch> |
83 | </sizepolicy> |
84 | @@ -584,7 +616,7 @@ |
85 | <property name="minimumSize"> |
86 | <size> |
87 | <width>220</width> |
88 | - <height>0</height> |
89 | + <height>100</height> |
90 | </size> |
91 | </property> |
92 | <property name="maximumSize"> |
93 | @@ -663,5 +695,6 @@ |
94 | </item> |
95 | </layout> |
96 | </widget> |
97 | + <resources/> |
98 | <connections/> |
99 | </ui> |
100 | |
101 | === added file 'data/qt/stylesheet.qss' |
102 | --- data/qt/stylesheet.qss 1970-01-01 00:00:00 +0000 |
103 | +++ data/qt/stylesheet.qss 2012-02-21 23:01:20 +0000 |
104 | @@ -0,0 +1,119 @@ |
105 | +QWidget { |
106 | + font-family: "Ubuntu"; |
107 | + color: #333333; |
108 | +} |
109 | + |
110 | +QWizard, |
111 | +QDialog { |
112 | + background-color: white; |
113 | +} |
114 | + |
115 | +QLabel#password_assistance { |
116 | + border-image: url(":/balloon_shape.png"); |
117 | +} |
118 | + |
119 | +QLineEdit { |
120 | + border: 1px solid #aea79f; |
121 | +} |
122 | + |
123 | +QPushButton { |
124 | + border-radius: 5px; |
125 | + border-style: solid; |
126 | + padding: 6px; |
127 | + padding-left: 20px; |
128 | + padding-right: 20px; |
129 | + border-width: 1px; |
130 | + height: 14px; |
131 | +} |
132 | + |
133 | +QPushButton[default="true"] { |
134 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
135 | + stop: 0 #fe9e84,stop: 1.0 #dd4814); |
136 | + color: white; |
137 | + border-color: #999999; |
138 | +} |
139 | + |
140 | +QPushButton:hover[default="true"] { |
141 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
142 | + stop: 0 #ffb19c,stop: 1.0 #dd4814); |
143 | + color: white; |
144 | + border-color: #999999; |
145 | +} |
146 | + |
147 | +QPushButton:pressed[default="true"] { |
148 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
149 | + stop: 0 #b93f14,stop: 1.0 #dd4814); |
150 | + color: white; |
151 | + border-color: #999999; |
152 | +} |
153 | + |
154 | +QPushButton[default="false"] { |
155 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
156 | + stop: 0 #ffffff,stop: 1.0 #e6e6e6); |
157 | + color: #333333; |
158 | + border-color: #999999; |
159 | +} |
160 | + |
161 | +QPushButton:hover[default="false"] { |
162 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
163 | + stop: 0 #ffffff,stop: 1.0 #ededed); |
164 | + color: #333333; |
165 | + border-color: #999999; |
166 | +} |
167 | + |
168 | +QPushButton:pressed[default="false"] { |
169 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
170 | + stop: 0 #d9d9d9,stop: 1.0 #fefefe); |
171 | + color: #333333; |
172 | + border-color: #999999; |
173 | +} |
174 | + |
175 | +QPushButton[DisabledState="true"] { |
176 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
177 | + stop: 0 #eaeaea, stop: 1.0 #cacaca); |
178 | + color: #595959; |
179 | + border-color: #939389; |
180 | +} |
181 | + |
182 | +QPushButton[DisabledState="false"] { |
183 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
184 | + stop: 0 #fe9e84,stop: 1.0 #dd4814); |
185 | + color: white; |
186 | + border-color: #999999; |
187 | +} |
188 | + |
189 | +QPushButton:hover[DisabledState="false"] { |
190 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
191 | + stop: 0 #ffb19c,stop: 1.0 #dd4814); |
192 | + color: white; |
193 | + border-color: #999999; |
194 | +} |
195 | + |
196 | +QPushButton:pressed[DisabledState="false"] { |
197 | + background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, |
198 | + stop: 0 #b93f14,stop: 1.0 #dd4814); |
199 | + color: white; |
200 | + border-color: #999999; |
201 | +} |
202 | + |
203 | +QFrame#frm_box { |
204 | + background: #ffffff; |
205 | + border-radius: 5px; |
206 | + border-style: solid; |
207 | + border-color: #939389; |
208 | + border-width: 1px; |
209 | + color: white; |
210 | + min-height: 100px; |
211 | +} |
212 | + |
213 | +QFrame#frm_box > QLabel { |
214 | + font-size: 20px; |
215 | +} |
216 | + |
217 | +QLabel#title_label { |
218 | + font-size: 20px; |
219 | +} |
220 | + |
221 | +QFrame#header { |
222 | + padding: 10px; |
223 | +} |
224 | |
225 | === modified file 'run-tests' |
226 | --- run-tests 2012-02-09 22:19:31 +0000 |
227 | +++ run-tests 2012-02-21 23:01:20 +0000 |
228 | @@ -47,7 +47,7 @@ |
229 | fi |
230 | |
231 | echo "*** Running GTK test suite for ""$MODULE"" ***" |
232 | -$XVFB_CMDLINE u1trial --reactor=gi --gui -p "$QT_TESTS_PATH" -i "test_windows.py" "$MODULE" |
233 | +$XVFB_CMDLINE u1trial --reactor=gi --gui -p "$QT_TESTS_PATH" -i "test_windows.py,test_qt.py" "$MODULE" |
234 | rm -rf _trial_temp |
235 | |
236 | # hack to avoid: |
237 | |
238 | === modified file 'setup.py' |
239 | --- setup.py 2012-02-15 16:32:29 +0000 |
240 | +++ setup.py 2012-02-21 23:01:20 +0000 |
241 | @@ -153,11 +153,6 @@ |
242 | |
243 | def run(self): |
244 | """Execute the command.""" |
245 | - # pylint: disable=W0703 |
246 | - try: |
247 | - self._wrapuic() |
248 | - except Exception, e: |
249 | - self.warn("Error wrapping uic to use gettext: %s" % e) |
250 | basepath = os.path.join('data', 'qt') |
251 | # TODO: build the resource files so that we can include them |
252 | #self.build_rc(os.path.join(basepath, 'icons_rc.py'), |
253 | @@ -172,40 +167,6 @@ |
254 | |
255 | build_extra.build_extra.run(self) |
256 | |
257 | - # pylint: disable=E1002 |
258 | - _wrappeduic = False |
259 | - |
260 | - @classmethod |
261 | - def _wrapuic(cls): |
262 | - """Wrap uic to use gettext's _() in place of tr()""" |
263 | - if cls._wrappeduic: |
264 | - return |
265 | - |
266 | - from PyQt4.uic.Compiler import compiler, qtproxies, indenter |
267 | - |
268 | - # pylint: disable=C0103 |
269 | - class _UICompiler(compiler.UICompiler): |
270 | - """Speciallized compiler for qt .ui files.""" |
271 | - def createToplevelWidget(self, classname, widgetname): |
272 | - o = indenter.getIndenter() |
273 | - o.level = 0 |
274 | - o.write('from gettext import gettext as _') |
275 | - return super(_UICompiler, self).createToplevelWidget(classname, |
276 | - widgetname) |
277 | - compiler.UICompiler = _UICompiler |
278 | - |
279 | - class _i18n_string(qtproxies.i18n_string): |
280 | - """Provide a translated text.""" |
281 | - |
282 | - def __str__(self): |
283 | - return "_('%s')" % self.string.encode('string-escape') |
284 | - |
285 | - qtproxies.i18n_string = _i18n_string |
286 | - |
287 | - cls._wrappeduic = True |
288 | - # pylint: enable=C0103 |
289 | - # pylint: enable=E1002 |
290 | - |
291 | |
292 | class SSOClean(DistUtilsExtra.auto.clean_build_tree): |
293 | """Class to clean up after the build.""" |
294 | |
295 | === modified file 'ubuntu_sso/credentials.py' |
296 | --- ubuntu_sso/credentials.py 2012-02-11 19:25:01 +0000 |
297 | +++ ubuntu_sso/credentials.py 2012-02-21 23:01:20 +0000 |
298 | @@ -148,7 +148,9 @@ |
299 | value = getattr(self, arg) |
300 | if value: |
301 | args.append('--%s' % arg) |
302 | - args.append("%s" % str(value)) |
303 | + if not isinstance(value, basestring): |
304 | + value = str(value) |
305 | + args.append(value) |
306 | |
307 | if login_only: |
308 | args.append('--login_only') |
309 | |
310 | === modified file 'ubuntu_sso/gtk/gui.py' |
311 | --- ubuntu_sso/gtk/gui.py 2012-02-11 19:25:01 +0000 |
312 | +++ ubuntu_sso/gtk/gui.py 2012-02-21 23:01:20 +0000 |
313 | @@ -111,6 +111,7 @@ |
314 | # To be replaced by values from the theme (LP: #616526) |
315 | HELP_TEXT_COLOR = parse_color("#bfbfbf") |
316 | WARNING_TEXT_COLOR = parse_color("red") |
317 | +LARGE_MARKUP = u'<span size="x-large">%s</span>' |
318 | |
319 | |
320 | def log_call(f): |
321 | @@ -173,9 +174,9 @@ |
322 | |
323 | def get_text(self): |
324 | """Get text only if it's not the label nor empty.""" |
325 | - result = super(LabeledEntry, self).get_text() |
326 | + result = super(LabeledEntry, self).get_text().decode('utf8') |
327 | if result == self.label or result.isspace(): |
328 | - result = '' |
329 | + result = u'' |
330 | return result |
331 | |
332 | def set_warning(self, warning_msg): |
333 | @@ -209,10 +210,10 @@ |
334 | self._done = False # whether the whole process was completed or not |
335 | |
336 | self.app_name = app_name |
337 | - self.app_label = '<b>%s</b>' % self.app_name |
338 | - self.ping_url = kwargs.get('ping_url', '') |
339 | - self.tc_url = kwargs.get('tc_url', '') |
340 | - self.help_text = kwargs.get('help_text', '') |
341 | + self.app_label = u'<b>%s</b>' % self.app_name |
342 | + self.ping_url = kwargs.get('ping_url', u'') |
343 | + self.tc_url = kwargs.get('tc_url', u'') |
344 | + self.help_text = kwargs.get('help_text', u'') |
345 | self.login_only = kwargs.get('login_only', False) |
346 | window_id = kwargs.get('window_id', 0) |
347 | self.close_callback = kwargs.get('close_callback', NO_OP) |
348 | @@ -338,15 +339,14 @@ |
349 | def success_vbox(self): |
350 | """The success page.""" |
351 | message = SUCCESS % {'app_name': self.app_name} |
352 | - message = '<span size="x-large">%s</span>' % message |
353 | + message = LARGE_MARKUP % message |
354 | self.finish_vbox.label.set_markup(message) |
355 | return self.finish_vbox |
356 | |
357 | @property |
358 | def error_vbox(self): |
359 | """The error page.""" |
360 | - self.finish_vbox.label.set_markup('<span size="x-large">%s</span>' % |
361 | - ERROR) |
362 | + self.finish_vbox.label.set_markup(LARGE_MARKUP % ERROR) |
363 | return self.finish_vbox |
364 | |
365 | # helpers |
366 | @@ -362,7 +362,7 @@ |
367 | result = f(app_name, *args, **kwargs) |
368 | else: |
369 | logger.info('%s: ignoring call since received app_name '\ |
370 | - '"%s" (expected "%s")', |
371 | + '%r (expected %r)', |
372 | f.__name__, app_name, self.app_name) |
373 | return result |
374 | |
375 | @@ -459,8 +459,7 @@ |
376 | |
377 | def _set_header(self, header): |
378 | """Set 'header' as the window title and header.""" |
379 | - markup = '<span size="x-large">%s</span>' |
380 | - self.header_label.set_markup(markup % header) |
381 | + self.header_label.set_markup(LARGE_MARKUP % header) |
382 | self.window.set_title(self.header_label.get_text()) # avoid markup |
383 | |
384 | def _set_current_page(self, current_page, warning_text=None): |
385 | @@ -792,9 +791,8 @@ |
386 | f = self.backend.register_user |
387 | error_handler = partial(self._handle_error, f, |
388 | self.on_user_registration_error) |
389 | - f(unicode(self.app_name), email1.decode('utf8'), |
390 | - password1.decode('utf8'), name.decode('utf8'), |
391 | - unicode(self._captcha_id), captcha_solution.decode('utf8'), |
392 | + f(self.app_name, self.user_email, self.user_password, name, |
393 | + self._captcha_id, captcha_solution, |
394 | reply_handler=NO_OP, error_handler=error_handler) |
395 | |
396 | def on_verify_token_button_clicked(self, *args, **kwargs): |
397 | @@ -1035,7 +1033,7 @@ |
398 | """Captcha image has been generated and is available to be shown.""" |
399 | if captcha_id is None: |
400 | logger.warning('on_captcha_generated: captcha_id is None for ' |
401 | - 'app_name "%s".', app_name) |
402 | + 'app_name %r.', app_name) |
403 | self._captcha_id = captcha_id |
404 | self._set_captcha_image() |
405 | |
406 | |
407 | === modified file 'ubuntu_sso/gtk/tests/test_gui.py' |
408 | --- ubuntu_sso/gtk/tests/test_gui.py 2012-02-11 01:51:57 +0000 |
409 | +++ ubuntu_sso/gtk/tests/test_gui.py 2012-02-21 23:01:20 +0000 |
410 | @@ -165,7 +165,7 @@ |
411 | tmp = Gdk.RGBA() |
412 | assert tmp.parse(gdk_color.to_string()) |
413 | |
414 | - msg = 'Text color must be "%s" (got "%s" instead).' |
415 | + msg = 'Text color must be %r (got %r instead).' |
416 | self.assertEqual(rgba_color, tmp, msg % (rgba_color, tmp)) |
417 | |
418 | def assert_backend_called(self, method, *args, **kwargs): |
419 | @@ -211,7 +211,7 @@ |
420 | def assert_correct_label(self): |
421 | """Check that the entry has the correct label.""" |
422 | # text content is correct |
423 | - msg = 'Text content must be "%s" (got "%s" instead).' |
424 | + msg = 'Text content must be %r (got %r instead).' |
425 | expected = self.label |
426 | actual = super(gui.LabeledEntry, self.entry).get_text() |
427 | self.assertEqual(expected, actual, msg % (expected, actual)) |
428 | @@ -231,7 +231,7 @@ |
429 | |
430 | def test_tooltip(self): |
431 | """Entry have the correct tooltip.""" |
432 | - msg = 'Tooltip must be "%s" (got "%s" instead).' |
433 | + msg = 'Tooltip must be %r (got %r instead).' |
434 | expected = self.label |
435 | actual = self.entry.get_tooltip_text() |
436 | # tooltip is correct |
437 | @@ -404,7 +404,7 @@ |
438 | |
439 | def assert_entries_are_packed_to_ui(self, container_name, entries): |
440 | """Every entry is properly packed in the ui 'container_name'.""" |
441 | - msg = 'Entry "%s" must be packed in "%s" but is not.' |
442 | + msg = 'Entry %r must be packed in %r but is not.' |
443 | container = getattr(self.ui, container_name) |
444 | for kind in entries: |
445 | name = '%s_entry' % kind |
446 | @@ -414,7 +414,7 @@ |
447 | |
448 | def assert_warnings_visibility(self, visible=False): |
449 | """Every warning label should be 'visible'.""" |
450 | - msg = '"%s" should have %sempty content.' |
451 | + msg = '%r should have %sempty content.' |
452 | for name in self.ui.widgets: |
453 | widget = getattr(self.ui, name) |
454 | if 'warning' in name: |
455 | @@ -429,7 +429,7 @@ |
456 | self.assertTrue(label.get_property('visible')) |
457 | |
458 | # warning content is correct |
459 | - actual = label.get_text() |
460 | + actual = label.get_text().decode('utf-8') |
461 | self.assertEqual(actual, message) |
462 | |
463 | # content color is correct |
464 | @@ -547,7 +547,7 @@ |
465 | |
466 | def test_initial_text_for_entries(self): |
467 | """Entries have the correct text at startup.""" |
468 | - msg = 'Text for "%s" must be "%s" (got "%s" instead).' |
469 | + msg = 'Text for %r must be %r (got %r instead).' |
470 | for name in self.ui.entries: |
471 | entry = getattr(self.ui, name) |
472 | expected = getattr(gui.utils.ui, name.upper()) |
473 | @@ -557,14 +557,14 @@ |
474 | |
475 | def test_entries_activates_default(self): |
476 | """Entries have the activates default prop set.""" |
477 | - msg = '"%s" must have activates_default set to True.' |
478 | + msg = '%r must have activates_default set to True.' |
479 | for name in self.ui.entries: |
480 | entry = getattr(self.ui, name) |
481 | self.assertTrue(entry.get_activates_default(), msg % (name,)) |
482 | |
483 | def test_password_fields_are_password(self): |
484 | """Password fields have the is_password flag set.""" |
485 | - msg = '"%s" should be a password LabeledEntry instance.' |
486 | + msg = '%r should be a password LabeledEntry instance.' |
487 | passwords = filter(lambda name: 'password' in name, |
488 | self.ui.entries) |
489 | for name in passwords: |
490 | @@ -578,7 +578,7 @@ |
491 | def test_cancel_buttons_close_window(self): |
492 | """Every cancel button should close the window when clicked.""" |
493 | self.patch(self.ui.backend, 'disconnect_from_signal', lambda *a: None) |
494 | - msg = '"%s" should close the window when clicked.' |
495 | + msg = '%r should close the window when clicked.' |
496 | buttons = filter(lambda name: 'cancel_button' in name or |
497 | 'close_button' in name, self.ui.widgets) |
498 | for name in buttons: |
499 | @@ -597,15 +597,16 @@ |
500 | self.ui.finish_success() |
501 | self.assert_pages_visibility(finish=True) |
502 | self.assertEqual(gui.SUCCESS % {'app_name': APP_NAME}, |
503 | - self.ui.finish_vbox.label.get_text()) |
504 | - result = self.ui.finish_vbox.label.get_text() |
505 | + self.ui.finish_vbox.label.get_text().decode('utf8')) |
506 | + result = self.ui.finish_vbox.label.get_text().decode('utf8') |
507 | self.assertTrue(self.ui.app_name in result) |
508 | |
509 | def test_finish_error_shows_error_page(self): |
510 | """When calling 'finish_error' the error page is shown.""" |
511 | self.ui.finish_error() |
512 | self.assert_pages_visibility(finish=True) |
513 | - self.assertEqual(gui.ERROR, self.ui.finish_vbox.label.get_text()) |
514 | + self.assertEqual(gui.ERROR, |
515 | + self.ui.finish_vbox.label.get_text().decode('utf8')) |
516 | |
517 | |
518 | class SetTransientForTestCase(UbuntuSSOClientTestCase): |
519 | @@ -649,9 +650,9 @@ |
520 | |
521 | def test_initial_text_for_header_label(self): |
522 | """The header must have the correct text at startup.""" |
523 | - msg = 'Text for the header must be "%s" (got "%s" instead).' |
524 | + msg = 'Text for the header must be %r (got %r instead).' |
525 | expected = gui.JOIN_HEADER_LABEL % {'app_name': APP_NAME} |
526 | - actual = self.ui.header_label.get_text() |
527 | + actual = self.ui.header_label.get_text().decode('utf8') |
528 | # text content is correct |
529 | self.assertEqual(expected, actual, msg % (expected, actual)) |
530 | |
531 | @@ -670,26 +671,26 @@ |
532 | |
533 | def test_initial_texts_for_checkbuttons(self): |
534 | """Check buttons have the correct text at startup.""" |
535 | - msg = 'Text for "%s" must be "%s" (got "%s" instead).' |
536 | + msg = 'Text for %r must be %r (got %r instead).' |
537 | expected = gui.YES_TO_UPDATES % {'app_name': APP_NAME} |
538 | - actual = self.ui.yes_to_updates_checkbutton.get_label() |
539 | + actual = self.ui.yes_to_updates_checkbutton.get_label().decode('utf8') |
540 | self.assertEqual(expected, actual, msg % ('yes_to_updates_checkbutton', |
541 | expected, actual)) |
542 | expected = gui.YES_TO_TC % {'app_name': APP_NAME} |
543 | - actual = self.ui.yes_to_tc_checkbutton.get_label() |
544 | + actual = self.ui.yes_to_tc_checkbutton.get_label().decode('utf8') |
545 | self.assertEqual(expected, actual, |
546 | msg % ('yes_to_tc_checkbutton', expected, actual)) |
547 | |
548 | def test_checkbutton_is_checked_at_startup(self): |
549 | """Checkbuttons are checked by default.""" |
550 | - msg = '"%s" is checked by default.' |
551 | + msg = '%r is checked by default.' |
552 | name = 'yes_to_updates_checkbutton' |
553 | widget = getattr(self.ui, name) |
554 | self.assertTrue(widget.get_active(), msg % name) |
555 | |
556 | def test_checkbutton_isnt_checked_at_startup(self): |
557 | """Checkbuttons are checked by default.""" |
558 | - msg = '"%s" is checked by default.' |
559 | + msg = '%r is checked by default.' |
560 | name = 'yes_to_tc_checkbutton' |
561 | widget = getattr(self.ui, name) |
562 | self.assertFalse(widget.get_active(), msg % name) |
563 | @@ -732,7 +733,8 @@ |
564 | 'the processing spinner should be active.') |
565 | self.assertTrue(label.get_property('visible'), |
566 | 'the processing label should be visible.') |
567 | - self.assertEqual(label.get_text(), gui.ONE_MOMENT_PLEASE, |
568 | + self.assertEqual(label.get_text().decode('utf8'), |
569 | + gui.ONE_MOMENT_PLEASE, |
570 | 'the processing label text must be correct.') |
571 | |
572 | def test_captcha_image_is_not_visible_at_startup(self): |
573 | @@ -775,7 +777,7 @@ |
574 | 'the captcha_loading spinner should be active.') |
575 | self.assertTrue(label.get_property('visible'), |
576 | 'the captcha_loading label should be visible.') |
577 | - self.assertEqual(label.get_text(), gui.LOADING, |
578 | + self.assertEqual(label.get_text().decode('utf8'), gui.LOADING, |
579 | 'the captcha_loading label text must be correct.') |
580 | |
581 | def test_join_ok_button_is_disabled_until_captcha_is_available(self): |
582 | @@ -814,7 +816,7 @@ |
583 | def test_on_captcha_generated_logs_captcha_id_when_none(self): |
584 | """If the captcha id is None, a warning is logged.""" |
585 | self.ui.on_captcha_generated(app_name=APP_NAME, captcha_id=None) |
586 | - self.assertTrue(self.memento.check(logging.WARNING, APP_NAME)) |
587 | + self.assertTrue(self.memento.check(logging.WARNING, repr(APP_NAME))) |
588 | self.assertTrue(self.memento.check(logging.WARNING, |
589 | 'captcha_id is None')) |
590 | |
591 | @@ -837,7 +839,7 @@ |
592 | |
593 | def test_login_button_has_correct_wording(self): |
594 | """The sign in button has the proper wording.""" |
595 | - actual = self.ui.login_button.get_label() |
596 | + actual = self.ui.login_button.get_label().decode('utf8') |
597 | self.assertEqual(gui.LOGIN_BUTTON_LABEL, actual) |
598 | |
599 | def test_join_ok_button_does_nothing_if_clicked_but_disabled(self): |
600 | @@ -870,7 +872,7 @@ |
601 | """When captcha was retrieved after error, the warning is removed.""" |
602 | self.ui.on_captcha_generation_error(APP_NAME, error=self.error) |
603 | self.ui.on_captcha_generated(app_name=APP_NAME, captcha_id=CAPTCHA_ID) |
604 | - self.assertEqual(self.ui.warning_label.get_text(), '') |
605 | + self.assertEqual(self.ui.warning_label.get_text().decode('utf8'), '') |
606 | |
607 | |
608 | class NoTermsAndConditionsTestCase(UbuntuSSOClientTestCase): |
609 | @@ -953,12 +955,13 @@ |
610 | |
611 | def test_tc_button_has_the_proper_wording(self): |
612 | """Terms & Conditions has the proper wording.""" |
613 | - self.assertEqual(self.ui.tc_button.get_label(), gui.TC_BUTTON) |
614 | + self.assertEqual(self.ui.tc_button.get_label().decode('utf8'), |
615 | + gui.TC_BUTTON) |
616 | |
617 | def test_tc_has_no_help_text(self): |
618 | """The help text is removed.""" |
619 | self.ui.on_tc_browser_notify_load_status(self.browser) |
620 | - self.assertEqual('', self.ui.help_label.get_text()) |
621 | + self.assertEqual('', self.ui.help_label.get_text().decode('utf8')) |
622 | |
623 | def test_tc_browser_opens_the_proper_url(self): |
624 | """Terms & Conditions browser shows the proper uri.""" |
625 | @@ -1115,8 +1118,8 @@ |
626 | |
627 | def test_help_label_display_correct_wording(self): |
628 | """The help_label display VERIFY_EMAIL_LABEL.""" |
629 | - msg = 'help_label must read "%s" (got "%s" instead).' |
630 | - actual = self.ui.help_label.get_label() |
631 | + msg = 'help_label must read %r (got %r instead).' |
632 | + actual = self.ui.help_label.get_label().decode('utf8') |
633 | expected = gui.VERIFY_EMAIL_LABEL % {'app_name': APP_NAME, |
634 | 'email': EMAIL} |
635 | self.assertEqual(expected, actual, msg % (expected, actual)) |
636 | @@ -1160,7 +1163,7 @@ |
637 | """On email validated the help text is not removed.""" |
638 | self.ui.on_email_validated(app_name=APP_NAME, email=EMAIL) |
639 | self.assertEqual(self.ui.verify_email_vbox.help_text, |
640 | - self.ui.help_label.get_label()) |
641 | + self.ui.help_label.get_label().decode('utf8')) |
642 | |
643 | def test_on_email_validation_error_verify_email_is_shown(self): |
644 | """On email validation error, the verify_email page is shown.""" |
645 | @@ -1186,16 +1189,16 @@ |
646 | def test_success_label_is_correct(self): |
647 | """The success message is correct.""" |
648 | self.assertEqual(gui.SUCCESS % {'app_name': APP_NAME}, |
649 | - self.ui.success_vbox.label.get_text()) |
650 | - markup = self.ui.success_vbox.label.get_label() |
651 | + self.ui.success_vbox.label.get_text().decode('utf8')) |
652 | + markup = self.ui.success_vbox.label.get_label().decode('utf8') |
653 | self.assertTrue('<span size="x-large">' in markup) |
654 | self.assertTrue(self.ui.app_name in markup) |
655 | |
656 | def test_error_label_is_correct(self): |
657 | """The error message is correct.""" |
658 | self.assertEqual(gui.ERROR, |
659 | - self.ui.error_vbox.label.get_text()) |
660 | - markup = self.ui.error_vbox.label.get_label() |
661 | + self.ui.error_vbox.label.get_text().decode('utf8')) |
662 | + markup = self.ui.error_vbox.label.get_label().decode('utf8') |
663 | self.assertTrue('<span size="x-large">' in markup) |
664 | |
665 | def test_on_finish_close_button_clicked_closes_window(self): |
666 | @@ -1346,7 +1349,7 @@ |
667 | """Password help text is correctly displayed.""" |
668 | self.assertTrue(self.ui.password_help_label.get_property('visible'), |
669 | 'password help text is visible.') |
670 | - self.assertEqual(self.ui.password_help_label.get_text(), |
671 | + self.assertEqual(self.ui.password_help_label.get_text().decode('utf8'), |
672 | gui.PASSWORD_HELP) |
673 | self.assertNotIn('register_user', self.ui.backend._called) |
674 | |
675 | @@ -1436,16 +1439,16 @@ |
676 | |
677 | def test_initial_text_for_header_label(self): |
678 | """The header must have the correct text when logging in.""" |
679 | - msg = 'Text for the header must be "%s" (got "%s" instead).' |
680 | + msg = 'Text for the header must be %r (got %r instead).' |
681 | expected = gui.LOGIN_HEADER_LABEL % {'app_name': APP_NAME} |
682 | - actual = self.ui.header_label.get_text() |
683 | + actual = self.ui.header_label.get_text().decode('utf8') |
684 | self.assertEqual(expected, actual, msg % (expected, actual)) |
685 | |
686 | def test_initial_text_for_help_label(self): |
687 | """The help must have the correct text at startup.""" |
688 | - msg = 'Text for the help must be "%s" (got "%s" instead).' |
689 | + msg = 'Text for the help must be %r (got %r instead).' |
690 | expected = gui.CONNECT_HELP_LABEL % {'app_name': APP_NAME} |
691 | - actual = self.ui.help_label.get_text() |
692 | + actual = self.ui.help_label.get_text().decode('utf8') |
693 | self.assertEqual(expected, actual, msg % (expected, actual)) |
694 | |
695 | def test_entries_are_packed_to_ui_for_login(self): |
696 | @@ -1628,23 +1631,23 @@ |
697 | |
698 | def test_forgotten_password_button_has_the_proper_wording(self): |
699 | """The forgotten_password_button has the proper wording.""" |
700 | - self.assertEqual(self.ui.forgotten_password_button.get_label(), |
701 | - gui.FORGOTTEN_PASSWORD_BUTTON) |
702 | + actual = self.ui.forgotten_password_button.get_label() |
703 | + self.assertEqual(actual.decode('utf8'), gui.FORGOTTEN_PASSWORD_BUTTON) |
704 | |
705 | def test_on_forgotten_password_button_clicked_help_text(self): |
706 | """Clicking forgotten_password_button the help is properly changed.""" |
707 | wanted = gui.REQUEST_PASSWORD_TOKEN_LABEL % {'app_name': APP_NAME} |
708 | - self.assertEqual(self.ui.help_label.get_text(), wanted) |
709 | + self.assertEqual(self.ui.help_label.get_text().decode('utf8'), wanted) |
710 | |
711 | def test_on_forgotten_password_button_clicked_header_label(self): |
712 | """Clicking forgotten_password_button the title is properly changed.""" |
713 | - self.assertEqual(self.ui.header_label.get_text(), |
714 | + self.assertEqual(self.ui.header_label.get_text().decode('utf8'), |
715 | gui.RESET_PASSWORD) |
716 | |
717 | def test_on_forgotten_password_button_clicked_ok_button(self): |
718 | """Clicking forgotten_password_button the ok button reads 'Next'.""" |
719 | - self.assertEqual(self.ui.request_password_token_ok_button.get_label(), |
720 | - gui.NEXT) |
721 | + actual = self.ui.request_password_token_ok_button.get_label() |
722 | + self.assertEqual(actual.decode('utf8'), gui.NEXT) |
723 | |
724 | def test_on_forgotten_password_button_clicked_morphs_window(self): |
725 | """Clicking forgotten_password_button the proper page is shown.""" |
726 | @@ -1691,7 +1694,7 @@ |
727 | self.click_request_password_token_with_valid_data() |
728 | self.ui.on_password_reset_token_sent(app_name=APP_NAME, email=EMAIL) |
729 | |
730 | - self.assertEqual(self.ui.help_label.get_text(), |
731 | + self.assertEqual(self.ui.help_label.get_text().decode('utf8'), |
732 | gui.SET_NEW_PASSWORD_LABEL % {'email': EMAIL}) |
733 | |
734 | def test_on_password_reset_token_sent_ok_button(self): |
735 | @@ -1699,8 +1702,8 @@ |
736 | self.click_request_password_token_with_valid_data() |
737 | self.ui.on_password_reset_token_sent(app_name=APP_NAME, email=EMAIL) |
738 | |
739 | - self.assertEqual(self.ui.set_new_password_ok_button.get_label(), |
740 | - gui.RESET_PASSWORD) |
741 | + actual = self.ui.set_new_password_ok_button.get_label() |
742 | + self.assertEqual(actual.decode('utf8'), gui.RESET_PASSWORD) |
743 | |
744 | def test_on_password_reset_error_shows_login_page(self): |
745 | """When reset token wasn't successfuly sent the login page is shown.""" |
746 | @@ -1872,8 +1875,8 @@ |
747 | """Password help text is correctly displayed.""" |
748 | visible = self.ui.reset_password_help_label.get_property('visible') |
749 | self.assertTrue(visible, 'password help text is visible.') |
750 | - self.assertEqual(self.ui.reset_password_help_label.get_text(), |
751 | - gui.PASSWORD_HELP) |
752 | + actual = self.ui.reset_password_help_label.get_text() |
753 | + self.assertEqual(actual.decode('utf8'), gui.PASSWORD_HELP) |
754 | self.assertNotIn('set_new_password', self.ui.backend._called) |
755 | |
756 | def test_warning_is_shown_if_password_mismatch(self): |
757 | @@ -1951,7 +1954,7 @@ |
758 | """Callbacks do nothing but logging when app_name doesn't match.""" |
759 | mismatch_app_name = self.ui.app_name * 2 |
760 | for method in self.ui._signals.itervalues(): |
761 | - msgs = ('ignoring', method.__name__, mismatch_app_name) |
762 | + msgs = ('ignoring', method.__name__, repr(mismatch_app_name)) |
763 | method(mismatch_app_name, 'dummy') |
764 | self.assertTrue(self.memento.check(logging.INFO, *msgs)) |
765 | self.memento.records = [] |
766 | @@ -2068,7 +2071,8 @@ |
767 | |
768 | def test_help_text_is_used(self): |
769 | """The passed help_text is used.""" |
770 | - self.assertEqual(self.ui.help_label.get_text(), HELP_TEXT) |
771 | + self.assertEqual(self.ui.help_label.get_text().decode('utf8'), |
772 | + HELP_TEXT) |
773 | |
774 | |
775 | class ReturnCodeTestCase(UbuntuSSOClientTestCase): |
776 | @@ -2087,7 +2091,7 @@ |
777 | def test_every_cancel_calls_proper_callback(self): |
778 | """When any cancel button is clicked, USER_CANCELLATION is called.""" |
779 | self.patch(self.ui.backend, 'disconnect_from_signal', lambda *a: None) |
780 | - msg = 'USER_CANCELLATION should be returned when "%s" is clicked.' |
781 | + msg = 'USER_CANCELLATION should be returned when %r is clicked.' |
782 | buttons = filter(lambda name: 'cancel_button' in name, self.ui.widgets) |
783 | for name in buttons: |
784 | widget = getattr(self.ui, name) |
785 | |
786 | === modified file 'ubuntu_sso/keyring/tests/test_linux.py' |
787 | --- ubuntu_sso/keyring/tests/test_linux.py 2012-01-26 15:34:16 +0000 |
788 | +++ ubuntu_sso/keyring/tests/test_linux.py 2012-02-21 23:01:20 +0000 |
789 | @@ -26,7 +26,6 @@ |
790 | |
791 | from ubuntu_sso import keyring as common_keyring |
792 | from ubuntu_sso.keyring import linux as keyring |
793 | -from ubuntu_sso.tests import APP_NAME |
794 | |
795 | |
796 | class MockItem(object): |
797 | @@ -168,9 +167,9 @@ |
798 | sample_creds = {"name": "sample creds name"} |
799 | kr = keyring.Keyring() |
800 | self.patch(keyring, "get_token_name", keyring.get_old_token_name) |
801 | - yield kr.set_credentials(APP_NAME, sample_creds) |
802 | + yield kr.set_credentials("app name", sample_creds) |
803 | |
804 | - result = yield kr.get_credentials(APP_NAME) |
805 | + result = yield kr.get_credentials("app name") |
806 | self.assertEqual(result, sample_creds) |
807 | |
808 | @inlineCallbacks |
809 | |
810 | === modified file 'ubuntu_sso/main/__init__.py' |
811 | --- ubuntu_sso/main/__init__.py 2012-02-11 01:51:57 +0000 |
812 | +++ ubuntu_sso/main/__init__.py 2012-02-21 23:01:20 +0000 |
813 | @@ -318,7 +318,7 @@ |
814 | def CredentialsFound(self, app_name, credentials): |
815 | """Signal thrown when the credentials are found.""" |
816 | self.ref_count -= 1 |
817 | - logger.info('%s: emitting CredentialsFound with app_name "%s".', |
818 | + logger.info('%s: emitting CredentialsFound with app_name %r.', |
819 | self.__class__.__name__, app_name) |
820 | self.proxy.CredentialsFound(app_name, credentials) |
821 | |
822 | |
823 | === modified file 'ubuntu_sso/main/linux.py' |
824 | --- ubuntu_sso/main/linux.py 2012-02-14 21:53:58 +0000 |
825 | +++ ubuntu_sso/main/linux.py 2012-02-21 23:01:20 +0000 |
826 | @@ -25,7 +25,6 @@ |
827 | |
828 | """ |
829 | |
830 | -import os |
831 | import signal |
832 | |
833 | import dbus |
834 | @@ -439,10 +438,10 @@ |
835 | return defer.succeed(result) |
836 | |
837 | |
838 | -if os.environ.get('USE_QT_MAINLOOP'): |
839 | +try: |
840 | from ubuntu_sso.main import qt |
841 | source = qt |
842 | -else: |
843 | +except ImportError: # no PyQt4.QtCore in the system |
844 | from ubuntu_sso.main import glib |
845 | source = glib |
846 | |
847 | |
848 | === modified file 'ubuntu_sso/main/qt.py' |
849 | --- ubuntu_sso/main/qt.py 2012-01-26 14:54:13 +0000 |
850 | +++ ubuntu_sso/main/qt.py 2012-02-21 23:01:20 +0000 |
851 | @@ -22,10 +22,30 @@ |
852 | |
853 | from PyQt4 import QtCore |
854 | |
855 | - |
856 | -def timeout_func(*a, **kw): |
857 | +TIMERS = set() |
858 | + |
859 | + |
860 | +def timeout_func(interval, callback, *a, **kw): |
861 | """Delay import of dynamic bindings to avoid crashes.""" |
862 | - # use a QTimer to simulate a looping call |
863 | + |
864 | + # QTimers don't support priorities |
865 | + kw.pop("priority", None) |
866 | + |
867 | + timer = QtCore.QTimer() |
868 | + TIMERS.add(timer) |
869 | + |
870 | + def _callback(): |
871 | + """Call the real callback, with arguments, until it returns False.""" |
872 | + if timer in TIMERS: |
873 | + result = callback(*a, **kw) |
874 | + if not result: |
875 | + timer.stop() |
876 | + TIMERS.remove(timer) |
877 | + # Probably overkill |
878 | + timer.deleteLater() |
879 | + |
880 | + timer.timeout.connect(_callback) |
881 | + timer.start(interval) |
882 | |
883 | |
884 | def shutdown_func(*a, **kw): |
885 | |
886 | === modified file 'ubuntu_sso/main/tests/test_common.py' |
887 | --- ubuntu_sso/main/tests/test_common.py 2012-02-10 17:18:22 +0000 |
888 | +++ ubuntu_sso/main/tests/test_common.py 2012-02-21 23:01:20 +0000 |
889 | @@ -919,7 +919,8 @@ |
890 | @defer.inlineCallbacks |
891 | def setUp(self): |
892 | yield super(CredentialsManagementOpsTestCase, self).setUp() |
893 | - self.args = dict((k, str(v)) for k, v in self.base_args.iteritems()) |
894 | + self.args = dict(self.base_args) |
895 | + self.args[WINDOW_ID_KEY] = str(self.args[WINDOW_ID_KEY]) |
896 | self.cred_args = self.base_args.copy() |
897 | |
898 | def test_register(self): |
899 | @@ -955,12 +956,16 @@ |
900 | class CredentialsManagementSignalsTestCase(CredentialsManagementTestCase): |
901 | """Tests for the CredentialsManagement DBus signals.""" |
902 | |
903 | + def assert_signal_logged(self, signal, *args): |
904 | + """Check that signal info was properly logged.""" |
905 | + signal(APP_NAME, *args) |
906 | + msgs = [self.obj.__class__.__name__, |
907 | + signal.__name__, repr(APP_NAME)] |
908 | + self.assertTrue(self.memento.check_info(*msgs)) |
909 | + |
910 | def test_credentials_found(self): |
911 | """The CredentialsFound signal.""" |
912 | - self.obj.CredentialsFound(APP_NAME, TOKEN) |
913 | - msgs = (self.obj.__class__.__name__, |
914 | - self.obj.CredentialsFound.__name__, APP_NAME) |
915 | - self.assertTrue(self.memento.check_info(*msgs)) |
916 | + self.assert_signal_logged(self.obj.CredentialsFound, TOKEN) |
917 | |
918 | msg = 'credentials must not be logged (found %r in log).' |
919 | for val in TOKEN.itervalues(): |
920 | @@ -968,24 +973,15 @@ |
921 | |
922 | def test_credentials_not_found(self): |
923 | """The CredentialsNotFound signal.""" |
924 | - self.obj.CredentialsNotFound(APP_NAME) |
925 | - msgs = (self.obj.__class__.__name__, |
926 | - self.obj.CredentialsNotFound.__name__, APP_NAME) |
927 | - self.assertTrue(self.memento.check_info(*msgs)) |
928 | + self.assert_signal_logged(self.obj.CredentialsNotFound) |
929 | |
930 | def test_credentials_cleared(self): |
931 | """The CredentialsCleared signal.""" |
932 | - self.obj.CredentialsCleared(APP_NAME) |
933 | - msgs = (self.obj.__class__.__name__, |
934 | - self.obj.CredentialsCleared.__name__, APP_NAME) |
935 | - self.assertTrue(self.memento.check_info(*msgs)) |
936 | + self.assert_signal_logged(self.obj.CredentialsCleared) |
937 | |
938 | def test_credentials_stored(self): |
939 | """The CredentialsStored signal.""" |
940 | - self.obj.CredentialsStored(APP_NAME) |
941 | - msgs = (self.obj.__class__.__name__, |
942 | - self.obj.CredentialsStored.__name__, APP_NAME) |
943 | - self.assertTrue(self.memento.check_info(*msgs)) |
944 | + self.assert_signal_logged(self.obj.CredentialsStored) |
945 | |
946 | def test_credentials_error(self): |
947 | """The CredentialsError signal.""" |
948 | @@ -993,15 +989,12 @@ |
949 | self.obj.CredentialsError(APP_NAME, error) |
950 | msgs = (self.obj.__class__.__name__, |
951 | self.obj.CredentialsError.__name__, |
952 | - APP_NAME, str(error)) |
953 | + repr(APP_NAME), repr(error)) |
954 | self.assertTrue(self.memento.check_error(*msgs)) |
955 | |
956 | def test_authorization_denied(self): |
957 | """The AuthorizationDenied signal.""" |
958 | - self.obj.AuthorizationDenied(APP_NAME) |
959 | - msgs = (self.obj.__class__.__name__, |
960 | - self.obj.AuthorizationDenied.__name__, APP_NAME) |
961 | - self.assertTrue(self.memento.check_info(*msgs)) |
962 | + self.assert_signal_logged(self.obj.AuthorizationDenied) |
963 | |
964 | |
965 | class UbuntuSSOServiceTestCase(BaseTestCase): |
966 | |
967 | === added file 'ubuntu_sso/main/tests/test_qt.py' |
968 | --- ubuntu_sso/main/tests/test_qt.py 1970-01-01 00:00:00 +0000 |
969 | +++ ubuntu_sso/main/tests/test_qt.py 2012-02-21 23:01:20 +0000 |
970 | @@ -0,0 +1,69 @@ |
971 | +# -*- coding: utf-8 -*- |
972 | +# |
973 | +# Copyright 2012 Canonical Ltd. |
974 | +# |
975 | +# This program is free software: you can redistribute it and/or modify it |
976 | +# under the terms of the GNU General Public License version 3, as published |
977 | +# by the Free Software Foundation. |
978 | +# |
979 | +# This program is distributed in the hope that it will be useful, but |
980 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
981 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
982 | +# PURPOSE. See the GNU General Public License for more details. |
983 | +# |
984 | +# You should have received a copy of the GNU General Public License along |
985 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
986 | +"""Qt specific tests for the main module.""" |
987 | + |
988 | +# pylint: disable=F0401 |
989 | +from PyQt4 import QtCore |
990 | +from twisted.internet import defer |
991 | + |
992 | +from ubuntu_sso.main import qt |
993 | +from ubuntu_sso.tests import TestCase |
994 | + |
995 | + |
996 | +class MiscTestCase(TestCase): |
997 | + """Tests for module level misc functions.""" |
998 | + |
999 | + def clean_timers(self): |
1000 | + """Remove all timers.""" |
1001 | + qt.TIMERS = set() |
1002 | + |
1003 | + @defer.inlineCallbacks |
1004 | + def setUp(self): |
1005 | + yield super(MiscTestCase, self).setUp() |
1006 | + self.addCleanup(self.clean_timers) |
1007 | + |
1008 | + def test_timeout_func_ignores_priority(self): |
1009 | + """Should not pass priority as argument.""" |
1010 | + qt.timeout_func(0, self._set_called, priority="crazy") |
1011 | + QtCore.QCoreApplication.instance().processEvents() |
1012 | + self.assertEqual(self._called, ((), {})) |
1013 | + |
1014 | + def test_timeout_func_keeps_reference(self): |
1015 | + """Should keep a reference to the timer created.""" |
1016 | + self.assertEqual(len(qt.TIMERS), 0) |
1017 | + qt.timeout_func(0, self._set_called, priority="crazy") |
1018 | + self.assertEqual(len(qt.TIMERS), 1) |
1019 | + |
1020 | + def test_timeout_func_removes_reference(self): |
1021 | + """Remove reference to timer when callback returns False.""" |
1022 | + self.assertEqual(len(qt.TIMERS), 0) |
1023 | + qt.timeout_func(0, self._set_called, priority="crazy") |
1024 | + self.assertEqual(len(qt.TIMERS), 1) |
1025 | + QtCore.QCoreApplication.instance().processEvents() |
1026 | + self.assertEqual(len(qt.TIMERS), 0) |
1027 | + |
1028 | + def test_timeout_func_timer_activation(self): |
1029 | + """The timer should be activated with the right period.""" |
1030 | + self.assertEqual(len(qt.TIMERS), 0) |
1031 | + qt.timeout_func(1337, self._set_called, priority="crazy") |
1032 | + self.assertEqual(len(qt.TIMERS), 1) |
1033 | + self.assertEqual(list(qt.TIMERS)[0].interval(), 1337) |
1034 | + |
1035 | + def test_timeout_func_argument_passing(self): |
1036 | + """The right arguments should be passed to the callback.""" |
1037 | + qt.timeout_func(0, self._set_called, 1, name="a") |
1038 | + QtCore.QCoreApplication.instance().processEvents() |
1039 | + self.assertEqual(self._called, ((1,), {"name": "a"})) |
1040 | |
1041 | === modified file 'ubuntu_sso/qt/__init__.py' |
1042 | --- ubuntu_sso/qt/__init__.py 2012-02-09 18:28:40 +0000 |
1043 | +++ ubuntu_sso/qt/__init__.py 2012-02-21 23:01:20 +0000 |
1044 | @@ -16,21 +16,11 @@ |
1045 | |
1046 | """The Qt graphical interface for the Ubuntu Single Sign On Client.""" |
1047 | |
1048 | -import gettext |
1049 | import collections |
1050 | |
1051 | |
1052 | -_ = gettext.gettext |
1053 | - |
1054 | ERROR_ALL = '__all__' |
1055 | ERROR_MESSAGE = 'message' |
1056 | -LOCAL_FOLDERS_TITLE = _("Syncing your computer with the cloud") |
1057 | -LOCAL_FOLDERS_SPACE_HEADER = _("Space (%s)") |
1058 | -LOCAL_FOLDERS_OFFER_LABEL = _("The folders you have selected to sync " |
1059 | - "take over your %(quota)s space. You can remove some folders or add " |
1060 | - "some extra space") |
1061 | -LOCAL_FOLDERS_CALCULATING = _("Calculating") |
1062 | -NEXT = _("Next") |
1063 | |
1064 | |
1065 | # Based on the gtk implementation |
1066 | |
1067 | === modified file 'ubuntu_sso/qt/common.py' |
1068 | --- ubuntu_sso/qt/common.py 2012-02-09 19:21:09 +0000 |
1069 | +++ ubuntu_sso/qt/common.py 2012-02-21 23:01:20 +0000 |
1070 | @@ -18,6 +18,7 @@ |
1071 | """Common functionality used by the UI modules.""" |
1072 | |
1073 | import re |
1074 | + |
1075 | from ubuntu_sso.utils.ui import ( |
1076 | PASSWORD_DIGIT, |
1077 | PASSWORD_LENGTH, |
1078 | |
1079 | === modified file 'ubuntu_sso/qt/current_user_sign_in_page.py' |
1080 | --- ubuntu_sso/qt/current_user_sign_in_page.py 2012-02-13 20:27:48 +0000 |
1081 | +++ ubuntu_sso/qt/current_user_sign_in_page.py 2012-02-21 23:01:20 +0000 |
1082 | @@ -16,15 +16,17 @@ |
1083 | |
1084 | """Page to allow the user to login into Ubuntu Single Sign On.""" |
1085 | |
1086 | -import gettext |
1087 | +from functools import partial |
1088 | |
1089 | from PyQt4 import QtGui, QtCore |
1090 | from twisted.internet import defer |
1091 | |
1092 | +from ubuntu_sso import NO_OP |
1093 | from ubuntu_sso.qt import build_general_error_message |
1094 | from ubuntu_sso.qt.gui import SSOWizardPage |
1095 | from ubuntu_sso.logger import setup_logging |
1096 | from ubuntu_sso.utils.ui import ( |
1097 | + CANCEL_BUTTON, |
1098 | EMAIL_LABEL, |
1099 | FORGOTTEN_PASSWORD_BUTTON, |
1100 | is_correct_email, |
1101 | @@ -33,10 +35,10 @@ |
1102 | ) |
1103 | |
1104 | |
1105 | -FORGOTTEN_PASSWORD_LINK_STYLE = '<a href="#">{forgotten_text}</a>' |
1106 | - |
1107 | - |
1108 | -_ = gettext.gettext |
1109 | +FORGOTTEN_PASSWORD_LINK_STYLE = ('<a href="#" style="color:#dd4814;">' |
1110 | + '{forgotten_text}</a>') |
1111 | + |
1112 | + |
1113 | logger = setup_logging('ubuntu_sso.current_user_sign_in_page') |
1114 | |
1115 | |
1116 | @@ -85,8 +87,7 @@ |
1117 | |
1118 | def initializePage(self): |
1119 | """Setup UI details.""" |
1120 | - self.setButtonText(QtGui.QWizard.CancelButton, |
1121 | - _("Cancel")) |
1122 | + self.setButtonText(QtGui.QWizard.CancelButton, CANCEL_BUTTON) |
1123 | # Layout without custom button 1, |
1124 | # without finish button |
1125 | self.wizard().setButtonLayout([ |
1126 | @@ -103,6 +104,10 @@ |
1127 | self.ui.sign_in_button.style().polish( |
1128 | self.ui.sign_in_button) |
1129 | |
1130 | + def cleanupPage(self): |
1131 | + """Reset the wizard buttons.""" |
1132 | + self.wizard().setButtonLayout([QtGui.QWizard.Stretch]) |
1133 | + |
1134 | def _set_translated_strings(self): |
1135 | """Set the translated strings.""" |
1136 | logger.debug('CurrentUserSignInPage._set_translated_strings') |
1137 | @@ -147,19 +152,24 @@ |
1138 | args = args + (self.ping_url,) |
1139 | else: |
1140 | f = self.backend.login |
1141 | - f(*args) |
1142 | + |
1143 | + self.overlay.show() |
1144 | + error_handler = partial(self._handle_error, f, self.on_login_error) |
1145 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
1146 | |
1147 | def on_login_error(self, app_name, error): |
1148 | """There was an error when login in.""" |
1149 | # let the user know |
1150 | logger.error('Got error when login %s, error: %s', |
1151 | self.app_name, error) |
1152 | + self.overlay.hide() |
1153 | self.message_box.critical(self, self.app_name, |
1154 | build_general_error_message(error)) |
1155 | |
1156 | def on_logged_in(self, app_name, result): |
1157 | """We managed to log in.""" |
1158 | logger.info('Logged in for %s', app_name) |
1159 | + self.overlay.hide() |
1160 | email = unicode(self.ui.email_edit.text()) |
1161 | self.userLoggedIn.emit(app_name, email) |
1162 | logger.debug('Wizard.loginSuccess emitted.') |
1163 | |
1164 | === modified file 'ubuntu_sso/qt/email_verification_page.py' |
1165 | --- ubuntu_sso/qt/email_verification_page.py 2012-02-13 14:04:27 +0000 |
1166 | +++ ubuntu_sso/qt/email_verification_page.py 2012-02-21 23:01:20 +0000 |
1167 | @@ -16,9 +16,12 @@ |
1168 | |
1169 | """Email Verification page UI.""" |
1170 | |
1171 | +from functools import partial |
1172 | + |
1173 | from PyQt4 import QtCore |
1174 | from twisted.internet import defer |
1175 | |
1176 | +from ubuntu_sso import NO_OP |
1177 | from ubuntu_sso.qt import build_general_error_message |
1178 | from ubuntu_sso.qt.gui import SSOWizardPage |
1179 | from ubuntu_sso.logger import setup_logging |
1180 | @@ -115,7 +118,9 @@ |
1181 | logger.info('Calling validate_email with email %r, password <hidden>, ' |
1182 | 'app_name %r and email_token %r.', self.email, |
1183 | self.app_name, code) |
1184 | - f(*args) |
1185 | + error_handler = partial(self._handle_error, f, |
1186 | + self.on_email_validation_error) |
1187 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
1188 | |
1189 | def on_email_validated(self, app_name, *args, **kwargs): |
1190 | """Signal thrown after the email is validated.""" |
1191 | |
1192 | === modified file 'ubuntu_sso/qt/enhanced_check_box.py' |
1193 | --- ubuntu_sso/qt/enhanced_check_box.py 2012-02-02 15:57:02 +0000 |
1194 | +++ ubuntu_sso/qt/enhanced_check_box.py 2012-02-21 23:01:20 +0000 |
1195 | @@ -18,7 +18,7 @@ |
1196 | |
1197 | """Customized Check Box to support links.""" |
1198 | |
1199 | -from PyQt4 import QtGui |
1200 | +from PyQt4 import QtGui, QtCore |
1201 | |
1202 | |
1203 | class EnhancedCheckBox(QtGui.QCheckBox): |
1204 | @@ -28,9 +28,12 @@ |
1205 | QtGui.QCheckBox.__init__(self) |
1206 | hbox = QtGui.QHBoxLayout() |
1207 | self.text_label = QtGui.QLabel(text) |
1208 | + self.text_label.setAlignment(QtCore.Qt.AlignTop) |
1209 | self.text_label.setOpenExternalLinks(True) |
1210 | padding = self.iconSize().width() |
1211 | - self.text_label.setStyleSheet("padding-left: {0}px;".format(padding)) |
1212 | + self.text_label.setStyleSheet("margin-top: -3px;" |
1213 | + "padding-left: {0}px;".format(padding)) |
1214 | + hbox.setContentsMargins(padding, 0, 0, 0) |
1215 | hbox.addWidget(self.text_label) |
1216 | self.setLayout(hbox) |
1217 | |
1218 | |
1219 | === modified file 'ubuntu_sso/qt/forgotten_password_page.py' |
1220 | --- ubuntu_sso/qt/forgotten_password_page.py 2012-02-13 21:50:16 +0000 |
1221 | +++ ubuntu_sso/qt/forgotten_password_page.py 2012-02-21 23:01:20 +0000 |
1222 | @@ -16,9 +16,12 @@ |
1223 | |
1224 | """Forgotten Password page UI.""" |
1225 | |
1226 | +from functools import partial |
1227 | + |
1228 | from PyQt4 import QtCore |
1229 | from twisted.internet import defer |
1230 | |
1231 | +from ubuntu_sso import NO_OP |
1232 | from ubuntu_sso.qt.gui import SSOWizardEnhancedEditPage |
1233 | from ubuntu_sso.utils.ui import ( |
1234 | EMAIL_LABEL, |
1235 | @@ -139,12 +142,21 @@ |
1236 | def _connect_ui(self): |
1237 | """Connect the diff signals from the Ui.""" |
1238 | self.email_address_line_edit.textChanged.connect(self._validate) |
1239 | - self.send_button.clicked.connect( |
1240 | - lambda: self.backend.request_password_reset_token( |
1241 | - self.app_name, |
1242 | - self.email_address)) |
1243 | + |
1244 | + self.send_button.clicked.connect(self.request_new_password) |
1245 | self.try_again_button.clicked.connect(self.on_try_again) |
1246 | |
1247 | + def request_new_password(self): |
1248 | + """Send the request password operation.""" |
1249 | + args = (self.app_name, self.email_address) |
1250 | + f = self.backend.request_password_reset_token |
1251 | + |
1252 | + error_handler = partial(self._handle_error, f, |
1253 | + self.on_password_reset_error) |
1254 | + |
1255 | + self.overlay.show() |
1256 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
1257 | + |
1258 | def _validate(self): |
1259 | """Validate that we have an email.""" |
1260 | email = unicode(self.email_address_line_edit.text()) |
1261 | @@ -163,12 +175,14 @@ |
1262 | def on_password_reset_token_sent(self, app_name, result): |
1263 | """Action taken when we managed to get the password reset done.""" |
1264 | # ignore the result and move to the reset page |
1265 | + self.overlay.hide() |
1266 | self.passwordResetTokenSent.emit() |
1267 | # pylint: enable=W0212 |
1268 | |
1269 | def on_password_reset_error(self, app_name, error): |
1270 | """Action taken when there was an error requesting the reset.""" |
1271 | # set the error message |
1272 | + self.overlay.hide() |
1273 | msg = REQUEST_PASSWORD_TOKEN_TECH_ERROR |
1274 | if error['errtype'] == 'ResetPasswordTokenError': |
1275 | # the account provided is wrong, lets tell the user to try |
1276 | |
1277 | === modified file 'ubuntu_sso/qt/gui.py' |
1278 | --- ubuntu_sso/qt/gui.py 2012-02-13 16:16:03 +0000 |
1279 | +++ ubuntu_sso/qt/gui.py 2012-02-21 23:01:20 +0000 |
1280 | @@ -15,7 +15,6 @@ |
1281 | # with this program. If not, see <http://www.gnu.org/licenses/>. |
1282 | """Qt implementation of the UI.""" |
1283 | |
1284 | -import gettext |
1285 | from functools import wraps |
1286 | |
1287 | # pylint: disable=F0401,E0611 |
1288 | @@ -23,8 +22,8 @@ |
1289 | from PyQt4.QtCore import Qt |
1290 | from PyQt4.QtGui import ( |
1291 | QApplication, |
1292 | - QWidget, |
1293 | QCursor, |
1294 | + QFrame, |
1295 | QHBoxLayout, |
1296 | QVBoxLayout, |
1297 | QMessageBox, |
1298 | @@ -37,18 +36,19 @@ |
1299 | from ubuntu_sso import main |
1300 | from ubuntu_sso.qt.loadingoverlay import LoadingOverlay |
1301 | from ubuntu_sso.logger import setup_logging |
1302 | - |
1303 | - |
1304 | -_ = gettext.gettext |
1305 | +from ubuntu_sso.utils.ui import GENERIC_BACKEND_ERROR |
1306 | + |
1307 | + |
1308 | logger = setup_logging('ubuntu_sso.gui') |
1309 | |
1310 | |
1311 | -class Header(QWidget): |
1312 | +class Header(QFrame): |
1313 | """Header Class for Title and Subtitle in all wizard pages.""" |
1314 | |
1315 | def __init__(self): |
1316 | """Create a new instance.""" |
1317 | - QWidget.__init__(self) |
1318 | + super(Header, self).__init__() |
1319 | + self.setObjectName('header') |
1320 | vbox = QVBoxLayout(self) |
1321 | vbox.setContentsMargins(0, 0, 0, 10) |
1322 | self.title_label = QLabel() |
1323 | @@ -149,6 +149,12 @@ |
1324 | match = self.backend.connect_to_signal(signal, method) |
1325 | self._signals_receivers[signal] = match |
1326 | |
1327 | + def _handle_error(self, remote_call, handler, error): |
1328 | + """Handle any error when calling the remote backend.""" |
1329 | + logger.error('Remote call %r failed with: %r', remote_call, error) |
1330 | + errordict = {'message': GENERIC_BACKEND_ERROR} |
1331 | + handler(self.app_name, errordict) |
1332 | + |
1333 | |
1334 | class EnhancedLineEdit(object): |
1335 | """Represents and enhanced lineedit. |
1336 | |
1337 | === modified file 'ubuntu_sso/qt/main.py' |
1338 | --- ubuntu_sso/qt/main.py 2012-02-13 15:43:59 +0000 |
1339 | +++ ubuntu_sso/qt/main.py 2012-02-21 23:01:20 +0000 |
1340 | @@ -18,14 +18,26 @@ |
1341 | |
1342 | import sys |
1343 | |
1344 | -from PyQt4 import QtGui |
1345 | +from PyQt4 import QtGui, QtCore |
1346 | |
1347 | +# Module used to include the resources into this file |
1348 | +# Unused import resources_rc, pylint: disable=W0611 |
1349 | +from ubuntu_sso.qt.ui import resources_rc |
1350 | +# pylint: enable=W0611 |
1351 | from ubuntu_sso.qt.ubuntu_sso_wizard import UbuntuSSOClientGUI |
1352 | |
1353 | |
1354 | def main(**kwargs): |
1355 | """Start the QT mainloop and open the main window.""" |
1356 | app = QtGui.QApplication(sys.argv) |
1357 | + |
1358 | + QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-R.ttf') |
1359 | + QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-B.ttf') |
1360 | + |
1361 | + # Apply Style Sheet -- The windows version may be different |
1362 | + qss = QtCore.QResource(":/stylesheet.qss") |
1363 | + app.setStyleSheet(qss.data()) |
1364 | + |
1365 | # Unused variable 'ui', pylint: disable=W0612 |
1366 | ui = UbuntuSSOClientGUI(close_callback=app.exit, **kwargs) |
1367 | app.exec_() |
1368 | |
1369 | === modified file 'ubuntu_sso/qt/network_detection_page.py' |
1370 | --- ubuntu_sso/qt/network_detection_page.py 2012-02-13 20:27:48 +0000 |
1371 | +++ ubuntu_sso/qt/network_detection_page.py 2012-02-21 23:01:20 +0000 |
1372 | @@ -16,17 +16,17 @@ |
1373 | |
1374 | """Pages from SSO.""" |
1375 | |
1376 | - |
1377 | -import gettext |
1378 | - |
1379 | from twisted.internet import defer |
1380 | from PyQt4 import QtGui |
1381 | |
1382 | from ubuntu_sso import networkstate |
1383 | |
1384 | from ubuntu_sso.qt.ui import network_detection_ui |
1385 | - |
1386 | -_ = gettext.gettext |
1387 | +from ubuntu_sso.utils.ui import ( |
1388 | + CLOSE_AND_SETUP_LATER, |
1389 | + NETWORK_DETECTION_TITLE, |
1390 | + TRY_AGAIN_BUTTON, |
1391 | +) |
1392 | |
1393 | |
1394 | class NetworkDetectionPage(QtGui.QWizardPage): |
1395 | @@ -35,7 +35,7 @@ |
1396 | |
1397 | def __init__(self, banner_pixmap=None, parent=None): |
1398 | super(NetworkDetectionPage, self).__init__(parent) |
1399 | - self.setTitle(_("Network detection")) |
1400 | + self.setTitle(NETWORK_DETECTION_TITLE) |
1401 | self.ui = network_detection_ui.Ui_Form() |
1402 | self.ui.setupUi(self) |
1403 | if banner_pixmap is not None: |
1404 | @@ -47,9 +47,9 @@ |
1405 | """Set UI details.""" |
1406 | self.wizard()._next_id = None |
1407 | |
1408 | - self.setButtonText(QtGui.QWizard.CustomButton1, _("Try again")) |
1409 | + self.setButtonText(QtGui.QWizard.CustomButton1, TRY_AGAIN_BUTTON) |
1410 | self.setButtonText(QtGui.QWizard.CancelButton, |
1411 | - _("Close window and set up later")) |
1412 | + CLOSE_AND_SETUP_LATER) |
1413 | self.wizard().setButtonLayout([ |
1414 | QtGui.QWizard.Stretch, |
1415 | QtGui.QWizard.CustomButton1, |
1416 | |
1417 | === modified file 'ubuntu_sso/qt/reset_password_page.py' |
1418 | --- ubuntu_sso/qt/reset_password_page.py 2012-02-10 21:09:38 +0000 |
1419 | +++ ubuntu_sso/qt/reset_password_page.py 2012-02-21 23:01:20 +0000 |
1420 | @@ -16,11 +16,14 @@ |
1421 | |
1422 | """Reset Password page UI.""" |
1423 | |
1424 | +from functools import partial |
1425 | + |
1426 | from PyQt4.QtCore import SIGNAL |
1427 | from PyQt4.QtCore import pyqtSignal |
1428 | from PyQt4.QtGui import QApplication |
1429 | from twisted.internet import defer |
1430 | |
1431 | +from ubuntu_sso import NO_OP |
1432 | from ubuntu_sso.qt import build_general_error_message |
1433 | from ubuntu_sso.qt.gui import SSOWizardEnhancedEditPage |
1434 | from ubuntu_sso.qt import common |
1435 | @@ -175,14 +178,15 @@ |
1436 | |
1437 | def on_password_changed(self, app_name, result): |
1438 | """Let user know that the password was changed.""" |
1439 | + self.overlay.hide() |
1440 | email = unicode(self.wizard().forgotten.ui.email_line_edit.text()) |
1441 | - self.overlay.hide() |
1442 | self.passwordChanged.emit(email) |
1443 | |
1444 | def on_password_change_error(self, app_name, error): |
1445 | """Let the user know that there was an error.""" |
1446 | logger.error('Got error changing password for %s, error: %s', |
1447 | self.app_name, error) |
1448 | + self.overlay.hide() |
1449 | self.message_box.critical(self, self.app_name, |
1450 | build_general_error_message(error)) |
1451 | |
1452 | @@ -193,7 +197,12 @@ |
1453 | password = unicode(self.ui.password_line_edit.text()) |
1454 | logger.info('Setting new password for %r and email %r with code %r', |
1455 | self.app_name, email, code) |
1456 | - self.backend.set_new_password(self.app_name, email, code, password) |
1457 | + args = (self.app_name, email, code, password) |
1458 | + f = self.backend.set_new_password |
1459 | + error_handler = partial(self._handle_error, f, |
1460 | + self.on_password_change_error) |
1461 | + self.overlay.show() |
1462 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
1463 | |
1464 | def is_correct_password_confirmation(self, password): |
1465 | """Return if the password is correct.""" |
1466 | |
1467 | === modified file 'ubuntu_sso/qt/setup_account_page.py' |
1468 | --- ubuntu_sso/qt/setup_account_page.py 2012-02-13 20:27:48 +0000 |
1469 | +++ ubuntu_sso/qt/setup_account_page.py 2012-02-21 23:01:20 +0000 |
1470 | @@ -19,6 +19,7 @@ |
1471 | import StringIO |
1472 | import tempfile |
1473 | import os |
1474 | +from functools import partial |
1475 | |
1476 | # pylint: disable=F0401 |
1477 | try: |
1478 | @@ -30,6 +31,7 @@ |
1479 | from PyQt4 import QtGui, QtCore |
1480 | from twisted.internet import defer |
1481 | |
1482 | +from ubuntu_sso import NO_OP |
1483 | from ubuntu_sso.qt import build_general_error_message |
1484 | from ubuntu_sso.qt import common |
1485 | from ubuntu_sso.qt.gui import SSOWizardEnhancedEditPage |
1486 | @@ -53,7 +55,6 @@ |
1487 | is_min_required_password, |
1488 | is_correct_email, |
1489 | JOIN_HEADER_LABEL, |
1490 | - NAME, |
1491 | NAME_ENTRY, |
1492 | NAME_INVALID, |
1493 | PASSWORD, |
1494 | @@ -123,8 +124,8 @@ |
1495 | privacy_policy=privacy_policy_link) |
1496 | |
1497 | self.terms_checkbox = enhanced_check_box.EnhancedCheckBox(terms) |
1498 | + self.ui.hlayout_check.addWidget(self.terms_checkbox) |
1499 | self.terms_checkbox.setVisible(bool(toc_link or policy_link)) |
1500 | - self.ui.hlayout_check.addWidget(self.terms_checkbox) |
1501 | |
1502 | self.set_up_button = None |
1503 | self.captcha_received = False |
1504 | @@ -175,7 +176,7 @@ |
1505 | self.set_up_button.clicked.connect(self.set_next_validation) |
1506 | self.set_up_button.setEnabled(False) |
1507 | |
1508 | - self.ui.name_label.setText(NAME) |
1509 | + self.ui.name_label.setText(NAME_ENTRY) |
1510 | self.ui.email_label.setText(EMAIL) |
1511 | self.ui.confirm_email_label.setText(RETYPE_EMAIL) |
1512 | self.ui.password_label.setText(PASSWORD) |
1513 | @@ -198,7 +199,7 @@ |
1514 | #pylint: enable=C0103 |
1515 | |
1516 | def _set_translated_strings(self): |
1517 | - """Set the different gettext translated strings.""" |
1518 | + """Set the strings.""" |
1519 | logger.debug('SetUpAccountPage._set_translated_strings') |
1520 | # set the translated string |
1521 | self.ui.name_label.setText(NAME_ENTRY) |
1522 | @@ -259,7 +260,7 @@ |
1523 | captcha_solution = unicode(self.ui.captcha_solution_edit.text()) |
1524 | |
1525 | # Check for len(name) > 0 to ensure that a bool is assigned to enabled |
1526 | - if self.terms_checkbox.isVisible(): |
1527 | + if not self.terms_checkbox.isVisible(): |
1528 | checkbox_terms = True |
1529 | else: |
1530 | checkbox_terms = self.terms_checkbox.isChecked() |
1531 | @@ -281,10 +282,14 @@ |
1532 | # lets clean behind us, do we have the old file arround? |
1533 | if self.captcha_file and os.path.exists(self.captcha_file): |
1534 | os.unlink(self.captcha_file) |
1535 | - fd = tempfile.TemporaryFile(mode='r') |
1536 | + fd = tempfile.NamedTemporaryFile() |
1537 | file_name = fd.name |
1538 | self.captcha_file = file_name |
1539 | - self.backend.generate_captcha(self.app_name, file_name) |
1540 | + args = (self.app_name, file_name) |
1541 | + f = self.backend.generate_captcha |
1542 | + error_handler = partial(self._handle_error, f, |
1543 | + self.on_captcha_generation_error) |
1544 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
1545 | self.on_captcha_refreshing() |
1546 | |
1547 | def _set_titles(self): |
1548 | @@ -393,9 +398,12 @@ |
1549 | # validate the current info of the form, try to perform the action |
1550 | # to register the user, and then move foward |
1551 | if self.validate_form(): |
1552 | - self.backend.register_user(self.app_name, email, |
1553 | - password, name, captcha_id, |
1554 | - captcha_solution) |
1555 | + args = (self.app_name, email, password, name, captcha_id, |
1556 | + captcha_solution) |
1557 | + f = self.backend.register_user |
1558 | + error_handler = partial(self._handle_error, f, |
1559 | + self.on_user_registration_error) |
1560 | + f(*args, reply_handler=NO_OP, error_handler=error_handler) |
1561 | # Update validation page's title, which contains the email |
1562 | self.userRegistered.emit(email, password) |
1563 | # pylint: enable=W0212 |
1564 | |
1565 | === modified file 'ubuntu_sso/qt/sign_in_page.py' |
1566 | --- ubuntu_sso/qt/sign_in_page.py 2012-02-13 20:27:48 +0000 |
1567 | +++ ubuntu_sso/qt/sign_in_page.py 2012-02-21 23:01:20 +0000 |
1568 | @@ -16,19 +16,17 @@ |
1569 | |
1570 | """Page to allow the user to sign in.""" |
1571 | |
1572 | -import gettext |
1573 | - |
1574 | from PyQt4 import QtGui, QtCore |
1575 | |
1576 | from ubuntu_sso.qt.gui import SSOWizardPage |
1577 | from ubuntu_sso.logger import setup_logging |
1578 | from ubuntu_sso.utils.ui import ( |
1579 | + CLOSE_AND_SETUP_LATER, |
1580 | EXISTING_ACCOUNT_CHOICE_BUTTON, |
1581 | SET_UP_ACCOUNT_CHOICE_BUTTON, |
1582 | ) |
1583 | |
1584 | |
1585 | -_ = gettext.gettext |
1586 | logger = setup_logging('ubuntu_sso.sing_in_page') |
1587 | |
1588 | |
1589 | @@ -76,7 +74,7 @@ |
1590 | |
1591 | def initializePage(self): |
1592 | """Setup UI details.""" |
1593 | - self.ui.cancel_button.setText(_("Close window and setup later")) |
1594 | + self.ui.cancel_button.setText(CLOSE_AND_SETUP_LATER) |
1595 | self.ui.cancel_button.clicked.connect(self.singInCanceled.emit) |
1596 | # Layout without custom button 1, |
1597 | # without finish button |
1598 | |
1599 | === modified file 'ubuntu_sso/qt/tests/__init__.py' |
1600 | --- ubuntu_sso/qt/tests/__init__.py 2012-02-09 18:28:40 +0000 |
1601 | +++ ubuntu_sso/qt/tests/__init__.py 2012-02-21 23:01:20 +0000 |
1602 | @@ -21,7 +21,10 @@ |
1603 | from twisted.trial.unittest import TestCase |
1604 | from ubuntu_sso.qt import loadingoverlay |
1605 | |
1606 | -from ubuntu_sso import main |
1607 | +from ubuntu_sso import ( |
1608 | + main, |
1609 | + NO_OP, |
1610 | +) |
1611 | |
1612 | |
1613 | class FakedObject(object): |
1614 | @@ -29,7 +32,7 @@ |
1615 | |
1616 | next_result = None |
1617 | exposed_methods = ['connect_to_signal', |
1618 | - 'generate_captcha'] |
1619 | + 'generate_captcha', 'request_password_reset_token'] |
1620 | |
1621 | def __init__(self, *args, **kwargs): |
1622 | self._args = args |
1623 | @@ -384,6 +387,23 @@ |
1624 | """Store 'args' and 'kwargs' for test assertions.""" |
1625 | self._called = (args, kwargs) |
1626 | |
1627 | + # pylint: disable=E1101, W0212 |
1628 | + def assert_backend_called(self, method, *args, **kwargs): |
1629 | + """Check that 'method(*args, **kwargs)' was called in the backend.""" |
1630 | + self.assertIn(method, self.ui.backend._called) |
1631 | + |
1632 | + call = self.ui.backend._called[method] |
1633 | + self.assertEqual(call[0], args) |
1634 | + |
1635 | + reply_handler = call[1].pop('reply_handler') |
1636 | + self.assertEqual(reply_handler, NO_OP) |
1637 | + |
1638 | + error_handler = call[1].pop('error_handler') |
1639 | + self.assertEqual(error_handler.func, self.ui._handle_error) |
1640 | + |
1641 | + self.assertEqual(call[1], kwargs) |
1642 | + # pylint: enable=E1101, W0212 |
1643 | + |
1644 | |
1645 | class BaseTestCaseUI(TestCase): |
1646 | """Base Test Case.""" |
1647 | |
1648 | === modified file 'ubuntu_sso/qt/tests/test_current_user_sign_in_page.py' |
1649 | --- ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-02-13 17:19:05 +0000 |
1650 | +++ ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-02-21 23:01:20 +0000 |
1651 | @@ -25,6 +25,7 @@ |
1652 | BaseTestCase, |
1653 | FakedBackend, |
1654 | FakedObject, |
1655 | + FakeOverlay, |
1656 | FakePageUiStyle, |
1657 | FakeSignal, |
1658 | FakeWizard, |
1659 | @@ -40,6 +41,7 @@ |
1660 | @defer.inlineCallbacks |
1661 | def setUp(self): |
1662 | yield super(CurrentUserSignInTestCase, self).setUp() |
1663 | + self.patch(gui, "LoadingOverlay", FakeOverlay) |
1664 | self.patch(gui.main, "get_sso_client", FakedBackend) |
1665 | self.signals_results = [] |
1666 | self.patch(current_user_sign_in_page.CurrentUserSignInPage, |
1667 | @@ -48,18 +50,20 @@ |
1668 | "passwordForgotten", FakeSignal()) |
1669 | self.patch(current_user_sign_in_page.CurrentUserSignInPage, |
1670 | "userNotValidated", FakeSignal()) |
1671 | + self.app_name = 'my_app' |
1672 | self.ui = current_user_sign_in_page.CurrentUserSignInPage( |
1673 | current_user_sign_in_ui.Ui_CurrentUserSignInPage(), |
1674 | '', |
1675 | + app_name=self.app_name, |
1676 | parent=None) |
1677 | self.wizard = FakeWizard() |
1678 | self.patch(self.ui, 'wizard', lambda: self.wizard) |
1679 | |
1680 | def test_init(self): |
1681 | """Test the construction of the object.""" |
1682 | - self.assertTrue('LoggedIn' in self.ui._signals) |
1683 | - self.assertTrue('LoginError' in self.ui._signals) |
1684 | - self.assertTrue('UserNotValidated' in self.ui._signals) |
1685 | + self.assertIn('LoggedIn', self.ui._signals) |
1686 | + self.assertIn('LoginError', self.ui._signals) |
1687 | + self.assertIn('UserNotValidated', self.ui._signals) |
1688 | self.assertTrue(callable(self.ui._signals['LoggedIn'])) |
1689 | self.assertTrue(callable(self.ui._signals['LoginError'])) |
1690 | self.assertTrue(callable(self.ui._signals['UserNotValidated'])) |
1691 | @@ -81,9 +85,9 @@ |
1692 | self.patch(self.ui, "_connect_ui", |
1693 | faked_object._connect_ui) |
1694 | self.ui.setup_page() |
1695 | - self.assertTrue('_set_translated_strings' in faked_object._called) |
1696 | - self.assertTrue('_setup_signals' in faked_object._called) |
1697 | - self.assertTrue('_connect_ui' in faked_object._called) |
1698 | + self.assertIn('_set_translated_strings', faked_object._called) |
1699 | + self.assertIn('_setup_signals', faked_object._called) |
1700 | + self.assertIn('_connect_ui', faked_object._called) |
1701 | # pylint: enable=E1101 |
1702 | |
1703 | def test_on_user_not_validated(self): |
1704 | @@ -98,7 +102,7 @@ |
1705 | self.signals_results.append((email, password)) |
1706 | self.ui.userNotValidated.connect(slot) |
1707 | self.ui.on_user_not_validated() |
1708 | - self.assertTrue((email, password) in self.signals_results) |
1709 | + self.assertIn((email, password), self.signals_results) |
1710 | |
1711 | def test_initialize_page(self): |
1712 | """Test the initialization method.""" |
1713 | @@ -110,8 +114,8 @@ |
1714 | self.ui.initializePage() |
1715 | self.assertEqual(wizard.buttons_text[QtGui.QWizard.CancelButton], |
1716 | "Cancel") |
1717 | - self.assertTrue(('setButtonLayout', |
1718 | - (([QtGui.QWizard.BackButton, QtGui.QWizard.Stretch],), {})) in |
1719 | + self.assertIn(('setButtonLayout', |
1720 | + (([QtGui.QWizard.BackButton, QtGui.QWizard.Stretch],), {})), |
1721 | wizard.called) |
1722 | self.assertTrue(button.properties['default']) |
1723 | self.assertFalse(button.isEnabled()) |
1724 | @@ -178,12 +182,14 @@ |
1725 | self.patch(FakedObject, "exposed_methods", exposed_methods) |
1726 | faked_object = FakedObject() |
1727 | self.patch(self.ui, "backend", faked_object) |
1728 | - self.ui.ui.email_edit.setText('valid@email') |
1729 | - self.ui.ui.password_edit.setText('123456') |
1730 | + email = 'valid@email' |
1731 | + password = '123456' |
1732 | + self.ui.ui.email_edit.setText(email) |
1733 | + self.ui.ui.password_edit.setText(password) |
1734 | self.ui.login() |
1735 | - self.assertTrue('login_and_ping' in self.ui.backend._called) |
1736 | - self.assertEqual(self.ui.backend._called['login_and_ping'], |
1737 | - ((None, u'valid@email', u'123456', ping), {})) |
1738 | + self.assertEqual(self.ui.overlay.show_counter, 1) |
1739 | + self.assert_backend_called('login_and_ping', |
1740 | + self.app_name, email, password, ping) |
1741 | |
1742 | def test_login_without_ping(self): |
1743 | """Test the login method.""" |
1744 | @@ -192,12 +198,14 @@ |
1745 | self.patch(FakedObject, "exposed_methods", exposed_methods) |
1746 | faked_object = FakedObject() |
1747 | self.patch(self.ui, "backend", faked_object) |
1748 | - self.ui.ui.email_edit.setText('valid@email') |
1749 | - self.ui.ui.password_edit.setText('123456') |
1750 | + email = 'valid@email' |
1751 | + password = '123456' |
1752 | + self.ui.ui.email_edit.setText(email) |
1753 | + self.ui.ui.password_edit.setText(password) |
1754 | self.ui.login() |
1755 | - self.assertTrue('login' in self.ui.backend._called) |
1756 | - self.assertEqual(self.ui.backend._called['login'], |
1757 | - ((None, u'valid@email', u'123456'), {})) |
1758 | + self.assertEqual(self.ui.overlay.show_counter, 1) |
1759 | + self.assert_backend_called('login', |
1760 | + self.app_name, email, password) |
1761 | |
1762 | def test_on_login_error(self): |
1763 | """Test the on_login_error method.""" |
1764 | @@ -206,6 +214,7 @@ |
1765 | self.ui.app_name = app_name |
1766 | error = {'errtype': 'UserNotValidated'} |
1767 | self.ui.on_login_error(app_name, error) |
1768 | + self.assertEqual(self.ui.overlay.hide_counter, 2) |
1769 | expected = ((self.ui, 'my_app', ''), {}) |
1770 | self.assertTrue(expected, self._called) |
1771 | |
1772 | @@ -221,7 +230,8 @@ |
1773 | self.signals_results.append((app, email)) |
1774 | self.ui.userLoggedIn.connect(slot) |
1775 | self.ui.on_logged_in(app_name, None) |
1776 | - self.assertTrue((app_name, email) in self.signals_results) |
1777 | + self.assertEqual(self.ui.overlay.hide_counter, 2) |
1778 | + self.assertIn((app_name, email), self.signals_results) |
1779 | |
1780 | def test_on_forgotten_password(self): |
1781 | """Test the on_forgotten_password method.""" |
1782 | @@ -231,7 +241,7 @@ |
1783 | self.signals_results.append(1) |
1784 | self.ui.passwordForgotten.connect(slot) |
1785 | self.ui.on_forgotten_password() |
1786 | - self.assertTrue(1 in self.signals_results) |
1787 | + self.assertIn(1, self.signals_results) |
1788 | |
1789 | def test_on_forgotten_password_link_clicked(self): |
1790 | """Test the on_forgotten_password method.""" |
1791 | @@ -241,4 +251,4 @@ |
1792 | self.signals_results.append(1) |
1793 | self.ui.passwordForgotten.connect(slot) |
1794 | self.ui.ui.forgot_password_label.linkActivated.emit("link") |
1795 | - self.assertTrue(1 in self.signals_results) |
1796 | + self.assertIn(1, self.signals_results) |
1797 | |
1798 | === modified file 'ubuntu_sso/qt/tests/test_email_verification.py' |
1799 | --- ubuntu_sso/qt/tests/test_email_verification.py 2012-02-13 14:04:27 +0000 |
1800 | +++ ubuntu_sso/qt/tests/test_email_verification.py 2012-02-21 23:01:20 +0000 |
1801 | @@ -51,8 +51,8 @@ |
1802 | |
1803 | def test_init(self): |
1804 | """Test the construction of the object.""" |
1805 | - self.assertTrue('EmailValidated' in self.ui._signals) |
1806 | - self.assertTrue('EmailValidationError' in self.ui._signals) |
1807 | + self.assertIn('EmailValidated', self.ui._signals) |
1808 | + self.assertIn('EmailValidationError', self.ui._signals) |
1809 | self.assertTrue(callable(self.ui._signals['EmailValidated'])) |
1810 | self.assertTrue(callable(self.ui._signals['EmailValidationError'])) |
1811 | self.assertEqual(self.ui.backend, FakedBackend.sso_login) |
1812 | @@ -70,8 +70,8 @@ |
1813 | self.patch(self.ui, "_connect_ui_elements", |
1814 | faked_object._connect_ui_elements) |
1815 | self.ui.setup_page() |
1816 | - self.assertTrue('_setup_signals' in faked_object._called) |
1817 | - self.assertTrue('_connect_ui_elements' in faked_object._called) |
1818 | + self.assertIn('_setup_signals', faked_object._called) |
1819 | + self.assertIn('_connect_ui_elements', faked_object._called) |
1820 | # pylint: enable=E1101 |
1821 | |
1822 | def test_verification_code(self): |
1823 | @@ -166,7 +166,7 @@ |
1824 | self.signals_results.append((app, email)) |
1825 | self.ui.registrationSuccess.connect(slot) |
1826 | self.ui.on_email_validated(app_name) |
1827 | - self.assertTrue((app_name, email) in self.signals_results) |
1828 | + self.assertIn((app_name, email), self.signals_results) |
1829 | |
1830 | def test_validate_email_with_ping(self): |
1831 | """Test the login method.""" |
1832 | @@ -185,9 +185,8 @@ |
1833 | faked_object = FakedObject() |
1834 | self.patch(self.ui, "backend", faked_object) |
1835 | self.ui.validate_email() |
1836 | - self.assertTrue('validate_email_and_ping' in self.ui.backend._called) |
1837 | - self.assertEqual(self.ui.backend._called['validate_email_and_ping'], |
1838 | - ((app_name, email, password, code, ping), {})) |
1839 | + self.assert_backend_called('validate_email_and_ping', |
1840 | + app_name, email, password, code, ping) |
1841 | |
1842 | def test_validate_email_without_ping(self): |
1843 | """Test the login method.""" |
1844 | @@ -206,6 +205,5 @@ |
1845 | faked_object = FakedObject() |
1846 | self.patch(self.ui, "backend", faked_object) |
1847 | self.ui.validate_email() |
1848 | - self.assertTrue('validate_email' in self.ui.backend._called) |
1849 | - self.assertEqual(self.ui.backend._called['validate_email'], |
1850 | - ((app_name, email, password, code), {})) |
1851 | + self.assert_backend_called('validate_email', |
1852 | + app_name, email, password, code) |
1853 | |
1854 | === modified file 'ubuntu_sso/qt/tests/test_enhanced_check_box.py' |
1855 | --- ubuntu_sso/qt/tests/test_enhanced_check_box.py 2012-02-02 15:57:02 +0000 |
1856 | +++ ubuntu_sso/qt/tests/test_enhanced_check_box.py 2012-02-21 23:01:20 +0000 |
1857 | @@ -1,6 +1,4 @@ |
1858 | # -*- coding: utf-8 -*- |
1859 | - |
1860 | -# Authors: Diego Sarmentero <diego.sarmentero@canonical.com> |
1861 | # |
1862 | # Copyright 2011 Canonical Ltd. |
1863 | # |
1864 | @@ -18,8 +16,6 @@ |
1865 | |
1866 | """Tests for the EnhancedCheckBox widget.""" |
1867 | |
1868 | -import re |
1869 | - |
1870 | from PyQt4 import QtCore |
1871 | |
1872 | from ubuntu_sso.qt import enhanced_check_box |
1873 | @@ -34,9 +30,6 @@ |
1874 | check = enhanced_check_box.EnhancedCheckBox("text") |
1875 | self.assertEqual(check.text(), "text") |
1876 | self.assertTrue(check.text_label.openExternalLinks()) |
1877 | - style_sheet = unicode(check.text_label.styleSheet()) |
1878 | - size = re.sub("\D", "", style_sheet) |
1879 | - self.assertEqual(check.iconSize().width(), int(size)) |
1880 | self.assertEqual(check.receivers( |
1881 | QtCore.SIGNAL('stateChanged(int)')), 1) |
1882 | |
1883 | |
1884 | === modified file 'ubuntu_sso/qt/tests/test_forgotten_password.py' |
1885 | --- ubuntu_sso/qt/tests/test_forgotten_password.py 2012-02-13 21:50:16 +0000 |
1886 | +++ ubuntu_sso/qt/tests/test_forgotten_password.py 2012-02-21 23:01:20 +0000 |
1887 | @@ -25,6 +25,7 @@ |
1888 | BaseTestCase, |
1889 | FakedBackend, |
1890 | FakedObject, |
1891 | + FakeOverlay, |
1892 | FakePageUiStyle, |
1893 | FakeSignal, |
1894 | FakeWizard, |
1895 | @@ -40,23 +41,36 @@ |
1896 | def setUp(self): |
1897 | yield super(ForgottenPasswordTestCase, self).setUp() |
1898 | self.signals_results = [] |
1899 | + self.patch(gui, "LoadingOverlay", FakeOverlay) |
1900 | + self.patch(gui.main, "get_sso_client", FakedBackend) |
1901 | self.patch(forgotten_password_page.ForgottenPasswordPage, |
1902 | "passwordResetTokenSent", FakeSignal()) |
1903 | - self.patch(gui.main, "get_sso_client", FakedBackend) |
1904 | + self.app_name = 'my_app' |
1905 | self.ui = forgotten_password_page.ForgottenPasswordPage( |
1906 | forgotten_password_ui.Ui_ForgottenPasswordPage(), |
1907 | - parent=None) |
1908 | + app_name=self.app_name, parent=None) |
1909 | self.wizard = FakeWizard() |
1910 | self.patch(self.ui, 'wizard', lambda: self.wizard) |
1911 | |
1912 | def test_init(self): |
1913 | """Test the construction of the object.""" |
1914 | - self.assertTrue('PasswordResetTokenSent' in self.ui._signals) |
1915 | - self.assertTrue('PasswordResetError' in self.ui._signals) |
1916 | + self.assertIn('PasswordResetTokenSent', self.ui._signals) |
1917 | + self.assertIn('PasswordResetError', self.ui._signals) |
1918 | self.assertTrue(callable(self.ui._signals['PasswordResetTokenSent'])) |
1919 | self.assertTrue(callable(self.ui._signals['PasswordResetError'])) |
1920 | self.assertEqual(self.ui.backend, FakedBackend.sso_login) |
1921 | |
1922 | + def test_request_new_password(self): |
1923 | + """Test the request_new_password function.""" |
1924 | + app_name = 'my_app' |
1925 | + email = 'email@example.com' |
1926 | + self.ui.app_name = app_name |
1927 | + self.ui.ui.email_line_edit.setText(email) |
1928 | + self.ui.request_new_password() |
1929 | + self.assertEqual(self.ui.overlay.show_counter, 1) |
1930 | + self.assert_backend_called('request_password_reset_token', |
1931 | + app_name, email) |
1932 | + |
1933 | def test_setup_page(self): |
1934 | """Test that the backend is received and the methods are called.""" |
1935 | exposed_methods = [ |
1936 | @@ -78,11 +92,11 @@ |
1937 | self.patch(self.ui, "_register_fields", |
1938 | faked_object._register_fields) |
1939 | self.ui.setup_page() |
1940 | - self.assertTrue('_setup_signals' in faked_object._called) |
1941 | - self.assertTrue('_set_translated_strings' in faked_object._called) |
1942 | - self.assertTrue('_connect_ui' in faked_object._called) |
1943 | - self.assertTrue('_set_enhanced_line_edit' in faked_object._called) |
1944 | - self.assertTrue('_register_fields' in faked_object._called) |
1945 | + self.assertIn('_setup_signals', faked_object._called) |
1946 | + self.assertIn('_set_translated_strings', faked_object._called) |
1947 | + self.assertIn('_connect_ui', faked_object._called) |
1948 | + self.assertIn('_set_enhanced_line_edit', faked_object._called) |
1949 | + self.assertIn('_register_fields', faked_object._called) |
1950 | |
1951 | def test_email_widget(self): |
1952 | """Test the email_widget property.""" |
1953 | @@ -120,6 +134,12 @@ |
1954 | self.assertEqual(value, self.ui.ui.send_button) |
1955 | self.assertTrue(isinstance(value, QtGui.QPushButton)) |
1956 | |
1957 | + def test_send_button_clicked(self): |
1958 | + """Test the send_button property.""" |
1959 | + self.ui.send_button.clicked.emit(True) |
1960 | + self.assert_backend_called('request_password_reset_token', |
1961 | + self.app_name, '') |
1962 | + |
1963 | def test_try_again_widget(self): |
1964 | """Test the try_again_widget property.""" |
1965 | value = self.ui.try_again_widget |
1966 | @@ -211,6 +231,7 @@ |
1967 | self.signals_results.append(1) |
1968 | self.ui.passwordResetTokenSent.connect(slot) |
1969 | self.ui.on_password_reset_token_sent('app_name', {}) |
1970 | + self.assertEqual(self.ui.overlay.hide_counter, 2) |
1971 | self.assertTrue(1 in self.signals_results) |
1972 | |
1973 | def test_on_password_reset_error(self): |
1974 | @@ -227,6 +248,7 @@ |
1975 | self.assertFalse(self.ui.email_widget.isVisible()) |
1976 | self.assertFalse(self.ui.forgotted_password_intro_label.isVisible()) |
1977 | self.assertTrue(self.ui.try_again_widget.isVisible()) |
1978 | + self.assertEqual(self.ui.overlay.hide_counter, 2) |
1979 | |
1980 | def test_on_password_reset_error_with_token_error(self): |
1981 | """Test on_password_reset_error method.""" |
1982 | |
1983 | === modified file 'ubuntu_sso/qt/tests/test_network_detection.py' |
1984 | --- ubuntu_sso/qt/tests/test_network_detection.py 2012-02-02 15:44:18 +0000 |
1985 | +++ ubuntu_sso/qt/tests/test_network_detection.py 2012-02-21 23:01:20 +0000 |
1986 | @@ -60,10 +60,8 @@ |
1987 | "wizard", FakeWizardButtonStyle) |
1988 | self.network_detection.initializePage() |
1989 | self.assertTrue(self.network_detection.btn_try_again.isDefault()) |
1990 | - self.assertTrue( |
1991 | - 'polish' in self.network_detection.btn_try_again.data) |
1992 | - self.assertTrue( |
1993 | - 'unpolish' in self.network_detection.btn_try_again.data) |
1994 | + self.assertIn('polish', self.network_detection.btn_try_again.data) |
1995 | + self.assertIn('unpolish', self.network_detection.btn_try_again.data) |
1996 | self.assertEqual( |
1997 | self.network_detection.btn_try_again.data['polish'], |
1998 | self.network_detection.btn_try_again) |
1999 | |
2000 | === modified file 'ubuntu_sso/qt/tests/test_reset_password.py' |
2001 | --- ubuntu_sso/qt/tests/test_reset_password.py 2012-02-09 18:09:29 +0000 |
2002 | +++ ubuntu_sso/qt/tests/test_reset_password.py 2012-02-21 23:01:20 +0000 |
2003 | @@ -19,7 +19,6 @@ |
2004 | |
2005 | from PyQt4 import QtGui, QtCore |
2006 | from twisted.internet import defer |
2007 | -from twisted.trial.unittest import TestCase |
2008 | |
2009 | from ubuntu_sso.utils.ui import ( |
2010 | PASSWORD1_ENTRY, |
2011 | @@ -33,7 +32,12 @@ |
2012 | RESET_TITLE, |
2013 | ) |
2014 | from ubuntu_sso.qt.ui.reset_password_ui import Ui_ResetPasswordPage |
2015 | -from ubuntu_sso.qt.tests import FakedBackend |
2016 | +from ubuntu_sso.qt.tests import ( |
2017 | + BaseTestCase, |
2018 | + FakedBackend, |
2019 | + FakedObject, |
2020 | + FakeWizard, |
2021 | +) |
2022 | |
2023 | |
2024 | class FakePasswordAssistance(object): |
2025 | @@ -50,52 +54,76 @@ |
2026 | FakePasswordAssistance._called = False |
2027 | |
2028 | |
2029 | -class ResetPasswordTestCase(TestCase): |
2030 | +# We need this Fake until a future refactor. |
2031 | +class FakeForgottenPage(object): |
2032 | + |
2033 | + """Fake Forgotten Page.""" |
2034 | + |
2035 | + def __init__(self): |
2036 | + self.ui = self |
2037 | + self.email_line_edit = self |
2038 | + self.line_text = '' |
2039 | + |
2040 | + # pylint: disable=C0103 |
2041 | + def setText(self, text): |
2042 | + """Fake setText for Line edit.""" |
2043 | + self.line_text = text |
2044 | + # pylint: enable=C0103 |
2045 | + |
2046 | + def text(self): |
2047 | + """Fake text for line edit.""" |
2048 | + return self.line_text |
2049 | + |
2050 | + |
2051 | +class ResetPasswordTestCase(BaseTestCase): |
2052 | """Test the ResetPasswordPage code.""" |
2053 | |
2054 | @defer.inlineCallbacks |
2055 | def setUp(self): |
2056 | yield super(ResetPasswordTestCase, self).setUp() |
2057 | self.patch(gui.main, "get_sso_client", FakedBackend) |
2058 | - self.page = ResetPasswordPage(Ui_ResetPasswordPage(), |
2059 | - 'app_name', |
2060 | - None) |
2061 | + self.app_name = 'my_app' |
2062 | + self.ui = ResetPasswordPage(Ui_ResetPasswordPage(), |
2063 | + app_name=self.app_name, |
2064 | + parent=None) |
2065 | + self.wizard = FakeWizard() |
2066 | + self.patch(self.ui, 'wizard', lambda: self.wizard) |
2067 | self.fake = FakePasswordAssistance() |
2068 | |
2069 | def test_init(self): |
2070 | """Check the initial state of ResetPassword.""" |
2071 | - self.assertEqual(self.page.ui.password_line_edit.receivers( |
2072 | + self.assertEqual(self.ui.ui.password_line_edit.receivers( |
2073 | QtCore.SIGNAL('textEdited(QString)')), 1) |
2074 | - self.assertEqual(self.page.ui.confirm_password_line_edit.receivers( |
2075 | + self.assertEqual(self.ui.ui.confirm_password_line_edit.receivers( |
2076 | QtCore.SIGNAL('textEdited(QString)')), 1) |
2077 | |
2078 | def test_initialize(self): |
2079 | """Check the Title and Subtitle.""" |
2080 | - self.page.show() |
2081 | - self.page.initializePage() |
2082 | - self.addCleanup(self.page.hide) |
2083 | - self.assertEqual(self.page.header.title_label.text(), RESET_TITLE) |
2084 | - self.assertEqual(self.page.header.subtitle_label.text(), |
2085 | + self.ui.show() |
2086 | + self.ui.initializePage() |
2087 | + self.addCleanup(self.ui.hide) |
2088 | + self.assertEqual(self.ui.header.title_label.text(), RESET_TITLE) |
2089 | + self.assertEqual(self.ui.header.subtitle_label.text(), |
2090 | RESET_SUBTITLE) |
2091 | - self.assertEqual(self.page.ui.password_label.text(), PASSWORD1_ENTRY) |
2092 | - self.assertEqual(self.page.ui.confirm_password_label.text(), |
2093 | + self.assertEqual(self.ui.ui.password_label.text(), PASSWORD1_ENTRY) |
2094 | + self.assertEqual(self.ui.ui.confirm_password_label.text(), |
2095 | PASSWORD2_ENTRY) |
2096 | - self.assertEqual(self.page.ui.reset_code.text(), RESET_CODE_ENTRY) |
2097 | + self.assertEqual(self.ui.ui.reset_code.text(), RESET_CODE_ENTRY) |
2098 | |
2099 | def test_focus_changed_password_visibility(self): |
2100 | """Check visibility changes when focus_changed() is executed.""" |
2101 | - self.page.show() |
2102 | - self.addCleanup(self.page.hide) |
2103 | - self.page.focus_changed(None, self.page.ui.password_line_edit) |
2104 | - self.assertTrue(self.page.ui.password_assistance.isVisible()) |
2105 | + self.ui.show() |
2106 | + self.addCleanup(self.ui.hide) |
2107 | + self.ui.focus_changed(None, self.ui.ui.password_line_edit) |
2108 | + self.assertTrue(self.ui.ui.password_assistance.isVisible()) |
2109 | |
2110 | def test_show_hide_event(self): |
2111 | """Check connections to focusChanged on show and hide event.""" |
2112 | - self.page.show() |
2113 | - self.addCleanup(self.page.hide) |
2114 | + self.ui.show() |
2115 | + self.addCleanup(self.ui.hide) |
2116 | self.assertEqual(QtGui.QApplication.instance().receivers( |
2117 | QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)")), 1) |
2118 | - self.page.hide() |
2119 | + self.ui.hide() |
2120 | self.assertEqual(QtGui.QApplication.instance().receivers( |
2121 | QtCore.SIGNAL("focusChanged(QWidget*, QWidget*)")), 0) |
2122 | |
2123 | @@ -105,22 +133,40 @@ |
2124 | """Check functions execution when focus_changed() is executed.""" |
2125 | self.patch(common, 'password_default_assistance', self.fake.call) |
2126 | self.addCleanup(self.fake.clenaup) |
2127 | - self.page.show() |
2128 | - self.addCleanup(self.page.hide) |
2129 | + self.ui.show() |
2130 | + self.addCleanup(self.ui.hide) |
2131 | self.assertFalse(FakePasswordAssistance._called) |
2132 | - self.page.focus_changed(None, self.page.ui.password_line_edit) |
2133 | - self.assertTrue(self.page.ui.password_assistance.isVisible()) |
2134 | + self.ui.focus_changed(None, self.ui.ui.password_line_edit) |
2135 | + self.assertTrue(self.ui.ui.password_assistance.isVisible()) |
2136 | self.assertTrue(FakePasswordAssistance._called) |
2137 | |
2138 | def test_focus_changed_2(self): |
2139 | """Check functions execution when focus_changed() is executed.""" |
2140 | self.patch(common, 'password_check_match', self.fake.call) |
2141 | self.addCleanup(self.fake.clenaup) |
2142 | - self.page.show() |
2143 | - self.addCleanup(self.page.hide) |
2144 | + self.ui.show() |
2145 | + self.addCleanup(self.ui.hide) |
2146 | self.assertFalse(FakePasswordAssistance._called) |
2147 | - self.page.focus_changed(None, self.page.ui.confirm_password_line_edit) |
2148 | - self.assertTrue(self.page.ui.password_assistance.isVisible()) |
2149 | + self.ui.focus_changed(None, self.ui.ui.confirm_password_line_edit) |
2150 | + self.assertTrue(self.ui.ui.password_assistance.isVisible()) |
2151 | self.assertTrue(FakePasswordAssistance._called) |
2152 | |
2153 | # pylint: enable=W0212 |
2154 | + |
2155 | + def test_set_new_password(self): |
2156 | + """Test set_new_password method.""" |
2157 | + email = 'email@example.com' |
2158 | + code = 'code' |
2159 | + password = 'password' |
2160 | + forgotten = FakeForgottenPage() |
2161 | + forgotten.setText(email) |
2162 | + self.patch(self.wizard, "forgotten", forgotten) |
2163 | + exposed_methods = ['set_new_password'] |
2164 | + self.patch(FakedObject, "exposed_methods", exposed_methods) |
2165 | + faked_object = FakedObject() |
2166 | + self.patch(self.ui, "backend", faked_object) |
2167 | + self.ui.ui.reset_code_line_edit.setText(code) |
2168 | + self.ui.ui.password_line_edit.setText(password) |
2169 | + self.ui.set_new_password() |
2170 | + self.assert_backend_called('set_new_password', |
2171 | + self.app_name, email, code, password) |
2172 | |
2173 | === modified file 'ubuntu_sso/qt/tests/test_setup_account.py' |
2174 | --- ubuntu_sso/qt/tests/test_setup_account.py 2012-02-10 21:09:38 +0000 |
2175 | +++ ubuntu_sso/qt/tests/test_setup_account.py 2012-02-21 23:01:20 +0000 |
2176 | @@ -44,11 +44,13 @@ |
2177 | self.signals_results = [] |
2178 | self.patch(setup_account_page.SetupAccountPage, |
2179 | "userRegistered", FakeSignal()) |
2180 | + self.app_name = 'my_app' |
2181 | self.ui = setup_account_page.SetupAccountPage( |
2182 | setup_account_ui.Ui_SetUpAccountPage(), |
2183 | 'subtitle', |
2184 | 'toc_link', |
2185 | 'policy_link', |
2186 | + app_name=self.app_name, |
2187 | parent=None) |
2188 | self.wizard = FakeWizard() |
2189 | self.patch(self.ui, 'wizard', lambda: self.wizard) |
2190 | @@ -75,6 +77,41 @@ |
2191 | setup_account_page.ERROR % setup_account_page.EMPTY_NAME) |
2192 | self.ui.hide() |
2193 | |
2194 | + def test_enable_setup_button_with_visible_check(self): |
2195 | + """Test _enable_setup_button method with terms check visible.""" |
2196 | + self.ui.ui.name_edit.setText('name') |
2197 | + email = 'email@example.com' |
2198 | + self.ui.ui.email_edit.setText(email) |
2199 | + self.ui.ui.confirm_email_edit.setText(email) |
2200 | + password = 'T3st3rqwe' |
2201 | + self.ui.ui.password_edit.setText(password) |
2202 | + self.ui.ui.confirm_password_edit.setText(password) |
2203 | + self.ui.ui.captcha_solution_edit.setText('captcha solution') |
2204 | + self.ui.terms_checkbox.setChecked(True) |
2205 | + |
2206 | + self.ui.show() |
2207 | + self.addCleanup(self.ui.hide) |
2208 | + self.ui.terms_checkbox.setVisible(True) |
2209 | + self.ui.ui.captcha_solution_edit.textEdited.emit('') |
2210 | + self.assertTrue(self.ui.set_up_button.isEnabled()) |
2211 | + |
2212 | + def test_enable_setup_button_without_visible_check(self): |
2213 | + """Test _enable_setup_button method with terms check not visible.""" |
2214 | + self.ui.ui.name_edit.setText('name') |
2215 | + email = 'email@example.com' |
2216 | + self.ui.ui.email_edit.setText(email) |
2217 | + self.ui.ui.confirm_email_edit.setText(email) |
2218 | + password = 'T3st3rqwe' |
2219 | + self.ui.ui.password_edit.setText(password) |
2220 | + self.ui.ui.confirm_password_edit.setText(password) |
2221 | + self.ui.ui.captcha_solution_edit.setText('captcha solution') |
2222 | + |
2223 | + self.ui.show() |
2224 | + self.addCleanup(self.ui.hide) |
2225 | + self.ui.terms_checkbox.setVisible(False) |
2226 | + self.ui.ui.captcha_solution_edit.textEdited.emit('') |
2227 | + self.assertTrue(self.ui.set_up_button.isEnabled()) |
2228 | + |
2229 | def test_password_default_assistance(self): |
2230 | """Status when the password line edit receive focus and shows popup. |
2231 | |
2232 | @@ -155,7 +192,10 @@ |
2233 | self.signals_results.append((email, password)) |
2234 | self.ui.userRegistered.connect(slot) |
2235 | self.ui.set_next_validation() |
2236 | - self.assertTrue((email, password) in self.signals_results) |
2237 | + self.assertIn((email, password), self.signals_results) |
2238 | + self.assert_backend_called('register_user', |
2239 | + self.app_name, email, password, name, captcha_id, |
2240 | + captcha_solution) |
2241 | |
2242 | def test_set_next_validation(self): |
2243 | """Test on_user_registered method.""" |
2244 | @@ -169,7 +209,13 @@ |
2245 | self.signals_results.append((email, password)) |
2246 | self.ui.userRegistered.connect(slot) |
2247 | self.ui.on_user_registered('app_name', None) |
2248 | - self.assertTrue((email, password) in self.signals_results) |
2249 | + self.assertIn((email, password), self.signals_results) |
2250 | + |
2251 | + def test_captcha_image_is_requested_as_startup(self): |
2252 | + """The captcha image is requested at startup.""" |
2253 | + # assert generate_captcha was called |
2254 | + self.assert_backend_called('generate_captcha', |
2255 | + self.app_name, self.ui.captcha_file) |
2256 | |
2257 | |
2258 | class SetupAccountFakeWizardTestCase(BaseTestCase): |
2259 | @@ -221,7 +267,8 @@ |
2260 | self.assertFalse(self.ui.captcha_received) |
2261 | |
2262 | # labels |
2263 | - self.assertEqual(self.ui.ui.name_label.text(), setup_account_page.NAME) |
2264 | + self.assertEqual(self.ui.ui.name_label.text(), |
2265 | + setup_account_page.NAME_ENTRY) |
2266 | self.assertEqual(self.ui.ui.email_label.text(), |
2267 | setup_account_page.EMAIL) |
2268 | self.assertEqual(self.ui.ui.confirm_email_label.text(), |
2269 | |
2270 | === modified file 'ubuntu_sso/qt/tests/test_sign_in_page.py' |
2271 | --- ubuntu_sso/qt/tests/test_sign_in_page.py 2012-02-10 21:09:38 +0000 |
2272 | +++ ubuntu_sso/qt/tests/test_sign_in_page.py 2012-02-21 23:01:20 +0000 |
2273 | @@ -55,7 +55,7 @@ |
2274 | self.signals_results.append(1) |
2275 | self.ui.existingAccountSelected.connect(slot) |
2276 | self.ui._set_next_existing() |
2277 | - self.assertTrue(1 in self.signals_results) |
2278 | + self.assertIn(1, self.signals_results) |
2279 | |
2280 | def test_set_next_new(self): |
2281 | """Test _set_next_existing method.""" |
2282 | @@ -65,5 +65,5 @@ |
2283 | self.signals_results.append(1) |
2284 | self.ui.newAccountSelected.connect(slot) |
2285 | self.ui._set_next_new() |
2286 | - self.assertTrue(1 in self.signals_results) |
2287 | + self.assertIn(1, self.signals_results) |
2288 | # pylint: enable=W0212 |
2289 | |
2290 | === modified file 'ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py' |
2291 | --- ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py 2012-02-13 20:37:57 +0000 |
2292 | +++ ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py 2012-02-21 23:01:20 +0000 |
2293 | @@ -89,6 +89,6 @@ |
2294 | self.ui.show() |
2295 | self.addCleanup(self.ui.hide) |
2296 | self.ui.sign_in_page.ui.cancel_button.clicked.emit(True) |
2297 | - self.assertTrue('close' in faked_object._called) |
2298 | - self.assertTrue('reject' not in faked_object._called) |
2299 | + self.assertIn('close', faked_object._called) |
2300 | + self.assertNotIn('reject', faked_object._called) |
2301 | # pylint: enable=W0212, E1101 |
2302 | |
2303 | === modified file 'ubuntu_sso/qt/ubuntu_sso_wizard.py' |
2304 | --- ubuntu_sso/qt/ubuntu_sso_wizard.py 2012-02-14 18:42:00 +0000 |
2305 | +++ ubuntu_sso/qt/ubuntu_sso_wizard.py 2012-02-21 23:01:20 +0000 |
2306 | @@ -151,6 +151,7 @@ |
2307 | self.setWizardStyle(QWizard.ModernStyle) |
2308 | self.button(QWizard.CancelButton).clicked.connect( |
2309 | self.on_user_cancelation) |
2310 | + self.resize(550, 500) |
2311 | |
2312 | # pylint: disable=C0103 |
2313 | def nextId(self): |
2314 | |
2315 | === modified file 'ubuntu_sso/tests/__init__.py' |
2316 | --- ubuntu_sso/tests/__init__.py 2012-02-10 17:18:22 +0000 |
2317 | +++ ubuntu_sso/tests/__init__.py 2012-02-21 23:01:20 +0000 |
2318 | @@ -26,20 +26,20 @@ |
2319 | |
2320 | from ubuntu_sso.keyring import get_token_name |
2321 | |
2322 | -APP_NAME = u'The Super App!' |
2323 | +APP_NAME = u'I ♥ Ubuntu' |
2324 | CAPTCHA_ID = u'test ñiña' |
2325 | CAPTCHA_PATH = os.path.abspath(os.path.join(os.curdir, 'ubuntu_sso', 'tests', |
2326 | 'files', 'captcha.png')) |
2327 | CAPTCHA_SOLUTION = u'william Byrd ñandú' |
2328 | EMAIL = u'test@example.com' |
2329 | -EMAIL_TOKEN = u'B2Pgtf' |
2330 | +EMAIL_TOKEN = u'B2P☺ gtf' |
2331 | GTK_GUI_EXE = 'ubuntu-sso-login-gtk' |
2332 | -HELP_TEXT = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed |
2333 | -lorem nibh. Suspendisse gravida nulla non nunc suscipit pulvinar tempus ut |
2334 | -augue. Morbi consequat, ligula a elementum pretium, dolor nulla tempus metus, |
2335 | -sed viverra nisi risus non velit.""" |
2336 | -NAME = u'Juanito Pérez' |
2337 | -PASSWORD = u'h3lloWorld' |
2338 | +HELP_TEXT = u'☛ Lorem ipsum dolor sit amet, consectetur adipiscing elit. ' \ |
2339 | +'Nam sed lorem nibh. Suspendisse gravida nulla non nunc suscipit pulvinar ' \ |
2340 | +'tempus ut augue. Morbi consequat, ligula a elementum pretium, ' \ |
2341 | +'dolor nulla tempus metus, sed viverra nisi risus non velit.' |
2342 | +NAME = u'Juanito ☀ Pérez' |
2343 | +PASSWORD = u'h3lloWorld☑ ' |
2344 | PING_URL = u'http://localhost/ping-me/' |
2345 | POLICY_URL = u'http://localhost/policy/' |
2346 | RESET_PASSWORD_TOKEN = u'8G5Wtq' |
2347 | |
2348 | === modified file 'ubuntu_sso/utils/__init__.py' |
2349 | --- ubuntu_sso/utils/__init__.py 2012-02-11 19:25:01 +0000 |
2350 | +++ ubuntu_sso/utils/__init__.py 2012-02-21 23:01:20 +0000 |
2351 | @@ -54,9 +54,11 @@ |
2352 | |
2353 | # otherwise, try to load 'dir_constant' from installation path |
2354 | try: |
2355 | + # Unused variable 'ubuntu_sso', pylint: disable=W0612, F0401, E0611 |
2356 | + import ubuntu_sso.constants |
2357 | module = sys.modules.get('ubuntu_sso.constants') |
2358 | return getattr(module, dir_constant) |
2359 | - except AttributeError: |
2360 | + except (ImportError, AttributeError): |
2361 | msg = '_get_dir: can not build a valid path. Giving up. ' \ |
2362 | '__file__ is %r, constants module not available.' |
2363 | logger.error(msg, __file__) |
2364 | @@ -69,7 +71,9 @@ |
2365 | found, return the value of the PROJECT_DIR. |
2366 | |
2367 | """ |
2368 | - return _get_dir(dir_name=DATA_SUFFIX, dir_constant='PROJECT_DIR') |
2369 | + result = _get_dir(dir_name=DATA_SUFFIX, dir_constant='PROJECT_DIR') |
2370 | + assert result is not None, '%r dir can not be None.' % DATA_SUFFIX |
2371 | + return result |
2372 | |
2373 | |
2374 | def get_data_file(*args): |
2375 | @@ -84,7 +88,9 @@ |
2376 | found, return the value of the BIN_DIR. |
2377 | |
2378 | """ |
2379 | - return _get_dir(dir_name=BIN_SUFFIX, dir_constant='BIN_DIR') |
2380 | + result = _get_dir(dir_name=BIN_SUFFIX, dir_constant='BIN_DIR') |
2381 | + assert result is not None, '%r dir can not be None.' % BIN_SUFFIX |
2382 | + return result |
2383 | |
2384 | |
2385 | class RequestHead(urllib2.Request): |
2386 | |
2387 | === modified file 'ubuntu_sso/utils/runner/glib.py' |
2388 | --- ubuntu_sso/utils/runner/glib.py 2012-02-10 17:03:56 +0000 |
2389 | +++ ubuntu_sso/utils/runner/glib.py 2012-02-21 23:01:20 +0000 |
2390 | @@ -27,7 +27,7 @@ |
2391 | logger = setup_logging("ubuntu_sso.utils.runner.glib") |
2392 | |
2393 | |
2394 | -NO_SUCH_FILE_OR_DIR = '(No such file or directory)' |
2395 | +NO_SUCH_FILE_OR_DIR = 'No such file or directory' |
2396 | |
2397 | |
2398 | def spawn_program(args, reply_handler, error_handler): |
2399 | @@ -66,8 +66,17 @@ |
2400 | GLib.SpawnFlags.STDOUT_TO_DEV_NULL | \ |
2401 | GLib.SpawnFlags.STDERR_TO_DEV_NULL |
2402 | pid = None |
2403 | + |
2404 | + bytes_args = [] |
2405 | + for arg in args: |
2406 | + if isinstance(arg, unicode): |
2407 | + arg = arg.encode('utf-8') |
2408 | + if not isinstance(arg, basestring): |
2409 | + arg = str(arg) |
2410 | + bytes_args.append(arg) |
2411 | + |
2412 | try: |
2413 | - pid, _, _, _ = GLib.spawn_async(argv=args, flags=flags) |
2414 | + pid, _, _, _ = GLib.spawn_async(argv=bytes_args, flags=flags) |
2415 | except GLib.GError, e: |
2416 | handle_error(e) |
2417 | else: |
2418 | |
2419 | === added file 'ubuntu_sso/utils/runner/tests/test_glib.py' |
2420 | --- ubuntu_sso/utils/runner/tests/test_glib.py 1970-01-01 00:00:00 +0000 |
2421 | +++ ubuntu_sso/utils/runner/tests/test_glib.py 2012-02-21 23:01:20 +0000 |
2422 | @@ -0,0 +1,132 @@ |
2423 | +# -*- coding: utf-8 -*- |
2424 | +# |
2425 | +# Copyright 2012 Canonical Ltd. |
2426 | +# |
2427 | +# This program is free software: you can redistribute it and/or modify it |
2428 | +# under the terms of the GNU General Public License version 3, as published |
2429 | +# by the Free Software Foundation. |
2430 | +# |
2431 | +# This program is distributed in the hope that it will be useful, but |
2432 | +# WITHOUT ANY WARRANTY; without even the implied warranties of |
2433 | +# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR |
2434 | +# PURPOSE. See the GNU General Public License for more details. |
2435 | +# |
2436 | +# You should have received a copy of the GNU General Public License along |
2437 | +# with this program. If not, see <http://www.gnu.org/licenses/>. |
2438 | + |
2439 | +"""Tests for the glib runner helper module.""" |
2440 | + |
2441 | +import subprocess |
2442 | + |
2443 | +# pylint: disable=E0611 |
2444 | +from gi.repository import GLib |
2445 | +# pylint: enable=E0611 |
2446 | +from twisted.internet import defer |
2447 | + |
2448 | +from ubuntu_sso.utils import runner |
2449 | +from ubuntu_sso.utils.runner import glib |
2450 | +from ubuntu_sso.utils.runner.tests.test_runner import SpawnProgramTestCase |
2451 | + |
2452 | + |
2453 | +class FakedSignal(object): |
2454 | + """Fake a glib signal.""" |
2455 | + |
2456 | + def __init__(self, name): |
2457 | + self.name = name |
2458 | + self._handlers = [] |
2459 | + |
2460 | + def connect(self, handler): |
2461 | + """Connect 'handler' with this signal.""" |
2462 | + self._handlers.append(handler) |
2463 | + |
2464 | + def emit(self, *args, **kwargs): |
2465 | + """Emit this signal.""" |
2466 | + for handler in self._handlers: |
2467 | + handler(*args, **kwargs) |
2468 | + |
2469 | + |
2470 | +class FakedProcess(object): |
2471 | + """Fake a glib Process.""" |
2472 | + |
2473 | + _argv = _flags = None |
2474 | + _pid = 123456 |
2475 | + _pids = [] |
2476 | + _status_code = 0 |
2477 | + |
2478 | + SpawnFlags = GLib.SpawnFlags |
2479 | + GError = GLib.GError |
2480 | + |
2481 | + def __init__(self): |
2482 | + self.pid = lambda: self._pid |
2483 | + self.started = FakedSignal('started') |
2484 | + self.finished = FakedSignal('finished') |
2485 | + self.error = FakedSignal('error') |
2486 | + |
2487 | + def spawn_async(self, argv, flags): |
2488 | + """Spwan a process.""" |
2489 | + if 'None' in argv: |
2490 | + exc = GLib.GError() |
2491 | + exc.message = str('Can not handle None') |
2492 | + exc.code = 24 |
2493 | + raise exc |
2494 | + |
2495 | + self._argv = argv |
2496 | + self._flags = flags |
2497 | + |
2498 | + try: |
2499 | + subprocess.call(argv) |
2500 | + except Exception, e: |
2501 | + exc = GLib.GError() |
2502 | + exc.message = str(e) |
2503 | + exc.code = 42 |
2504 | + raise exc |
2505 | + |
2506 | + self._pids.append(self._pid) |
2507 | + return (self._pid, None, None, None) |
2508 | + |
2509 | + def child_watch_add(self, pid, child_watch): |
2510 | + """Addd a child watch.""" |
2511 | + if pid in self._pids: |
2512 | + child_watch(pid, self._status_code) |
2513 | + |
2514 | + def spawn_close_pid(self, pid): |
2515 | + """Close the 'pid'.""" |
2516 | + self._pids.remove(pid) |
2517 | + |
2518 | + |
2519 | +class GLibSpawnProgramTestCase(SpawnProgramTestCase): |
2520 | + """The test suite for the spawn_program method (using GLib).""" |
2521 | + |
2522 | + use_reactor = False |
2523 | + |
2524 | + @defer.inlineCallbacks |
2525 | + def setUp(self): |
2526 | + yield super(GLibSpawnProgramTestCase, self).setUp() |
2527 | + # Since we can't mix plan glib runner and the gireactor, we patch |
2528 | + # GLib.spawn_async and fake the conditions so the glib runner is chosen |
2529 | + self.process = FakedProcess() |
2530 | + self.patch(glib, 'GLib', self.process) |
2531 | + self.patch(runner, 'is_twisted_reactor_installed', lambda: False) |
2532 | + self.patch(runner, 'is_qt4_main_loop_installed', lambda: False) |
2533 | + |
2534 | + # Access to a protected member _flags, _argv of a client class |
2535 | + # pylint: disable=W0212 |
2536 | + |
2537 | + @defer.inlineCallbacks |
2538 | + def test_flags_are_correct(self): |
2539 | + """The flags are the correct ones.""" |
2540 | + yield self.spawn_fn(self.args) |
2541 | + |
2542 | + flags = GLib.SpawnFlags.DO_NOT_REAP_CHILD | \ |
2543 | + GLib.SpawnFlags.SEARCH_PATH | \ |
2544 | + GLib.SpawnFlags.STDOUT_TO_DEV_NULL | \ |
2545 | + GLib.SpawnFlags.STDERR_TO_DEV_NULL |
2546 | + self.assertEqual(self.process._flags, flags) |
2547 | + |
2548 | + @defer.inlineCallbacks |
2549 | + def test_argv_is_bytes(self): |
2550 | + """The argv parameter is converted to bytes.""" |
2551 | + yield self.spawn_fn(self.args) |
2552 | + |
2553 | + bytes_args = [a.encode('utf-8') for a in self.args] |
2554 | + self.assertEqual(self.process._argv, bytes_args) |
2555 | |
2556 | === modified file 'ubuntu_sso/utils/runner/tests/test_qt.py' |
2557 | --- ubuntu_sso/utils/runner/tests/test_qt.py 2012-02-10 15:44:28 +0000 |
2558 | +++ ubuntu_sso/utils/runner/tests/test_qt.py 2012-02-21 23:01:20 +0000 |
2559 | @@ -64,8 +64,16 @@ |
2560 | self.started.emit() |
2561 | |
2562 | args = (program,) + tuple(arguments) |
2563 | + |
2564 | + # subprocess expects bytes |
2565 | + bytes_args = [] |
2566 | + for arg in args: |
2567 | + if isinstance(arg, unicode): |
2568 | + arg = arg.encode('utf-8') |
2569 | + bytes_args.append(arg) |
2570 | + |
2571 | try: |
2572 | - subprocess.call(args) |
2573 | + subprocess.call(bytes_args) |
2574 | except OSError, e: |
2575 | if e.errno == 2: |
2576 | self.error.emit(self.FailedToStart) |
2577 | |
2578 | === modified file 'ubuntu_sso/utils/runner/tests/test_runner.py' |
2579 | --- ubuntu_sso/utils/runner/tests/test_runner.py 2012-02-08 02:13:03 +0000 |
2580 | +++ ubuntu_sso/utils/runner/tests/test_runner.py 2012-02-21 23:01:20 +0000 |
2581 | @@ -24,21 +24,23 @@ |
2582 | from ubuntu_sso.utils import runner |
2583 | |
2584 | |
2585 | -TEST_ME_DIR = 'test-me' |
2586 | +TEST_ME_DIR = u'test-me-more-♥' |
2587 | +TEST_ME_DIR_BYTES = TEST_ME_DIR.encode('utf-8') |
2588 | |
2589 | |
2590 | class SpawnProgramTestCase(TestCase): |
2591 | """The test suite for the spawn_program method.""" |
2592 | |
2593 | timeout = 3 |
2594 | - args = ('python', '-c', 'import os; os.system("mkdir %s")' % TEST_ME_DIR) |
2595 | + args = (u'python', u'-c', |
2596 | + u'import os; os.system("mkdir %s")' % TEST_ME_DIR) |
2597 | |
2598 | @defer.inlineCallbacks |
2599 | def setUp(self): |
2600 | yield super(SpawnProgramTestCase, self).setUp() |
2601 | - assert not os.path.exists(TEST_ME_DIR) |
2602 | - self.addCleanup(lambda: os.path.exists(TEST_ME_DIR) and |
2603 | - os.rmdir(TEST_ME_DIR)) |
2604 | + assert not os.path.exists(TEST_ME_DIR_BYTES) |
2605 | + self.addCleanup(lambda: os.path.exists(TEST_ME_DIR_BYTES) and |
2606 | + os.rmdir(TEST_ME_DIR_BYTES)) |
2607 | |
2608 | def spawn_fn(self, args): |
2609 | """The target function to test.""" |
2610 | @@ -46,8 +48,8 @@ |
2611 | |
2612 | def assert_command_was_run(self): |
2613 | """The spawnned commnad was correctly run.""" |
2614 | - self.assertTrue(os.path.exists(TEST_ME_DIR)) |
2615 | - self.assertTrue(os.path.isdir(TEST_ME_DIR)) |
2616 | + self.assertTrue(os.path.exists(TEST_ME_DIR_BYTES)) |
2617 | + self.assertTrue(os.path.isdir(TEST_ME_DIR_BYTES)) |
2618 | |
2619 | @defer.inlineCallbacks |
2620 | def test_program_is_spawned(self): |
2621 | |
2622 | === modified file 'ubuntu_sso/utils/runner/tx.py' |
2623 | --- ubuntu_sso/utils/runner/tx.py 2012-02-08 18:29:39 +0000 |
2624 | +++ ubuntu_sso/utils/runner/tx.py 2012-02-21 23:01:20 +0000 |
2625 | @@ -68,6 +68,14 @@ |
2626 | program = args[0] |
2627 | argv = args[1:] |
2628 | |
2629 | + bytes_args = [] |
2630 | + for arg in argv: |
2631 | + if isinstance(arg, unicode): |
2632 | + arg = arg.encode('utf-8') |
2633 | + if not isinstance(arg, basestring): |
2634 | + arg = str(arg) |
2635 | + bytes_args.append(arg) |
2636 | + |
2637 | if program and not os.access(program, os.X_OK): |
2638 | # handle searching the executable in the PATH, since |
2639 | # twisted will not solve that for us :-/ |
2640 | @@ -81,7 +89,7 @@ |
2641 | break |
2642 | |
2643 | try: |
2644 | - d = utils.getProcessOutputAndValue(program, argv, env=os.environ) |
2645 | + d = utils.getProcessOutputAndValue(program, bytes_args, env=os.environ) |
2646 | except OSError, e: |
2647 | error_handler(msg=e, failed_to_start=True) |
2648 | except Exception, e: |
2649 | |
2650 | === modified file 'ubuntu_sso/utils/tests/test_common.py' |
2651 | --- ubuntu_sso/utils/tests/test_common.py 2012-02-11 19:25:01 +0000 |
2652 | +++ ubuntu_sso/utils/tests/test_common.py 2012-02-21 23:01:20 +0000 |
2653 | @@ -124,8 +124,7 @@ |
2654 | self.patch(utils.os.path, 'exists', lambda path: False) |
2655 | sys.modules[CONSTANTS_MODULE] = None |
2656 | |
2657 | - result = self.get_dir() |
2658 | - self.assertTrue(result is None) |
2659 | + self.assertRaises(AssertionError, self.get_dir) |
2660 | msg = 'get_dir: can not build a valid path.' |
2661 | self.assertTrue(self.memento.check_error(msg)) |
2662 | |
2663 | |
2664 | === modified file 'ubuntu_sso/utils/ui.py' |
2665 | --- ubuntu_sso/utils/ui.py 2012-02-13 20:27:48 +0000 |
2666 | +++ ubuntu_sso/utils/ui.py 2012-02-21 23:01:20 +0000 |
2667 | @@ -21,11 +21,12 @@ |
2668 | |
2669 | from ubuntu_sso.logger import setup_logging |
2670 | |
2671 | + |
2672 | +gettext.install('ubuntu-sso-client', unicode=True) |
2673 | logger = setup_logging('ubuntu_sso.utils.ui') |
2674 | |
2675 | |
2676 | -gettext.textdomain('ubuntu-sso-client') |
2677 | -_ = gettext.gettext |
2678 | +# Undefined variable '_', pylint: disable=E0602 |
2679 | |
2680 | # all the text that is used in the gui |
2681 | AGREE_TO_PRIVACY_POLICY = _('By signing up to {app_name} you agree to ' |
2682 | @@ -33,11 +34,13 @@ |
2683 | AGREE_TO_TERMS = _('By signing up to {app_name} you agree to ' |
2684 | 'our {terms_and_conditions}') |
2685 | AGREE_TO_TERMS_AND_PRIVACY_POLICY = AGREE_TO_TERMS + _(' and {privacy_policy}') |
2686 | +CANCEL_BUTTON = _('Cancel') |
2687 | CAPTCHA_SOLUTION_ENTRY = _('Type the characters above') |
2688 | CAPTCHA_LOAD_ERROR = _('There was a problem getting the captcha, ' |
2689 | 'reloading...') |
2690 | CAPTCHA_RELOAD_TOOLTIP = _('Reload') |
2691 | CAPTCHA_REQUIRED_ERROR = _('The captcha is a required field') |
2692 | +CLOSE_AND_SETUP_LATER = _('Close window and setup later') |
2693 | CONGRATULATIONS = _("Congratulations, {app_name} is installed!") |
2694 | PROXY_CREDS_DIALOG_TITLE = _('Add proxy settings') |
2695 | PROXY_CREDS_HEADER = _('You are connecting through a proxy.') |
2696 | @@ -76,10 +79,10 @@ |
2697 | LOGIN_HEADER_LABEL = _('Connect to %(app_name)s') |
2698 | LOGIN_PASSWORD_ENTRY = _('Password') |
2699 | LOGIN_PASSWORD_LABEL = LOGIN_PASSWORD_ENTRY |
2700 | -NAME = _("Name") |
2701 | NAME_ENTRY = _('Name') |
2702 | NAME_INVALID = _('The name must not be empty.') |
2703 | NEXT = _('Next') |
2704 | +NETWORK_DETECTION_TITLE = _('Network detection') |
2705 | ONE_MOMENT_PLEASE = _('One moment please...') |
2706 | PASSWORD = _("Create a password") |
2707 | PASSWORD_CHANGED = _('Your password was successfully changed.') |
2708 | @@ -140,6 +143,8 @@ |
2709 | YES_TO_TC = _('I agree with the %(app_name)s terms and conditions') |
2710 | YES_TO_UPDATES = _('Yes! Email me %(app_name)s tips and updates.') |
2711 | |
2712 | +# pylint: enable=E0602 |
2713 | + |
2714 | |
2715 | def get_password_strength(password): |
2716 | """Return the strength of the password. |
+1