Merge lp:~nataliabidart/ubuntuone-control-panel/stable-3-0-update into lp:ubuntuone-control-panel/stable-3-0

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 242
Merged at revision: 242
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/stable-3-0-update
Merge into: lp:ubuntuone-control-panel/stable-3-0
Diff against target: 735 lines (+437/-37)
22 files modified
data/qt/device_remote.ui (+50/-0)
data/qt/ubuntuone.qss (+9/-2)
run-tests (+3/-2)
run-tests.bat (+3/-2)
setup.py (+10/-5)
ubuntuone/controlpanel/dbustests/__init__.py (+1/-1)
ubuntuone/controlpanel/dbustests/test_gui_service.py (+1/-1)
ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py (+1/-1)
ubuntuone/controlpanel/gui/qt/device.py (+23/-7)
ubuntuone/controlpanel/gui/qt/devices.py (+4/-1)
ubuntuone/controlpanel/gui/qt/folders.py (+0/-4)
ubuntuone/controlpanel/gui/qt/tests/test_devices.py (+2/-1)
ubuntuone/controlpanel/gui/qt/tests/test_folders.py (+0/-4)
ubuntuone/controlpanel/tests/__init__.py (+1/-1)
ubuntuone/controlpanel/tests/test_sd_client.py (+1/-1)
ubuntuone/controlpanel/utils/__init__.py (+16/-2)
ubuntuone/controlpanel/utils/tests/__init__.py (+18/-0)
ubuntuone/controlpanel/utils/tests/test_linux.py (+38/-0)
ubuntuone/controlpanel/utils/tests/test_utils.py (+3/-1)
ubuntuone/controlpanel/utils/tests/test_windows.py (+179/-0)
ubuntuone/controlpanel/utils/windows.py (+73/-0)
ubuntuone/controlpanel/web_client/tests/test_txwebclient.py (+1/-1)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/stable-3-0-update
Reviewer Review Type Date Requested Status
Roberto Alsina (community) Approve
Review via email: mp+86296@code.launchpad.net

Commit message

[ Natalia B. Bidart <email address hidden> ]
  - Install all QT packages (LP: #905354).
  - List as python package 'utils' (LP: #898810).
  - Fixed typo on login screen (LP: #890410).

[ Diego Sarmentero <email address hidden> ]
  - Fixed: On the devices tab in u1cp, the icons are misaligned (LP: #856362).
  - Fixed QT UI folder view explore button (LP: #822698).

[ Manuel de la Pena <email address hidden> ]
  - Moved auto-update code from the u1-windows-installer to the control panel.
  - Changed the import from ubuntuone-dev-tools so that we do not use the
    deprecated API.

Description of the change

All green in ubuntu, and windows (tested windows 7).

IRL tested on Ubuntu.

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

Looks good, (light) IRL on Windows

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'data/qt/device_remote.ui'
2--- data/qt/device_remote.ui 1970-01-01 00:00:00 +0000
3+++ data/qt/device_remote.ui 2011-12-19 21:16:23 +0000
4@@ -0,0 +1,50 @@
5+<?xml version="1.0" encoding="UTF-8"?>
6+<ui version="4.0">
7+ <class>Form</class>
8+ <widget class="QWidget" name="Form">
9+ <property name="geometry">
10+ <rect>
11+ <x>0</x>
12+ <y>0</y>
13+ <width>264</width>
14+ <height>45</height>
15+ </rect>
16+ </property>
17+ <property name="windowTitle">
18+ <string notr="true">Form</string>
19+ </property>
20+ <layout class="QHBoxLayout" name="horizontalLayout">
21+ <item>
22+ <widget class="QLabel" name="device_icon_label">
23+ <property name="pixmap">
24+ <pixmap resource="images.qrc">:/computer.png</pixmap>
25+ </property>
26+ </widget>
27+ </item>
28+ <item>
29+ <widget class="QLabel" name="device_name_label">
30+ <property name="text">
31+ <string>Local device</string>
32+ </property>
33+ </widget>
34+ </item>
35+ <item>
36+ <spacer name="horizontalSpacer">
37+ <property name="orientation">
38+ <enum>Qt::Horizontal</enum>
39+ </property>
40+ <property name="sizeHint" stdset="0">
41+ <size>
42+ <width>217</width>
43+ <height>20</height>
44+ </size>
45+ </property>
46+ </spacer>
47+ </item>
48+ </layout>
49+ </widget>
50+ <resources>
51+ <include location="images.qrc"/>
52+ </resources>
53+ <connections/>
54+</ui>
55
56=== modified file 'data/qt/ubuntuone.qss'
57--- data/qt/ubuntuone.qss 2011-09-23 15:05:27 +0000
58+++ data/qt/ubuntuone.qss 2011-12-19 21:16:23 +0000
59@@ -126,11 +126,18 @@
60 }
61
62 QPushButton#explore_folder_button {
63- border: none;
64- background: none;
65+ background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
66+ stop: 0 #fbfbfb, stop: 1.0 #e6e6e6);
67+ height: 15px;
68+ border-radius: 7px;
69+ border-color: #908e8d;
70 color: #595959;
71 padding-left: 10px;
72 padding-right: 10px;
73+ margin-top: 5px;
74+ margin-bottom: 5px;
75+ margin-right: 20px;
76+ margin-left: 20px;
77 }
78
79 QPushButton#twitter_button,
80
81=== modified file 'run-tests'
82--- run-tests 2011-10-05 18:17:47 +0000
83+++ run-tests 2011-12-19 21:16:23 +0000
84@@ -18,6 +18,7 @@
85
86 QT_TESTS_PATH=ubuntuone/controlpanel/gui/qt/tests
87 GTK_TESTS_PATH=ubuntuone/controlpanel/gui/gtk/tests
88+WINDOWS_TESTS=test_windows.py
89
90 set -e
91
92@@ -50,9 +51,9 @@
93 ./setup.py build
94 echo "Running test suite for ""$MODULE"
95 if [ "$USE_QT" -eq 0 ]; then
96- `which xvfb-run` u1trial --ignore-paths $QT_TESTS_PATH "$MODULE"
97+ `which xvfb-run` u1trial --ignore-paths "$QT_TESTS_PATH" -i "$WINDOWS_TESTS" "$MODULE"
98 else
99- `which xvfb-run` u1trial --ignore-paths $GTK_TESTS_PATH --reactor=qt4 --gui "$MODULE"
100+ `which xvfb-run` u1trial --ignore-paths "$GTK_TESTS_PATH" -i "$WINDOWS_TESTS" --reactor=qt4 --gui "$MODULE"
101 fi
102 style_check
103 rm -rf _trial_temp
104
105=== modified file 'run-tests.bat'
106--- run-tests.bat 2011-10-06 20:38:39 +0000
107+++ run-tests.bat 2011-12-19 21:16:23 +0000
108@@ -20,12 +20,13 @@
109
110 SET MODULE="ubuntuone"
111 SET PYTHONEXEPATH="C:\Python27"
112-SET IGNORE_PATHS="ubuntuone\controlpanel\gui\gtk, ubuntuone\controlpanel\dbustests, ubuntuone\controlpanel\web_client\tests\test_libsoup.py"
113+SET IGNORE_PATHS="ubuntuone\controlpanel\gui\gtk, ubuntuone\controlpanel\dbustests"
114+SET IGNORE_MODULES="test_linux.py, test_libsoup.py"
115
116 "%PYTHONEXEPATH%\python.exe" setup.py build
117 ECHO Running tests
118 :: execute the tests with a number of ignored linux only modules
119-"%PYTHONEXEPATH%\python.exe" "%PYTHONEXEPATH%\Scripts\u1trial" --reactor=qt4 --gui -p %IGNORE_PATHS% %MODULE%
120+"%PYTHONEXEPATH%\python.exe" "%PYTHONEXEPATH%\Scripts\u1trial" --reactor=qt4 --gui -p %IGNORE_PATHS% -i %IGNORE_MODULES% %MODULE%
121 :: Clean the build from the setupt.py
122 ECHO Cleaning the generated code before running the style checks...
123 "%PYTHONEXEPATH%\python.exe" setup.py clean
124
125=== modified file 'setup.py'
126--- setup.py 2011-12-01 19:27:00 +0000
127+++ setup.py 2011-12-19 21:16:23 +0000
128@@ -229,18 +229,23 @@
129
130 DistUtilsExtra.auto.setup(
131 name='ubuntuone-control-panel',
132- version='2.99',
133+ version='2.99.0',
134 license='GPL v3',
135 author='Natalia Bidart',
136 author_email='natalia.bidart@canonical.com',
137 description='Ubuntu One Control Panel',
138- long_description='Application to manage an Ubuntu One account. Provides' \
139- ' a DBus service to query/modify all the Ubuntu One bits.',
140+ long_description='Application to manage an Ubuntu One account.',
141 url='https://launchpad.net/ubuntuone-control-panel',
142 packages=[
143- 'ubuntuone', 'ubuntuone.controlpanel', 'ubuntuone.controlpanel.gui',
144- 'ubuntuone.controlpanel.gui.gtk', 'ubuntuone.controlpanel.gui.qt',
145+ 'ubuntuone',
146+ 'ubuntuone.controlpanel',
147+ 'ubuntuone.controlpanel.gui',
148+ 'ubuntuone.controlpanel.gui.gtk',
149+ 'ubuntuone.controlpanel.gui.qt',
150+ 'ubuntuone.controlpanel.gui.qt.main',
151+ 'ubuntuone.controlpanel.gui.qt.ui',
152 'ubuntuone.controlpanel.sd_client',
153+ 'ubuntuone.controlpanel.utils',
154 'ubuntuone.controlpanel.web_client',
155 ],
156 extra_path='ubuntuone-control-panel',
157
158=== modified file 'ubuntuone/controlpanel/dbustests/__init__.py'
159--- ubuntuone/controlpanel/dbustests/__init__.py 2011-10-24 21:48:27 +0000
160+++ ubuntuone/controlpanel/dbustests/__init__.py 2011-12-19 21:16:23 +0000
161@@ -23,7 +23,7 @@
162
163 from twisted.internet import defer
164
165-from ubuntuone.devtools.testcase import DBusTestCase as TestCase
166+from ubuntuone.devtools.testcases.dbus import DBusTestCase as TestCase
167
168 from ubuntuone.controlpanel import dbus_service
169
170
171=== modified file 'ubuntuone/controlpanel/dbustests/test_gui_service.py'
172--- ubuntuone/controlpanel/dbustests/test_gui_service.py 2011-10-24 21:48:27 +0000
173+++ ubuntuone/controlpanel/dbustests/test_gui_service.py 2011-12-19 21:16:23 +0000
174@@ -27,7 +27,7 @@
175 from twisted.internet import defer
176
177 from ubuntuone.controlpanel.gui.gtk import gui
178-from ubuntuone.devtools.testcase import DBusTestCase
179+from ubuntuone.devtools.testcases.dbus import DBusTestCase
180 from twisted.trial.unittest import TestCase
181
182
183
184=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py'
185--- ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py 2011-10-24 21:48:27 +0000
186+++ ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py 2011-12-19 21:16:23 +0000
187@@ -30,7 +30,7 @@
188 )
189 from ubuntuone.controlpanel.tests import TOKEN
190
191-from ubuntuone.devtools.testcase import skipIf
192+from ubuntuone.devtools.testcases import skipIf
193
194 # Attribute 'yyy' defined outside __init__, access to a protected member
195 # pylint: disable=W0201, W0212
196
197=== modified file 'ubuntuone/controlpanel/gui/qt/device.py'
198--- ubuntuone/controlpanel/gui/qt/device.py 2011-09-07 16:56:39 +0000
199+++ ubuntuone/controlpanel/gui/qt/device.py 2011-12-19 21:16:23 +0000
200@@ -29,10 +29,9 @@
201 from ubuntuone.controlpanel.gui import DEVICE_CONFIRM_REMOVE
202 from ubuntuone.controlpanel.gui.qt import (
203 handle_errors,
204- icon_from_name,
205 pixmap_from_name,
206 )
207-from ubuntuone.controlpanel.gui.qt.ui import device_ui
208+from ubuntuone.controlpanel.gui.qt.ui import device_ui, device_remote_ui
209 from ubuntuone.controlpanel.logger import setup_logging
210
211 COMPUTER_ICON = "computer"
212@@ -94,10 +93,27 @@
213 self.removeCanceled.emit()
214
215
216+class DeviceRemoteWidget(QtGui.QWidget):
217+
218+ """Remote Device widget for Devices List."""
219+
220+ def __init__(self, device_info):
221+ super(DeviceRemoteWidget, self).__init__()
222+ self.ui = device_remote_ui.Ui_Form()
223+ self.ui.setupUi(self)
224+
225+ text = device_info["name"]
226+ icon_name = icon_name_from_type(device_info["type"])
227+ pixmap = pixmap_from_name(icon_name)
228+ self.ui.device_icon_label.setPixmap(pixmap)
229+ self.ui.device_name_label.setText(text)
230+
231+ def text(self):
232+ """Return the text displayed in the Widget."""
233+ return self.ui.device_name_label.text()
234+
235+
236 def get_device_for_list_widget(device_info):
237- """Return a QListWidgetItem representing a device with the proper info."""
238- text = device_info["name"]
239- icon_name = icon_name_from_type(device_info["type"])
240- icon = icon_from_name(icon_name)
241- item = QtGui.QListWidgetItem(icon, text)
242+ """Return a DeviceRemoteWidget with device proper info."""
243+ item = DeviceRemoteWidget(device_info)
244 return item
245
246=== modified file 'ubuntuone/controlpanel/gui/qt/devices.py'
247--- ubuntuone/controlpanel/gui/qt/devices.py 2011-09-07 16:56:39 +0000
248+++ ubuntuone/controlpanel/gui/qt/devices.py 2011-12-19 21:16:23 +0000
249@@ -99,5 +99,8 @@
250
251 def create_remote_device(self, device_info):
252 """Add a remote device to the list."""
253- item = device.get_device_for_list_widget(device_info)
254+ widget = device.get_device_for_list_widget(device_info)
255+ item = QtGui.QListWidgetItem()
256+
257 self.ui.list_devices.addItem(item)
258+ self.ui.list_devices.setItemWidget(item, widget)
259
260=== modified file 'ubuntuone/controlpanel/gui/qt/folders.py'
261--- ubuntuone/controlpanel/gui/qt/folders.py 2011-09-12 15:00:24 +0000
262+++ ubuntuone/controlpanel/gui/qt/folders.py 2011-12-19 21:16:23 +0000
263@@ -175,10 +175,6 @@
264 model_index = self.ui.folders.indexFromItem(child, EXPLORE_COL)
265 button = QtGui.QPushButton(parent=self.ui.folders)
266 button.setFlat(True)
267- icon = icon_from_name(FOLDER_ICON_NAME)
268- button.icon_obj = icon # hack!
269- button.setIcon(icon_from_name(FOLDER_ICON_NAME))
270- button.setIconSize(QtCore.QSize(12, 12))
271 button.setText(EXPLORE)
272 button.setObjectName('explore_folder_button')
273 policy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,
274
275=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_devices.py'
276--- ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2011-09-01 21:19:27 +0000
277+++ ubuntuone/controlpanel/gui/qt/tests/test_devices.py 2011-12-19 21:16:23 +0000
278@@ -84,7 +84,8 @@
279 self.assertEqual(self.ui.ui.list_devices.count(),
280 len(remote))
281 for i, remote_device in enumerate(remote):
282- device = self.ui.ui.list_devices.item(i)
283+ item = self.ui.ui.list_devices.item(i)
284+ device = self.ui.ui.list_devices.itemWidget(item)
285 self.assertEqual(device.text(), remote_device['name'])
286
287 def test_process_info_twice(self):
288
289=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_folders.py'
290--- ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2011-09-12 15:00:24 +0000
291+++ ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2011-12-19 21:16:23 +0000
292@@ -171,10 +171,6 @@
293 model_index = folders.indexFromItem(item, gui.EXPLORE_COL)
294 button = folders.indexWidget(model_index)
295 self.assertEqual(button.isFlat(), True)
296- self.assertEqual(button.icon_obj.icon_name,
297- gui.FOLDER_ICON_NAME)
298- self.assertEqual(button.iconSize().width(), 12)
299- self.assertEqual(button.iconSize().height(), 12)
300 self.assertEqual(button.isEnabled(),
301 bool(volume['subscribed']))
302
303
304=== modified file 'ubuntuone/controlpanel/tests/__init__.py'
305--- ubuntuone/controlpanel/tests/__init__.py 2011-10-24 21:48:27 +0000
306+++ ubuntuone/controlpanel/tests/__init__.py 2011-12-19 21:16:23 +0000
307@@ -23,7 +23,7 @@
308
309 from twisted.internet import defer
310
311-from ubuntuone.devtools.testcase import TestCase as BaseTestCase
312+from ubuntuone.devtools.testcases import TestCase as BaseTestCase
313
314 from ubuntuone.controlpanel.backend import (
315 DEVICE_TYPE_COMPUTER, DEVICE_TYPE_PHONE,
316
317=== modified file 'ubuntuone/controlpanel/tests/test_sd_client.py'
318--- ubuntuone/controlpanel/tests/test_sd_client.py 2011-10-24 21:48:27 +0000
319+++ ubuntuone/controlpanel/tests/test_sd_client.py 2011-12-19 21:16:23 +0000
320@@ -24,7 +24,7 @@
321
322 from twisted.internet import defer
323 from twisted.internet.defer import inlineCallbacks, returnValue
324-from ubuntuone.devtools.testcase import skipIfNotOS
325+from ubuntuone.devtools.testcases import skipIfNotOS
326 # No name 'tools' in module 'ubuntuone.platform'
327 # pylint: disable=E0611
328 from ubuntuone.platform import tools
329
330=== added directory 'ubuntuone/controlpanel/utils'
331=== renamed file 'ubuntuone/controlpanel/utils.py' => 'ubuntuone/controlpanel/utils/__init__.py'
332--- ubuntuone/controlpanel/utils.py 2011-06-29 18:10:16 +0000
333+++ ubuntuone/controlpanel/utils/__init__.py 2011-12-19 21:16:23 +0000
334@@ -1,6 +1,5 @@
335 # -*- coding: utf-8 -*-
336
337-# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
338 #
339 # Copyright 2010 Canonical Ltd.
340 #
341@@ -19,6 +18,7 @@
342 """Miscellaneous utilities."""
343
344 import os
345+import sys
346
347 from ubuntuone.controlpanel.logger import setup_logging
348
349@@ -30,6 +30,19 @@
350 ERROR_TYPE = 'error_type'
351 ERROR_MESSAGE = 'error_msg'
352
353+# ignore issues with the name of the method
354+# pylint: disable=C0103
355+
356+# import the platform dependent code.
357+if sys.platform == 'win32':
358+ from ubuntuone.controlpanel.utils import windows
359+ are_updates_present = windows.are_updates_present
360+ perform_update = windows.perform_update
361+else:
362+ are_updates_present = lambda *args, **kwargs: False
363+ perform_update = lambda *args, **kwargs: None
364+# pylint: enable=C0103
365+
366
367 def get_project_dir():
368 """Return the absolute path to this project's data/ dir.
369@@ -38,7 +51,8 @@
370 """
371 module = os.path.dirname(__file__)
372 result = os.path.abspath(os.path.join(module, os.path.pardir,
373- os.path.pardir, DATA_SUFFIX))
374+ os.path.pardir, os.path.pardir,
375+ DATA_SUFFIX))
376 logger.debug('get_project_dir: trying use data dir at %r (exists? %s)',
377 result, os.path.exists(result))
378 if os.path.exists(result):
379
380=== added directory 'ubuntuone/controlpanel/utils/tests'
381=== added file 'ubuntuone/controlpanel/utils/tests/__init__.py'
382--- ubuntuone/controlpanel/utils/tests/__init__.py 1970-01-01 00:00:00 +0000
383+++ ubuntuone/controlpanel/utils/tests/__init__.py 2011-12-19 21:16:23 +0000
384@@ -0,0 +1,18 @@
385+# -*- coding: utf-8 -*-
386+
387+#
388+# Copyright 2010 Canonical Ltd.
389+#
390+# This program is free software: you can redistribute it and/or modify it
391+# under the terms of the GNU General Public License version 3, as published
392+# by the Free Software Foundation.
393+#
394+# This program is distributed in the hope that it will be useful, but
395+# WITHOUT ANY WARRANTY; without even the implied warranties of
396+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
397+# PURPOSE. See the GNU General Public License for more details.
398+#
399+# You should have received a copy of the GNU General Public License along
400+# with this program. If not, see <http://www.gnu.org/licenses/>.
401+
402+"""Test utils."""
403
404=== added file 'ubuntuone/controlpanel/utils/tests/test_linux.py'
405--- ubuntuone/controlpanel/utils/tests/test_linux.py 1970-01-01 00:00:00 +0000
406+++ ubuntuone/controlpanel/utils/tests/test_linux.py 2011-12-19 21:16:23 +0000
407@@ -0,0 +1,38 @@
408+# -*- coding: utf-8 -*-
409+
410+#
411+# Copyright 2011 Canonical Ltd.
412+#
413+# This program is free software: you can redistribute it and/or modify it
414+# under the terms of the GNU General Public License version 3, as published
415+# by the Free Software Foundation.
416+#
417+# This program is distributed in the hope that it will be useful, but
418+# WITHOUT ANY WARRANTY; without even the implied warranties of
419+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
420+# PURPOSE. See the GNU General Public License for more details.
421+#
422+# You should have received a copy of the GNU General Public License along
423+# with this program. If not, see <http://www.gnu.org/licenses/>.
424+
425+"""Test the linux utils functions."""
426+
427+
428+from twisted.internet import defer
429+
430+from ubuntuone.controlpanel import utils
431+from ubuntuone.controlpanel.tests import TestCase
432+
433+
434+class AutoupdaterTestCase(TestCase):
435+ """Test the code that is used for the auto update process."""
436+
437+ @defer.inlineCallbacks
438+ def test_are_updates_present(self):
439+ """We should never have updates."""
440+ are_present = yield utils.are_updates_present(None)
441+ self.assertFalse(are_present)
442+
443+ def test_perform_update(self):
444+ """Test the method that performs the update."""
445+ self.assertEqual(None, utils.perform_update())
446
447=== renamed file 'ubuntuone/controlpanel/tests/test_utils.py' => 'ubuntuone/controlpanel/utils/tests/test_utils.py'
448--- ubuntuone/controlpanel/tests/test_utils.py 2011-10-24 21:48:27 +0000
449+++ ubuntuone/controlpanel/utils/tests/test_utils.py 2011-12-19 21:16:23 +0000
450@@ -73,7 +73,9 @@
451 """The relative path for the data directory is correctly retrieved."""
452 module = utils.os.path.dirname(utils.__file__)
453 rel_data = utils.os.path.join(module, utils.os.path.pardir,
454- utils.os.path.pardir, utils.DATA_SUFFIX)
455+ utils.os.path.pardir,
456+ utils.os.path.pardir,
457+ utils.DATA_SUFFIX)
458 expected_dir = utils.os.path.abspath(rel_data)
459
460 # ensure expected_path exists at os level
461
462=== added file 'ubuntuone/controlpanel/utils/tests/test_windows.py'
463--- ubuntuone/controlpanel/utils/tests/test_windows.py 1970-01-01 00:00:00 +0000
464+++ ubuntuone/controlpanel/utils/tests/test_windows.py 2011-12-19 21:16:23 +0000
465@@ -0,0 +1,179 @@
466+# -*- coding: utf-8 -*-
467+
468+#
469+# Copyright 2011 Canonical Ltd.
470+#
471+# This program is free software: you can redistribute it and/or modify it
472+# under the terms of the GNU General Public License version 3, as published
473+# by the Free Software Foundation.
474+#
475+# This program is distributed in the hope that it will be useful, but
476+# WITHOUT ANY WARRANTY; without even the implied warranties of
477+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
478+# PURPOSE. See the GNU General Public License for more details.
479+#
480+# You should have received a copy of the GNU General Public License along
481+# with this program. If not, see <http://www.gnu.org/licenses/>.
482+
483+"""Test the windows utils functions."""
484+
485+import os
486+
487+from twisted.internet import defer
488+
489+from ubuntuone.controlpanel import utils
490+from ubuntuone.controlpanel.tests import TestCase
491+
492+# let me use protected methods
493+# pylint: disable=W0212
494+
495+
496+class AutoupdaterTestCase(TestCase):
497+ """Test the code that is used for the auto update process."""
498+
499+ @defer.inlineCallbacks
500+ def setUp(self):
501+ """Prepare for the diff tests."""
502+ yield super(AutoupdaterTestCase, self).setUp()
503+ self.auto_update_path = r'path\to\exe'
504+ self.return_from_call = 0
505+ self.command = None
506+ self.args = []
507+
508+ def fake_execute_process(command, args=None, path=None):
509+ """Fake async process execution."""
510+ self.command = command
511+ self.args = args
512+ return self.return_from_call
513+
514+ self.patch(utils.windows, 'getProcessValue', fake_execute_process)
515+ self.patch(utils.windows, '_get_update_path',
516+ lambda: self.auto_update_path)
517+
518+ @defer.inlineCallbacks
519+ def test_are_updates_present_true(self):
520+ """Test when updates are present."""
521+ # the idea is simple, set the value to be returned from
522+ # the fake call, assert that we get true and also that
523+ # we did use the correct parameters.
524+ self.return_from_call = 0
525+ are_present = yield utils.are_updates_present()
526+ self.assertTrue(are_present, 'Updates should be present.')
527+ # lets assert that we did use the correct args
528+ expected_args = ('--mode', 'unattended')
529+ self.assertEqual(expected_args, self.args)
530+ self.assertEqual(self.command, self.auto_update_path)
531+
532+ @defer.inlineCallbacks
533+ def test_are_updates_present_false(self):
534+ """Test when updates are not present."""
535+ # similar to test_are_updates_present_true but with diff retcode
536+ self.return_from_call = 40
537+ are_present = yield utils.are_updates_present()
538+ self.assertFalse(are_present, 'Updates should NOT be present.')
539+ # lets assert that we did use the correct args
540+ expected_args = ('--mode', 'unattended')
541+ self.assertEqual(expected_args, self.args)
542+ self.assertEqual(self.command, self.auto_update_path)
543+
544+ def test_perform_update(self):
545+ """Test the method that performs the update."""
546+ self.patch(utils.windows.win32api, 'ShellExecute', self._set_called)
547+ utils.perform_update()
548+ self.assertIn(self.auto_update_path, self._called[0][2])
549+ self.assertEqual('runas', self._called[0][1])
550+ self.assertEqual('--unattendedmodeui none', self._called[0][3])
551+ self.assertEqual('', self._called[0][4])
552+ self.assertEqual(0, self._called[0][5])
553+
554+
555+class GetPathTestCase(TestCase):
556+ """Test the code that is used for the auto update process."""
557+
558+ @defer.inlineCallbacks
559+ def setUp(self):
560+ """Set the different tests."""
561+ yield super(GetPathTestCase, self).setUp()
562+ self.called = []
563+ self.exec_path = 'path/to/current/exe'
564+ self.exists = True
565+
566+ def fake_abspath(path):
567+ """Fake os.path.abspath."""
568+ self.called.append('os.path.abspath')
569+ return path
570+
571+ def fake_dirname(path):
572+ """Fake os.path.dirname."""
573+ self.called.append('os.path.dirname')
574+ return path
575+
576+ def fake_exists(path):
577+ """Fake os.path.exists."""
578+ self.called.append('os.path.exists')
579+ return self.exists
580+
581+ # patch the os.path functions used
582+ self.patch(utils.windows.os.path, 'abspath', fake_abspath)
583+ self.patch(utils.windows.os.path, 'dirname', fake_dirname)
584+ self.patch(utils.windows.os.path, 'exists', fake_exists)
585+
586+ def _delete_frozen_state(self):
587+ """Delete the frozen state."""
588+ del utils.windows.sys.frozen
589+ del utils.windows.sys.executable
590+
591+ def test_get_auto_update_path_frozen(self):
592+ """Test the method used to get the autoupdate."""
593+ # patch the diff parts of sys so that we get fake paths
594+ is_frozen = hasattr(utils.windows.sys, 'frozen')
595+ if not is_frozen:
596+ utils.windows.sys.frozen = True
597+ utils.windows.sys.executable = self.exec_path
598+ self.addCleanup(self._delete_frozen_state)
599+
600+ # called method and assert that we have the correct result
601+ path = utils.windows._get_update_path()
602+ self.assertEqual(os.path.join(self.exec_path,
603+ utils.windows.AUTOUPDATE_EXE_NAME), path)
604+ self.assertTrue('os.path.abspath' in self.called)
605+ self.assertTrue('os.path.dirname' in self.called)
606+ self.assertTrue('os.path.exists' in self.called)
607+
608+ def _reset_frozen_state(self, old_frozen, old_exec_path):
609+ """Reset the frozen state."""
610+ utils.windows.sys.frozen = old_frozen
611+ utils.windows.sys.executable = old_exec_path
612+
613+ def _reset__file__(self, path):
614+ """Reset the value of __file__."""
615+ utils.windows.__file__ = path
616+
617+ def test_get_auto_update_path_not_frozen(self):
618+ """Test the method used to get the autoupdate."""
619+ is_frozen = hasattr(utils.windows.sys, 'frozen')
620+ if is_frozen:
621+ old_frozen = utils.windows.sys.frozen
622+ old_exec_path = utils.windows.sys.executable
623+ del utils.windows.sys.frozen
624+ del utils.windows.sys.executable
625+ self.addCleanup(self._reset_frozen_state, old_frozen,
626+ old_exec_path)
627+ # set a fake __file__ for the module
628+ old_file = utils.windows.__file__
629+ utils.windows.__file__ = self.exec_path
630+ self.addCleanup(self._reset__file__, old_file)
631+
632+ path = utils.windows._get_update_path()
633+ self.assertEqual(os.path.join(self.exec_path,
634+ utils.windows.AUTOUPDATE_EXE_NAME), path)
635+ self.assertEqual(2, self.called.count('os.path.dirname'))
636+ self.assertTrue('os.path.exists' in self.called)
637+
638+ def test_get_auto_update_path_not_present(self):
639+ """Test the method used to get the autoupdate."""
640+ self.exists = False
641+
642+ # called method and assert that we have the correct result
643+ path = utils.windows._get_update_path()
644+ self.assertEqual(None, path)
645
646=== added file 'ubuntuone/controlpanel/utils/windows.py'
647--- ubuntuone/controlpanel/utils/windows.py 1970-01-01 00:00:00 +0000
648+++ ubuntuone/controlpanel/utils/windows.py 2011-12-19 21:16:23 +0000
649@@ -0,0 +1,73 @@
650+# -*- coding: utf-8 -*-
651+
652+#
653+# Copyright 2011 Canonical Ltd.
654+#
655+# This program is free software: you can redistribute it and/or modify it
656+# under the terms of the GNU General Public License version 3, as published
657+# by the Free Software Foundation.
658+#
659+# This program is distributed in the hope that it will be useful, but
660+# WITHOUT ANY WARRANTY; without even the implied warranties of
661+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
662+# PURPOSE. See the GNU General Public License for more details.
663+#
664+# You should have received a copy of the GNU General Public License along
665+# with this program. If not, see <http://www.gnu.org/licenses/>.
666+
667+"""Autoupdate functions for windows."""
668+
669+import os
670+import sys
671+
672+# Avoid pylint error on Linux
673+# pylint: disable=F0401
674+import win32api
675+# pylint: enable=F0401
676+
677+from twisted.internet import defer
678+from twisted.internet.utils import getProcessValue
679+
680+from ubuntuone.controlpanel.logger import setup_logging
681+
682+logger = setup_logging('utils')
683+AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe'
684+
685+
686+def _get_update_path():
687+ """Return the path in which the autoupdate command is found."""
688+ if hasattr(sys, 'frozen'):
689+ exec_path = os.path.abspath(sys.executable)
690+ else:
691+ exec_path = os.path.dirname(__file__)
692+ folder = os.path.dirname(exec_path)
693+ update_path = os.path.join(folder, AUTOUPDATE_EXE_NAME)
694+ if os.path.exists(update_path):
695+ return update_path
696+ return None
697+
698+
699+@defer.inlineCallbacks
700+def are_updates_present():
701+ """Return if there are updates for Ubuntu One."""
702+ result = False
703+ retcode = None
704+ update_path = _get_update_path()
705+ if update_path is not None:
706+ # If there is an update present we will get 0, non-zero otherwise
707+ retcode = yield getProcessValue(update_path, args=('--mode',
708+ 'unattended'), path=os.path.dirname(update_path))
709+ result = retcode == 0
710+ logger.debug('are_updates_present: update path: %r, return code: %r,'
711+ ' result: %r', update_path, retcode, result)
712+ defer.returnValue(result)
713+
714+
715+def perform_update():
716+ """Spawn the autoupdate process and call the stop function."""
717+ update_path = _get_update_path()
718+ if update_path is not None:
719+ # lets call the updater with the commands that are required,
720+ win32api.ShellExecute(None, 'runas',
721+ update_path,
722+ '--unattendedmodeui none', '', 0)
723
724=== modified file 'ubuntuone/controlpanel/web_client/tests/test_txwebclient.py'
725--- ubuntuone/controlpanel/web_client/tests/test_txwebclient.py 2011-10-24 21:48:27 +0000
726+++ ubuntuone/controlpanel/web_client/tests/test_txwebclient.py 2011-12-19 21:16:23 +0000
727@@ -24,7 +24,7 @@
728 from twisted.internet import defer, reactor
729 from twisted.internet.defer import inlineCallbacks
730 from twisted.web import server, resource
731-from ubuntuone.devtools.testcase import skipIfOS
732+from ubuntuone.devtools.testcases import skipIfOS
733
734 from ubuntuone.controlpanel.web_client import txwebclient
735 from ubuntuone.controlpanel.tests import TestCase

Subscribers

People subscribed via source and target branches