Merge lp:~nataliabidart/ubuntu-sso-client/use-login-only into lp:ubuntu-sso-client

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 899
Merged at revision: 888
Proposed branch: lp:~nataliabidart/ubuntu-sso-client/use-login-only
Merge into: lp:ubuntu-sso-client
Diff against target: 2912 lines (+562/-1252)
28 files modified
data/qt/choose_sign_in.ui (+0/-163)
run-tests.bat (+1/-1)
ubuntu_sso/qt/current_user_sign_in_page.py (+9/-18)
ubuntu_sso/qt/email_verification_page.py (+18/-21)
ubuntu_sso/qt/error_page.py (+11/-4)
ubuntu_sso/qt/forgotten_password_page.py (+13/-20)
ubuntu_sso/qt/loadingoverlay.py (+4/-11)
ubuntu_sso/qt/network_detection_page.py (+17/-8)
ubuntu_sso/qt/reset_password_page.py (+22/-29)
ubuntu_sso/qt/setup_account_page.py (+66/-68)
ubuntu_sso/qt/sign_in_page.py (+0/-97)
ubuntu_sso/qt/sso_wizard_page.py (+51/-18)
ubuntu_sso/qt/success_page.py (+13/-4)
ubuntu_sso/qt/tests/__init__.py (+89/-37)
ubuntu_sso/qt/tests/test_current_user_sign_in_page.py (+4/-70)
ubuntu_sso/qt/tests/test_email_verification.py (+16/-66)
ubuntu_sso/qt/tests/test_enchanced_line_edit.py (+2/-5)
ubuntu_sso/qt/tests/test_error_page.py (+26/-0)
ubuntu_sso/qt/tests/test_forgotten_password.py (+7/-59)
ubuntu_sso/qt/tests/test_loadingoverlay.py (+8/-8)
ubuntu_sso/qt/tests/test_network_detection.py (+19/-33)
ubuntu_sso/qt/tests/test_reset_password.py (+19/-48)
ubuntu_sso/qt/tests/test_setup_account.py (+19/-58)
ubuntu_sso/qt/tests/test_sign_in_page.py (+0/-69)
ubuntu_sso/qt/tests/test_sso_wizard_page.py (+12/-96)
ubuntu_sso/qt/tests/test_success_page.py (+26/-0)
ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py (+24/-48)
ubuntu_sso/qt/ubuntu_sso_wizard.py (+66/-193)
To merge this branch: bzr merge lp:~nataliabidart/ubuntu-sso-client/use-login-only
Reviewer Review Type Date Requested Status
Diego Sarmentero (community) Approve
Roberto Alsina (community) Approve
Review via email: mp+94455@code.launchpad.net

Commit message

