Merge lp:~ralsina/ubuntuone-windows-installer/no-credentials into lp:ubuntuone-windows-installer

Proposed by Roberto Alsina
Status: Merged
Approved by: Roberto Alsina
Approved revision: 45
Merged at revision: 41
Proposed branch: lp:~ralsina/ubuntuone-windows-installer/no-credentials
Merge into: lp:ubuntuone-windows-installer
Diff against target: 490 lines (+213/-125)
8 files modified
ubuntuone_installer/gui/qt/gui.py (+3/-31)
ubuntuone_installer/gui/qt/main/tests/test_windows.py (+128/-0)
ubuntuone_installer/gui/qt/main/windows.py (+54/-18)
ubuntuone_installer/gui/qt/tests/test_gui.py (+3/-73)
ubuntuone_installer/gui/qt/utils/__init__.py (+3/-1)
ubuntuone_installer/gui/qt/utils/linux.py (+6/-0)
ubuntuone_installer/gui/qt/utils/tests/test_windows.py (+1/-1)
ubuntuone_installer/gui/qt/utils/windows.py (+15/-1)
To merge this branch: bzr merge lp:~ralsina/ubuntuone-windows-installer/no-credentials
Reviewer Review Type Date Requested Status
Diego Sarmentero (community) Approve
Natalia Bidart (community) Approve
Review via email: mp+72935@code.launchpad.net

Commit message

Start the control panel directly if the user already has credentials.

Description of the change

Start the control panel directly if the user already has credentials.

To post a comment you must log in.
44. By Roberto Alsina

solve merge conflict

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

Looks good!

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

"start_control_panel" function should be moved into "utils" (platform dependent) module as the uninstall function, because both are checking if sys.platform == "win32".

review: Needs Fixing
45. By Roberto Alsina

