Merge lp:~ralsina/ubuntuone-windows-installer/ui-come-back-to-installer into lp:ubuntuone-windows-installer

Proposed by Roberto Alsina
Status: Merged
Approved by: Natalia Bidart
Approved revision: 50
Merged at revision: 25
Proposed branch: lp:~ralsina/ubuntuone-windows-installer/ui-come-back-to-installer
Merge into: lp:ubuntuone-windows-installer
Diff against target: 1027 lines (+379/-370)
12 files modified
bin/ubuntuone-installer-qt (+0/-3)
data/qt/local_folders.ui (+63/-33)
ubuntuone_installer/gui/qt/currentuser.py (+55/-0)
ubuntuone_installer/gui/qt/embedded_sso.py (+0/-61)
ubuntuone_installer/gui/qt/forgotten.py (+34/-34)
ubuntuone_installer/gui/qt/gui.py (+24/-2)
ubuntuone_installer/gui/qt/local_folders.py (+7/-2)
ubuntuone_installer/gui/qt/main/tests/test_main.py (+0/-97)
ubuntuone_installer/gui/qt/main/windows.py (+21/-29)
ubuntuone_installer/gui/qt/sync_now_or_later.py (+44/-44)
ubuntuone_installer/gui/qt/tests/test_currentuser.py (+90/-0)
ubuntuone_installer/gui/qt/tests/test_gui.py (+41/-65)
To merge this branch: bzr merge lp:~ralsina/ubuntuone-windows-installer/ui-come-back-to-installer
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Diego Sarmentero (community) Approve
Review via email: mp+70015@code.launchpad.net

Commit message

Moved the wizard UI from ussoc's process, back into the installer process.

Added one u1cp widget (the add folder button) to test that this fixes the problems embedding u1cp UI into the installer.

Added check to skip pages if there are credentials in the system.

Description of the change

Moved the wizard UI from ussoc's process, back into the installer process.

Added one u1cp widget (the add folder button) to test that this fixes the problems embedding u1cp UI into the installer.

Added check to skip pages if there are credentials in the system.

To post a comment you must log in.
Revision history for this message
Diego Sarmentero (diegosarmentero) wrote :

+1

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

There are no test for the new module currentuser.

review: Needs Fixing
37. By Roberto Alsina

added tests for the currentuser module.

38. By Roberto Alsina

better docstrings.

39. By Roberto Alsina

merge

40. By Roberto Alsina

 test fix

41. By Roberto Alsina

merge

42. By Roberto Alsina

no need for embedded_sso anymore

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

> There are no test for the new module currentuser.

Tests added.

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

* Can you please unify these two imports into one?

from ubuntuone.platform.credentials import (
    APP_NAME,
    TC_URL,
)
from ubuntuone.platform.credentials import CredentialsManagementTool

* We need a blank line between these two:

import sys
from PyQt4 import QtGui

* The code inside the try-except in currentuser.py should not be this:

+ print e, type(e), repr(e)

but a call to logger.exception.

* Four double quotes instead of 3:

""""Fake the wizard() method of QWizardPage.""

* The faked credentialsmanagementtool should return a fired deferred with an empty dict, to simulate the absence of credentials.

review: Needs Fixing
43. By Roberto Alsina

Use a successful deferred

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

Seems like a test is not passing:

Traceback (most recent call last):
  File "E:\u1\windows-installer\review_ui-come-back-to-installer\ubuntuone_installer\gui\qt\tests\test_gui.py", line 464, in test_total_size
    u"Space (1337)")
twisted.trial.unittest.FailTest: not equal:
a = u'Space (1.3 KiB)'
b = u'Space (1337)'

review: Needs Fixing
44. By Roberto Alsina

fixes

45. By Roberto Alsina

fixes

46. By Roberto Alsina

fix race condition in test

47. By Roberto Alsina

fixes

48. By Roberto Alsina

log credential exceptions

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

I'm getting these lint issues:

ubuntuone_installer/gui/qt/gui.py:
    28: [W0611] Unused import returnValue
    28: [W0611] Unused import inlineCallbacks

ubuntuone_installer/gui/qt/tests/test_gui.py:
    382: [E0102, MainWindowTestCase.test_license_next] method already defined line 378
    395: [W0201, FakeSignal.connect] Attribute 'target' defined outside __init__
    27: [W0611] Unused import reactor
    36: [W0611] Unused import ubuntu_sso
    31: [W0611] Unused import TC_URL

review: Needs Fixing
49. By Roberto Alsina

lint fixes

50. By Roberto Alsina

fixes

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

Looks great now!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'bin/ubuntuone-installer-qt'
--- bin/ubuntuone-installer-qt 2011-07-13 20:21:48 +0000
+++ bin/ubuntuone-installer-qt 2011-08-02 20:49:39 +0000
@@ -27,8 +27,6 @@
2727
28from optparse import OptionParser28from optparse import OptionParser
2929
30from twisted.internet import reactor
31
32from ubuntuone_installer import TRANSLATION_DOMAIN30from ubuntuone_installer import TRANSLATION_DOMAIN
3331
34gettext.textdomain(TRANSLATION_DOMAIN)32gettext.textdomain(TRANSLATION_DOMAIN)
@@ -48,4 +46,3 @@
48 parser = parser_options()46 parser = parser_options()
49 (options, args) = parser.parse_args(sys.argv)47 (options, args) = parser.parse_args(sys.argv)
50 main.main()48 main.main()
51 reactor.run()
5249
=== modified file 'data/qt/local_folders.ui'
--- data/qt/local_folders.ui 2011-06-28 15:46:02 +0000
+++ data/qt/local_folders.ui 2011-08-02 20:49:39 +0000
@@ -17,11 +17,11 @@
17 <item>17 <item>
18 <widget class="QLabel" name="label">18 <widget class="QLabel" name="label">
19 <property name="text">19 <property name="text">
20 <string>Ok! Now it's time to choose wich folder sync to the cloud from this computer.20 <string>Let's get started! First choose which folder you want to sync to your Ubuntu One personal cloud from this computer.
21We started by suggesting a few</string>21To help you get going we have suggested a few.</string>
22 </property>22 </property>
23 <property name="textFormat">23 <property name="textFormat">
24 <enum>Qt::RichText</enum>24 <enum>Qt::PlainText</enum>
25 </property>25 </property>
26 <property name="wordWrap">26 <property name="wordWrap">
27 <bool>true</bool>27 <bool>true</bool>
@@ -50,23 +50,28 @@
50 </property>50 </property>
51 </spacer>51 </spacer>
52 </item>52 </item>
53 <item>
54 <widget class="QPushButton" name="pushButton_2">
55 <property name="text">
56 <string>Add a folder</string>
57 </property>
58 </widget>
59 </item>
60 </layout>53 </layout>
61 </item>54 </item>
62 <item>55 <item>
63 <widget class="QTreeWidget" name="folder_list">56 <widget class="QTreeWidget" name="folder_list">
57 <property name="indentation">
58 <number>0</number>
59 </property>
60 <property name="rootIsDecorated">
61 <bool>false</bool>
62 </property>
63 <property name="uniformRowHeights">
64 <bool>true</bool>
65 </property>
66 <property name="allColumnsShowFocus">
67 <bool>true</bool>
68 </property>
64 <attribute name="headerStretchLastSection">69 <attribute name="headerStretchLastSection">
65 <bool>false</bool>70 <bool>false</bool>
66 </attribute>71 </attribute>
67 <column>72 <column>
68 <property name="text">73 <property name="text">
69 <string>My Folders</string>74 <string>Sync these folders on my computer</string>
70 </property>75 </property>
71 </column>76 </column>
72 <column>77 <column>
@@ -74,26 +79,44 @@
74 <string>Space (Total)</string>79 <string>Space (Total)</string>
75 </property>80 </property>
76 </column>81 </column>
77 <column>82 </widget>
78 <property name="text">83 </item>
79 <string>Remove</string>84 <item>
80 </property>85 <layout class="QHBoxLayout" name="horizontalLayout_3">
81 </column>86 <item>
82 </widget>87 <spacer name="horizontalSpacer_4">
83 </item>88 <property name="orientation">
84 <item>89 <enum>Qt::Horizontal</enum>
85 <widget class="QCheckBox" name="checkBox">90 </property>
86 <property name="text">91 <property name="sizeHint" stdset="0">
87 <string>Connect automatically when computer starts</string>92 <size>
88 </property>93 <width>40</width>
89 </widget>94 <height>20</height>
90 </item>95 </size>
91 <item>96 </property>
92 <widget class="QCheckBox" name="checkBox_2">97 </spacer>
93 <property name="text">98 </item>
94 <string>Automatically sync all selected folders from this computer to the cloud</string>99 <item>
95 </property>100 <widget class="AddFolderButton" name="add_folder_button">
96 </widget>101 <property name="text">
102 <string>Add a folder</string>
103 </property>
104 </widget>
105 </item>
106 <item>
107 <spacer name="horizontalSpacer_5">
108 <property name="orientation">
109 <enum>Qt::Horizontal</enum>
110 </property>
111 <property name="sizeHint" stdset="0">
112 <size>
113 <width>40</width>
114 <height>20</height>
115 </size>
116 </property>
117 </spacer>
118 </item>
119 </layout>
97 </item>120 </item>
98 <item>121 <item>
99 <widget class="QFrame" name="offer_frame">122 <widget class="QFrame" name="offer_frame">
@@ -113,7 +136,7 @@
113 <item>136 <item>
114 <widget class="QLabel" name="offer_label">137 <widget class="QLabel" name="offer_label">
115 <property name="text">138 <property name="text">
116 <string>The folders you have selected to sync take over your 2GB space. You can remove some folders or add some extra space</string>139 <string>The folders you have selected to sync take over your 5GB storage space by 6.5GB. You can remove some folders or add some extra storage now.</string>
117 </property>140 </property>
118 <property name="wordWrap">141 <property name="wordWrap">
119 <bool>true</bool>142 <bool>true</bool>
@@ -138,7 +161,7 @@
138 <item>161 <item>
139 <widget class="QPushButton" name="pushButton">162 <widget class="QPushButton" name="pushButton">
140 <property name="text">163 <property name="text">
141 <string>add more space</string>164 <string>Add more storage</string>
142 </property>165 </property>
143 </widget>166 </widget>
144 </item>167 </item>
@@ -162,6 +185,13 @@
162 </item>185 </item>
163 </layout>186 </layout>
164 </widget>187 </widget>
188 <customwidgets>
189 <customwidget>
190 <class>AddFolderButton</class>
191 <extends>QPushButton</extends>
192 <header>ubuntuone.controlpanel.gui.qt.addfolder</header>
193 </customwidget>
194 </customwidgets>
165 <resources/>195 <resources/>
166 <connections/>196 <connections/>
167</ui>197</ui>
168198
=== added file 'ubuntuone_installer/gui/qt/currentuser.py'
--- ubuntuone_installer/gui/qt/currentuser.py 1970-01-01 00:00:00 +0000
+++ ubuntuone_installer/gui/qt/currentuser.py 2011-08-02 20:49:39 +0000
@@ -0,0 +1,55 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Roberto Alsina <roberto.alsina@canonical.com>
4#
5# Copyright 2011 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Custom controller for current user page."""
20
21from twisted.internet.defer import inlineCallbacks
22
23from ubuntu_sso.qt import controllers
24
25from ubuntuone.platform.credentials import (
26 CredentialsManagementTool,
27 CredentialsError,
28)
29
30from ubuntuone_installer.logger import setup_logging
31
32# Invalid name logger
33# pylint: disable=C0103
34logger = setup_logging('qt.currentuser')
35# pylint: enable=C0103
36
37
38class CurrentUserController(controllers.CurrentUserController):
39 """Custom controller for current user page."""
40
41 @inlineCallbacks
42 def login(self, *args):
43 """Perform the login using the self.backend."""
44 email = unicode(self.view.ui.email_edit.text())
45 password = unicode(self.view.ui.password_edit.text())
46 credtool = CredentialsManagementTool()
47 try:
48 d = yield credtool.login_email_password(
49 email=email,
50 password=password,
51 )
52 self.on_logged_in(self.view.wizard().app_name, d)
53 except CredentialsError, e:
54 logger.exception("Error getting credentials:")
55 self.on_login_error(e.args[0])
056
=== removed file 'ubuntuone_installer/gui/qt/embedded_sso.py'
--- ubuntuone_installer/gui/qt/embedded_sso.py 2011-07-27 14:53:56 +0000
+++ ubuntuone_installer/gui/qt/embedded_sso.py 1970-01-01 00:00:00 +0000
@@ -1,61 +0,0 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Roberto Alsina <roberto.alsina@canonical.com>
4#
5# Copyright 2011 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""The user interface for the Ubuntu One Installer's SSO client."""
20
21import ubuntu_sso.qt.gui as sso_gui
22
23from ubuntuone_installer.gui.qt.gui import MainWindow
24
25
26class UbuntuSSOClientGUI(object):
27 """A custom Client GUI for SSO."""
28
29 def __init__(self, app_name, tc_url, help_text,
30 window_id=0, login_only=False):
31 """Create a new instance."""
32
33 # create the controller and the ui, then set the cb and call the show
34 # method so that we can work
35 self.controller = sso_gui.UbuntuSSOWizardController(
36 app_name,
37 user_cancellation_callback=self._user_cancellation_callback)
38 self.view = MainWindow()
39
40 self.login_success_callback = lambda x, y: None
41 self.registration_success_callback = lambda x, y: None
42 self.user_cancellation_callback = lambda x: None
43
44 self.view.loginSuccess.connect(self._login_success_callback)
45 self.view.registrationSuccess.connect(
46 self._registration_success_callback)
47 self.view.userCancellation.connect(self._user_cancellation_callback)
48
49 self.view.show()
50
51 def _login_success_callback(self, app_name, email):
52 """Call the real callback, set by the Credentials object"""
53 self.login_success_callback(str(app_name), str(email))
54
55 def _registration_success_callback(self, app_name, email):
56 """Call the real callback, set by the Credentials object"""
57 self.registration_success_callback(str(app_name), str(email))
58
59 def _user_cancellation_callback(self, app_name):
60 """Call the real callback, set by the Credentials object"""
61 self.user_cancellation_callback(str(app_name))
620
=== modified file 'ubuntuone_installer/gui/qt/forgotten.py'
--- ubuntuone_installer/gui/qt/forgotten.py 2011-07-19 21:06:06 +0000
+++ ubuntuone_installer/gui/qt/forgotten.py 2011-08-02 20:49:39 +0000
@@ -1,34 +1,34 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
22
3# Authors: Roberto Alsina <roberto.alsina@canonical.com>3# Authors: Roberto Alsina <roberto.alsina@canonical.com>
4#4#
5# Copyright 2011 Canonical Ltd.5# Copyright 2011 Canonical Ltd.
6#6#
7# This program is free software: you can redistribute it and/or modify it7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.9# by the Free Software Foundation.
10#10#
11# This program is distributed in the hope that it will be useful, but11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.14# PURPOSE. See the GNU General Public License for more details.
15#15#
16# You should have received a copy of the GNU General Public License along16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.17# with this program. If not, see <http://www.gnu.org/licenses/>.
1818
19"""Custom forgotten password controller."""19"""Custom forgotten password controller."""
2020
21from ubuntu_sso.qt import controllers21from ubuntu_sso.qt import controllers
2222
2323
24class ForgottenPasswordController(controllers.ForgottenPasswordController):24class ForgottenPasswordController(controllers.ForgottenPasswordController):
25 """A custom forgotten password controller.25 """A custom forgotten password controller.
2626
27 This controller hides the overlay as needed.27 This controller hides the overlay as needed.
28 """28 """
2929
30 def on_password_reset_error(self, app_name, error):30 def on_password_reset_error(self, app_name, error):
31 """Hide the overlay, then do as the default controller does."""31 """Hide the overlay, then do as the default controller does."""
32 self.view.wizard().overlay.hide()32 self.view.wizard().overlay.hide()
33 super(ForgottenPasswordController,33 super(ForgottenPasswordController,
34 self).on_password_reset_error(app_name, error)34 self).on_password_reset_error(app_name, error)
3535
=== modified file 'ubuntuone_installer/gui/qt/gui.py'
--- ubuntuone_installer/gui/qt/gui.py 2011-08-02 14:12:22 +0000
+++ ubuntuone_installer/gui/qt/gui.py 2011-08-02 20:49:39 +0000
@@ -45,7 +45,6 @@
45from ubuntu_sso.qt.reset_password_ui import Ui_ResetPasswordPage45from ubuntu_sso.qt.reset_password_ui import Ui_ResetPasswordPage
46from ubuntu_sso.qt.controllers import (46from ubuntu_sso.qt.controllers import (
47 ChooseSignInController,47 ChooseSignInController,
48 CurrentUserController,
49 EmailVerificationController,48 EmailVerificationController,
50 ErrorController,49 ErrorController,
51 ResetPasswordController,50 ResetPasswordController,
@@ -58,6 +57,7 @@
5857
59from ubuntuone.platform.credentials import (58from ubuntuone.platform.credentials import (
60 APP_NAME,59 APP_NAME,
60 CredentialsManagementTool,
61 TC_URL,61 TC_URL,
62)62)
6363
@@ -75,6 +75,7 @@
75# pylint: enable=W061175# pylint: enable=W0611
7676
77from ubuntuone_installer.gui.qt.are_you_sure import AreYouSure77from ubuntuone_installer.gui.qt.are_you_sure import AreYouSure
78from ubuntuone_installer.gui.qt.currentuser import CurrentUserController
78from ubuntuone_installer.gui.qt.forgotten import ForgottenPasswordController79from ubuntuone_installer.gui.qt.forgotten import ForgottenPasswordController
79from ubuntuone_installer.gui.qt.local_folders import LocalFoldersPage80from ubuntuone_installer.gui.qt.local_folders import LocalFoldersPage
80from ubuntuone_installer.gui.qt.sync_now_or_later import SyncNowOrLaterPage81from ubuntuone_installer.gui.qt.sync_now_or_later import SyncNowOrLaterPage
@@ -101,6 +102,7 @@
101 super(LicensePage, self).__init__(parent)102 super(LicensePage, self).__init__(parent)
102 self.ui = license_ui.Ui_Form()103 self.ui = license_ui.Ui_Form()
103 self.ui.setupUi(self)104 self.ui.setupUi(self)
105 self._next_id = None
104106
105 # Invalid names of Qt-inherited methods107 # Invalid names of Qt-inherited methods
106 # pylint: disable=C0103108 # pylint: disable=C0103
@@ -146,6 +148,12 @@
146 printer.setPageSize(QtGui.QPrinter.A4)148 printer.setPageSize(QtGui.QPrinter.A4)
147 document.print_(printer)149 document.print_(printer)
148150
151 def nextId(self):
152 """Return next page's ID."""
153 if self._next_id is None:
154 return super(LicensePage, self).nextId()
155 return self._next_id
156
149157
150class SignInPage(QtGui.QWizardPage):158class SignInPage(QtGui.QWizardPage):
151 """Wizard Page that lets the user Sign into Ubuntu One."""159 """Wizard Page that lets the user Sign into Ubuntu One."""
@@ -330,7 +338,9 @@
330 # PyQt doesn't support the (int, page) version of addPage, so338 # PyQt doesn't support the (int, page) version of addPage, so
331 # Add the pages in the right order339 # Add the pages in the right order
332 # pylint: disable=C0103340 # pylint: disable=C0103
333 self.LICENSE_PAGE = self.addPage(LicensePage())341
342 self.LICENSE_PAGE = LicensePage()
343 self.LICENSE_PAGE_ID = self.addPage(self.LICENSE_PAGE)
334344
335 #SSO Pages345 #SSO Pages
336 title_page = TITLE_STYLE % SIGN_IN346 title_page = TITLE_STYLE % SIGN_IN
@@ -424,10 +434,22 @@
424 # Apply font to the entire application434 # Apply font to the entire application
425 QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-R.ttf')435 QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-R.ttf')
426 QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-B.ttf')436 QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-B.ttf')
437 credtool = CredentialsManagementTool()
438 d = credtool.find_credentials()
439 d.addCallback(self.creds_cb)
440 d.addErrback(lambda exc: logger.error(
441 'Error while getting the credentials: %r', exc))
427442
428 # Invalid name "closeEvent"443 # Invalid name "closeEvent"
429 # pylint: disable=C0103444 # pylint: disable=C0103
430445
446 def creds_cb(self, token):
447 """Change wizard flow if we have credentials."""
448 if not token:
449 self.LICENSE_PAGE._next_id = self.SIGNIN_PAGE
450 else:
451 self.LICENSE_PAGE._next_id = self.local_folders_page_id
452
431 def critical(self, *args, **kwargs):453 def critical(self, *args, **kwargs):
432 """Wrapper for QMessageBox.critical that hides the overlay."""454 """Wrapper for QMessageBox.critical that hides the overlay."""
433 self.overlay.hide()455 self.overlay.hide()
434456
=== modified file 'ubuntuone_installer/gui/qt/local_folders.py'
--- ubuntuone_installer/gui/qt/local_folders.py 2011-07-22 16:32:35 +0000
+++ ubuntuone_installer/gui/qt/local_folders.py 2011-08-02 20:49:39 +0000
@@ -103,8 +103,13 @@
103 # Special Folder "My Documents"103 # Special Folder "My Documents"
104 dll = ctypes.windll.shell32104 dll = ctypes.windll.shell32
105 buf = ctypes.create_string_buffer(300)105 buf = ctypes.create_string_buffer(300)
106 dll.SHGetSpecialFolderPathA(None, buf, 0x0005, False)106 dll.SHGetSpecialFolderPathA(None, buf, 5, False)
107 result = [buf.value, ]107 docs = buf.value
108 dll.SHGetSpecialFolderPathA(None, buf, 13, False)
109 music = buf.value
110 dll.SHGetSpecialFolderPathA(None, buf, 39, False)
111 pictures = buf.value
112 return [docs, music, pictures]
108 else:113 else:
109 result = ['To be implemented']114 result = ['To be implemented']
110 return result115 return result
111116
=== removed file 'ubuntuone_installer/gui/qt/main/tests/test_main.py'
--- ubuntuone_installer/gui/qt/main/tests/test_main.py 2011-07-27 15:09:28 +0000
+++ ubuntuone_installer/gui/qt/main/tests/test_main.py 1970-01-01 00:00:00 +0000
@@ -1,97 +0,0 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Roberto Alsina <roberto.alsina@canonical.com>
4#
5# Copyright 2011 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""The test suite for the Qt UI of the Ubuntu One Installer."""
20
21from ubuntuone_installer.tests import TestCase
22
23import ubuntuone_installer.gui.qt.main.windows as main_module
24
25# pylint: disable=W0212
26
27from ubuntuone.platform.credentials import (
28 APP_NAME,
29 DESCRIPTION,
30 TC_URL,
31)
32
33
34class FakeSSOCred(object):
35 """A fake sso_cred."""
36
37 _registered_to_signal = False
38 _login_args = ()
39 on_credentials_found = None
40
41 def register_to_signals(self):
42 """Fake method."""
43 self._registered_to_signal = True
44
45 def login_or_register_to_get_credentials(self, *args, **kwargs):
46 """Fake method."""
47 self._login_args = (args, kwargs)
48
49
50class FakeSSOClient(object):
51
52 """Fake UbuntuSSOClient."""
53
54 sso_cred = FakeSSOCred()
55 testcase = None
56
57 def connect(self):
58 """Fake method."""
59 self.testcase._connected = True
60 return self
61
62
63class MainTestCase(TestCase):
64
65 """Tests for the main() function."""
66
67 _connected = False
68
69 def setUp(self):
70 """Prepare tests."""
71 self.patch(main_module, "UbuntuSSOClient", FakeSSOClient)
72 main_module.UbuntuSSOClient.testcase = self
73
74 def test_connect(self):
75 """Test that we instantiate the SSO Client and connect."""
76 main_module.main()
77 self.assertEqual(FakeSSOClient.testcase._connected, True)
78
79 def test_credentials_found_cb(self):
80 """Test that the credentials found signal is connected."""
81 main_module.main()
82 self.assertEqual(
83 FakeSSOClient.sso_cred.on_credentials_found_cb.__name__,
84 "stop")
85
86 def test_registered(self):
87 """Test that the credentials registers to signals."""
88 main_module.main()
89 self.assertEqual(FakeSSOClient.sso_cred._registered_to_signal,
90 True)
91
92 def test_check_register_args(self):
93 """Test that the credentials registers to signals."""
94 main_module.main()
95 self.assertEqual(FakeSSOClient.sso_cred._login_args,
96 ((APP_NAME, TC_URL, DESCRIPTION, 0),
97 {'ui_module': 'ubuntuone_installer.gui.qt.embedded_sso'}))
980
=== modified file 'ubuntuone_installer/gui/qt/main/windows.py'
--- ubuntuone_installer/gui/qt/main/windows.py 2011-07-27 14:53:56 +0000
+++ ubuntuone_installer/gui/qt/main/windows.py 2011-08-02 20:49:39 +0000
@@ -19,34 +19,26 @@
1919
20# pylint: disable=E1101, F0401, W040420# pylint: disable=E1101, F0401, W0404
2121
22from twisted.internet.defer import inlineCallbacks22import sys
23from ubuntu_sso.main.windows import UbuntuSSOClient23
2424from PyQt4 import QtGui
25from ubuntuone.platform.credentials import (25
26 APP_NAME,26
27 DESCRIPTION,27def stop(*args):
28 TC_URL,28 """End the process."""
29)29 from twisted.internet import reactor
3030 reactor.stop()
3131
32@inlineCallbacks32
33def main():33def main():
34 """Perform a client request to be logged in."""34 """Perform a client request to be logged in."""
35 client = UbuntuSSOClient()35
36 client = yield client.connect()36 app = QtGui.QApplication(sys.argv)
3737 import qtreactor.qt4reactor
38 @inlineCallbacks38 qtreactor.qt4reactor.install()
39 def stop(*args):39 from ubuntuone_installer.gui.qt.gui import MainWindow
40 """End the process."""40 from twisted.internet import reactor
41 from twisted.internet import reactor41 window = MainWindow(close_callback=stop)
42 yield client.sso_cred.unregister_to_signals()42 app.window = window
43 reactor.stop()43 window.show()
4444 reactor.run()
45 client.sso_cred.on_credentials_found_cb = stop
46 client.sso_cred.on_authorization_denied_cb = stop
47 client.sso_cred.on_credentials_error_cb = stop
48 yield client.sso_cred.register_to_signals()
49 yield client.sso_cred.login_or_register_to_get_credentials(APP_NAME,
50 TC_URL,
51 DESCRIPTION, 0,
52 ui_module="ubuntuone_installer.gui.qt.embedded_sso")
5345
=== modified file 'ubuntuone_installer/gui/qt/sync_now_or_later.py'
--- ubuntuone_installer/gui/qt/sync_now_or_later.py 2011-06-29 11:44:23 +0000
+++ ubuntuone_installer/gui/qt/sync_now_or_later.py 2011-08-02 20:49:39 +0000
@@ -1,44 +1,44 @@
1# -*- coding: utf-8 -*-1# -*- coding: utf-8 -*-
22
3# Authors: Roberto Alsina <roberto.alsina@canonical.com>3# Authors: Roberto Alsina <roberto.alsina@canonical.com>
4#4#
5# Copyright 2011 Canonical Ltd.5# Copyright 2011 Canonical Ltd.
6#6#
7# This program is free software: you can redistribute it and/or modify it7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.9# by the Free Software Foundation.
10#10#
11# This program is distributed in the hope that it will be useful, but11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.14# PURPOSE. See the GNU General Public License for more details.
15#15#
16# You should have received a copy of the GNU General Public License along16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.17# with this program. If not, see <http://www.gnu.org/licenses/>.
1818
19"""The user interface for the Ubuntu One Installer."""19"""The user interface for the Ubuntu One Installer."""
2020
21from PyQt4 import QtGui21from PyQt4 import QtGui
2222
23from ubuntuone_installer.gui.qt.ui import sync_now_or_later_ui23from ubuntuone_installer.gui.qt.ui import sync_now_or_later_ui
2424
2525
26class SyncNowOrLaterPage(QtGui.QWizardPage):26class SyncNowOrLaterPage(QtGui.QWizardPage):
27 """User can choose whether to sync now, later, or selectively"""27 """User can choose whether to sync now, later, or selectively"""
2828
29 def __init__(self, parent=None):29 def __init__(self, parent=None):
30 QtGui.QWizardPage.__init__(self, parent)30 QtGui.QWizardPage.__init__(self, parent)
31 self.ui = sync_now_or_later_ui.Ui_Form()31 self.ui = sync_now_or_later_ui.Ui_Form()
32 self.ui.setupUi(self)32 self.ui.setupUi(self)
33 self.registerField("sync_now", self.ui.sync_now)33 self.registerField("sync_now", self.ui.sync_now)
34 self.registerField("sync_later", self.ui.sync_later)34 self.registerField("sync_later", self.ui.sync_later)
35 self.registerField("sync_custom", self.ui.sync_custom)35 self.registerField("sync_custom", self.ui.sync_custom)
3636
37 # Invalid names of Qt-inherited methods37 # Invalid names of Qt-inherited methods
38 # pylint: disable=C010338 # pylint: disable=C0103
3939
40 def initializePage(self):40 def initializePage(self):
41 """Setup UI details"""41 """Setup UI details"""
42 self.wizard().setOption(QtGui.QWizard.HaveCustomButton1, False)42 self.wizard().setOption(QtGui.QWizard.HaveCustomButton1, False)
43 self.wizard().setOption(QtGui.QWizard.NoCancelButton, True)43 self.wizard().setOption(QtGui.QWizard.NoCancelButton, True)
44 self.wizard()._next_id = None44 self.wizard()._next_id = None
4545
=== added file 'ubuntuone_installer/gui/qt/tests/test_currentuser.py'
--- ubuntuone_installer/gui/qt/tests/test_currentuser.py 1970-01-01 00:00:00 +0000
+++ ubuntuone_installer/gui/qt/tests/test_currentuser.py 2011-08-02 20:49:39 +0000
@@ -0,0 +1,90 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Roberto Alsina <roberto.alsina@canonical.com>
4#
5# Copyright 2011 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Tests for the CurrentUserController."""
20
21from ubuntuone_installer.gui.qt import currentuser
22from ubuntuone_installer.gui.qt.tests import BaseTestCase
23
24
25class FakeView(object):
26
27 """A Fake view for the controller."""
28
29 def __init__(self):
30 """Setup."""
31 self.view = self
32 self.ui = self
33 self.email_edit = self
34 self.password_edit = self
35 self.app_name = "APP"
36
37 def text(self):
38 """Return some text."""
39 return "text"
40
41 def wizard(self):
42 """Fake the wizard() method of QWizardPage."""
43 return self
44
45
46class FakeCredentialsManagementToolSuccess(object):
47
48 """A fake CredentialsManagementTool where login succeeds."""
49
50 def login_email_password(self, *args, **kwargs):
51 """Fake credentials."""
52 return {"x": "y"}
53
54
55class FakeCredentialsManagementToolFailure(object):
56
57 """A fake CredentialsManagementTool where login fails."""
58
59 def login_email_password(self, *args, **kwargs):
60 """Raises a credentials exception."""
61 raise currentuser.CredentialsError("Failure")
62
63
64class CurrentUserTestCase(BaseTestCase):
65
66 """Test the CurrentUserController."""
67
68 class_ui = FakeView
69
70 def setUp(self):
71 """Initialize this test instance."""
72 self.controller = currentuser.CurrentUserController()
73 self.controller.view = FakeView()
74 super(CurrentUserTestCase, self).setUp()
75
76 def test_login_success(self):
77 """Check that login works correctly."""
78 self.patch(currentuser, 'CredentialsManagementTool',
79 FakeCredentialsManagementToolSuccess)
80 self.patch(self.controller, 'on_logged_in', self._set_called)
81 self.controller.login()
82 self.assertEqual(self._called, (('APP', {'x': 'y'}), {}))
83
84 def test_login_failure(self):
85 """Check that login fails correctly."""
86 self.patch(currentuser, 'CredentialsManagementTool',
87 FakeCredentialsManagementToolFailure)
88 self.patch(self.controller, 'on_login_error', self._set_called)
89 self.controller.login()
90 self.assertEqual(self._called, (('Failure',), {}))
091
=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-02 14:12:22 +0000
+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-02 20:49:39 +0000
@@ -24,18 +24,14 @@
24import shutil24import shutil
25import tempfile25import tempfile
2626
27from twisted.internet import defer
28
27from PyQt4 import QtCore29from PyQt4 import QtCore
2830
29from ubuntuone.platform.credentials import (31from ubuntuone.platform.credentials import APP_NAME
30 APP_NAME,
31 TC_URL,
32)
33
34import ubuntu_sso
3532
36from ubuntuone_installer.gui.qt import gui33from ubuntuone_installer.gui.qt import gui
37from ubuntuone_installer.gui.qt.tests import BaseTestCase34from ubuntuone_installer.gui.qt.tests import BaseTestCase
38from ubuntuone_installer.gui.qt import embedded_sso
39from ubuntuone_installer.gui.qt import forgotten35from ubuntuone_installer.gui.qt import forgotten
40from ubuntuone_installer.gui.qt import local_folders36from ubuntuone_installer.gui.qt import local_folders
41from ubuntuone_installer.gui.qt import setup_account37from ubuntuone_installer.gui.qt import setup_account
@@ -51,6 +47,15 @@
51 u'token_secret': u'qFYImEtlczPbsCnYyuwLoPDlPEnvNcIktZphPQklAWrvyfFMV'}47 u'token_secret': u'qFYImEtlczPbsCnYyuwLoPDlPEnvNcIktZphPQklAWrvyfFMV'}
5248
5349
50class FakeFailureCredentialsManagementTool(object):
51
52 """A fake CredentialsManagementTool that fails."""
53
54 def find_credentials(self):
55 """Return a deferred that never triggers callback."""
56 return defer.succeed({})
57
58
54class FakeController(object):59class FakeController(object):
5560
56 """A fake controller for the tests."""61 """A fake controller for the tests."""
@@ -99,6 +104,9 @@
99 """Fake hide."""104 """Fake hide."""
100 self.hide_counter += 1105 self.hide_counter += 1
101106
107 def resize(self, *args):
108 """Fake resize."""
109
102110
103class MainWindowTestCase(BaseTestCase):111class MainWindowTestCase(BaseTestCase):
104 """Test the qt main window."""112 """Test the qt main window."""
@@ -118,6 +126,8 @@
118 self.patch(gui, "ResetPasswordController", FakeController)126 self.patch(gui, "ResetPasswordController", FakeController)
119 self.patch(gui, "AreYouSure", FakeAreYouSure)127 self.patch(gui, "AreYouSure", FakeAreYouSure)
120 self.patch(gui, "LoadingOverlay", FakeOverlay)128 self.patch(gui, "LoadingOverlay", FakeOverlay)
129 self.patch(gui, "CredentialsManagementTool",
130 FakeFailureCredentialsManagementTool)
121 super(MainWindowTestCase, self).setUp()131 super(MainWindowTestCase, self).setUp()
122132
123 def test_critical(self):133 def test_critical(self):
@@ -291,7 +301,7 @@
291301
292 def test_stage_progression_1(self):302 def test_stage_progression_1(self):
293 """Check that each page in the wizard sets the correct stage."""303 """Check that each page in the wizard sets the correct stage."""
294 self.ui.on_currentIdChanged(self.ui.LICENSE_PAGE)304 self.ui.on_currentIdChanged(self.ui.LICENSE_PAGE_ID)
295 self.assertEqual(self.ui.sideWidget().stage, 0)305 self.assertEqual(self.ui.sideWidget().stage, 0)
296306
297 def test_stage_progression_2(self):307 def test_stage_progression_2(self):
@@ -360,11 +370,25 @@
360 QtCore.QCoreApplication.instance().processEvents()370 QtCore.QCoreApplication.instance().processEvents()
361 self.assertEqual(self.ui.result(), self.ui.Rejected)371 self.assertEqual(self.ui.result(), self.ui.Rejected)
362372
373 def test_license_next(self):
374 """Test what's the license page's nextID."""
375 self.assertEqual(self.ui.LICENSE_PAGE.nextId(), self.ui.SIGNIN_PAGE)
376
377 def test_license_next_with_creds(self):
378 """Test what's the license page's nextID."""
379 self.ui.creds_cb("fakecreds")
380 self.assertEqual(self.ui.LICENSE_PAGE.nextId(),
381 self.ui.local_folders_page_id)
382
363383
364class FakeSignal(object):384class FakeSignal(object):
365385
366 """A fake PyQt signal."""386 """A fake PyQt signal."""
367387
388 def __init__(self, *args, **kwargs):
389 """Initialize."""
390 self.target = lambda *args: None
391
368 def connect(self, target):392 def connect(self, target):
369 """Fake connect."""393 """Fake connect."""
370 self.target = target394 self.target = target
@@ -388,51 +412,6 @@
388 self.shown = True412 self.shown = True
389413
390414
391class SSOGuiTestCase(BaseTestCase):
392 """Test the custom SSO GUI."""
393
394 class_ui = embedded_sso.UbuntuSSOClientGUI
395
396 def setUp(self):
397 """Initialize this test instance."""
398 self.kwargs = {
399 'app_name': APP_NAME,
400 'tc_url': TC_URL,
401 'help_text': '',
402 }
403 self.patch(embedded_sso, "MainWindow", FakeMainWindow)
404 super(SSOGuiTestCase, self).setUp()
405
406 def test_sso_client_gui(self):
407 """Ensure the class instantiates correctly."""
408 self.assertIsInstance(
409 self.ui.controller,
410 ubuntu_sso.qt.controllers.UbuntuSSOWizardController)
411 self.assertIsInstance(self.ui.view, FakeMainWindow)
412
413 def test_login_callback(self):
414 """Test that the login success callback is correctly handled."""
415 self.ui.login_success_callback = self._set_called
416 self.ui.view.loginSuccess.emit("app", "email")
417 self.assertEqual(self._called, (('app', 'email'), {}))
418
419 def test_registration_callback(self):
420 """Test that the registration success callback is correctly handled."""
421 self.ui.registration_success_callback = self._set_called
422 self.ui.view.registrationSuccess.emit("app", "email")
423 self.assertEqual(self._called, (('app', 'email'), {}))
424
425 def test_cancellation_callback(self):
426 """Test that the cancellation callback is called right."""
427 self.ui.user_cancellation_callback = self._set_called
428 self.ui.view.userCancellation.emit("app")
429 self.assertEqual(self._called, (('app',), {}))
430
431 def test_view_is_shown(self):
432 """Test that the view is actually shown."""
433 self.assertTrue(self.ui.view.shown)
434
435
436class LocalFoldersTestCase(BaseTestCase):415class LocalFoldersTestCase(BaseTestCase):
437 """Test the LocalFoldersPage code."""416 """Test the LocalFoldersPage code."""
438417
@@ -465,16 +444,10 @@
465 self.assertEqual(path, self.tmpdir)444 self.assertEqual(path, self.tmpdir)
466 self.assertEqual(size, 1337)445 self.assertEqual(size, 1337)
467446
468 def test_item_addition_removal(self):447 def test_item_addition(self):
469 """Add an item (plus the default one), then remove them."""448 """Add an item (plus the default one), then remove them."""
470 self.ui.add_folder(self.tmpdir)449 self.ui.add_folder(self.tmpdir)
471 self.assertEqual(2, self.ui.ui.folder_list.topLevelItemCount())450 self.assertEqual(4, self.ui.ui.folder_list.topLevelItemCount())
472 self.ui.on_folder_list_itemClicked(
473 self.ui.ui.folder_list.topLevelItem(0), 2)
474 self.ui.on_folder_list_itemClicked(
475 self.ui.ui.folder_list.topLevelItem(0), 2)
476 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
477 self.assertEqual({}, self.ui.items)
478451
479 def test_total_size(self):452 def test_total_size(self):
480 """Test that the header reflects the change in item sizes."""453 """Test that the header reflects the change in item sizes."""
@@ -484,6 +457,8 @@
484 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())457 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
485 item = self.ui.add_folder(self.tmpdir)458 item = self.ui.add_folder(self.tmpdir)
486 item.size = 1337459 item.size = 1337
460 item.thread.run()
461 item.thread.join()
487 self.ui.update_sizes()462 self.ui.update_sizes()
488 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),463 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
489 u"Space (1337)")464 u"Space (1337)")
@@ -515,6 +490,7 @@
515 item = self.ui.add_folder(os.path.join("xyzzy", "xyzzy", "xyzzy"))490 item = self.ui.add_folder(os.path.join("xyzzy", "xyzzy", "xyzzy"))
516 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())491 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
517 item.thread.run()492 item.thread.run()
493 item.thread.join()
518 self.ui.update_sizes()494 self.ui.update_sizes()
519 self.assertEqual(0, item.size)495 self.assertEqual(0, item.size)
520 # world did not explode496 # world did not explode
@@ -758,16 +734,16 @@
758 self.ui.on_currentIdChanged(self.ui.LICENSE_PAGE)734 self.ui.on_currentIdChanged(self.ui.LICENSE_PAGE)
759 self.assertEqual(735 self.assertEqual(
760 True,736 True,
761 sideWidget().ui.states_frame.isVisible())737 self.ui.sideWidget().ui.states_frame.isVisible())
762 self.ui.on_currentIdChanged(self.ui.SIGNIN_PAGE)738 self.ui.on_currentIdChanged(self.ui.SIGNIN_PAGE)
763 self.assertEqual(739 self.assertEqual(
764 True,740 True,
765 sideWidget().ui.states_frame.isVisible())741 self.ui.sideWidget().ui.states_frame.isVisible())
766 self.ui.on_currentIdChanged(self.ui.local_folders_page_id)742 self.ui.on_currentIdChanged(self.ui.local_folders_page_id)
767 self.assertEqual(743 self.assertEqual(
768 True,744 True,
769 sideWidget().ui.states_frame.isVisible())745 self.ui.sideWidget().ui.states_frame.isVisible())
770 self.ui.on_currentIdChanged(self.ui.CONGRATULATIONS_PAGE)746 self.ui.on_currentIdChanged(self.ui.CONGRATULATIONS_PAGE)
771 self.assertEqual(747 self.assertEqual(
772 True,748 True,
773 sideWidget().ui.states_frame.isVisible())749 self.ui.sideWidget().ui.states_frame.isVisible())

Subscribers

People subscribed via source and target branches