- Move the 'choose sign in page' to client code (U1 control panel
  in this case) (LP: #933576).
- Make use of the 'login_only' parameter that is being passed to the
  UbuntuSSOWizard (LP: #939558).

To post a comment you must log in.
890. By Natalia Bidart

- Also remove choose_sign_in.ui file (no longer needed in this project).

891. By Natalia Bidart

Merged trunk in.

892. By Natalia Bidart

- Fixed window tests run.

893. By Natalia Bidart

Movind the line_edit connects to _connect_ui method.

894. By Natalia Bidart

Merged dependency branch in.

895. By Natalia Bidart

Making test pass.

896. By Natalia Bidart

Merged trunk in.

897. By Natalia Bidart

Fixing another test.

898. By Natalia Bidart

Lint fixes.

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

+1

review: Approve
899. By Natalia Bidart

Fixed pep8 issues.

Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== removed file 'data/qt/choose_sign_in.ui'
2--- data/qt/choose_sign_in.ui 2012-02-22 16:58:08 +0000
3+++ data/qt/choose_sign_in.ui 1970-01-01 00:00:00 +0000
4@@ -1,163 +0,0 @@
5-<?xml version="1.0" encoding="UTF-8"?>
6-<ui version="4.0">
7- <class>ChooseSignInPage</class>
8- <widget class="QWizardPage" name="ChooseSignInPage">
9- <property name="geometry">
10- <rect>
11- <x>0</x>
12- <y>0</y>
13- <width>432</width>
14- <height>387</height>
15- </rect>
16- </property>
17- <layout class="QVBoxLayout" name="verticalLayout_2">
18- <property name="leftMargin">
19- <number>0</number>
20- </property>
21- <property name="topMargin">
22- <number>0</number>
23- </property>
24- <property name="rightMargin">
25- <number>0</number>
26- </property>
27- <item>
28- <layout class="QHBoxLayout" name="horizontalLayout_2">
29- <item>
30- <widget class="QLabel" name="image_label">
31- <property name="sizePolicy">
32- <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
33- <horstretch>0</horstretch>
34- <verstretch>0</verstretch>
35- </sizepolicy>
36- </property>
37- <property name="minimumSize">
38- <size>
39- <width>400</width>
40- <height>150</height>
41- </size>
42- </property>
43- <property name="text">
44- <string/>
45- </property>
46- <property name="textFormat">
47- <enum>Qt::PlainText</enum>
48- </property>
49- <property name="alignment">
50- <set>Qt::AlignCenter</set>
51- </property>
52- <property name="wordWrap">
53- <bool>true</bool>
54- </property>
55- </widget>
56- </item>
57- </layout>
58- </item>
59- <item>
60- <widget class="QLabel" name="message_label">
61- <property name="font">
62- <font>
63- <pointsize>11</pointsize>
64- <weight>50</weight>
65- <bold>false</bold>
66- </font>
67- </property>
68- <property name="text">
69- <string notr="true">Congratulations, app_name is installed!</string>
70- </property>
71- <property name="alignment">
72- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
73- </property>
74- </widget>
75- </item>
76- <item>
77- <spacer name="verticalSpacer_3">
78- <property name="orientation">
79- <enum>Qt::Vertical</enum>
80- </property>
81- <property name="sizeType">
82- <enum>QSizePolicy::Fixed</enum>
83- </property>
84- <property name="sizeHint" stdset="0">
85- <size>
86- <width>20</width>
87- <height>30</height>
88- </size>
89- </property>
90- </spacer>
91- </item>
92- <item>
93- <layout class="QHBoxLayout" name="horizontalLayout">
94- <item>
95- <spacer name="horizontalSpacer_2">
96- <property name="orientation">
97- <enum>Qt::Horizontal</enum>
98- </property>
99- <property name="sizeHint" stdset="0">
100- <size>
101- <width>20</width>
102- <height>20</height>
103- </size>
104- </property>
105- </spacer>
106- </item>
107- <item>
108- <layout class="QVBoxLayout" name="verticalLayout">
109- <item>
110- <widget class="QPushButton" name="existing_account_button">
111- <property name="text">
112- <string notr="true"/>
113- </property>
114- </widget>
115- </item>
116- <item>
117- <widget class="QPushButton" name="setup_account_button">
118- <property name="text">
119- <string notr="true"/>
120- </property>
121- </widget>
122- </item>
123- <item>
124- <widget class="QPushButton" name="cancel_button">
125- <property name="text">
126- <string notr="true"/>
127- </property>
128- </widget>
129- </item>
130- </layout>
131- </item>
132- <item>
133- <spacer name="horizontalSpacer">
134- <property name="orientation">
135- <enum>Qt::Horizontal</enum>
136- </property>
137- <property name="sizeType">
138- <enum>QSizePolicy::Expanding</enum>
139- </property>
140- <property name="sizeHint" stdset="0">
141- <size>
142- <width>20</width>
143- <height>20</height>
144- </size>
145- </property>
146- </spacer>
147- </item>
148- </layout>
149- </item>
150- <item>
151- <spacer name="verticalSpacer_2">
152- <property name="orientation">
153- <enum>Qt::Vertical</enum>
154- </property>
155- <property name="sizeHint" stdset="0">
156- <size>
157- <width>20</width>
158- <height>50</height>
159- </size>
160- </property>
161- </spacer>
162- </item>
163- </layout>
164- </widget>
165- <resources/>
166- <connections/>
167-</ui>
168
169=== modified file 'run-tests.bat'
170--- run-tests.bat 2012-01-31 19:02:36 +0000
171+++ run-tests.bat 2012-02-24 17:28:19 +0000
172@@ -99,7 +99,7 @@
173 "%PYTHONEXEPATH%\python.exe" setup.py build
174 ECHO Running tests
175 :: execute the tests with a number of ignored linux only modules
176-"%PYTHONEXEPATH%\python.exe" "%PYTHONEXEPATH%\Scripts\u1trial" -i "test_linux.py, test_txsecrets.py" -p "ubuntu_sso\gtk" --reactor=qt4 --gui %PARAMS% ubuntu_sso
177+"%PYTHONEXEPATH%\python.exe" "%PYTHONEXEPATH%\Scripts\u1trial" -i "test_linux.py, test_txsecrets.py, test_qt.py, test_glib.py" -p "ubuntu_sso\gtk" --reactor=qt4 --gui %PARAMS% ubuntu_sso
178 :: Clean the build from the setupt.py
179 ECHO Cleaning the generated code
180 "%PYTHONEXEPATH%\python.exe" setup.py clean
181
182=== modified file 'ubuntu_sso/qt/current_user_sign_in_page.py'
183--- ubuntu_sso/qt/current_user_sign_in_page.py 2012-02-18 15:02:49 +0000
184+++ ubuntu_sso/qt/current_user_sign_in_page.py 2012-02-24 17:28:19 +0000
185@@ -19,12 +19,12 @@
186 from functools import partial
187
188 from PyQt4 import QtGui, QtCore
189-from twisted.internet import defer
190
191 from ubuntu_sso import NO_OP
192+from ubuntu_sso.logger import setup_logging
193 from ubuntu_sso.qt import build_general_error_message
194-from ubuntu_sso.qt.gui import SSOWizardPage
195-from ubuntu_sso.logger import setup_logging
196+from ubuntu_sso.qt.sso_wizard_page import SSOWizardPage
197+from ubuntu_sso.qt.ui.current_user_sign_in_ui import Ui_CurrentUserSignInPage
198 from ubuntu_sso.utils.ui import (
199 CANCEL_BUTTON,
200 EMAIL_LABEL,
201@@ -45,15 +45,15 @@
202 class CurrentUserSignInPage(SSOWizardPage):
203 """Wizard Page that lets a current user Sign into Ubuntu Single Sign On."""
204
205+ ui_class = Ui_CurrentUserSignInPage
206 userLoggedIn = QtCore.pyqtSignal('QString', 'QString')
207 passwordForgotten = QtCore.pyqtSignal()
208 userNotValidated = QtCore.pyqtSignal('QString', 'QString')
209
210- def __init__(self, ui, ping_url, *args, **kwargs):
211- super(CurrentUserSignInPage, self).__init__(ui, *args, **kwargs)
212- self.ping_url = ping_url
213-
214- self._signals = {
215+ @property
216+ def _signals(self):
217+ """The signals to connect to the backend."""
218+ result = {
219 'LoggedIn':
220 self._filter_by_app_name(self.on_logged_in),
221 'LoginError':
222@@ -61,7 +61,7 @@
223 'UserNotValidated':
224 self._filter_by_app_name(self.on_user_not_validated),
225 }
226- self.setup_page()
227+ return result
228
229 def on_user_not_validated(self, *args):
230 """Show the validate email page."""
231@@ -69,15 +69,6 @@
232 password = unicode(self.ui.password_edit.text())
233 self.userNotValidated.emit(email, password)
234
235- @defer.inlineCallbacks
236- def setup_page(self):
237- """Setup the widget components."""
238- self.backend = yield self.get_backend()
239- self._set_translated_strings()
240- # lets add call backs to be execute for the calls we are interested
241- self._setup_signals()
242- self._connect_ui()
243-
244 # Invalid names of Qt-inherited methods
245 # pylint: disable=C0103
246
247
248=== modified file 'ubuntu_sso/qt/email_verification_page.py'
249--- ubuntu_sso/qt/email_verification_page.py 2012-02-22 16:58:08 +0000
250+++ ubuntu_sso/qt/email_verification_page.py 2012-02-24 17:28:19 +0000
251@@ -19,19 +19,19 @@
252 from functools import partial
253
254 from PyQt4 import QtCore
255-from twisted.internet import defer
256
257 from ubuntu_sso import NO_OP
258+from ubuntu_sso.logger import setup_logging
259 from ubuntu_sso.qt import build_general_error_message
260-from ubuntu_sso.qt.gui import SSOWizardPage
261-from ubuntu_sso.logger import setup_logging
262+from ubuntu_sso.qt.sso_wizard_page import SSOWizardPage
263+from ubuntu_sso.qt.ui.email_verification_ui import Ui_EmailVerificationPage
264 from ubuntu_sso.utils.ui import (
265+ ERROR_EMAIL_TOKEN,
266 NEXT,
267 VERIFICATION_CODE,
268 VERIFY_EMAIL_TITLE,
269 VERIFY_EMAIL_CONTENT,
270 )
271-from ubuntu_sso.utils.ui import ERROR_EMAIL_TOKEN
272
273
274 logger = setup_logging('ubuntu_sso.email_verification_page')
275@@ -40,27 +40,24 @@
276 class EmailVerificationPage(SSOWizardPage):
277 """Widget used to input the email verification code."""
278
279+ ui_class = Ui_EmailVerificationPage
280 registrationSuccess = QtCore.pyqtSignal('QString', 'QString')
281
282- def __init__(self, ui, ping_url, *args, **kwargs):
283- super(EmailVerificationPage, self).__init__(ui, *args, **kwargs)
284- self.ping_url = ping_url
285+ def __init__(self, *args, **kwargs):
286 self.email = ''
287 self.password = ''
288- self._signals = {
289+ super(EmailVerificationPage, self).__init__(*args, **kwargs)
290+
291+ @property
292+ def _signals(self):
293+ """The signals to connect to the backend."""
294+ result = {
295 'EmailValidated':
296 self._filter_by_app_name(self.on_email_validated),
297 'EmailValidationError':
298 self._filter_by_app_name(self.on_email_validation_error),
299 }
300- self.setup_page()
301-
302- @defer.inlineCallbacks
303- def setup_page(self):
304- """Setup the ui components."""
305- self.backend = yield self.get_backend()
306- self._setup_signals()
307- self._connect_ui_elements()
308+ return result
309
310 @property
311 def verification_code(self):
312@@ -72,9 +69,9 @@
313 """Return the button that move to the next stage."""
314 return self.ui.next_button
315
316- def _connect_ui_elements(self):
317+ def _connect_ui(self):
318 """Set the connection of signals."""
319- logger.debug('EmailVerificationController._connect_ui_elements')
320+ logger.debug('EmailVerificationController._connect_ui')
321 self.ui.verification_code_edit.textChanged.connect(
322 self.validate_form)
323 self.next_button.clicked.connect(self.validate_email)
324@@ -89,7 +86,7 @@
325 self.next_button.style().unpolish(self.next_button)
326 self.next_button.style().polish(self.next_button)
327
328- def _set_titles(self):
329+ def _set_translated_strings(self):
330 """Set the different titles."""
331 logger.debug('EmailVerificationController._set_titles')
332 self.header.set_title(VERIFY_EMAIL_TITLE)
333@@ -104,9 +101,9 @@
334 """This class needs to have a public set_titles.
335
336 Since the subtitle contains data that is only known after SetupAccount
337- and _set_titles is only called on initialization.
338+ and _set_translated_strings is only called on initialization.
339 """
340- self._set_titles()
341+ self._set_translated_strings()
342
343 def validate_email(self):
344 """Call the next action."""
345
346=== modified file 'ubuntu_sso/qt/error_page.py'
347--- ubuntu_sso/qt/error_page.py 2012-02-07 18:59:36 +0000
348+++ ubuntu_sso/qt/error_page.py 2012-02-24 17:28:19 +0000
349@@ -16,14 +16,21 @@
350
351 """Email Verification page UI."""
352
353-from ubuntu_sso.qt.gui import SSOWizardPage
354+from ubuntu_sso.qt.sso_wizard_page import SSOWizardPage
355+from ubuntu_sso.qt.ui.error_message_ui import Ui_ErrorPage
356 from ubuntu_sso.utils.ui import ERROR
357
358
359 class ErrorPage(SSOWizardPage):
360 """Widget used to show the diff errors."""
361
362- def __init__(self, ui, *args, **kwargs):
363- super(ErrorPage, self).__init__(ui, *args, **kwargs)
364+ ui_class = Ui_ErrorPage
365+ next = None
366+
367+ def _set_translated_strings(self):
368+ """Set the translated strings."""
369+ self.ui.error_message_label.setText(ERROR)
370+
371+ def _connect_ui(self):
372+ """Connect the buttons to perform actions."""
373 self.next = -1
374- self.ui.error_message_label.setText(ERROR)
375
376=== modified file 'ubuntu_sso/qt/forgotten_password_page.py'
377--- ubuntu_sso/qt/forgotten_password_page.py 2012-02-16 14:13:36 +0000
378+++ ubuntu_sso/qt/forgotten_password_page.py 2012-02-24 17:28:19 +0000
379@@ -19,10 +19,10 @@
380 from functools import partial
381
382 from PyQt4 import QtCore
383-from twisted.internet import defer
384
385 from ubuntu_sso import NO_OP
386-from ubuntu_sso.qt.gui import SSOWizardEnhancedEditPage
387+from ubuntu_sso.qt.sso_wizard_page import SSOWizardEnhancedEditPage
388+from ubuntu_sso.qt.ui.forgotten_password_ui import Ui_ForgottenPasswordPage
389 from ubuntu_sso.utils.ui import (
390 EMAIL_LABEL,
391 is_correct_email,
392@@ -37,29 +37,19 @@
393 class ForgottenPasswordPage(SSOWizardEnhancedEditPage):
394 """Widget used to deal with users that forgot the password."""
395
396+ ui_class = Ui_ForgottenPasswordPage
397 passwordResetTokenSent = QtCore.pyqtSignal()
398
399- def __init__(self, ui, *args, **kwargs):
400- super(ForgottenPasswordPage, self).__init__(ui, *args, **kwargs)
401- self._signals = {
402+ @property
403+ def _signals(self):
404+ """The signals to connect to the backend."""
405+ result = {
406 'PasswordResetTokenSent':
407 self._filter_by_app_name(self.on_password_reset_token_sent),
408 'PasswordResetError':
409 self._filter_by_app_name(self.on_password_reset_error),
410 }
411- self.setup_page()
412-
413- @defer.inlineCallbacks
414- def setup_page(self):
415- """Setup the widget components."""
416- self.backend = yield self.get_backend()
417- self._setup_signals()
418- # hide the error label
419- self.try_again_widget.setVisible(False)
420- self._set_translated_strings()
421- self._connect_ui()
422- self._set_enhanced_line_edit()
423- self._register_fields()
424+ return result
425
426 @property
427 def email_widget(self):
428@@ -144,8 +134,13 @@
429 self.email_address_line_edit.textChanged.connect(self._validate)
430
431 self.send_button.clicked.connect(self.request_new_password)
432+
433+ self.try_again_widget.setVisible(False)
434 self.try_again_button.clicked.connect(self.on_try_again)
435
436+ self._set_enhanced_line_edit()
437+ self._register_fields()
438+
439 def request_new_password(self):
440 """Send the request password operation."""
441 args = (self.app_name, self.email_address)
442@@ -171,13 +166,11 @@
443 self.try_again_widget.setVisible(False)
444 self.email_widget.setVisible(True)
445
446- # pylint: disable=W0212
447 def on_password_reset_token_sent(self, app_name, result):
448 """Action taken when we managed to get the password reset done."""
449 # ignore the result and move to the reset page
450 self.overlay.hide()
451 self.passwordResetTokenSent.emit()
452- # pylint: enable=W0212
453
454 def on_password_reset_error(self, app_name, error):
455 """Action taken when there was an error requesting the reset."""
456
457=== modified file 'ubuntu_sso/qt/loadingoverlay.py'
458--- ubuntu_sso/qt/loadingoverlay.py 2012-02-22 16:58:08 +0000
459+++ ubuntu_sso/qt/loadingoverlay.py 2012-02-24 17:28:19 +0000
460@@ -1,5 +1,5 @@
461 # -*- coding: utf-8 -*-
462-
463+#
464 # Copyright 2012 Canonical Ltd.
465 #
466 # This program is free software: you can redistribute it and/or modify it
467@@ -45,7 +45,7 @@
468
469 self.ui.label.setText(LOADING_OVERLAY)
470
471- # Invalid name "paintEvent"
472+ # Invalid name "paintEvent", "eventFilter", "showEvent", "timerEvent"
473 # pylint: disable=C0103
474
475 def paintEvent(self, event):
476@@ -60,9 +60,6 @@
477 painter.end()
478 QtGui.QFrame.paintEvent(self, event)
479
480- # Invalid name "eventFilter"
481- # pylint: disable=C0103
482-
483 def eventFilter(self, obj, event):
484 """Filter events from Frame content to draw the dot animation."""
485 if getattr(self, 'ui', None) is not None and \
486@@ -99,9 +96,6 @@
487 painter.end()
488 return False
489
490- # Invalid name "showEvent"
491- # pylint: disable=C0103
492-
493 def showEvent(self, event):
494 """Start the dot animation."""
495 self.ui.frm_box.installEventFilter(self)
496@@ -112,9 +106,6 @@
497 if not self.timer:
498 self.timer = self.startTimer(200)
499
500- # Invalid name "timerEvent"
501- # pylint: disable=C0103
502-
503 def timerEvent(self, event):
504 """Execute a loop to update the dot animation."""
505 if self.counter in (0, 4):
506@@ -124,3 +115,5 @@
507 else:
508 self.counter -= 1
509 self.update()
510+
511+ # pylint: enable=C0103
512
513=== modified file 'ubuntu_sso/qt/network_detection_page.py'
514--- ubuntu_sso/qt/network_detection_page.py 2012-02-22 16:58:08 +0000
515+++ ubuntu_sso/qt/network_detection_page.py 2012-02-24 17:28:19 +0000
516@@ -1,5 +1,5 @@
517 # -*- coding: utf-8 -*-
518-
519+#
520 # Copyright 2012 Canonical Ltd.
521 #
522 # This program is free software: you can redistribute it and/or modify it
523@@ -21,6 +21,7 @@
524
525 from ubuntu_sso import networkstate
526
527+from ubuntu_sso.qt.sso_wizard_page import SSOWizardPage
528 from ubuntu_sso.qt.ui import network_detection_ui
529 from ubuntu_sso.utils.ui import (
530 CLOSE_AND_SETUP_LATER,
531@@ -30,21 +31,21 @@
532 )
533
534
535-class NetworkDetectionPage(QtGui.QWizardPage):
536+class NetworkDetectionPage(SSOWizardPage):
537
538 """Widget to show if we don't detect a network connection."""
539
540- def __init__(self, app_name, banner_pixmap=None, parent=None):
541- super(NetworkDetectionPage, self).__init__(parent)
542- self.app_name = app_name
543- self.setTitle(NETWORK_DETECTION_TITLE)
544- self.ui = network_detection_ui.Ui_Form()
545- self.ui.setupUi(self)
546+ ui_class = network_detection_ui.Ui_Form
547+
548+ def __init__(self, *args, **kwargs):
549+ super(NetworkDetectionPage, self).__init__(*args, **kwargs)
550+ banner_pixmap = kwargs.pop('banner_pixmap', None)
551 if banner_pixmap is not None:
552 self.ui.image_label.setPixmap(banner_pixmap)
553 self.btn_try_again = None
554
555 # pylint: disable=C0103
556+
557 def initializePage(self):
558 """Set UI details."""
559 self.wizard()._next_id = None
560@@ -70,6 +71,7 @@
561 self.btn_try_again.style().unpolish(self.btn_try_again)
562 self.btn_try_again.style().polish(self.btn_try_again)
563 self.wizard().customButtonClicked.connect(self.try_again)
564+
565 # pylint: enable=C0103
566
567 @defer.inlineCallbacks
568@@ -81,3 +83,10 @@
569 self.wizard()._next_id = self.wizard().SIGN_IN_PAGE_ID
570 self.wizard().next()
571 self.wizard()._next_id = None
572+
573+ def _set_translated_strings(self):
574+ """Implement in each child."""
575+ self.setTitle(NETWORK_DETECTION_TITLE)
576+
577+ def _connect_ui(self):
578+ """Implement in each child."""
579
580=== modified file 'ubuntu_sso/qt/reset_password_page.py'
581--- ubuntu_sso/qt/reset_password_page.py 2012-02-16 14:13:36 +0000
582+++ ubuntu_sso/qt/reset_password_page.py 2012-02-24 17:28:19 +0000
583@@ -18,15 +18,14 @@
584
585 from functools import partial
586
587-from PyQt4.QtCore import SIGNAL
588-from PyQt4.QtCore import pyqtSignal
589+from PyQt4.QtCore import SIGNAL, pyqtSignal
590 from PyQt4.QtGui import QApplication
591-from twisted.internet import defer
592
593 from ubuntu_sso import NO_OP
594-from ubuntu_sso.qt import build_general_error_message
595-from ubuntu_sso.qt.gui import SSOWizardEnhancedEditPage
596-from ubuntu_sso.qt import common
597+from ubuntu_sso.logger import setup_logging
598+from ubuntu_sso.qt import build_general_error_message, common
599+from ubuntu_sso.qt.sso_wizard_page import SSOWizardEnhancedEditPage
600+from ubuntu_sso.qt.ui.reset_password_ui import Ui_ResetPasswordPage
601 from ubuntu_sso.utils.ui import (
602 is_min_required_password,
603 PASSWORD1_ENTRY,
604@@ -37,7 +36,6 @@
605 RESET_TITLE,
606 RESET_SUBTITLE,
607 )
608-from ubuntu_sso.logger import setup_logging
609
610
611 logger = setup_logging('ubuntu_sso.reset_password_page')
612@@ -46,35 +44,19 @@
613 class ResetPasswordPage(SSOWizardEnhancedEditPage):
614 """Widget used to allow the user change his password."""
615
616+ ui_class = Ui_ResetPasswordPage
617 passwordChanged = pyqtSignal('QString')
618
619- def __init__(self, ui, app_name=None, parent=None):
620- """Create a new instance."""
621- super(ResetPasswordPage, self).__init__(ui, app_name, parent)
622- self.ui.password_line_edit.textEdited.connect(
623- lambda: common.password_assistance(self.ui.password_line_edit,
624- self.ui.password_assistance,
625- common.NORMAL))
626- self.ui.confirm_password_line_edit.textEdited.connect(
627- lambda: common.password_check_match(self.ui.password_line_edit,
628- self.ui.confirm_password_line_edit,
629- self.ui.password_assistance))
630- self._signals = {
631+ @property
632+ def _signals(self):
633+ """The signals to connect to the backend."""
634+ result = {
635 'PasswordChanged':
636 self._filter_by_app_name(self.on_password_changed),
637 'PasswordChangeError':
638 self._filter_by_app_name(self.on_password_change_error),
639 }
640- self.setup_page()
641-
642- @defer.inlineCallbacks
643- def setup_page(self):
644- """Setup the widget components."""
645- self.backend = yield self.get_backend()
646- self._setup_signals()
647- self._set_translated_strings()
648- self._connect_ui()
649- self._add_line_edits_validations()
650+ return result
651
652 def focus_changed(self, old, now):
653 """Check who has the focus to activate password popups if necessary."""
654@@ -136,6 +118,15 @@
655
656 def _connect_ui(self):
657 """Connect the different ui signals."""
658+ self.ui.password_line_edit.textEdited.connect(
659+ lambda: common.password_assistance(self.ui.password_line_edit,
660+ self.ui.password_assistance,
661+ common.NORMAL))
662+ self.ui.confirm_password_line_edit.textEdited.connect(
663+ lambda: common.password_check_match(self.ui.password_line_edit,
664+ self.ui.confirm_password_line_edit,
665+ self.ui.password_assistance))
666+
667 self.ui.reset_password_button.clicked.connect(
668 self.set_new_password)
669 self.ui.reset_code_line_edit.textChanged.connect(self._validate)
670@@ -143,6 +134,8 @@
671 self.ui.confirm_password_line_edit.textChanged.connect(
672 self._validate)
673
674+ self._add_line_edits_validations()
675+
676 def _validate(self):
677 """Enable the submit button if data is valid."""
678 enabled = True
679
680=== modified file 'ubuntu_sso/qt/setup_account_page.py'
681--- ubuntu_sso/qt/setup_account_page.py 2012-02-24 14:58:30 +0000
682+++ ubuntu_sso/qt/setup_account_page.py 2012-02-24 17:28:19 +0000
683@@ -29,13 +29,16 @@
684 # pylint: enable=F0401
685
686 from PyQt4 import QtGui, QtCore
687-from twisted.internet import defer
688
689 from ubuntu_sso import NO_OP
690-from ubuntu_sso.qt import build_general_error_message
691-from ubuntu_sso.qt import common
692-from ubuntu_sso.qt.gui import SSOWizardEnhancedEditPage
693-from ubuntu_sso.qt import enhanced_check_box
694+from ubuntu_sso.logger import setup_logging
695+from ubuntu_sso.qt import (
696+ build_general_error_message,
697+ common,
698+ enhanced_check_box,
699+)
700+from ubuntu_sso.qt.sso_wizard_page import SSOWizardEnhancedEditPage
701+from ubuntu_sso.qt.ui.setup_account_ui import Ui_SetUpAccountPage
702 from ubuntu_sso.utils.ui import (
703 AGREE_TO_PRIVACY_POLICY,
704 AGREE_TO_TERMS,
705@@ -71,12 +74,10 @@
706 TERMS_TEXT,
707 TITLE,
708 )
709-from ubuntu_sso.logger import setup_logging
710
711
712 logger = setup_logging('ubuntu_sso.setup_account_page')
713
714-# pylint: disable=C0103
715 ERROR = u'<font color="#df2d1f"><b> %s </b></font>'
716 TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
717
718@@ -92,47 +93,21 @@
719 class SetupAccountPage(SSOWizardEnhancedEditPage):
720 """Customized Setup Account page for SSO."""
721
722+ ui_class = Ui_SetUpAccountPage
723 userRegistered = QtCore.pyqtSignal('QString', 'QString')
724
725- def __init__(self, ui, subtitle, toc_link, policy_link, *args, **kwargs):
726- super(SetupAccountPage, self).__init__(ui, *args, **kwargs)
727- self._subtitle = subtitle
728+ def __init__(self, *args, **kwargs):
729+ self.captcha_file = None
730 self.captcha_id = None
731- self.captcha_file = None
732- self.ui.captcha_view.setPixmap(QtGui.QPixmap())
733- self.ui.password_edit.textEdited.connect(
734- lambda: common.password_assistance(self.ui.password_edit,
735- self.ui.password_assistance,
736- common.NORMAL))
737-
738- if toc_link:
739- terms_links = TERMS_LINK.format(toc_link=toc_link,
740- terms_text=TERMS_TEXT)
741- if policy_link:
742- privacy_policy_link = PRIVACY_POLICY_LINK.format(
743- policy_link=policy_link,
744- privacy_policy_text=PRIVACY_POLICY_TEXT)
745-
746- terms = ''
747- if toc_link and policy_link:
748- terms = AGREE_TO_TERMS_AND_PRIVACY_POLICY.format(
749- app_name=self.app_name,
750- terms_and_conditions=terms_links,
751- privacy_policy=privacy_policy_link)
752- elif toc_link:
753- terms = AGREE_TO_TERMS.format(app_name=self.app_name,
754- terms_and_conditions=terms_links)
755- elif policy_link:
756- terms = AGREE_TO_PRIVACY_POLICY.format(app_name=self.app_name,
757- privacy_policy=privacy_policy_link)
758-
759- self.terms_checkbox = enhanced_check_box.EnhancedCheckBox(terms)
760- self.ui.hlayout_check.addWidget(self.terms_checkbox)
761- self.terms_checkbox.setVisible(bool(toc_link or policy_link))
762-
763+ self.captcha_received = False
764 self.set_up_button = None
765- self.captcha_received = False
766- self._signals = {
767+ self.terms_checkbox = None
768+ super(SetupAccountPage, self).__init__(*args, **kwargs)
769+
770+ @property
771+ def _signals(self):
772+ """The signals to connect to the backend."""
773+ result = {
774 'CaptchaGenerated':
775 self._filter_by_app_name(self.on_captcha_generated),
776 'CaptchaGenerationError':
777@@ -142,31 +117,16 @@
778 'UserRegistrationError':
779 self._filter_by_app_name(self.on_user_registration_error),
780 }
781- self.setup_page()
782-
783- @defer.inlineCallbacks
784- def setup_page(self):
785- """Setup the widget components."""
786- # request the backend to be used with the ui
787- self.backend = yield self.get_backend()
788- # set the callbacks for the captcha generation
789- self._setup_signals()
790- self._connect_ui_elements()
791- self._refresh_captcha()
792- self._set_translated_strings()
793- self._set_line_edits_validations()
794- self._register_fields()
795+ return result
796
797 # Invalid name "initializePage"
798 # pylint: disable=C0103
799
800 def initializePage(self):
801 """Setup UI details."""
802- # We need to override some texts from SSO
803- # to match our spec
804 title_page = TITLE_STYLE % TITLE.format(app_name=self.app_name)
805 self.setTitle(title_page)
806- self.setSubTitle(self._subtitle)
807+ self.setSubTitle(self.help_text)
808 # Set Setup Account button
809 self.wizard().setOption(QtGui.QWizard.HaveCustomButton3, True)
810 try:
811@@ -199,7 +159,8 @@
812 self.ui.confirm_email_assistance.setVisible(False)
813 self.ui.password_assistance.setVisible(False)
814 self.ui.refresh_label.setVisible(True)
815- #pylint: enable=C0103
816+
817+ # pylint: enable=C0103
818
819 def _set_translated_strings(self):
820 """Set the strings."""
821@@ -218,6 +179,33 @@
822 self.ui.refresh_label.setText(CAPTCHA_RELOAD_MESSAGE %
823 {'reload_link': link})
824
825+ if self.tc_url:
826+ terms_links = TERMS_LINK.format(toc_link=self.tc_url,
827+ terms_text=TERMS_TEXT)
828+ if self.policy_url:
829+ privacy_policy_link = PRIVACY_POLICY_LINK.format(
830+ policy_link=self.policy_url,
831+ privacy_policy_text=PRIVACY_POLICY_TEXT)
832+
833+ terms = ''
834+ if self.tc_url and self.policy_url:
835+ terms = AGREE_TO_TERMS_AND_PRIVACY_POLICY.format(
836+ app_name=self.app_name,
837+ terms_and_conditions=terms_links,
838+ privacy_policy=privacy_policy_link)
839+ elif self.tc_url:
840+ terms = AGREE_TO_TERMS.format(app_name=self.app_name,
841+ terms_and_conditions=terms_links)
842+ elif self.policy_url:
843+ terms = AGREE_TO_PRIVACY_POLICY.format(app_name=self.app_name,
844+ privacy_policy=privacy_policy_link)
845+
846+ self.terms_checkbox = enhanced_check_box.EnhancedCheckBox(terms)
847+ self.ui.hlayout_check.addWidget(self.terms_checkbox)
848+ self.terms_checkbox.setVisible(bool(self.tc_url or self.policy_url))
849+
850+ self._register_fields()
851+
852 def _set_line_edits_validations(self):
853 """Set the validations to be performed on the edits."""
854 logger.debug('SetUpAccountPage._set_line_edits_validations')
855@@ -240,9 +228,17 @@
856 self.ui.password_edit.textChanged.connect(
857 self.ui.confirm_password_edit.textChanged.emit)
858
859- def _connect_ui_elements(self):
860+ def _connect_ui(self):
861 """Set the connection of signals."""
862- logger.debug('SetUpAccountPage._connect_ui_elements')
863+ logger.debug('SetUpAccountPage._connect_ui')
864+ self._set_line_edits_validations()
865+
866+ self.ui.captcha_view.setPixmap(QtGui.QPixmap())
867+ self.ui.password_edit.textEdited.connect(
868+ lambda: common.password_assistance(self.ui.password_edit,
869+ self.ui.password_assistance,
870+ common.NORMAL))
871+
872 self.ui.refresh_label.linkActivated.connect(lambda url: \
873 self._refresh_captcha())
874 # We need to check if we enable the button on many signals
875@@ -257,6 +253,8 @@
876 self._enable_setup_button)
877 self.terms_checkbox.stateChanged.connect(self._enable_setup_button)
878
879+ self._refresh_captcha()
880+
881 def _enable_setup_button(self):
882 """Only enable the setup button if the form is valid."""
883 name = unicode(self.ui.name_edit.text()).strip()
884@@ -393,7 +391,6 @@
885 self.message_box.critical(self, self.app_name, '\n'.join(messages))
886 return condition
887
888- # pylint: disable=W0212
889 def set_next_validation(self):
890 """Set the validation as the next page."""
891 logger.debug('SetUpAccountPage.set_next_validation')
892@@ -413,7 +410,6 @@
893 f(*args, reply_handler=NO_OP, error_handler=error_handler)
894 # Update validation page's title, which contains the email
895 self.userRegistered.emit(email, password)
896- # pylint: enable=W0212
897
898 def is_correct_email(self, email_address):
899 """Return if the email is correct."""
900@@ -484,7 +480,8 @@
901 label.setText(ERROR % msg)
902 label.setVisible(True)
903
904- #pylint: disable=C0103
905+ # pylint: disable=C0103
906+
907 def showEvent(self, event):
908 """Set set_up_button as default button when the page is shown."""
909 # This method should stays here because if we move it to initializePage
910@@ -514,7 +511,8 @@
911 except TypeError:
912 pass
913 super(SetupAccountPage, self).hideEvent(event)
914- #pylint: enable=C0103
915+
916+ # pylint: enable=C0103
917
918 def on_captcha_refreshing(self):
919 """Show overlay when captcha is refreshing."""
920
921=== removed file 'ubuntu_sso/qt/sign_in_page.py'
922--- ubuntu_sso/qt/sign_in_page.py 2012-02-17 18:43:17 +0000
923+++ ubuntu_sso/qt/sign_in_page.py 1970-01-01 00:00:00 +0000
924@@ -1,97 +0,0 @@
925-# -*- coding: utf-8 -*-
926-#
927-# Copyright 2012 Canonical Ltd.
928-#
929-# This program is free software: you can redistribute it and/or modify it
930-# under the terms of the GNU General Public License version 3, as published
931-# by the Free Software Foundation.
932-#
933-# This program is distributed in the hope that it will be useful, but
934-# WITHOUT ANY WARRANTY; without even the implied warranties of
935-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
936-# PURPOSE. See the GNU General Public License for more details.
937-#
938-# You should have received a copy of the GNU General Public License along
939-# with this program. If not, see <http://www.gnu.org/licenses/>.
940-
941-"""Page to allow the user to sign in."""
942-
943-from PyQt4 import QtGui, QtCore
944-
945-from ubuntu_sso.qt.gui import SSOWizardPage
946-from ubuntu_sso.logger import setup_logging
947-from ubuntu_sso.utils.ui import (
948- CLOSE_AND_SETUP_LATER,
949- EXISTING_ACCOUNT_CHOICE_BUTTON,
950- SET_UP_ACCOUNT_CHOICE_BUTTON,
951-)
952-
953-
954-logger = setup_logging('ubuntu_sso.sing_in_page')
955-
956-
957-class SignInPage(SSOWizardPage):
958- """Wizard Page that lets the user Sign into Ubuntu Single Sign On."""
959-
960- existingAccountSelected = QtCore.pyqtSignal()
961- newAccountSelected = QtCore.pyqtSignal()
962- singInCanceled = QtCore.pyqtSignal()
963-
964- def __init__(self, ui, image_pixmap, *args, **kwargs):
965- super(SignInPage, self).__init__(ui, *args, **kwargs)
966- self.ui.image_label.setPixmap(image_pixmap)
967- self._set_up_translated_strings()
968- self._connect_buttons()
969-
970- def _set_up_translated_strings(self):
971- """Set the correct strings for the UI."""
972- logger.debug('SingInPage._set_up_translated_strings')
973- self.ui.message_label.setText('')
974- self.ui.existing_account_button.setText(
975- EXISTING_ACCOUNT_CHOICE_BUTTON)
976- self.ui.setup_account_button.setText(
977- SET_UP_ACCOUNT_CHOICE_BUTTON)
978-
979- def _connect_buttons(self):
980- """Connect the buttons to the actions to perform."""
981- logger.debug('SingInPage._connect_buttons')
982- self.ui.existing_account_button.clicked.connect(
983- self._set_next_existing)
984- self.ui.setup_account_button.clicked.connect(self._set_next_new)
985-
986- def _set_next_existing(self):
987- """Set the next id and fire signal."""
988- logger.debug('SignInPage._set_next_existing')
989- self.existingAccountSelected.emit()
990-
991- def _set_next_new(self):
992- """Set the next id and fire signal."""
993- logger.debug('SignInPage._set_next_new')
994- self.newAccountSelected.emit()
995-
996- # Invalid names of Qt-inherited methods
997- # pylint: disable=C0103
998-
999- def initializePage(self):
1000- """Setup UI details."""
1001- self.ui.cancel_button.setText(CLOSE_AND_SETUP_LATER)
1002- self.ui.cancel_button.clicked.connect(self.singInCanceled.emit)
1003- # Layout without custom button 1,
1004- # without finish button
1005- # without cancel
1006- self.wizard().setButtonLayout([
1007- QtGui.QWizard.Stretch,
1008- QtGui.QWizard.NextButton])
1009-
1010- def showEvent(self, event):
1011- """Set existing_account_button as default when the page is shown."""
1012- super(SignInPage, self).showEvent(event)
1013- self.ui.existing_account_button.setDefault(True)
1014- self.ui.existing_account_button.style().unpolish(
1015- self.ui.existing_account_button)
1016- self.ui.existing_account_button.style().polish(
1017- self.ui.existing_account_button)
1018-
1019- def nextId(self):
1020- """Provide the next id."""
1021- return self.next
1022
1023=== renamed file 'ubuntu_sso/qt/gui.py' => 'ubuntu_sso/qt/sso_wizard_page.py'
1024--- ubuntu_sso/qt/gui.py 2012-02-23 20:16:46 +0000
1025+++ ubuntu_sso/qt/sso_wizard_page.py 2012-02-24 17:28:19 +0000
1026@@ -35,13 +35,13 @@
1027 from twisted.internet import defer
1028
1029 from ubuntu_sso import main
1030+from ubuntu_sso.logger import setup_logging
1031 from ubuntu_sso.qt import PREFERED_UI_SIZE
1032 from ubuntu_sso.qt.loadingoverlay import LoadingOverlay
1033-from ubuntu_sso.logger import setup_logging
1034 from ubuntu_sso.utils.ui import GENERIC_BACKEND_ERROR
1035
1036
1037-logger = setup_logging('ubuntu_sso.gui')
1038+logger = setup_logging('ubuntu_sso.sso_wizard_page')
1039
1040
1041 class Header(QFrame):
1042@@ -92,32 +92,53 @@
1043 class SSOWizardPage(QWizardPage):
1044 """Root class for all wizard pages."""
1045
1046- def __init__(self, ui, app_name=None, title='', subtitle='', parent=None):
1047+ ui_class = None
1048+ _signals = {} # override in children
1049+
1050+ def __init__(self, app_name, **kwargs):
1051 """Create a new instance."""
1052- super(SSOWizardPage, self).__init__(parent)
1053- self.ui = ui
1054- self.ui.setupUi(self)
1055+ parent = kwargs.pop('parent', None)
1056+ super(SSOWizardPage, self).__init__(parent=parent)
1057+
1058+ self.ui = None
1059+ if self.ui_class is not None:
1060+ # self.ui_class is not callable, pylint: disable=E1102
1061+ self.ui = self.ui_class()
1062+ self.ui.setupUi(self)
1063+
1064 self.overlay = LoadingOverlay(self)
1065 self.overlay.hide()
1066+
1067+ # store common useful data provided by the app
1068 self.app_name = app_name
1069+ self.ping_url = kwargs.get('ping_url', '')
1070+ self.tc_url = kwargs.get('tc_url', '')
1071+ self.policy_url = kwargs.get('policy_url', '')
1072+ self.help_text = kwargs.get('help_text', '')
1073+
1074 self.header = Header()
1075- self.header.set_title(title)
1076- self.header.set_subtitle(subtitle)
1077+ self.header.set_title(title='')
1078+ self.header.set_subtitle(subtitle='')
1079 self.layout().insertWidget(0, self.header)
1080+
1081 self.message_box = QMessageBox
1082- self._signals = {}
1083 self._signals_receivers = {}
1084 self.backend = None
1085
1086+ self.setup_page()
1087+
1088 @defer.inlineCallbacks
1089- def get_backend(self):
1090- """Return the backend used by the controller."""
1091- if self.backend is None:
1092- client = yield main.get_sso_client()
1093- self.backend = client.sso_login
1094- defer.returnValue(self.backend)
1095+ def setup_page(self):
1096+ """Setup the widget components."""
1097+ client = yield main.get_sso_client()
1098+ self.backend = client.sso_login
1099+
1100+ self._setup_signals()
1101+ self._set_translated_strings()
1102+ self._connect_ui()
1103
1104 # pylint: disable=C0103
1105+
1106 def resizeEvent(self, event):
1107 """Resize the overlay to fit all the widget."""
1108 QWizardPage.resizeEvent(self, event)
1109@@ -130,6 +151,7 @@
1110 def setSubTitle(self, subtitle=''):
1111 """Set the Wizard Page Subtitle."""
1112 self.header.set_subtitle(subtitle)
1113+
1114 # pylint: enable=C0103
1115
1116 def _filter_by_app_name(self, f):
1117@@ -160,6 +182,14 @@
1118 match = self.backend.connect_to_signal(signal, method)
1119 self._signals_receivers[signal] = match
1120
1121+ def _set_translated_strings(self):
1122+ """Implement in each child."""
1123+ raise NotImplementedError()
1124+
1125+ def _connect_ui(self):
1126+ """Implement in each child."""
1127+ raise NotImplementedError()
1128+
1129 def _handle_error(self, remote_call, handler, error):
1130 """Handle any error when calling the remote backend."""
1131 logger.error('Remote call %r failed with: %r', remote_call, error)
1132@@ -210,11 +240,14 @@
1133 class SSOWizardEnhancedEditPage(SSOWizardPage):
1134 """Page that contains enhanced line edits."""
1135
1136- def __init__(self, ui, app_name=None, parent=None):
1137+ # Method '_connect_ui', '_set_translated_strings' is abstract in class
1138+ # 'SSOWizardPage' but is not overridden
1139+ # pylint: disable=W0223
1140+
1141+ def __init__(self, *args, **kwargs):
1142 """Create a new instance."""
1143 self._enhanced_edits = {}
1144- super(SSOWizardEnhancedEditPage, self).__init__(ui,
1145- app_name=app_name, parent=parent)
1146+ super(SSOWizardEnhancedEditPage, self).__init__(*args, **kwargs)
1147
1148 def set_line_edit_validation_rule(self, edit, cb):
1149 """Set a new enhanced edit so that we can show an icon."""
1150
1151=== modified file 'ubuntu_sso/qt/success_page.py'
1152--- ubuntu_sso/qt/success_page.py 2012-02-13 18:08:13 +0000
1153+++ ubuntu_sso/qt/success_page.py 2012-02-24 17:28:19 +0000
1154@@ -16,15 +16,24 @@
1155
1156 """Success page UI."""
1157
1158-from ubuntu_sso.qt.gui import SSOWizardPage
1159+from PyQt4 import QtGui
1160+
1161+from ubuntu_sso.qt.sso_wizard_page import SSOWizardPage
1162+from ubuntu_sso.qt.ui.success_message_ui import Ui_SuccessPage
1163 from ubuntu_sso.utils.ui import SUCCESS
1164
1165
1166 class SuccessPage(SSOWizardPage):
1167 """Page used to display success message."""
1168
1169- def __init__(self, ui, image_pixmap, *args, **kwargs):
1170- super(SuccessPage, self).__init__(ui, *args, **kwargs)
1171- self.ui.image_label.setPixmap(image_pixmap)
1172+ ui_class = Ui_SuccessPage
1173+
1174+ def _set_translated_strings(self):
1175+ """Set proper strings to widgets."""
1176+ # we may want to customize the image_label in some future
1177+ self.ui.image_label.setPixmap(QtGui.QPixmap())
1178 message = SUCCESS % {'app_name': self.app_name}
1179 self.ui.success_message_body.setText(message)
1180+
1181+ def _connect_ui(self):
1182+ """Nothing to connect."""
1183
1184=== modified file 'ubuntu_sso/qt/tests/__init__.py'
1185--- ubuntu_sso/qt/tests/__init__.py 2012-02-15 17:33:40 +0000
1186+++ ubuntu_sso/qt/tests/__init__.py 2012-02-24 17:28:19 +0000
1187@@ -19,20 +19,30 @@
1188 from PyQt4 import QtGui, QtCore
1189 from twisted.internet import defer
1190 from twisted.trial.unittest import TestCase
1191-from ubuntu_sso.qt import loadingoverlay
1192
1193-from ubuntu_sso import (
1194- main,
1195- NO_OP,
1196+from ubuntu_sso import main, NO_OP
1197+from ubuntu_sso.qt import sso_wizard_page
1198+from ubuntu_sso.tests import (
1199+ APP_NAME,
1200+ HELP_TEXT,
1201+ PING_URL,
1202+ POLICY_URL,
1203+ TC_URL,
1204+ WINDOW_ID,
1205 )
1206
1207+KWARGS = dict(app_name=APP_NAME, help_text=HELP_TEXT, ping_url=PING_URL,
1208+ policy_url=POLICY_URL, tc_url=TC_URL, window_id=WINDOW_ID)
1209+
1210+# is ok to access private method/attrs in tests
1211+# pylint: disable=W0212
1212+
1213
1214 class FakedObject(object):
1215 """Fake an object, record every call."""
1216
1217 next_result = None
1218- exposed_methods = ['connect_to_signal',
1219- 'generate_captcha', 'request_password_reset_token']
1220+ exposed_methods = []
1221
1222 def __init__(self, *args, **kwargs):
1223 self._args = args
1224@@ -52,10 +62,26 @@
1225 return inner
1226
1227
1228+class FakedSSOLoginBackend(FakedObject):
1229+ """A faked sso_login backend."""
1230+
1231+ exposed_methods = [
1232+ 'connect_to_signal',
1233+ 'generate_captcha',
1234+ 'login',
1235+ 'login_and_ping',
1236+ 'register_user',
1237+ 'request_password_reset_token',
1238+ 'set_new_password',
1239+ 'validate_email',
1240+ 'validate_email_and_ping',
1241+ ]
1242+
1243+
1244 class FakedBackend(object):
1245 """A faked backend."""
1246
1247- sso_login = FakedObject()
1248+ sso_login = FakedSSOLoginBackend()
1249
1250
1251 class FakePageUiStyle(object):
1252@@ -203,7 +229,7 @@
1253 self.overlay = FakeOverlay()
1254 self.local_folders_page = FakeWizardPage()
1255 self.folders_page = FakeWizardPage()
1256- self.app_name = 'app_name'
1257+ self.app_name = APP_NAME
1258
1259 def show(self):
1260 """Fake method."""
1261@@ -250,6 +276,7 @@
1262
1263
1264 class FakeWizard(object):
1265+
1266 """Replace wizard() function on wizard pages."""
1267
1268 customButtonClicked = QtCore.QObject()
1269@@ -374,6 +401,12 @@
1270 class BaseTestCase(TestCase):
1271 """The base test case."""
1272
1273+ kwargs = None
1274+ ui_class = None
1275+ ui_signals = ()
1276+ ui_backend_signals = ()
1277+ ui_wizard_class = FakeWizard
1278+
1279 @defer.inlineCallbacks
1280 def setUp(self):
1281 yield super(BaseTestCase, self).setUp()
1282@@ -383,11 +416,31 @@
1283 self.patch(main, 'get_sso_client',
1284 lambda *a: defer.succeed(backend))
1285
1286+ self.patch(sso_wizard_page, 'LoadingOverlay', FakeOverlay)
1287+
1288+ self.app_name = APP_NAME
1289+ self.ping_url = PING_URL
1290+ self.signals_results = []
1291+
1292+ # self.ui_class is not callable
1293+ # pylint: disable=E1102, C0103, W0212
1294+ self.ui = None
1295+ self.wizard = None
1296+ if self.ui_class is not None:
1297+ kwargs = dict(KWARGS) if self.kwargs is None else self.kwargs
1298+ self.ui = self.ui_class(**kwargs)
1299+
1300+ for signal in self.ui_signals:
1301+ self.patch(self.ui_class, signal, FakeSignal())
1302+
1303+ if self.ui_wizard_class is not None:
1304+ self.wizard = self.ui_wizard_class()
1305+ self.patch(self.ui, 'wizard', lambda: self.wizard)
1306+
1307 def _set_called(self, *args, **kwargs):
1308 """Store 'args' and 'kwargs' for test assertions."""
1309 self._called = (args, kwargs)
1310
1311- # pylint: disable=E1101, W0212
1312 def assert_backend_called(self, method, *args, **kwargs):
1313 """Check that 'method(*args, **kwargs)' was called in the backend."""
1314 self.assertIn(method, self.ui.backend._called)
1315@@ -402,34 +455,6 @@
1316 self.assertEqual(error_handler.func, self.ui._handle_error)
1317
1318 self.assertEqual(call[1], kwargs)
1319- # pylint: enable=E1101, W0212
1320-
1321-
1322-class BaseTestCaseUI(TestCase):
1323- """Base Test Case."""
1324-
1325- class_ui = None
1326- kwargs = {}
1327-
1328- @defer.inlineCallbacks
1329- def setUp(self):
1330- yield super(BaseTestCaseUI, self).setUp()
1331- # self.class_ui is not callable
1332- # pylint: disable=E1102, C0103, W0212
1333- self.ui = None
1334- self._called = False
1335- if self.class_ui is not None:
1336- self.ui = self.class_ui(**self.kwargs)
1337-
1338- if hasattr(self.ui, 'backend'):
1339- # clean backend calls
1340- self.ui.backend._called.clear()
1341-
1342- self.patch(loadingoverlay, 'LoadingOverlay', FakeOverlay)
1343-
1344- def _set_called(self, *args, **kwargs):
1345- """Store 'args' and 'kwargs' for test assertions."""
1346- self._called = (args, kwargs)
1347
1348 def get_pixmap_data(self, pixmap):
1349 """Get the raw data of a QPixmap."""
1350@@ -446,3 +471,30 @@
1351 d1 = self.get_pixmap_data(pixmap1)
1352 d2 = self.get_pixmap_data(pixmap2)
1353 self.assertEqual(d1, d2)
1354+
1355+ # pylint: enable=C0103
1356+
1357+ @defer.inlineCallbacks
1358+ def test_setup_page(self):
1359+ """Test the backend signal connection."""
1360+ if self.ui is None or getattr(self.ui, 'setup_page', None) is None:
1361+ return
1362+
1363+ called = []
1364+ self.patch(self.ui, '_setup_signals',
1365+ lambda *a: called.append('_setup_signals'))
1366+ self.patch(self.ui, '_connect_ui',
1367+ lambda *a: called.append('_connect_ui'))
1368+ self.patch(self.ui, '_set_translated_strings',
1369+ lambda *a: called.append('_set_translated_strings'))
1370+
1371+ yield self.ui.setup_page()
1372+
1373+ self.assertEqual(self.ui.backend, self.sso_login_backend)
1374+
1375+ for signal in self.ui_backend_signals:
1376+ self.assertIn(signal, self.ui._signals)
1377+ self.assertTrue(callable(self.ui._signals[signal]))
1378+
1379+ expected = ['_setup_signals', '_set_translated_strings', '_connect_ui']
1380+ self.assertEqual(expected, called)
1381
1382=== modified file 'ubuntu_sso/qt/tests/test_current_user_sign_in_page.py'
1383--- ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-02-16 18:40:41 +0000
1384+++ ubuntu_sso/qt/tests/test_current_user_sign_in_page.py 2012-02-24 17:28:19 +0000
1385@@ -17,78 +17,22 @@
1386 """Tests for the Setup Account page Qt UI."""
1387
1388 from PyQt4 import QtGui, QtCore
1389-from twisted.internet import defer
1390
1391-from ubuntu_sso.qt import gui
1392 from ubuntu_sso.qt import current_user_sign_in_page
1393 from ubuntu_sso.qt.tests import (
1394 BaseTestCase,
1395- FakedBackend,
1396- FakedObject,
1397- FakeOverlay,
1398 FakePageUiStyle,
1399- FakeSignal,
1400- FakeWizard,
1401 FakeWizardButtonStyle,
1402 )
1403-from ubuntu_sso.qt.ui import current_user_sign_in_ui
1404
1405
1406 # pylint: disable=W0212
1407 class CurrentUserSignInTestCase(BaseTestCase):
1408 """Test the SetupAccountPage code."""
1409
1410- @defer.inlineCallbacks
1411- def setUp(self):
1412- yield super(CurrentUserSignInTestCase, self).setUp()
1413- self.patch(gui, "LoadingOverlay", FakeOverlay)
1414- self.patch(gui.main, "get_sso_client", FakedBackend)
1415- self.signals_results = []
1416- self.patch(current_user_sign_in_page.CurrentUserSignInPage,
1417- "userLoggedIn", FakeSignal())
1418- self.patch(current_user_sign_in_page.CurrentUserSignInPage,
1419- "passwordForgotten", FakeSignal())
1420- self.patch(current_user_sign_in_page.CurrentUserSignInPage,
1421- "userNotValidated", FakeSignal())
1422- self.app_name = 'my_app'
1423- self.ui = current_user_sign_in_page.CurrentUserSignInPage(
1424- current_user_sign_in_ui.Ui_CurrentUserSignInPage(),
1425- '',
1426- app_name=self.app_name,
1427- parent=None)
1428- self.wizard = FakeWizard()
1429- self.patch(self.ui, 'wizard', lambda: self.wizard)
1430-
1431- def test_init(self):
1432- """Test the construction of the object."""
1433- self.assertIn('LoggedIn', self.ui._signals)
1434- self.assertIn('LoginError', self.ui._signals)
1435- self.assertIn('UserNotValidated', self.ui._signals)
1436- self.assertTrue(callable(self.ui._signals['LoggedIn']))
1437- self.assertTrue(callable(self.ui._signals['LoginError']))
1438- self.assertTrue(callable(self.ui._signals['UserNotValidated']))
1439- self.assertEqual(self.ui.backend, FakedBackend.sso_login)
1440-
1441- # pylint: disable=E1101
1442- def test_setup_page(self):
1443- """Test that the backend is received and the methods are called."""
1444- exposed_methods = [
1445- '_set_translated_strings',
1446- '_setup_signals',
1447- '_connect_ui']
1448- self.patch(FakedObject, "exposed_methods", exposed_methods)
1449- faked_object = FakedObject()
1450- self.patch(self.ui, "_set_translated_strings",
1451- faked_object._set_translated_strings)
1452- self.patch(self.ui, "_setup_signals",
1453- faked_object._setup_signals)
1454- self.patch(self.ui, "_connect_ui",
1455- faked_object._connect_ui)
1456- self.ui.setup_page()
1457- self.assertIn('_set_translated_strings', faked_object._called)
1458- self.assertIn('_setup_signals', faked_object._called)
1459- self.assertIn('_connect_ui', faked_object._called)
1460- # pylint: enable=E1101
1461+ ui_class = current_user_sign_in_page.CurrentUserSignInPage
1462+ ui_signals = ('userLoggedIn', 'passwordForgotten', 'userNotValidated')
1463+ ui_backend_signals = ('LoggedIn', 'LoginError', 'UserNotValidated')
1464
1465 def test_on_user_not_validated(self):
1466 """Test the navigation flow on user not validated."""
1467@@ -176,12 +120,6 @@
1468
1469 def test_login_with_ping(self):
1470 """Test the login method."""
1471- ping = 'http://ping.me'
1472- self.ui.ping_url = ping
1473- exposed_methods = ['login', 'login_and_ping']
1474- self.patch(FakedObject, "exposed_methods", exposed_methods)
1475- faked_object = FakedObject()
1476- self.patch(self.ui, "backend", faked_object)
1477 email = 'valid@email'
1478 password = '123456'
1479 self.ui.ui.email_edit.setText(email)
1480@@ -189,15 +127,11 @@
1481 self.ui.login()
1482 self.assertEqual(self.ui.overlay.show_counter, 1)
1483 self.assert_backend_called('login_and_ping',
1484- self.app_name, email, password, ping)
1485+ self.app_name, email, password, self.ping_url)
1486
1487 def test_login_without_ping(self):
1488 """Test the login method."""
1489 self.ui.ping_url = ''
1490- exposed_methods = ['login']
1491- self.patch(FakedObject, "exposed_methods", exposed_methods)
1492- faked_object = FakedObject()
1493- self.patch(self.ui, "backend", faked_object)
1494 email = 'valid@email'
1495 password = '123456'
1496 self.ui.ui.email_edit.setText(email)
1497
1498=== modified file 'ubuntu_sso/qt/tests/test_email_verification.py'
1499--- ubuntu_sso/qt/tests/test_email_verification.py 2012-02-23 20:16:46 +0000
1500+++ ubuntu_sso/qt/tests/test_email_verification.py 2012-02-24 17:28:19 +0000
1501@@ -17,62 +17,23 @@
1502 """Tests for the Setup Account page Qt UI."""
1503
1504 from PyQt4 import QtGui, QtCore
1505-from twisted.internet import defer
1506
1507-from ubuntu_sso.qt import gui
1508 from ubuntu_sso.qt import email_verification_page
1509 from ubuntu_sso.qt.tests import (
1510 BaseTestCase,
1511- FakedBackend,
1512- FakedObject,
1513 FakePageUiStyle,
1514- FakeSignal,
1515- FakeWizard,
1516 )
1517-from ubuntu_sso.qt.ui import email_verification_ui
1518-
1519-
1520+
1521+# is ok to access private method/attrs in tests
1522 # pylint: disable=W0212
1523+
1524+
1525 class EmailVerificationTestCase(BaseTestCase):
1526 """Test the SetupAccountPage code."""
1527
1528- @defer.inlineCallbacks
1529- def setUp(self):
1530- yield super(EmailVerificationTestCase, self).setUp()
1531- self.signals_results = []
1532- self.patch(gui.main, "get_sso_client", FakedBackend)
1533- self.patch(email_verification_page.EmailVerificationPage,
1534- "registrationSuccess", FakeSignal())
1535- self.ui = email_verification_page.EmailVerificationPage(
1536- email_verification_ui.Ui_EmailVerificationPage(), '',
1537- parent=None)
1538- self.wizard = FakeWizard()
1539- self.patch(self.ui, 'wizard', lambda: self.wizard)
1540-
1541- def test_init(self):
1542- """Test the construction of the object."""
1543- self.assertIn('EmailValidated', self.ui._signals)
1544- self.assertIn('EmailValidationError', self.ui._signals)
1545- self.assertTrue(callable(self.ui._signals['EmailValidated']))
1546- self.assertTrue(callable(self.ui._signals['EmailValidationError']))
1547- self.assertEqual(self.ui.backend, FakedBackend.sso_login)
1548-
1549- # pylint: disable=E1101
1550- def test_setup_page(self):
1551- """Test that the backend is received and the methods are called."""
1552- exposed_methods = [
1553- '_setup_signals',
1554- '_connect_ui_elements']
1555- self.patch(FakedObject, "exposed_methods", exposed_methods)
1556- faked_object = FakedObject()
1557- self.patch(self.ui, "_setup_signals",
1558- faked_object._setup_signals)
1559- self.patch(self.ui, "_connect_ui_elements",
1560- faked_object._connect_ui_elements)
1561- self.ui.setup_page()
1562- self.assertIn('_setup_signals', faked_object._called)
1563- self.assertIn('_connect_ui_elements', faked_object._called)
1564- # pylint: enable=E1101
1565+ ui_class = email_verification_page.EmailVerificationPage
1566+ ui_signals = ('registrationSuccess',)
1567+ ui_backend_signals = ('EmailValidated', 'EmailValidationError')
1568
1569 def test_verification_code(self):
1570 """Test the verification value returned."""
1571@@ -87,9 +48,9 @@
1572 self.assertEqual(value, self.ui.ui.next_button)
1573 self.assertTrue(isinstance(value, QtGui.QPushButton))
1574
1575- def test_connect_ui_elements(self):
1576+ def test_connect_ui(self):
1577 """Test the connect ui method."""
1578- self.ui._connect_ui_elements()
1579+ self.ui._connect_ui()
1580 # We expect 2 values because _connect_ui is called in the init too.
1581 self.assertEqual(self.ui.ui.verification_code_edit.receivers(
1582 QtCore.SIGNAL("textChanged(const QString&)")), 2)
1583@@ -170,40 +131,29 @@
1584
1585 def test_validate_email_with_ping(self):
1586 """Test the login method."""
1587- ping = 'http://ping.me'
1588- app_name = 'app_name'
1589 email = 'email@example.com'
1590 password = 'password'
1591 code = 'code'
1592- self.ui.ping_url = ping
1593- self.ui.app_name = app_name
1594 self.ui.email = email
1595 self.ui.password = password
1596 self.ui.ui.verification_code_edit.setText(code)
1597- exposed_methods = ['validate_email', 'validate_email_and_ping']
1598- self.patch(FakedObject, "exposed_methods", exposed_methods)
1599- faked_object = FakedObject()
1600- self.patch(self.ui, "backend", faked_object)
1601+
1602 self.ui.validate_email()
1603+
1604 self.assert_backend_called('validate_email_and_ping',
1605- app_name, email, password, code, ping)
1606+ self.app_name, email, password, code, self.ping_url)
1607
1608 def test_validate_email_without_ping(self):
1609 """Test the login method."""
1610- ping = ''
1611- app_name = 'app_name'
1612+ self.ui.ping_url = ''
1613 email = 'email@example.com'
1614 password = 'password'
1615 code = 'code'
1616- self.ui.ping_url = ping
1617- self.ui.app_name = app_name
1618 self.ui.email = email
1619 self.ui.password = password
1620 self.ui.ui.verification_code_edit.setText(code)
1621- exposed_methods = ['validate_email', 'validate_email_and_ping']
1622- self.patch(FakedObject, "exposed_methods", exposed_methods)
1623- faked_object = FakedObject()
1624- self.patch(self.ui, "backend", faked_object)
1625+
1626 self.ui.validate_email()
1627+
1628 self.assert_backend_called('validate_email',
1629- app_name, email, password, code)
1630+ self.app_name, email, password, code)
1631
1632=== modified file 'ubuntu_sso/qt/tests/test_enchanced_line_edit.py'
1633--- ubuntu_sso/qt/tests/test_enchanced_line_edit.py 2012-01-26 15:34:16 +0000
1634+++ ubuntu_sso/qt/tests/test_enchanced_line_edit.py 2012-02-24 17:28:19 +0000
1635@@ -18,13 +18,10 @@
1636
1637 import collections
1638
1639+from PyQt4 import QtGui, QtCore
1640 from twisted.trial.unittest import TestCase
1641
1642-# pylint: disable=E1101
1643-
1644-from PyQt4 import QtGui, QtCore
1645-
1646-from ubuntu_sso.qt.gui import EnhancedLineEdit
1647+from ubuntu_sso.qt.sso_wizard_page import EnhancedLineEdit
1648
1649
1650 class EnhancedLineEditTestCase(TestCase):
1651
1652=== added file 'ubuntu_sso/qt/tests/test_error_page.py'
1653--- ubuntu_sso/qt/tests/test_error_page.py 1970-01-01 00:00:00 +0000
1654+++ ubuntu_sso/qt/tests/test_error_page.py 2012-02-24 17:28:19 +0000
1655@@ -0,0 +1,26 @@
1656+# -*- coding: utf-8 -*-
1657+#
1658+# Copyright 2012 Canonical Ltd.
1659+#
1660+# This program is free software: you can redistribute it and/or modify it
1661+# under the terms of the GNU General Public License version 3, as published
1662+# by the Free Software Foundation.
1663+#
1664+# This program is distributed in the hope that it will be useful, but
1665+# WITHOUT ANY WARRANTY; without even the implied warranties of
1666+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1667+# PURPOSE. See the GNU General Public License for more details.
1668+#
1669+# You should have received a copy of the GNU General Public License along
1670+# with this program. If not, see <http://www.gnu.org/licenses/>.
1671+
1672+"""Test the error page."""
1673+
1674+from ubuntu_sso.qt.error_page import ErrorPage
1675+from ubuntu_sso.qt.tests import BaseTestCase
1676+
1677+
1678+class ErrorPageTestCase(BaseTestCase):
1679+ """Test that the correct widgets are used."""
1680+
1681+ ui_class = ErrorPage
1682
1683=== modified file 'ubuntu_sso/qt/tests/test_forgotten_password.py'
1684--- ubuntu_sso/qt/tests/test_forgotten_password.py 2012-02-18 15:12:09 +0000
1685+++ ubuntu_sso/qt/tests/test_forgotten_password.py 2012-02-24 17:28:19 +0000
1686@@ -17,48 +17,23 @@
1687 """Tests for the Setup Account page Qt UI."""
1688
1689 from PyQt4 import QtGui, QtCore
1690-from twisted.internet import defer
1691
1692-from ubuntu_sso.qt import gui
1693 from ubuntu_sso.qt import forgotten_password_page
1694 from ubuntu_sso.qt.tests import (
1695 BaseTestCase,
1696- FakedBackend,
1697- FakedObject,
1698- FakeOverlay,
1699 FakePageUiStyle,
1700- FakeSignal,
1701- FakeWizard,
1702 )
1703-from ubuntu_sso.qt.ui import forgotten_password_ui
1704-
1705-
1706+
1707+# is ok to access private method/attrs in tests
1708 # pylint: disable=W0212, E1101
1709+
1710+
1711 class ForgottenPasswordTestCase(BaseTestCase):
1712 """Test the SetupAccountPage code."""
1713
1714- @defer.inlineCallbacks
1715- def setUp(self):
1716- yield super(ForgottenPasswordTestCase, self).setUp()
1717- self.signals_results = []
1718- self.patch(gui, "LoadingOverlay", FakeOverlay)
1719- self.patch(gui.main, "get_sso_client", FakedBackend)
1720- self.patch(forgotten_password_page.ForgottenPasswordPage,
1721- "passwordResetTokenSent", FakeSignal())
1722- self.app_name = 'my_app'
1723- self.ui = forgotten_password_page.ForgottenPasswordPage(
1724- forgotten_password_ui.Ui_ForgottenPasswordPage(),
1725- app_name=self.app_name, parent=None)
1726- self.wizard = FakeWizard()
1727- self.patch(self.ui, 'wizard', lambda: self.wizard)
1728-
1729- def test_init(self):
1730- """Test the construction of the object."""
1731- self.assertIn('PasswordResetTokenSent', self.ui._signals)
1732- self.assertIn('PasswordResetError', self.ui._signals)
1733- self.assertTrue(callable(self.ui._signals['PasswordResetTokenSent']))
1734- self.assertTrue(callable(self.ui._signals['PasswordResetError']))
1735- self.assertEqual(self.ui.backend, FakedBackend.sso_login)
1736+ ui_class = forgotten_password_page.ForgottenPasswordPage
1737+ ui_siganls = ('passwordResetTokenSent',)
1738+ ui_backend_siganls = ('PasswordResetTokenSent', 'PasswordResetError')
1739
1740 def test_request_new_password(self):
1741 """Test the request_new_password function."""
1742@@ -71,33 +46,6 @@
1743 self.assert_backend_called('request_password_reset_token',
1744 app_name, email)
1745
1746- def test_setup_page(self):
1747- """Test that the backend is received and the methods are called."""
1748- exposed_methods = [
1749- '_setup_signals',
1750- '_set_translated_strings',
1751- '_connect_ui',
1752- '_set_enhanced_line_edit',
1753- '_register_fields']
1754- self.patch(FakedObject, "exposed_methods", exposed_methods)
1755- faked_object = FakedObject()
1756- self.patch(self.ui, "_setup_signals",
1757- faked_object._setup_signals)
1758- self.patch(self.ui, "_set_translated_strings",
1759- faked_object._set_translated_strings)
1760- self.patch(self.ui, "_connect_ui",
1761- faked_object._connect_ui)
1762- self.patch(self.ui, "_set_enhanced_line_edit",
1763- faked_object._set_enhanced_line_edit)
1764- self.patch(self.ui, "_register_fields",
1765- faked_object._register_fields)
1766- self.ui.setup_page()
1767- self.assertIn('_setup_signals', faked_object._called)
1768- self.assertIn('_set_translated_strings', faked_object._called)
1769- self.assertIn('_connect_ui', faked_object._called)
1770- self.assertIn('_set_enhanced_line_edit', faked_object._called)
1771- self.assertIn('_register_fields', faked_object._called)
1772-
1773 def test_email_widget(self):
1774 """Test the email_widget property."""
1775 value = self.ui.email_widget
1776
1777=== modified file 'ubuntu_sso/qt/tests/test_loadingoverlay.py'
1778--- ubuntu_sso/qt/tests/test_loadingoverlay.py 2012-02-03 14:51:41 +0000
1779+++ ubuntu_sso/qt/tests/test_loadingoverlay.py 2012-02-24 17:28:19 +0000
1780@@ -1,5 +1,5 @@
1781 # -*- coding: utf-8 -*-
1782-
1783+#
1784 # Copyright 2012 Canonical Ltd.
1785 #
1786 # This program is free software: you can redistribute it and/or modify it
1787@@ -16,21 +16,21 @@
1788
1789 """Tests for the Loading Overlay."""
1790
1791-from ubuntu_sso.qt import loadingoverlay as gui
1792+from ubuntu_sso.qt.loadingoverlay import LoadingOverlay
1793 from ubuntu_sso.qt.tests import BaseTestCase
1794
1795
1796 class LoadingOverlayTestCase(BaseTestCase):
1797 """Test the qt control panel."""
1798
1799- innerclass_ui = gui.loadingoverlay_ui
1800- innerclass_name = "Ui_Form"
1801- class_ui = gui.LoadingOverlay
1802+ kwargs = {}
1803+ ui_class = LoadingOverlay
1804+ ui_wizard_class = None
1805
1806- # pylint: disable=E1101
1807- def assert_status_correct(self):
1808+ def test_status_correct(self):
1809 """Test if the necessary variables for the animation exists"""
1810 self.ui.show()
1811+ self.addCleanup(self.ui.hide)
1812+
1813 self.assertTrue(self.ui.counter is not None)
1814 self.assertTrue(self.ui.orientation is not None)
1815- # pylint: enable=E1101
1816
1817=== modified file 'ubuntu_sso/qt/tests/test_network_detection.py'
1818--- ubuntu_sso/qt/tests/test_network_detection.py 2012-02-22 16:58:08 +0000
1819+++ ubuntu_sso/qt/tests/test_network_detection.py 2012-02-24 17:28:19 +0000
1820@@ -16,39 +16,28 @@
1821
1822 """The test suite for Network Detection UI."""
1823
1824-from twisted.internet import defer
1825-
1826 from PyQt4 import QtGui
1827
1828-from ubuntu_sso.tests import APP_NAME
1829 from ubuntu_sso.qt import network_detection_page
1830 from ubuntu_sso.qt.tests import (
1831 BaseTestCase,
1832 FakeWizardButtonStyle,
1833 )
1834
1835+# is ok to access private method/attrs in tests
1836+# pylint: disable=W0212, E1101
1837+
1838
1839 class NetworkDetectionTestCase(BaseTestCase):
1840
1841 """Test the CurrentUserController."""
1842
1843- @defer.inlineCallbacks
1844- def setUp(self):
1845- """Initialize this test instance."""
1846- yield super(NetworkDetectionTestCase, self).setUp()
1847- self.wizard = FakeWizardButtonStyle()
1848- self.network_detection = network_detection_page.NetworkDetectionPage(
1849- app_name=APP_NAME)
1850- self.patch(self.network_detection, 'wizard', self._get_wizard)
1851-
1852- def _get_wizard(self):
1853- """Fake wizard method for wizard page."""
1854- return self.wizard
1855-
1856- # pylint: disable=W0212
1857+ ui_class = network_detection_page.NetworkDetectionPage
1858+ ui_wizard_class = FakeWizardButtonStyle
1859+
1860 def test_initialize_page(self):
1861 """Check Network detection initialize page."""
1862- self.network_detection.initializePage()
1863+ self.ui.initializePage()
1864 self.assertEqual(self.wizard._next_id, None)
1865 self.assertTrue(('setButtonLayout', ([
1866 QtGui.QWizard.Stretch,
1867@@ -58,18 +47,16 @@
1868
1869 def test_initialize_page_button_property(self):
1870 """Test the Try Again button properties."""
1871- self.patch(self.network_detection,
1872- "wizard", FakeWizardButtonStyle)
1873- self.network_detection.initializePage()
1874- self.assertTrue(self.network_detection.btn_try_again.isDefault())
1875- self.assertIn('polish', self.network_detection.btn_try_again.data)
1876- self.assertIn('unpolish', self.network_detection.btn_try_again.data)
1877- self.assertEqual(
1878- self.network_detection.btn_try_again.data['polish'],
1879- self.network_detection.btn_try_again)
1880- self.assertEqual(
1881- self.network_detection.btn_try_again.data['unpolish'],
1882- self.network_detection.btn_try_again)
1883+ self.ui.initializePage()
1884+ self.assertTrue(self.ui.btn_try_again.isDefault())
1885+ self.assertIn('polish', self.ui.btn_try_again.data)
1886+ self.assertIn('unpolish', self.ui.btn_try_again.data)
1887+ self.assertEqual(
1888+ self.ui.btn_try_again.data['polish'],
1889+ self.ui.btn_try_again)
1890+ self.assertEqual(
1891+ self.ui.btn_try_again.data['unpolish'],
1892+ self.ui.btn_try_again)
1893
1894 def test_try_again_with_connection(self):
1895 """Check try again method with connection."""
1896@@ -78,7 +65,7 @@
1897 self.wizard._next_id = -1
1898 if 'next' in self.wizard.data:
1899 self.wizard.data.pop('next')
1900- self.network_detection.try_again()
1901+ self.ui.try_again()
1902 self.assertEqual(self.wizard._next_id, None)
1903 self.assertTrue(self.wizard.data.get('next', False))
1904
1905@@ -89,7 +76,6 @@
1906 self.wizard._next_id = -1
1907 if 'next' in self.wizard.data:
1908 self.wizard.data.pop('next')
1909- self.network_detection.try_again()
1910+ self.ui.try_again()
1911 self.assertEqual(self.wizard._next_id, -1)
1912 self.assertFalse(self.wizard.data.get('next', False))
1913- # pylint: enable=W0212
1914
1915=== modified file 'ubuntu_sso/qt/tests/test_reset_password.py'
1916--- ubuntu_sso/qt/tests/test_reset_password.py 2012-02-15 17:33:40 +0000
1917+++ ubuntu_sso/qt/tests/test_reset_password.py 2012-02-24 17:28:19 +0000
1918@@ -18,40 +18,19 @@
1919 # pylint: disable=F0401,E0611,E1101
1920
1921 from PyQt4 import QtGui, QtCore
1922-from twisted.internet import defer
1923
1924 from ubuntu_sso.utils.ui import (
1925 PASSWORD1_ENTRY,
1926 PASSWORD2_ENTRY,
1927- RESET_CODE_ENTRY)
1928-from ubuntu_sso.qt import gui
1929+ RESET_CODE_ENTRY,
1930+)
1931 from ubuntu_sso.qt import common
1932 from ubuntu_sso.qt.reset_password_page import (
1933 ResetPasswordPage,
1934 RESET_SUBTITLE,
1935 RESET_TITLE,
1936 )
1937-from ubuntu_sso.qt.ui.reset_password_ui import Ui_ResetPasswordPage
1938-from ubuntu_sso.qt.tests import (
1939- BaseTestCase,
1940- FakedBackend,
1941- FakedObject,
1942- FakeWizard,
1943-)
1944-
1945-
1946-class FakePasswordAssistance(object):
1947- """Fake password_assistance_* calls."""
1948-
1949- _called = False
1950-
1951- def call(self, *args, **kwargs):
1952- """Check if the method was called."""
1953- FakePasswordAssistance._called = True
1954-
1955- def clenaup(self):
1956- """Clean up the variable."""
1957- FakePasswordAssistance._called = False
1958+from ubuntu_sso.qt.tests import BaseTestCase
1959
1960
1961 # We need this Fake until a future refactor.
1962@@ -78,19 +57,11 @@
1963 class ResetPasswordTestCase(BaseTestCase):
1964 """Test the ResetPasswordPage code."""
1965
1966- @defer.inlineCallbacks
1967- def setUp(self):
1968- yield super(ResetPasswordTestCase, self).setUp()
1969- self.patch(gui.main, "get_sso_client", FakedBackend)
1970- self.app_name = 'my_app'
1971- self.ui = ResetPasswordPage(Ui_ResetPasswordPage(),
1972- app_name=self.app_name,
1973- parent=None)
1974- self.wizard = FakeWizard()
1975- self.patch(self.ui, 'wizard', lambda: self.wizard)
1976- self.fake = FakePasswordAssistance()
1977+ ui_class = ResetPasswordPage
1978+ ui_signals = ('passwordChanged',)
1979+ ui_backend_siganls = ('PasswordChanged', 'PasswordChangeError')
1980
1981- def test_init(self):
1982+ def test_password_line(self):
1983 """Check the initial state of ResetPassword."""
1984 self.assertEqual(self.ui.ui.password_line_edit.receivers(
1985 QtCore.SIGNAL('textEdited(QString)')), 1)
1986@@ -131,25 +102,27 @@
1987
1988 def test_focus_changed_1(self):
1989 """Check functions execution when focus_changed() is executed."""
1990- self.patch(common, 'password_default_assistance', self.fake.call)
1991- self.addCleanup(self.fake.clenaup)
1992+ self.patch(common, 'password_default_assistance', self._set_called)
1993+
1994 self.ui.show()
1995 self.addCleanup(self.ui.hide)
1996- self.assertFalse(FakePasswordAssistance._called)
1997+
1998+ self.assertFalse(self._called)
1999 self.ui.focus_changed(None, self.ui.ui.password_line_edit)
2000 self.assertTrue(self.ui.ui.password_assistance.isVisible())
2001- self.assertTrue(FakePasswordAssistance._called)
2002+ self.assertTrue(self._called)
2003
2004 def test_focus_changed_2(self):
2005 """Check functions execution when focus_changed() is executed."""
2006- self.patch(common, 'password_check_match', self.fake.call)
2007- self.addCleanup(self.fake.clenaup)
2008+ self.patch(common, 'password_check_match', self._set_called)
2009+
2010 self.ui.show()
2011 self.addCleanup(self.ui.hide)
2012- self.assertFalse(FakePasswordAssistance._called)
2013+
2014+ self.assertFalse(self._called)
2015 self.ui.focus_changed(None, self.ui.ui.confirm_password_line_edit)
2016 self.assertTrue(self.ui.ui.password_assistance.isVisible())
2017- self.assertTrue(FakePasswordAssistance._called)
2018+ self.assertTrue(self._called)
2019
2020 # pylint: enable=W0212
2021
2022@@ -161,12 +134,10 @@
2023 forgotten = FakeForgottenPage()
2024 forgotten.setText(email)
2025 self.patch(self.wizard, "forgotten", forgotten)
2026- exposed_methods = ['set_new_password']
2027- self.patch(FakedObject, "exposed_methods", exposed_methods)
2028- faked_object = FakedObject()
2029- self.patch(self.ui, "backend", faked_object)
2030 self.ui.ui.reset_code_line_edit.setText(code)
2031 self.ui.ui.password_line_edit.setText(password)
2032+
2033 self.ui.set_new_password()
2034+
2035 self.assert_backend_called('set_new_password',
2036 self.app_name, email, code, password)
2037
2038=== modified file 'ubuntu_sso/qt/tests/test_setup_account.py'
2039--- ubuntu_sso/qt/tests/test_setup_account.py 2012-02-18 15:12:09 +0000
2040+++ ubuntu_sso/qt/tests/test_setup_account.py 2012-02-24 17:28:19 +0000
2041@@ -18,45 +18,22 @@
2042
2043 from PyQt4 import QtGui, QtCore
2044
2045-from twisted.internet import defer
2046-
2047-from ubuntu_sso.qt import gui
2048-from ubuntu_sso.qt import common
2049-from ubuntu_sso.qt import setup_account_page
2050+from ubuntu_sso.qt import common, setup_account_page
2051 from ubuntu_sso.qt.tests import (
2052 BaseTestCase,
2053- FakedBackend,
2054- FakedObject,
2055- FakeOverlay,
2056- FakeSignal,
2057- FakeWizard,
2058+ HELP_TEXT,
2059 )
2060-from ubuntu_sso.qt.ui import setup_account_ui
2061
2062
2063 class SetupAccountTestCase(BaseTestCase):
2064 """Test the SetupAccountPage code."""
2065
2066- @defer.inlineCallbacks
2067- def setUp(self):
2068- yield super(SetupAccountTestCase, self).setUp()
2069- self.patch(gui.main, "get_sso_client", FakedBackend)
2070- self.signals_results = []
2071- self.patch(setup_account_page.SetupAccountPage,
2072- "userRegistered", FakeSignal())
2073- self.app_name = 'my_app'
2074- self.ui = setup_account_page.SetupAccountPage(
2075- setup_account_ui.Ui_SetUpAccountPage(),
2076- 'subtitle',
2077- 'toc_link',
2078- 'policy_link',
2079- app_name=self.app_name,
2080- parent=None)
2081- self.wizard = FakeWizard()
2082- self.patch(self.ui, 'wizard', lambda: self.wizard)
2083- self.patch(self.ui, "set_up_button", QtGui.QPushButton())
2084+ ui_class = setup_account_page.SetupAccountPage
2085+ ui_signals = ('userRegistered',)
2086+ ui_backend_signals = ('CaptchaGenerated', 'CaptchaGenerationError',
2087+ 'UserRegistered', 'UserRegistrationError')
2088
2089- def test_init(self):
2090+ def test_password_receiver(self):
2091 """Check the initial state of SetupAccount."""
2092 self.assertEqual(self.ui.ui.password_edit.receivers(
2093 QtCore.SIGNAL('textEdited(QString)')), 2)
2094@@ -79,6 +56,8 @@
2095
2096 def test_enable_setup_button_with_visible_check(self):
2097 """Test _enable_setup_button method with terms check visible."""
2098+ self.patch(self.ui, "set_up_button", QtGui.QPushButton())
2099+
2100 self.ui.ui.name_edit.setText('name')
2101 email = 'email@example.com'
2102 self.ui.ui.email_edit.setText(email)
2103@@ -97,6 +76,8 @@
2104
2105 def test_enable_setup_button_without_visible_check(self):
2106 """Test _enable_setup_button method with terms check not visible."""
2107+ self.patch(self.ui, "set_up_button", QtGui.QPushButton())
2108+
2109 self.ui.ui.name_edit.setText('name')
2110 email = 'email@example.com'
2111 self.ui.ui.email_edit.setText(email)
2112@@ -170,10 +151,6 @@
2113
2114 def test_on_user_registered(self):
2115 """Test on_user_registered method."""
2116- exposed_methods = ['register_user']
2117- self.patch(FakedObject, "exposed_methods", exposed_methods)
2118- faked_object = FakedObject()
2119- self.patch(self.ui, "backend", faked_object)
2120 self.patch(self.ui, "validate_form", lambda: True)
2121
2122 email = 'email@example'
2123@@ -190,8 +167,11 @@
2124 def slot(email, password):
2125 """Fake slot."""
2126 self.signals_results.append((email, password))
2127+
2128 self.ui.userRegistered.connect(slot)
2129+
2130 self.ui.set_next_validation()
2131+
2132 self.assertIn((email, password), self.signals_results)
2133 self.assert_backend_called('register_user',
2134 self.app_name, email, password, name, captcha_id,
2135@@ -217,29 +197,6 @@
2136 self.assert_backend_called('generate_captcha',
2137 self.app_name, self.ui.captcha_file)
2138
2139-
2140-class SetupAccountFakeWizardTestCase(BaseTestCase):
2141- """Test the SetupAccountPage code."""
2142-
2143- @defer.inlineCallbacks
2144- def setUp(self):
2145- """Initialize this test instance."""
2146- # Faking each SSO object instead of doing it lower
2147- # so we don't rely on any SSO behaviour
2148- yield super(SetupAccountFakeWizardTestCase, self).setUp()
2149- self.patch(gui, "LoadingOverlay", FakeOverlay)
2150- self.app_name = 'my_app'
2151- self._subtitle = 'subtitle'
2152- self.ui = setup_account_page.SetupAccountPage(
2153- setup_account_ui.Ui_SetUpAccountPage(),
2154- self._subtitle,
2155- 'toc_link',
2156- 'policy_link',
2157- app_name=self.app_name,
2158- parent=None)
2159- self.wizard = FakeWizard()
2160- self.patch(self.ui, 'wizard', lambda: self.wizard)
2161-
2162 def test_initialize_page(self):
2163 """Widgets are properly initialized."""
2164 self.ui.initializePage()
2165@@ -251,7 +208,11 @@
2166 title_expected = (setup_account_page.TITLE_STYLE %
2167 setup_account_page.TITLE.format(app_name=self.app_name))
2168 self.assertEqual(title, title_expected)
2169- self.assertEqual(self.ui.header.subtitle_label.text(), self._subtitle)
2170+
2171+ elided_text = unicode(self.ui.header.subtitle_label.text())
2172+ elided_text = elided_text[:len(elided_text) - 1]
2173+ self.assertTrue(HELP_TEXT.startswith(elided_text))
2174+ self.assertEqual(self.ui.header.subtitle_label.toolTip(), HELP_TEXT)
2175
2176 # set up account button
2177 expected = [QtGui.QWizard.BackButton, QtGui.QWizard.Stretch,
2178
2179=== removed file 'ubuntu_sso/qt/tests/test_sign_in_page.py'
2180--- ubuntu_sso/qt/tests/test_sign_in_page.py 2012-02-15 17:33:40 +0000
2181+++ ubuntu_sso/qt/tests/test_sign_in_page.py 1970-01-01 00:00:00 +0000
2182@@ -1,69 +0,0 @@
2183-# -*- coding: utf-8 -*-
2184-#
2185-# Copyright 2012 Canonical Ltd.
2186-#
2187-# This program is free software: you can redistribute it and/or modify it
2188-# under the terms of the GNU General Public License version 3, as published
2189-# by the Free Software Foundation.
2190-#
2191-# This program is distributed in the hope that it will be useful, but
2192-# WITHOUT ANY WARRANTY; without even the implied warranties of
2193-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2194-# PURPOSE. See the GNU General Public License for more details.
2195-#
2196-# You should have received a copy of the GNU General Public License along
2197-# with this program. If not, see <http://www.gnu.org/licenses/>.
2198-
2199-"""The test suite for Sign In UI."""
2200-
2201-from PyQt4 import QtGui
2202-from twisted.internet import defer
2203-
2204-from ubuntu_sso.qt import sign_in_page as gui
2205-from ubuntu_sso.qt.ui.choose_sign_in_ui import Ui_ChooseSignInPage
2206-from ubuntu_sso.qt.tests import BaseTestCase, FakeMainWindow, FakeSignal
2207-
2208-
2209-class SignInPageTestCase(BaseTestCase):
2210- """Test the SignInPage code."""
2211-
2212- @defer.inlineCallbacks
2213- def setUp(self):
2214- """Initialize this test instance."""
2215- yield super(SignInPageTestCase, self).setUp()
2216- self.signals_results = []
2217- self.patch(gui.SignInPage, "existingAccountSelected", FakeSignal())
2218- self.patch(gui.SignInPage, "newAccountSelected", FakeSignal())
2219- self.patch(gui.SignInPage, "singInCanceled", FakeSignal())
2220- self.ui = gui.SignInPage(Ui_ChooseSignInPage(), QtGui.QPixmap())
2221-
2222- def test_show_event(self):
2223- """Check the page is initialized correctly."""
2224- wizard = FakeMainWindow()
2225- self.patch(self.ui, 'wizard', lambda *args: wizard)
2226- self.ui.initializePage()
2227- self.ui.show()
2228- self.addCleanup(self.ui.hide)
2229- self.assertTrue(self.ui.ui.existing_account_button.isDefault())
2230-
2231- # pylint: disable=W0212
2232- def test_set_next_existing(self):
2233- """Test _set_next_existing method."""
2234-
2235- def slot():
2236- """Fake slot."""
2237- self.signals_results.append(1)
2238- self.ui.existingAccountSelected.connect(slot)
2239- self.ui._set_next_existing()
2240- self.assertIn(1, self.signals_results)
2241-
2242- def test_set_next_new(self):
2243- """Test _set_next_existing method."""
2244-
2245- def slot():
2246- """Fake slot."""
2247- self.signals_results.append(1)
2248- self.ui.newAccountSelected.connect(slot)
2249- self.ui._set_next_new()
2250- self.assertIn(1, self.signals_results)
2251- # pylint: enable=W0212
2252
2253=== renamed file 'ubuntu_sso/qt/tests/test_qt_views.py' => 'ubuntu_sso/qt/tests/test_sso_wizard_page.py'
2254--- ubuntu_sso/qt/tests/test_qt_views.py 2012-02-24 13:57:19 +0000
2255+++ ubuntu_sso/qt/tests/test_sso_wizard_page.py 2012-02-24 17:28:19 +0000
2256@@ -13,107 +13,23 @@
2257 #
2258 # You should have received a copy of the GNU General Public License along
2259 # with this program. If not, see <http://www.gnu.org/licenses/>.
2260-"""Test the interaction of the view with the auto generated code."""
2261-
2262-from unittest import TestCase
2263-from mocker import MATCH, Mocker
2264-
2265-from PyQt4 import QtGui
2266-
2267-from ubuntu_sso.qt.error_page import ErrorPage
2268-from ubuntu_sso.qt.sign_in_page import SignInPage
2269-from ubuntu_sso.qt.success_page import SuccessPage
2270+
2271+"""Test the SSOWizardPage and related."""
2272+
2273+from twisted.internet import defer
2274
2275 from ubuntu_sso.qt import PREFERED_UI_SIZE
2276-from ubuntu_sso.qt.gui import Header
2277-from ubuntu_sso.qt.ui.choose_sign_in_ui import Ui_ChooseSignInPage
2278-from ubuntu_sso.qt.ui.error_message_ui import Ui_ErrorPage
2279-from ubuntu_sso.qt.ui.success_message_ui import Ui_SuccessPage
2280-
2281-
2282-class FakeController(object):
2283- """A fake controller for the tests."""
2284-
2285- # pylint: disable=C0103
2286- def setupUi(self, view):
2287- """Fake the setup."""
2288- # pylint: enable=C0103
2289-
2290-
2291-class ChooseSignInPageTestCase(TestCase):
2292- """Test the ChooseSignInPage."""
2293-
2294- def setUp(self):
2295- """Set up the tests."""
2296- super(ChooseSignInPageTestCase, self).setUp()
2297- self.ui = Ui_ChooseSignInPage()
2298- self.controller = FakeController()
2299- self.widget = SignInPage(self.ui, QtGui.QPixmap())
2300-
2301- def tearDown(self):
2302- self.widget.close()
2303-
2304- def test_constructor(self):
2305- """Test the constructor of the class."""
2306- # used a mocked ui for this
2307- mocker = Mocker()
2308- ui = mocker.mock()
2309- ui.setupUi(MATCH(lambda x: isinstance(x, SignInPage)))
2310- mocker.replay()
2311- self.widget = SignInPage(self.ui, QtGui.QPixmap())
2312-
2313- def test_next_id(self):
2314- """Test the nextId method."""
2315- next_id = 1
2316- self.widget.next = next_id
2317- self.assertEqual(next_id, self.widget.nextId())
2318-
2319-
2320-class SuccessPageTestCase(TestCase):
2321- """Test that the correct widgets are used."""
2322-
2323- def setUp(self):
2324- """Setup tests."""
2325- super(SuccessPageTestCase, self).setUp()
2326- self.ui = Ui_SuccessPage()
2327- self.widget = SuccessPage(self.ui, QtGui.QPixmap())
2328-
2329- def test_constructor(self):
2330- """Test that the constructor works as expected."""
2331- mocker = Mocker()
2332- ui = mocker.mock()
2333- ui.setupUi(MATCH(lambda x: isinstance(x, SuccessPage)))
2334- mocker.replay()
2335- self.widget = SuccessPage(self.ui, QtGui.QPixmap())
2336-
2337-
2338-class ErrorPageTestCase(TestCase):
2339- """Test that the correct widgets are used."""
2340-
2341- def setUp(self):
2342- """Setup tests."""
2343- super(ErrorPageTestCase, self).setUp()
2344- self.ui = Ui_ErrorPage()
2345- self.controller = FakeController()
2346- self.widget = ErrorPage(self.ui, self.controller)
2347-
2348- def test_constructor(self):
2349- """Test that the constructor works as expected."""
2350- mocker = Mocker()
2351- ui = mocker.mock()
2352- controller = mocker.mock()
2353- ui.setupUi(MATCH(lambda x: isinstance(x, ErrorPage)))
2354- controller.setupUi(MATCH(lambda x: isinstance(x, ErrorPage)))
2355- mocker.replay()
2356- self.widget = ErrorPage(self.ui, self.controller)
2357-
2358-
2359-class HeaderTest(TestCase):
2360+from ubuntu_sso.qt.sso_wizard_page import Header
2361+from ubuntu_sso.qt.tests import BaseTestCase
2362+
2363+
2364+class HeaderTest(BaseTestCase):
2365+
2366 """Tests for injected Header in each Wizard Page."""
2367
2368+ @defer.inlineCallbacks
2369 def setUp(self):
2370- """Setup test."""
2371- super(HeaderTest, self).setUp()
2372+ yield super(HeaderTest, self).setUp()
2373 self.header = Header()
2374
2375 def test_label_state(self):
2376
2377=== added file 'ubuntu_sso/qt/tests/test_success_page.py'
2378--- ubuntu_sso/qt/tests/test_success_page.py 1970-01-01 00:00:00 +0000
2379+++ ubuntu_sso/qt/tests/test_success_page.py 2012-02-24 17:28:19 +0000
2380@@ -0,0 +1,26 @@
2381+# -*- coding: utf-8 -*-
2382+#
2383+# Copyright 2012 Canonical Ltd.
2384+#
2385+# This program is free software: you can redistribute it and/or modify it
2386+# under the terms of the GNU General Public License version 3, as published
2387+# by the Free Software Foundation.
2388+#
2389+# This program is distributed in the hope that it will be useful, but
2390+# WITHOUT ANY WARRANTY; without even the implied warranties of
2391+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
2392+# PURPOSE. See the GNU General Public License for more details.
2393+#
2394+# You should have received a copy of the GNU General Public License along
2395+# with this program. If not, see <http://www.gnu.org/licenses/>.
2396+
2397+"""Test the success page."""
2398+
2399+from ubuntu_sso.qt.success_page import SuccessPage
2400+from ubuntu_sso.qt.tests import BaseTestCase
2401+
2402+
2403+class SuccessPageTestCase(BaseTestCase):
2404+ """Test that the correct widgets are used."""
2405+
2406+ ui_class = SuccessPage
2407
2408=== modified file 'ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py'
2409--- ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py 2012-02-24 14:58:30 +0000
2410+++ ubuntu_sso/qt/tests/test_ubuntu_sso_wizard.py 2012-02-24 17:28:19 +0000
2411@@ -20,21 +20,24 @@
2412 from twisted.internet import defer
2413
2414 from ubuntu_sso.qt import PREFERED_UI_SIZE, ubuntu_sso_wizard
2415-from ubuntu_sso.qt.tests import (
2416- BaseTestCase,
2417- FakedObject,
2418-)
2419-
2420-
2421-class ReturnCodeTestCase(BaseTestCase):
2422- """Test the return codes."""
2423+from ubuntu_sso.qt.tests import BaseTestCase
2424+
2425+
2426+# is ok to access private method/attrs in tests
2427+# pylint: disable=W0212
2428+
2429+
2430+class UbuntuSSOClientGUITestCase(BaseTestCase):
2431+
2432+ """Test the UbuntuSSOClientGUI class."""
2433+
2434+ ui_class = ubuntu_sso_wizard.UbuntuSSOClientGUI
2435+ ui_wizard_class = None
2436
2437 @defer.inlineCallbacks
2438 def setUp(self):
2439- yield super(ReturnCodeTestCase, self).setUp()
2440+ yield super(UbuntuSSOClientGUITestCase, self).setUp()
2441 self.patch(ubuntu_sso_wizard.sys, 'exit', self._set_called)
2442- self.app_name = 'app_name'
2443- self.ui = ubuntu_sso_wizard.UbuntuSSOClientGUI(self.app_name)
2444
2445 def test_closing_main_window(self):
2446 """When closing the main window, USER_CANCELLATION is returned."""
2447@@ -42,44 +45,36 @@
2448 self.assertEqual(self._called,
2449 ((ubuntu_sso_wizard.USER_CANCELLATION,), {}))
2450
2451- # pylint: disable=W0212
2452 def test_close_main_window_reaching_success_page(self):
2453 """Closing the window in success page, USER_SUCCESS is returned."""
2454- email = 'email@example.com'
2455- self.ui.wizard._move_to_success_page(self.app_name, email)
2456+ self.ui.wizard._move_to_success_page()
2457 self.ui.close()
2458 self.assertEqual(self._called,
2459 ((ubuntu_sso_wizard.USER_SUCCESS,), {}))
2460- # pylint: enable=W0212
2461
2462- def test_closing_wizard(self):
2463+ def test_closing_wizard_no_parent(self):
2464 """When closing the wizard, USER_CANCELLATION is returned."""
2465 self.ui.wizard.setParent(None)
2466 self.ui.wizard.close()
2467 self.assertEqual(self._called,
2468 ((ubuntu_sso_wizard.USER_CANCELLATION,), {}))
2469
2470- # pylint: disable=W0212
2471- def test_close_wizard_reaching_success_page(self):
2472+ def test_close_wizard_no_parent_reaching_success_page(self):
2473 """Closing the wizard in success page, USER_SUCCESS is returned."""
2474 self.ui.wizard.setParent(None)
2475- email = 'email@example.com'
2476- self.ui.wizard._move_to_success_page(self.app_name, email)
2477+ self.ui.wizard._move_to_success_page()
2478 self.ui.wizard.close()
2479 self.assertEqual(self._called,
2480 ((ubuntu_sso_wizard.USER_SUCCESS,), {}))
2481- # pylint: enable=W0212
2482
2483
2484 class UbuntuSSOWizardTestCase(BaseTestCase):
2485
2486- """Test Case for UbuntuSSOWizard"""
2487+ """Test case for UbuntuSSOWizard class."""
2488
2489- @defer.inlineCallbacks
2490- def setUp(self):
2491- yield super(UbuntuSSOWizardTestCase, self).setUp()
2492- self.app_name = 'app_name'
2493- self.ui = ubuntu_sso_wizard.UbuntuSSOWizard(self.app_name)
2494+ ui_class = ubuntu_sso_wizard.UbuntuSSOWizard
2495+ ui_signals = ('recoverableError', 'loginSuccess', 'registrationSuccess')
2496+ ui_wizard_class = None
2497
2498 def test_window_size(self):
2499 """check the window size."""
2500@@ -89,32 +84,13 @@
2501 self.assertEqual(size.height(), PREFERED_UI_SIZE['height'])
2502 self.assertEqual(size.width(), PREFERED_UI_SIZE['width'])
2503
2504- # pylint: disable=W0212
2505 def test_move_to_success_page_state(self):
2506 """Test _move_to_success_page method."""
2507 self.patch(self.ui, 'setButtonLayout', self._set_called)
2508- self.ui._move_to_success_page(self.app_name)
2509+ self.ui._move_to_success_page()
2510 self.assertEqual(self.ui._next_id, -1)
2511 self.assertEqual(self.ui._next_id, -1)
2512 self.assertEqual(self._called,
2513 (([QtGui.QWizard.Stretch, QtGui.QWizard.FinishButton],), {}))
2514 self.assertTrue(self.ui.button(QtGui.QWizard.FinishButton).isEnabled())
2515- self.assertEqual(self.ui._done, ubuntu_sso_wizard.USER_SUCCESS)
2516- # pylint: enable=W0212
2517-
2518- # pylint: disable=W0212, E1101
2519- def test_sing_in_canceled_connection(self):
2520- """Test if sign in canceled signal calls close and not reject."""
2521- exposed_methods = [
2522- 'close',
2523- 'reject']
2524- self.patch(FakedObject, "exposed_methods", exposed_methods)
2525- faked_object = FakedObject()
2526- self.patch(self.ui, "closeEvent", faked_object.close)
2527- self.patch(self.ui, "reject", faked_object.reject)
2528- self.ui.show()
2529- self.addCleanup(self.ui.hide)
2530- self.ui.sign_in_page.ui.cancel_button.clicked.emit(True)
2531- self.assertIn('close', faked_object._called)
2532- self.assertNotIn('reject', faked_object._called)
2533- # pylint: enable=W0212, E1101
2534+ self.assertEqual(self.ui.exit_code, ubuntu_sso_wizard.USER_SUCCESS)
2535
2536=== modified file 'ubuntu_sso/qt/ubuntu_sso_wizard.py'
2537--- ubuntu_sso/qt/ubuntu_sso_wizard.py 2012-02-24 14:58:30 +0000
2538+++ ubuntu_sso/qt/ubuntu_sso_wizard.py 2012-02-24 17:28:19 +0000
2539@@ -1,5 +1,5 @@
2540 # -*- coding: utf-8 -*-
2541-
2542+#
2543 # Copyright 2012 Canonical Ltd.
2544 #
2545 # This program is free software: you can redistribute it and/or modify it
2546@@ -21,14 +21,11 @@
2547 from PyQt4.QtCore import pyqtSignal
2548 from PyQt4.QtGui import (
2549 QFrame,
2550- QPixmap,
2551 QVBoxLayout,
2552 QWizard,
2553 )
2554-from twisted.internet import defer
2555
2556 from ubuntu_sso import (
2557- NO_OP,
2558 USER_CANCELLATION,
2559 USER_SUCCESS,
2560 )
2561@@ -40,17 +37,7 @@
2562 from ubuntu_sso.qt.forgotten_password_page import ForgottenPasswordPage
2563 from ubuntu_sso.qt.reset_password_page import ResetPasswordPage
2564 from ubuntu_sso.qt.setup_account_page import SetupAccountPage
2565-from ubuntu_sso.qt.sign_in_page import SignInPage
2566 from ubuntu_sso.qt.success_page import SuccessPage
2567-from ubuntu_sso.qt.ui.choose_sign_in_ui import Ui_ChooseSignInPage
2568-from ubuntu_sso.qt.ui.current_user_sign_in_ui import Ui_CurrentUserSignInPage
2569-from ubuntu_sso.qt.ui.email_verification_ui import Ui_EmailVerificationPage
2570-from ubuntu_sso.qt.ui.error_message_ui import Ui_ErrorPage
2571-from ubuntu_sso.qt.ui.setup_account_ui import Ui_SetUpAccountPage
2572-from ubuntu_sso.qt.ui.success_message_ui import Ui_SuccessPage
2573-from ubuntu_sso.qt.ui.forgotten_password_ui import Ui_ForgottenPasswordPage
2574-from ubuntu_sso.qt.ui.reset_password_ui import Ui_ResetPasswordPage
2575-
2576
2577 logger = setup_logging('ubuntu_sso.gui')
2578
2579@@ -65,83 +52,61 @@
2580
2581 def __init__(self, app_name, **kwargs):
2582 """Create a new wizard."""
2583- parent = kwargs.get('parent')
2584- super(UbuntuSSOWizard, self).__init__(parent)
2585+ logger.debug('UbuntuSSOWizard: app_name %r, kwargs %r.',
2586+ app_name, kwargs)
2587+ parent = kwargs.pop('parent', None)
2588+ super(UbuntuSSOWizard, self).__init__(parent=parent)
2589 self._next_id = -1
2590 self.setOption(QWizard.HaveFinishButtonOnEarlyPages, True)
2591- self._done = USER_CANCELLATION
2592+ self.setOption(QWizard.NoBackButtonOnStartPage, True)
2593+ self.exit_code = USER_CANCELLATION
2594
2595- # store common useful data provided by the app
2596 self.app_name = app_name
2597- self.ping_url = kwargs.get('ping_url', '')
2598- self.tc_url = kwargs.get('tc_url', '')
2599- self.policy_url = kwargs.get('policy_url', '')
2600- self.help_text = kwargs.get('help_text', '')
2601- self.login_only = kwargs.get('login_only', False)
2602- self.close_callback = kwargs.get('close_callback', lambda: None)
2603- self.login_success_callback = NO_OP
2604- self.registration_success_callback = NO_OP
2605- self.user_cancellation_callback = NO_OP
2606+ self.login_only = kwargs.pop('login_only', False)
2607+ self.close_callback = kwargs.pop('close_callback', lambda: None)
2608+
2609+ # store the ids of the pages so that it is easier to access them later
2610+ self._pages = {}
2611+
2612+ # prepare kwargs to be suitable for the pages
2613+ kwargs['app_name'] = self.app_name
2614+ kwargs['parent'] = self
2615
2616 # set the diff pages of the QWizard
2617- self.sign_in_page = SignInPage(Ui_ChooseSignInPage(),
2618- QPixmap(),
2619- app_name=self.app_name,
2620- parent=self)
2621- self.sign_in_page.singInCanceled.connect(self.close)
2622- self.sign_in_page.existingAccountSelected.connect(
2623- self._move_to_login_page)
2624- self.sign_in_page.newAccountSelected.connect(
2625- self._move_to_setup_account_page)
2626-
2627- self.setup_account = SetupAccountPage(Ui_SetUpAccountPage(),
2628- self.help_text,
2629- self.tc_url,
2630- self.policy_url,
2631- app_name=self.app_name,
2632- parent=self)
2633- self.setup_account.userRegistered.connect(
2634- self._move_to_email_verification_page)
2635-
2636- self.current_user = CurrentUserSignInPage(Ui_CurrentUserSignInPage(),
2637- self.ping_url,
2638- app_name=self.app_name,
2639- parent=self)
2640+ if not self.login_only:
2641+ self.setup_account = SetupAccountPage(**kwargs)
2642+ self.setup_account.userRegistered.connect(
2643+ self._move_to_email_verification_page)
2644+ self.addPage(self.setup_account)
2645+
2646+ self.current_user = CurrentUserSignInPage(**kwargs)
2647 self.current_user.userNotValidated.connect(
2648 self._move_to_email_verification_page)
2649 self.current_user.userLoggedIn.connect(self._move_to_success_page)
2650 self.current_user.passwordForgotten.connect(
2651 self._move_to_forgotten_page)
2652+ self.addPage(self.current_user)
2653
2654- self.email_verification = EmailVerificationPage(
2655- Ui_EmailVerificationPage(),
2656- self.ping_url,
2657- app_name=self.app_name)
2658+ self.email_verification = EmailVerificationPage(**kwargs)
2659 self.email_verification.registrationSuccess.connect(
2660 self._move_to_success_page)
2661-
2662- self.success = SuccessPage(Ui_SuccessPage(), QPixmap(),
2663- app_name=self.app_name, parent=self)
2664- self.error = ErrorPage(Ui_ErrorPage(),
2665- app_name=self.app_name)
2666- self.forgotten = ForgottenPasswordPage(Ui_ForgottenPasswordPage(),
2667- app_name=self.app_name,
2668- parent=self)
2669+ self.addPage(self.email_verification)
2670+
2671+ self.success = SuccessPage(**kwargs)
2672+ self.addPage(self.success)
2673+
2674+ self.error = ErrorPage(**kwargs)
2675+ self.addPage(self.error)
2676+
2677+ self.forgotten = ForgottenPasswordPage(**kwargs)
2678 self.forgotten.passwordResetTokenSent.connect(
2679 self._move_to_reset_password_page)
2680+ self.addPage(self.forgotten)
2681
2682- self.reset_password = ResetPasswordPage(Ui_ResetPasswordPage(),
2683- app_name=self.app_name,
2684- parent=self)
2685- self.reset_password.passwordChanged.connect(
2686- self._go_back_to_current_page)
2687- # store the ids of the pages so that it is easier to access them later
2688- pages = [self.sign_in_page, self.setup_account,
2689- self.email_verification, self.current_user, self.success,
2690- self.error, self.forgotten, self.reset_password]
2691- self._pages = {}
2692- for page in pages:
2693- self._pages[page] = self.addPage(page)
2694+ self.reset_password = ResetPasswordPage(**kwargs)
2695+ back = lambda *a: self._go_back_to_current_page(self.current_user)
2696+ self.reset_password.passwordChanged.connect(back)
2697+ self.addPage(self.reset_password)
2698
2699 # set the buttons layout to only have cancel and back since the next
2700 # buttons are the ones used in the diff pages.
2701@@ -152,24 +117,29 @@
2702 self.setButtonLayout(buttons_layout)
2703 self.setWindowTitle(self.app_name)
2704 self.setWizardStyle(QWizard.ModernStyle)
2705- self.button(QWizard.CancelButton).clicked.connect(
2706- self.on_user_cancelation)
2707+ self.button(QWizard.CancelButton).clicked.connect(self.close)
2708 self.setMinimumSize(PREFERED_UI_SIZE['width'],
2709 PREFERED_UI_SIZE['height'])
2710
2711 # pylint: disable=C0103
2712+
2713 def nextId(self):
2714 """Return the id of the next page."""
2715 return self._next_id
2716+
2717+ def addPage(self, page):
2718+ """Add 'page' to this wizard."""
2719+ page_id = super(UbuntuSSOWizard, self).addPage(page)
2720+ self._pages[page] = page_id
2721+
2722 # pylint: enable=C0103
2723
2724- def _go_back_to_current_page(self, email):
2725- """Move back until it reaches the current user sign in page. """
2726- self.current_user.ui.email_edit.setText(email)
2727- current_user_id = self.current_user_page_id
2728+ def _go_back_to_page(self, page):
2729+ """Move back until it reaches the 'page'."""
2730+ page_id = self._pages[page]
2731 visited_pages = self.visitedPages()
2732 for index in reversed(visited_pages):
2733- if index == current_user_id:
2734+ if index == page_id:
2735 break
2736 self.back()
2737
2738@@ -179,12 +149,9 @@
2739 self.next()
2740 self._next_id = -1
2741
2742- def _move_to_email_verification_page(self, email, password):
2743+ def _move_to_email_verification_page(self):
2744 """Move to the email verification page wizard."""
2745 self._next_id = self.email_verification_page_id
2746- self.email_verification.email = unicode(email)
2747- self.email_verification.password = unicode(password)
2748- self.email_verification.set_titles(email)
2749 self.next()
2750 self._next_id = -1
2751
2752@@ -200,7 +167,7 @@
2753 self.next()
2754 self._next_id = -1
2755
2756- def _move_to_success_page(self, app_name='', email=''):
2757+ def _move_to_success_page(self):
2758 """Move to the success page wizard."""
2759 self._next_id = self.success_page_id
2760 self.next()
2761@@ -209,7 +176,7 @@
2762 QWizard.FinishButton])
2763 self.button(QWizard.FinishButton).setEnabled(True)
2764 self.button(QWizard.FinishButton).setFocus()
2765- self._done = USER_SUCCESS
2766+ self.exit_code = USER_SUCCESS
2767 self._next_id = -1
2768
2769 def _move_to_forgotten_page(self):
2770@@ -219,11 +186,6 @@
2771 self._next_id = -1
2772
2773 @property
2774- def sign_in_page_id(self):
2775- """Return the id of the page used for choosing sign in type."""
2776- return self._pages[self.sign_in_page]
2777-
2778- @property
2779 def setup_account_page_id(self):
2780 """Return the id of the page used for sign in."""
2781 return self._pages[self.setup_account]
2782@@ -258,76 +220,18 @@
2783 """Return the id of the error page."""
2784 return self._pages[self.error]
2785
2786- def on_user_cancelation(self):
2787- """Process the cancel action."""
2788- logger.debug('UbuntuSSOWizard.on_user_cancelation')
2789- self.user_cancellation_callback(self.app_name)
2790- self.close()
2791-
2792- @defer.inlineCallbacks
2793- def on_login_success(self, app_name, email):
2794- """Process the success of a login."""
2795- logger.debug('UbuntuSSOWizard.on_login_success')
2796- result = yield self.login_success_callback(
2797- unicode(app_name), unicode(email))
2798- logger.debug('Result from callback is %s', result)
2799- if result == 0:
2800- logger.info('Success in calling the given success_callback')
2801- self.show_success_message()
2802- else:
2803- logger.info('Error in calling the given success_callback')
2804- self.show_error_message()
2805-
2806- @defer.inlineCallbacks
2807- def on_registration_success(self, app_name, email):
2808- """Process the success of a registration."""
2809- logger.debug('UbuntuSSOWizard.on_registration_success')
2810- result = yield self.registration_success_callback(unicode(app_name),
2811- unicode(email))
2812- logger.debug('Result from callback is %s', result)
2813- if result == 0:
2814- logger.info('Success in calling the given registration_callback')
2815- self.show_success_message()
2816- else:
2817- logger.info('Success in calling the given registration_callback')
2818- self.show_error_message()
2819-
2820- def show_success_message(self):
2821- """Show the success message in the view."""
2822- logger.info('Showing success message.')
2823- # get the id of the success page, set it as the next id of the
2824- # current page and let the wizard move to the next step
2825- self.currentPage().next = self.success_page_id
2826- self.next()
2827- # show the finish button but with a close message
2828- buttons_layout = []
2829- buttons_layout.append(QWizard.Stretch)
2830- buttons_layout.append(QWizard.FinishButton)
2831- self.setButtonLayout(buttons_layout)
2832-
2833- def show_error_message(self):
2834- """Show the error page in the view."""
2835- logger.info('Showing error message.')
2836- # similar to the success page but using the error id
2837- self.currentPage().next = self.error_page_id
2838- self.next()
2839- # show the finish button but with a close message
2840- buttons_layout = []
2841- buttons_layout.append(QWizard.Stretch)
2842- buttons_layout.append(QWizard.FinishButton)
2843- self.setButtonLayout(buttons_layout)
2844-
2845- # pylint: disable=C0103, W0212
2846+ # pylint: disable=C0103
2847+
2848 def closeEvent(self, event):
2849 """Catch close event and send the proper return code."""
2850 if self.parent() is not None:
2851 self.parent().close()
2852 else:
2853- sys.exit(self._done)
2854- # pylint: enable=C0103, W0212
2855-
2856-
2857-# pylint: disable=W0201
2858+ sys.exit(self.exit_code)
2859+
2860+ # pylint: enable=C0103
2861+
2862+
2863 class UbuntuSSOClientGUI(QFrame):
2864 """Ubuntu single sign-on GUI."""
2865
2866@@ -345,41 +249,10 @@
2867 self.wizard = UbuntuSSOWizard(app_name=app_name, **kwargs)
2868 vbox.addWidget(self.wizard)
2869
2870- def get_login_success_callback(self):
2871- """Return the log in success cb."""
2872- return self.view.login_success_callback
2873-
2874- def set_login_success_callback(self, cb):
2875- """Set log in success cb."""
2876- self.view.login_success_callback = cb
2877-
2878- login_success_callback = property(get_login_success_callback,
2879- set_login_success_callback)
2880-
2881- def get_registration_success_callback(self):
2882- """Return the registration success cb."""
2883- return self.view.registration_success_callback
2884-
2885- def set_registration_success_callback(self, cb):
2886- """Set registration success cb."""
2887- self.view.registration_success_callback = cb
2888-
2889- registration_success_callback = property(get_registration_success_callback,
2890- set_registration_success_callback)
2891-
2892- def get_user_cancellation_callback(self):
2893- """Return the user cancellation callback."""
2894- return self.view.user_cancellation_callback
2895-
2896- def set_user_cancellation_callback(self, cb):
2897- """Set the user cancellation callback."""
2898- self.view.user_cancellation_callback = cb
2899-
2900- user_cancellation_callback = property(get_user_cancellation_callback,
2901- set_user_cancellation_callback)
2902-
2903- # pylint: disable=C0103, W0212
2904+ # pylint: disable=C0103
2905+
2906 def closeEvent(self, event):
2907 """Catch close event and send the proper return code."""
2908- sys.exit(self.wizard._done)
2909- # pylint: enable=C0103, W0212
2910+ sys.exit(self.wizard.exit_code)
2911+
2912+ # pylint: enable=C0103

Subscribers

People subscribed via source and target branches