refactored as suggested by diego

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=== modified file 'ubuntuone_installer/gui/qt/gui.py'
2--- ubuntuone_installer/gui/qt/gui.py 2011-08-23 17:43:40 +0000
3+++ ubuntuone_installer/gui/qt/gui.py 2011-08-29 12:42:23 +0000
4@@ -59,7 +59,6 @@
5
6 from ubuntuone.platform.credentials import (
7 APP_NAME,
8- CredentialsManagementTool,
9 TC_URL,
10 )
11
12@@ -90,6 +89,7 @@
13 TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
14 CREDENTIALS_ERROR_TITLE = _("Error getting credentials")
15 CREDENTIALS_ERROR = _('Application will close.\n\n%r')
16+STARTING_CP_ERROR = _('Error starting Ubuntu One')
17 # Invalid name logger
18 # pylint: disable=C0103
19 logger = setup_logging('qt.gui')
20@@ -291,6 +291,7 @@
21
22 self.setSideWidget(SideWidget())
23 self.overlay = LoadingOverlay(self)
24+ self.overlay.hide()
25
26 self.setOption(self.NoBackButtonOnStartPage, True)
27
28@@ -388,30 +389,9 @@
29 # Set Wizard buttons style
30 self.button(QtGui.QWizard.NextButton).setDefault(True)
31
32- credtool = CredentialsManagementTool()
33- d = credtool.find_credentials()
34- d.addCallback(self.creds_cb)
35- d.addErrback(self.creds_eb)
36-
37 # Invalid name "closeEvent"
38 # pylint: disable=C0103
39
40- def creds_eb(self, exc):
41- """Handle credentials error."""
42- self.LICENSE_PAGE._next_id = self.SIGNIN_PAGE
43- self.critical(CREDENTIALS_ERROR % exc.value)
44- logger.error(
45- 'Error while getting the credentials: %r', exc.value)
46- self.close()
47-
48- def creds_cb(self, token):
49- """Change wizard flow if we have credentials."""
50- self.overlay.hide()
51- if not token:
52- self.LICENSE_PAGE._next_id = self.SIGNIN_PAGE
53- else:
54- self.LICENSE_PAGE._next_id = self.local_folders_page_id
55-
56 def critical(self, message):
57 """Show a message at the bottom of the page on form errors."""
58 self.overlay.hide()
59@@ -451,15 +431,7 @@
60 """The main window is being closed, call any custom callback."""
61 # Finished, not cancelled
62 if result == 1: # Cancelled
63- # If we are in windows and "frozen", assume it's in
64- # the same folder as this .exe
65- if sys.platform == "win32" and hasattr(sys, "frozen"):
66- cp_path = os.path.join(os.path.dirname(
67- os.path.abspath(sys.executable)),
68- "ubuntuone-control-panel-qt.exe")
69- else:
70- cp_path = "ubuntuone-control-panel-qt"
71- subprocess.Popen([cp_path, ])
72+ utils.start_control_panel()
73 elif self.currentId() == self.LICENSE_PAGE_ID:
74 if not AreYouSure(self).exec_():
75 utils.uninstall_application()
76
77=== added file 'ubuntuone_installer/gui/qt/main/tests/test_windows.py'
78--- ubuntuone_installer/gui/qt/main/tests/test_windows.py 1970-01-01 00:00:00 +0000
79+++ ubuntuone_installer/gui/qt/main/tests/test_windows.py 2011-08-29 12:42:23 +0000
80@@ -0,0 +1,128 @@
81+# -*- coding: utf-8 -*-
82+
83+# Authors: Alejandro J. Cura <alecu@canonical.com>
84+# Roberto Alsina <roberto.alsina@canonical.com>
85+#
86+# Copyright 2011 Canonical Ltd.
87+#
88+# This program is free software: you can redistribute it and/or modify it
89+# under the terms of the GNU General Public License version 3, as published
90+# by the Free Software Foundation.
91+#
92+# This program is distributed in the hope that it will be useful, but
93+# WITHOUT ANY WARRANTY; without even the implied warranties of
94+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
95+# PURPOSE. See the GNU General Public License for more details.
96+#
97+# You should have received a copy of the GNU General Public License along
98+# with this program. If not, see <http://www.gnu.org/licenses/>.
99+
100+"""Tests for the Windows main."""
101+
102+from twisted.internet import defer
103+
104+from ubuntuone_installer.gui.qt import gui, utils
105+from ubuntuone_installer.gui.qt.main import windows
106+from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow
107+from ubuntuone_installer.tests import TestCase
108+
109+
110+class FakeFailingCredentialsManagementTool(object):
111+
112+ """A fake CredentialsManagementTool that fails."""
113+
114+ def find_credentials(self):
115+ """Return a failure."""
116+ return defer.fail(Exception())
117+
118+
119+class FakeNoCredentialsManagementTool(object):
120+
121+ """A fake CredentialsManagementTool that fakes no credentials."""
122+
123+ def find_credentials(self):
124+ """Return a success, but no credentials."""
125+ return defer.succeed({})
126+
127+
128+class FakeCredentialsManagementTool(object):
129+
130+ """A fake CredentialsManagementTool that fakes credentials."""
131+
132+ def find_credentials(self):
133+ """Return a success, but no credentials."""
134+ return defer.succeed("Something not false")
135+
136+
137+class FakeLogger(object):
138+
139+ """Fake Logger."""
140+
141+ error_args = None
142+
143+ def error(self, *args, **kwargs):
144+ """Save the error."""
145+ self.error_args = (args, kwargs)
146+
147+
148+class CredsFailureMainTestCase(TestCase):
149+
150+ """Test the qt main window."""
151+
152+ stopped = False
153+
154+ def stop(self):
155+ """A fake stop."""
156+ self.stopped = True
157+
158+ @defer.inlineCallbacks
159+ def test_failure(self):
160+ """Credential errors should display a critical message."""
161+ logger = FakeLogger()
162+ self.patch(windows, 'stop', self.stop)
163+ self.stopped = False
164+ yield windows.check_credentials(
165+ FakeFailingCredentialsManagementTool,
166+ gui, logger)
167+ # Should log the error
168+ self.assertEqual(logger.error_args[0][0],
169+ ('Error while getting the credentials: %r'))
170+ # Should stop the app
171+ self.assertTrue(self.stopped)
172+
173+ @defer.inlineCallbacks
174+ def test_no_creds(self):
175+ """No credentials should start the wizard."""
176+ logger = FakeLogger()
177+ fakemain = FakeMainWindow()
178+ self.patch(gui, 'MainWindow', lambda *args, **kwargs: fakemain)
179+ self.patch(windows, 'stop', self._set_called)
180+ self.assertFalse(fakemain.shown)
181+ self.patch(windows, 'stop', self.stop)
182+ self.stopped = False
183+ yield windows.check_credentials(
184+ FakeNoCredentialsManagementTool,
185+ gui, logger)
186+ # Should show the main window
187+ self.assertTrue(fakemain.shown)
188+ # Should not log errors
189+ self.assertEqual(logger.error_args, None)
190+ # Should not stop the app
191+ self.assertFalse(self.stopped)
192+
193+ @defer.inlineCallbacks
194+ def test_with_creds(self):
195+ """Having credentials should start the control panel."""
196+ logger = FakeLogger()
197+ self.patch(utils, 'start_control_panel', self._set_called)
198+ self.patch(windows, 'stop', self.stop)
199+ self.stopped = False
200+ yield windows.check_credentials(
201+ FakeCredentialsManagementTool,
202+ gui, logger)
203+ # Should not log errors
204+ self.assertEqual(logger.error_args, None)
205+ # Should start u1cp
206+ self.assertEqual(self._called, ((), {}))
207+ # Should stop the app
208+ self.assertTrue(self.stopped)
209
210=== modified file 'ubuntuone_installer/gui/qt/main/windows.py'
211--- ubuntuone_installer/gui/qt/main/windows.py 2011-08-12 01:07:04 +0000
212+++ ubuntuone_installer/gui/qt/main/windows.py 2011-08-29 12:42:23 +0000
213@@ -21,8 +21,8 @@
214
215 import sys
216
217-from PyQt4 import QtGui
218-from PyQt4 import QtCore
219+from PyQt4 import QtGui, QtCore
220+from twisted.internet import defer
221
222 # Module used to include the resources into this file
223 # pylint: disable=W0611
224@@ -36,26 +36,62 @@
225 reactor.stop()
226
227
228+def error_cb(exc, logger):
229+ """Handle credentials errors."""
230+ logger.error(
231+ 'Error while getting the credentials: %r', exc)
232+ stop()
233+
234+
235+def success_cb(creds, gui):
236+ """Handle credentials success."""
237+ if creds: # Have credentials already
238+ try:
239+ gui.utils.start_control_panel()
240+ except OSError:
241+ QtGui.QMessageBox.critical(
242+ None, "Ubuntu One", gui.STARTING_CP_ERROR)
243+ stop()
244+ else: # No credentials
245+ window = gui.MainWindow(close_callback=stop)
246+ # Set Application Style Sheet
247+ app = QtGui.QApplication.instance()
248+ qss = QtCore.QResource(":/ubuntuone.qss")
249+ app.setStyleSheet(QtCore.QString(qss.data()))
250+ # Apply font to the entire application
251+ QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-R.ttf')
252+ QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-B.ttf')
253+ # Set Application Icon
254+ app.setWindowIcon(QtGui.QIcon(":/ubuntu_one_favicon.png"))
255+ window.show()
256+
257+
258+@defer.inlineCallbacks
259+def check_credentials(credentials_tool, gui, logger):
260+ """Check credentials and either start u1cp or show the wizard."""
261+ credtool = credentials_tool()
262+ # pylint: disable=W0703
263+ try:
264+ creds = yield credtool.find_credentials()
265+ except Exception, exc:
266+ error_cb(exc, logger)
267+ else:
268+ success_cb(creds, gui)
269+
270+
271 def main():
272 """Perform a client request to be logged in."""
273-
274+ # pylint: disable=W0612
275 app = QtGui.QApplication(sys.argv)
276+ # pylint: enable=W0612
277 import qtreactor.qt4reactor
278 qtreactor.qt4reactor.install()
279- from ubuntuone_installer.gui.qt.gui import MainWindow
280+ from ubuntuone_installer.gui.qt import gui, utils
281 from twisted.internet import reactor
282- window = MainWindow(close_callback=stop)
283- app.window = window
284-
285- # Set Application Style Sheet
286- app = QtGui.QApplication.instance()
287- qss = QtCore.QResource(":/ubuntuone.qss")
288- app.setStyleSheet(QtCore.QString(qss.data()))
289- # Apply font to the entire application
290- QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-R.ttf')
291- QtGui.QFontDatabase.addApplicationFont(':/Ubuntu-B.ttf')
292- # Set Application Icon
293- app.setWindowIcon(QtGui.QIcon(":/ubuntu_one_favicon.png"))
294-
295- window.show()
296+ # All this has to be imported here because it installs a reactor
297+ from ubuntuone.platform.credentials import CredentialsManagementTool
298+ from ubuntuone_installer.logger import setup_logging
299+ logger = setup_logging('qt.gui')
300+
301+ check_credentials(CredentialsManagementTool, gui, logger)
302 reactor.run()
303
304=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
305--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-26 12:24:48 +0000
306+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-29 12:42:23 +0000
307@@ -31,22 +31,6 @@
308 from ubuntuone_installer.gui.qt.tests import BaseTestCase
309
310
311-TOKEN = {u'consumer_key': u'xQ7xDAz',
312- u'consumer_secret': u'KzCJWCTNbbntwfyCKKjomJDzlgqxLy',
313- u'token_name': u'test',
314- u'token': u'GkInOfSMGwTXAUoVQwLUoPxElEEUdhsLVNTPhxHJDUIeHCPNEo',
315- u'token_secret': u'qFYImEtlczPbsCnYyuwLoPDlPEnvNcIktZphPQklAWrvyfFMV'}
316-
317-
318-class FakeFailureCredentialsManagementTool(object):
319-
320- """A fake CredentialsManagementTool that fails."""
321-
322- def find_credentials(self):
323- """Return a deferred that never triggers callback."""
324- return defer.succeed({})
325-
326-
327 class FakeController(object):
328
329 """A fake controller for the tests."""
330@@ -165,8 +149,6 @@
331 self.patch(gui, "LocalFoldersPage", FakeLocalFoldersPage)
332 self.patch(qt.preferences, "PreferencesPanel", FakePreferencesPanel)
333 self.patch(qt.folders, "FoldersPanel", FakeFoldersPanel)
334- self.patch(gui, "CredentialsManagementTool",
335- FakeFailureCredentialsManagementTool)
336 super(MainWindowTestCase, self).setUp()
337
338 def test_execute_uninstall_on_licence_cancel(self):
339@@ -566,17 +548,6 @@
340 QtCore.QCoreApplication.instance().processEvents()
341 self.assertEqual(self.ui.result(), self.ui.Rejected)
342
343- def test_license_next(self):
344- """Test what's the license page's nextID."""
345- self.ui.creds_cb("fakecreds")
346- self.assertEqual(self.ui.LICENSE_PAGE.nextId(),
347- self.ui.local_folders_page_id)
348-
349- def test_license_next_default(self):
350- """By default, should be the sign in page."""
351- self.assertEqual(self.ui.LICENSE_PAGE.nextId(),
352- self.ui.SIGNIN_PAGE)
353-
354
355 class FakeSignal(object):
356
357@@ -604,50 +575,9 @@
358 userCancellation = FakeSignal()
359 shown = False
360
361+ def __init__(self, close_callback=None):
362+ pass
363+
364 def show(self):
365 """Fake method."""
366 self.shown = True
367-
368-
369-class FakeFailingCredentialsManagementTool(object):
370-
371- """A fake CredentialsManagementTool that fails."""
372-
373- def find_credentials(self):
374- """Return a deferred that never triggers callback."""
375- return defer.fail(Exception())
376-
377-
378-class CredsFailureMainWindowTestCase(BaseTestCase):
379- """Test the qt main window."""
380-
381- class_ui = gui.MainWindow
382-
383- def setUp(self):
384- """Initialize this test instance."""
385- # Faking each SSO object instead of doing it lower
386- # so we don't rely on any SSO behaviour
387- self.patch(gui, "SetUpAccountController", FakeController)
388- self.patch(gui, "TosController", FakeController)
389- self.patch(gui, "EmailVerificationController", FakeController)
390- self.patch(gui, "CurrentUserController", FakeController)
391- self.patch(gui, "SuccessController", FakeController)
392- self.patch(gui, "ForgottenPasswordController", FakeController)
393- self.patch(gui, "ResetPasswordController", FakeController)
394- self.patch(gui, "AreYouSure", FakeAreYouSure)
395- self.patch(gui, "LoadingOverlay", FakeOverlay)
396- self.patch(gui, "LocalFoldersPage", FakeLocalFoldersPage)
397- self.patch(qt.preferences, "PreferencesPanel", FakePreferencesPanel)
398- self.patch(qt.folders, "FoldersPanel", FakeFoldersPanel)
399- self.patch(gui, "CredentialsManagementTool",
400- FakeFailingCredentialsManagementTool)
401- super(CredsFailureMainWindowTestCase, self).setUp()
402-
403- def test_overlay_hiding(self):
404- """Credential errors should make the overlay hide."""
405- self.assertEqual(self.ui.overlay.hide_counter, 1)
406-
407- def test_critical(self):
408- """Credential errors should display a critical message."""
409- self.assertEqual(self.ui.form_errors_label.text(),
410- "Application will close.\n\nException()")
411
412=== modified file 'ubuntuone_installer/gui/qt/utils/__init__.py'
413--- ubuntuone_installer/gui/qt/utils/__init__.py 2011-08-23 17:27:56 +0000
414+++ ubuntuone_installer/gui/qt/utils/__init__.py 2011-08-29 12:42:23 +0000
415@@ -21,10 +21,12 @@
416
417 import sys
418
419-
420+# pylint: disable=C0103
421 if sys.platform == 'win32':
422 from ubuntuone_installer.gui.qt.utils import windows
423 uninstall_application = windows.uninstall_application
424+ start_control_panel = windows.start_control_panel
425 else:
426 from ubuntuone_installer.gui.qt.utils import linux
427 uninstall_application = linux.uninstall_application
428+ start_control_panel = linux.start_control_panel
429
430=== modified file 'ubuntuone_installer/gui/qt/utils/linux.py'
431--- ubuntuone_installer/gui/qt/utils/linux.py 2011-08-23 17:27:56 +0000
432+++ ubuntuone_installer/gui/qt/utils/linux.py 2011-08-29 12:42:23 +0000
433@@ -18,7 +18,13 @@
434
435 """Utils Functions Linux specific."""
436
437+import subprocess
438
439 def uninstall_application():
440 """Uninstall Ubuntu One."""
441 pass
442+
443+
444+def start_control_panel():
445+ """Start the control panel."""
446+ subprocess.Popen(["ubuntuone-control-panel-qt", ])
447
448=== modified file 'ubuntuone_installer/gui/qt/utils/tests/test_windows.py'
449--- ubuntuone_installer/gui/qt/utils/tests/test_windows.py 2011-08-26 18:41:33 +0000
450+++ ubuntuone_installer/gui/qt/utils/tests/test_windows.py 2011-08-29 12:42:23 +0000
451@@ -54,6 +54,6 @@
452 self.assertTrue(self._called[0][0] is None)
453 self.assertTrue("uninstall.exe" in self._called[0][2])
454 self.assertTrue('runas' == self._called[0][1])
455- self.assertTrue('--mode=qt' == self._called[0][3])
456+ self.assertTrue('--mode qt' == self._called[0][3])
457 self.assertTrue('' == self._called[0][4])
458 self.assertTrue(0 == self._called[0][5])
459
460=== modified file 'ubuntuone_installer/gui/qt/utils/windows.py'
461--- ubuntuone_installer/gui/qt/utils/windows.py 2011-08-26 18:41:33 +0000
462+++ ubuntuone_installer/gui/qt/utils/windows.py 2011-08-29 12:42:23 +0000
463@@ -19,8 +19,9 @@
464 """Utils Functions Windows specific."""
465
466
467+import os
468+import subprocess
469 import sys
470-import os
471
472 import win32api
473
474@@ -36,3 +37,16 @@
475 win32api.ShellExecute(None, 'runas',
476 uninstall_path,
477 '--mode qt', '', 0)
478+
479+
480+def start_control_panel():
481+ """Start the control panel."""
482+ # If we are in windows and "frozen", assume it's in
483+ # the same folder as this .exe
484+ if sys.platform == "win32" and hasattr(sys, "frozen"):
485+ cp_path = os.path.join(os.path.dirname(
486+ os.path.abspath(sys.executable)),
487+ "ubuntuone-control-panel-qt.exe")
488+ else:
489+ cp_path = "ubuntuone-control-panel-qt"
490+ subprocess.Popen([cp_path, ])

Subscribers

People subscribed via source and target branches