Merge lp:~dobey/ubuntuone-control-panel/update-from-trunk into lp:ubuntuone-control-panel/stable-3-0

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 259
Merged at revision: 259
Proposed branch: lp:~dobey/ubuntuone-control-panel/update-from-trunk
Merge into: lp:ubuntuone-control-panel/stable-3-0
Diff against target: 296 lines (+134/-8)
8 files modified
ubuntuone/controlpanel/gui/__init__.py (+4/-0)
ubuntuone/controlpanel/gui/qt/controlpanel.py (+1/-0)
ubuntuone/controlpanel/gui/qt/gui.py (+26/-2)
ubuntuone/controlpanel/gui/qt/loadingoverlay.py (+1/-1)
ubuntuone/controlpanel/gui/qt/tests/__init__.py (+7/-0)
ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py (+2/-0)
ubuntuone/controlpanel/gui/qt/tests/test_gui.py (+76/-5)
ubuntuone/controlpanel/gui/qt/tests/test_start.py (+17/-0)
To merge this branch: bzr merge lp:~dobey/ubuntuone-control-panel/update-from-trunk
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Review via email: mp+101470@code.launchpad.net

Commit message

[Diego Sarmentero]

  - Restarting the wizard on current device removed.

[Natalia Bidart]

  - Check for updates when the main window is shown. On linux, this is a no-op.
    On windows, this will check for new versions of the software and will
    prompt the user for confirmation to install updates.
  - Make the LOADING_OVERLAY_MARKUP use a smaller font.

To post a comment you must log in.
Revision history for this message
Roberto Alsina (ralsina) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ubuntuone/controlpanel/gui/__init__.py'
2--- ubuntuone/controlpanel/gui/__init__.py 2012-03-29 16:56:35 +0000
3+++ ubuntuone/controlpanel/gui/__init__.py 2012-04-11 01:13:24 +0000
4@@ -247,6 +247,10 @@
5 VALUE_ERROR = _('Value could not be retrieved.')
6 UNKNOWN_ERROR = _('Unknown error')
7 USAGE_LABEL = _('%(used)s of %(total)s')
8+# TODO: mark the following strings translatable after precise is released
9+UPDATE_TITLE = APP_NAME
10+UPDATE_SOFTWARE = ('There is a new update available.'
11+ ' Would you like to install it?')
12 QUIT_LABEL = _('Quit Ubuntu One')
13
14 # pylint: enable=E0602
15
16=== modified file 'ubuntuone/controlpanel/gui/qt/controlpanel.py'
17--- ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-30 17:34:33 +0000
18+++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-04-11 01:13:24 +0000
19@@ -93,6 +93,7 @@
20 @log_call(logger.debug)
21 def on_credentials_not_found(self):
22 """Credentials are not found or were removed."""
23+ self.ui.wizard.restart()
24 self.ui.switcher.setCurrentWidget(self.ui.wizard)
25 self.is_processing = False
26
27
28=== modified file 'ubuntuone/controlpanel/gui/qt/gui.py'
29--- ubuntuone/controlpanel/gui/qt/gui.py 2012-03-29 19:05:02 +0000
30+++ ubuntuone/controlpanel/gui/qt/gui.py 2012-04-11 01:13:24 +0000
31@@ -18,9 +18,13 @@
32
33 from PyQt4 import QtGui, QtCore
34
35+from twisted.internet import defer
36+
37+from ubuntuone.controlpanel import utils
38+from ubuntuone.controlpanel.logger import setup_logging
39+from ubuntuone.controlpanel.gui import UPDATE_TITLE, UPDATE_SOFTWARE
40 from ubuntuone.controlpanel.gui.qt.systray import TrayIcon
41 from ubuntuone.controlpanel.gui.qt.ui import mainwindow_ui
42-from ubuntuone.controlpanel.utils import add_to_autostart
43
44 # pylint: disable=E0611
45 try:
46@@ -30,6 +34,8 @@
47 USE_LIBUNITY = False
48 # pylint: enable=E0611
49
50+logger = setup_logging('qt.gui')
51+
52 U1_DOTDESKTOP = "ubuntuone-installer.desktop"
53
54
55@@ -49,7 +55,7 @@
56 self.installer = installer
57 if installer:
58 self.ui.control_panel.start_from_license()
59- add_to_autostart()
60+ utils.add_to_autostart()
61 if USE_LIBUNITY:
62 self.entry = Unity.LauncherEntry.get_for_desktop_id(U1_DOTDESKTOP)
63 else:
64@@ -87,6 +93,23 @@
65
66 # pylint: enable=C0103
67
68+ @defer.inlineCallbacks
69+ def check_updates(self):
70+ """Offer the user to update if there are updates available."""
71+ logger.debug('Checking for updates.')
72+ are_present = yield utils.are_updates_present()
73+ logger.info('Updates available? %r', are_present)
74+ if are_present:
75+ buttons = QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
76+ result = QtGui.QMessageBox.question(self, UPDATE_TITLE,
77+ UPDATE_SOFTWARE,
78+ buttons, QtGui.QMessageBox.Yes)
79+ if result == QtGui.QMessageBox.Yes:
80+ logger.info('Performing auto-update.')
81+ utils.perform_update()
82+ else:
83+ logger.info('User do not want to update.')
84+
85
86 def start(close_callback, minimized=False, with_icon=False, installer=False):
87 """Show the UI elements."""
88@@ -102,6 +125,7 @@
89 QtCore.Qt.LeftToRight, QtCore.Qt.AlignCenter,
90 window.size(), app.desktop().availableGeometry())
91 window.setGeometry(style)
92+ window.check_updates()
93 window.show()
94 else:
95 window = None
96
97=== modified file 'ubuntuone/controlpanel/gui/qt/loadingoverlay.py'
98--- ubuntuone/controlpanel/gui/qt/loadingoverlay.py 2012-03-14 20:01:00 +0000
99+++ ubuntuone/controlpanel/gui/qt/loadingoverlay.py 2012-04-11 01:13:24 +0000
100@@ -23,7 +23,7 @@
101 from ubuntuone.controlpanel.gui import LOADING_OVERLAY
102 from ubuntuone.controlpanel.gui.qt.ui import loadingoverlay_ui
103
104-LOADING_OVERLAY_MARKUP = u'<span style="font-size:xx-large;">{0}</span>'
105+LOADING_OVERLAY_MARKUP = u'<span style="font-size:x-large;">{0}</span>'
106
107
108 class LoadingOverlay(QtGui.QFrame):
109
110=== modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py'
111--- ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-03-28 12:06:28 +0000
112+++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2012-04-11 01:13:24 +0000
113@@ -210,6 +210,13 @@
114 cls.kwargs = kw
115 return cls.response
116
117+ @classmethod
118+ def question(cls, *a, **kw):
119+ """Simulate a question message."""
120+ cls.args = a
121+ cls.kwargs = kw
122+ return cls.response
123+
124 # Invalid name "setDetailedText", "setDefaultButton"
125 # pylint: disable=C0103
126
127
128=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py'
129--- ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-03-26 21:00:47 +0000
130+++ ubuntuone/controlpanel/gui/qt/tests/test_controlpanel.py 2012-04-11 01:13:24 +0000
131@@ -68,9 +68,11 @@
132
133 def test_on_credentials_not_found(self):
134 """The wizard panel is shown."""
135+ self.patch(self.ui.ui.wizard, 'restart', self._set_called)
136 self.ui.on_credentials_found()
137 self.ui.on_credentials_not_found()
138 self.assertIs(self.ui.ui.switcher.currentWidget(), self.ui.ui.wizard)
139+ self.assertEqual(self._called, ((), {}))
140
141 @defer.inlineCallbacks
142 def test_on_credentials_found_called(self):
143
144=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_gui.py'
145--- ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-03-26 13:30:07 +0000
146+++ ubuntuone/controlpanel/gui/qt/tests/test_gui.py 2012-04-11 01:13:24 +0000
147@@ -1,8 +1,6 @@
148 # -*- coding: utf-8 -*-
149-
150-# Authors: Alejandro J. Cura <alecu@canonical.com>
151 #
152-# Copyright 2011 Canonical Ltd.
153+# Copyright 2011-2012 Canonical Ltd.
154 #
155 # This program is free software: you can redistribute it and/or modify it
156 # under the terms of the GNU General Public License version 3, as published
157@@ -21,7 +19,7 @@
158 from twisted.internet import defer
159
160 from ubuntuone.controlpanel.gui.qt import gui
161-from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
162+from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase, FakedDialog
163
164
165 class FakeEntry(object):
166@@ -119,13 +117,86 @@
167 self.assertEqual(entry.called, (('urgent', "foo"), {}))
168
169
170+class CheckUpdatesNoUpdatesTestCase(MainWindowTestCase):
171+ """Test the check_updates method when there are no updates."""
172+
173+ updates_available = False
174+
175+ @defer.inlineCallbacks
176+ def setUp(self):
177+ """Set the different tests."""
178+ yield super(CheckUpdatesNoUpdatesTestCase, self).setUp()
179+ self.patch(gui.utils, 'are_updates_present',
180+ lambda: defer.succeed(self.updates_available))
181+ self.patch(gui.utils, 'perform_update',
182+ lambda: defer.fail(ValueError()))
183+
184+ @defer.inlineCallbacks
185+ def test_update_confirmation_dialog(self):
186+ """The confirmation dialog is not shown."""
187+ yield self.ui.check_updates()
188+ self.assertEqual(None, FakedDialog.args)
189+ self.assertEqual(None, FakedDialog.kwargs)
190+
191+ @defer.inlineCallbacks
192+ def test_perform_update(self):
193+ """The perform_update method is not called."""
194+ yield self.ui.check_updates()
195+ self.assertFalse(self._called)
196+
197+
198+class CheckUpdatesUserSaysNoTestCase(CheckUpdatesNoUpdatesTestCase):
199+ """Test check_updates when there are updates and user rejects them."""
200+
201+ updates_available = True
202+ user_response = gui.QtGui.QMessageBox.No
203+
204+ @defer.inlineCallbacks
205+ def setUp(self):
206+ """Set the different tests."""
207+ yield super(CheckUpdatesUserSaysNoTestCase, self).setUp()
208+ self.patch(FakedDialog, 'response', self.user_response)
209+
210+ @defer.inlineCallbacks
211+ def test_update_confirmation_dialog(self):
212+ """The confirmation dialog is shown with correct params."""
213+ yield self.ui.check_updates()
214+ args = (self.ui, gui.UPDATE_TITLE, gui.UPDATE_SOFTWARE,
215+ gui.QtGui.QMessageBox.Yes | gui.QtGui.QMessageBox.No,
216+ gui.QtGui.QMessageBox.Yes)
217+ self.assertEqual(args, FakedDialog.args)
218+ self.assertEqual({}, FakedDialog.kwargs)
219+
220+
221+class CheckUpdatesUserSaysYesTestCase(CheckUpdatesUserSaysNoTestCase):
222+ """Test check_updates when there are updates and user accepts them."""
223+
224+ user_response = gui.QtGui.QMessageBox.Yes
225+
226+ @defer.inlineCallbacks
227+ def setUp(self):
228+ """Set the different tests."""
229+ self.updated = defer.Deferred()
230+ yield super(CheckUpdatesUserSaysYesTestCase, self).setUp()
231+ self.patch(gui.utils, 'perform_update',
232+ lambda *a, **kw: self.updated.callback((a, kw)))
233+
234+ @defer.inlineCallbacks
235+ def test_perform_update(self):
236+ """The perform_update method is called."""
237+ yield self.ui.check_updates()
238+ result = yield self.updated # perform_update will fire this deferred
239+
240+ self.assertEqual(result, ((), {}))
241+
242+
243 class AutoStartTestCase(MainWindowTestCase):
244 """Test the add_to_autostart call."""
245
246 @defer.inlineCallbacks
247 def setUp(self):
248 # Be sure to patch add_to_autostart *before* class_ui creation occurs.
249- self.patch(gui, "add_to_autostart", self._set_called)
250+ self.patch(gui.utils, "add_to_autostart", self._set_called)
251 yield super(AutoStartTestCase, self).setUp()
252
253 def test_add_to_autostart(self):
254
255=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_start.py'
256--- ubuntuone/controlpanel/gui/qt/tests/test_start.py 2012-03-20 19:13:28 +0000
257+++ ubuntuone/controlpanel/gui/qt/tests/test_start.py 2012-04-11 01:13:24 +0000
258@@ -34,6 +34,7 @@
259
260 def __init__(self):
261 self.args = []
262+ self.updates_checked = defer.Deferred()
263
264 def __call__(self, *args, **kwargs):
265 self.args.append((args, kwargs))
266@@ -50,10 +51,17 @@
267 """Save the new geometry."""
268 self.style = style
269
270+ def check_updates(self):
271+ """Fake the check updates call."""
272+ self.updates_checked.callback(None)
273+ return self.updates_checked
274+
275
276 class StartTestCase(TestCase):
277 """Test the qt control panel."""
278
279+ timeout = 2
280+
281 @defer.inlineCallbacks
282 def setUp(self):
283 yield super(StartTestCase, self).setUp()
284@@ -106,3 +114,12 @@
285 gui.QtCore.Qt.AlignCenter, self.main_window.size(),
286 app.desktop().availableGeometry())
287 self.assertEqual(self.main_window.style, expected)
288+
289+ @defer.inlineCallbacks
290+ def test_updates_are_checked(self):
291+ """When creating the window, updates are checked."""
292+ gui.start(close_callback=self.close_cb)
293+
294+ # a timeout in this test means that the check_updates method
295+ # was not called
296+ yield self.main_window.updates_checked

Subscribers

People subscribed via source and target branches

to all changes: