Merge lp:~nataliabidart/ubuntuone-control-panel/uninstall into lp:ubuntuone-control-panel
- uninstall
- Merge into trunk
Proposed by
Natalia Bidart
Status: | Merged |
---|---|
Approved by: | Natalia Bidart |
Approved revision: | 310 |
Merged at revision: | 307 |
Proposed branch: | lp:~nataliabidart/ubuntuone-control-panel/uninstall |
Merge into: | lp:ubuntuone-control-panel |
Diff against target: |
475 lines (+174/-122) 7 files modified
ubuntuone/controlpanel/gui/qt/controlpanel.py (+3/-4) ubuntuone/controlpanel/gui/qt/gui.py (+1/-2) ubuntuone/controlpanel/gui/qt/tests/test_wizard.py (+12/-1) ubuntuone/controlpanel/gui/qt/wizard.py (+4/-8) ubuntuone/controlpanel/utils/__init__.py (+8/-4) ubuntuone/controlpanel/utils/tests/test_windows.py (+103/-69) ubuntuone/controlpanel/utils/windows.py (+43/-34) |
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-control-panel/uninstall |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Manuel de la Peña (community) | Approve | ||
Brian Curtin (community) | Approve | ||
Review via email: mp+100012@code.launchpad.net |
Commit message
- When user rejects the License, also uninstall the application (LP: #968327).
Description of the change
To post a comment you must log in.
- 307. By Natalia Bidart
-
Merged trunk in.
- 308. By Natalia Bidart
-
Merged trunk in.
- 309. By Natalia Bidart
-
- No more runas as parameter to shellexecute.
- 310. By Natalia Bidart
-
Restoring the 'runas' param for autoupdate.
Revision history for this message
Manuel de la Peña (mandel) wrote : | # |
Everything looks good from spain.
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/qt/controlpanel.py' | |||
2 | --- ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-21 19:17:21 +0000 | |||
3 | +++ ubuntuone/controlpanel/gui/qt/controlpanel.py 2012-03-30 17:37:31 +0000 | |||
4 | @@ -1,5 +1,5 @@ | |||
5 | 1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- |
7 | 2 | 2 | # | |
8 | 3 | # Copyright 2012 Canonical Ltd. | 3 | # Copyright 2012 Canonical Ltd. |
9 | 4 | # | 4 | # |
10 | 5 | # This program is free software: you can redistribute it and/or modify it | 5 | # This program is free software: you can redistribute it and/or modify it |
11 | @@ -174,7 +174,6 @@ | |||
12 | 174 | @log_call(logger.info) | 174 | @log_call(logger.info) |
13 | 175 | def start_from_license(self): | 175 | def start_from_license(self): |
14 | 176 | """Use the license page as first page.""" | 176 | """Use the license page as first page.""" |
18 | 177 | # license | 177 | license_id = self.ui.wizard.pages[self.ui.wizard.license_page] |
19 | 178 | self.ui.wizard.setStartId(self.ui.wizard.pages[ | 178 | self.ui.wizard.setStartId(license_id) |
17 | 179 | self.ui.wizard.license_page]) | ||
20 | 180 | self.ui.wizard.restart() | 179 | self.ui.wizard.restart() |
21 | 181 | 180 | ||
22 | === modified file 'ubuntuone/controlpanel/gui/qt/gui.py' | |||
23 | --- ubuntuone/controlpanel/gui/qt/gui.py 2012-03-26 13:23:57 +0000 | |||
24 | +++ ubuntuone/controlpanel/gui/qt/gui.py 2012-03-30 17:37:31 +0000 | |||
25 | @@ -43,8 +43,7 @@ | |||
26 | 43 | self.ui.setupUi(self) | 43 | self.ui.setupUi(self) |
27 | 44 | self.close_callback = close_callback | 44 | self.close_callback = close_callback |
28 | 45 | self._setup() | 45 | self._setup() |
31 | 46 | self.quit_action = QtGui.QAction(self, | 46 | self.quit_action = QtGui.QAction(self, triggered=self.close) |
30 | 47 | triggered=self.close) | ||
32 | 48 | self.quit_action.setShortcuts(["Ctrl+q", "Ctrl+w"]) | 47 | self.quit_action.setShortcuts(["Ctrl+q", "Ctrl+w"]) |
33 | 49 | self.addAction(self.quit_action) | 48 | self.addAction(self.quit_action) |
34 | 50 | self.installer = installer | 49 | self.installer = installer |
35 | 51 | 50 | ||
36 | === modified file 'ubuntuone/controlpanel/gui/qt/tests/test_wizard.py' | |||
37 | --- ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-26 21:00:47 +0000 | |||
38 | +++ ubuntuone/controlpanel/gui/qt/tests/test_wizard.py 2012-03-30 17:37:31 +0000 | |||
39 | @@ -157,6 +157,7 @@ | |||
40 | 157 | @defer.inlineCallbacks | 157 | @defer.inlineCallbacks |
41 | 158 | def setUp(self): | 158 | def setUp(self): |
42 | 159 | yield super(UbuntuOneWizardTestCase, self).setUp() | 159 | yield super(UbuntuOneWizardTestCase, self).setUp() |
43 | 160 | self.patch(gui.utils, 'uninstall_application', self.fail) | ||
44 | 160 | self.patch(self.ui.confirm_dialog, 'exec_', | 161 | self.patch(self.ui.confirm_dialog, 'exec_', |
45 | 161 | lambda: self.confirm_response) | 162 | lambda: self.confirm_response) |
46 | 162 | 163 | ||
47 | @@ -260,7 +261,7 @@ | |||
48 | 260 | button.click() | 261 | button.click() |
49 | 261 | 262 | ||
50 | 262 | self.assertEqual(self._called, (signal_args, {}), | 263 | self.assertEqual(self._called, (signal_args, {}), |
52 | 263 | msg % (name, signal, signal_args)) | 264 | msg % (name, signal, signal_args)) |
53 | 264 | self._called = False | 265 | self._called = False |
54 | 265 | 266 | ||
55 | 266 | def test_done_rejected(self): | 267 | def test_done_rejected(self): |
56 | @@ -336,6 +337,16 @@ | |||
57 | 336 | page_name = 'license' | 337 | page_name = 'license' |
58 | 337 | stage_name = 'install' | 338 | stage_name = 'install' |
59 | 338 | 339 | ||
60 | 340 | @defer.inlineCallbacks | ||
61 | 341 | def setUp(self): | ||
62 | 342 | yield super(UbuntuOneWizardLicensePage, self).setUp() | ||
63 | 343 | self.patch(gui.utils, 'uninstall_application', self._set_called) | ||
64 | 344 | |||
65 | 345 | def test_done_rejected(self): | ||
66 | 346 | """When the wizard is closed on the final page, emit rejected.""" | ||
67 | 347 | super(UbuntuOneWizardLicensePage, self).test_done_rejected() | ||
68 | 348 | self.assertEqual(self._called, ((), {})) | ||
69 | 349 | |||
70 | 339 | 350 | ||
71 | 340 | class UbuntuOneWizardLoginTestCase(UbuntuOneWizardTestCase): | 351 | class UbuntuOneWizardLoginTestCase(UbuntuOneWizardTestCase): |
72 | 341 | """Test the login through the wizard.""" | 352 | """Test the login through the wizard.""" |
73 | 342 | 353 | ||
74 | === modified file 'ubuntuone/controlpanel/gui/qt/wizard.py' | |||
75 | --- ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-26 20:15:58 +0000 | |||
76 | +++ ubuntuone/controlpanel/gui/qt/wizard.py 2012-03-30 17:37:31 +0000 | |||
77 | @@ -23,7 +23,7 @@ | |||
78 | 23 | from ubuntu_sso.qt.sso_wizard_page import BaseWizardPage | 23 | from ubuntu_sso.qt.sso_wizard_page import BaseWizardPage |
79 | 24 | from ubuntu_sso.utils.ui import CLOSE_AND_SETUP_LATER | 24 | from ubuntu_sso.utils.ui import CLOSE_AND_SETUP_LATER |
80 | 25 | 25 | ||
82 | 26 | from ubuntuone.controlpanel import cache | 26 | from ubuntuone.controlpanel import cache, utils |
83 | 27 | from ubuntuone.controlpanel.logger import log_call, setup_logging | 27 | from ubuntuone.controlpanel.logger import log_call, setup_logging |
84 | 28 | from ubuntuone.controlpanel.gui import ( | 28 | from ubuntuone.controlpanel.gui import ( |
85 | 29 | APP_NAME, | 29 | APP_NAME, |
86 | @@ -342,13 +342,9 @@ | |||
87 | 342 | response = self.confirm_dialog.exec_() | 342 | response = self.confirm_dialog.exec_() |
88 | 343 | if response == QtGui.QDialog.Accepted: | 343 | if response == QtGui.QDialog.Accepted: |
89 | 344 | logger.warning('UbuntuOneWizard: user canceled setup.') | 344 | logger.warning('UbuntuOneWizard: user canceled setup.') |
97 | 345 | self.rejected.emit() | 345 | if self.currentId() == self.pages[self.license_page]: |
98 | 346 | elif (self.currentId() == self.pages[self.license_page]): | 346 | logger.warning('UbuntuOneWizard: user wants to uninstall.') |
99 | 347 | response = self.confirm_dialog.exec_() | 347 | utils.uninstall_application() |
93 | 348 | if response == QtGui.QDialog.Accepted: | ||
94 | 349 | logger.warning('UbuntuOneWizard: user wants to uninstall.') | ||
95 | 350 | # TODO: needs implementation in this project | ||
96 | 351 | ##qt.utils.uninstall_application() | ||
100 | 352 | self.rejected.emit() | 348 | self.rejected.emit() |
101 | 353 | else: | 349 | else: |
102 | 354 | super(UbuntuOneWizard, self).done(result) | 350 | super(UbuntuOneWizard, self).done(result) |
103 | 355 | 351 | ||
104 | === modified file 'ubuntuone/controlpanel/utils/__init__.py' | |||
105 | --- ubuntuone/controlpanel/utils/__init__.py 2012-03-22 23:28:19 +0000 | |||
106 | +++ ubuntuone/controlpanel/utils/__init__.py 2012-03-30 17:37:31 +0000 | |||
107 | @@ -32,19 +32,23 @@ | |||
108 | 32 | # ignore issues with the name of the method | 32 | # ignore issues with the name of the method |
109 | 33 | # pylint: disable=C0103 | 33 | # pylint: disable=C0103 |
110 | 34 | 34 | ||
111 | 35 | no_op = lambda *args, **kwargs: None | ||
112 | 36 | |||
113 | 35 | # import the platform dependent code. | 37 | # import the platform dependent code. |
114 | 36 | if sys.platform == 'win32': | 38 | if sys.platform == 'win32': |
115 | 37 | from ubuntuone.controlpanel.utils import windows | 39 | from ubuntuone.controlpanel.utils import windows |
116 | 40 | add_to_autostart = windows.add_to_autostart | ||
117 | 38 | are_updates_present = windows.are_updates_present | 41 | are_updates_present = windows.are_updates_present |
118 | 39 | default_folders = windows.default_folders | 42 | default_folders = windows.default_folders |
119 | 40 | perform_update = windows.perform_update | 43 | perform_update = windows.perform_update |
121 | 41 | add_to_autostart = windows.add_to_autostart | 44 | uninstall_application = windows.uninstall_application |
122 | 42 | else: | 45 | else: |
123 | 43 | from ubuntuone.controlpanel.utils import linux | 46 | from ubuntuone.controlpanel.utils import linux |
125 | 44 | are_updates_present = lambda *args, **kwargs: False | 47 | add_to_autostart = no_op |
126 | 48 | are_updates_present = no_op | ||
127 | 45 | default_folders = linux.default_folders | 49 | default_folders = linux.default_folders |
130 | 46 | perform_update = lambda *args, **kwargs: None | 50 | perform_update = no_op |
131 | 47 | add_to_autostart = lambda *args, **kwargs: None | 51 | uninstall_application = no_op |
132 | 48 | 52 | ||
133 | 49 | # pylint: enable=C0103 | 53 | # pylint: enable=C0103 |
134 | 50 | 54 | ||
135 | 51 | 55 | ||
136 | === modified file 'ubuntuone/controlpanel/utils/tests/test_windows.py' | |||
137 | --- ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-27 18:55:37 +0000 | |||
138 | +++ ubuntuone/controlpanel/utils/tests/test_windows.py 2012-03-30 17:37:31 +0000 | |||
139 | @@ -1,7 +1,6 @@ | |||
140 | 1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- |
141 | 2 | |||
142 | 3 | # | 2 | # |
144 | 4 | # Copyright 2011 Canonical Ltd. | 3 | # Copyright 2011-2012 Canonical Ltd. |
145 | 5 | # | 4 | # |
146 | 6 | # This program is free software: you can redistribute it and/or modify it | 5 | # This program is free software: you can redistribute it and/or modify it |
147 | 7 | # under the terms of the GNU General Public License version 3, as published | 6 | # under the terms of the GNU General Public License version 3, as published |
148 | @@ -28,6 +27,34 @@ | |||
149 | 28 | # let me use protected methods | 27 | # let me use protected methods |
150 | 29 | # pylint: disable=W0212 | 28 | # pylint: disable=W0212 |
151 | 30 | 29 | ||
152 | 30 | SOME_EXE_NAME = 'foo.exe' | ||
153 | 31 | |||
154 | 32 | |||
155 | 33 | class FrozenTestCase(TestCase): | ||
156 | 34 | """A base test case for handling frozen/not frozen systems.""" | ||
157 | 35 | |||
158 | 36 | frozen = True | ||
159 | 37 | executable = 'path/to/current/exe/ubuntuone/dist/executable.exe' | ||
160 | 38 | |||
161 | 39 | @defer.inlineCallbacks | ||
162 | 40 | def setUp(self): | ||
163 | 41 | """Set the different tests.""" | ||
164 | 42 | yield super(FrozenTestCase, self).setUp() | ||
165 | 43 | |||
166 | 44 | for attr_name in ('frozen', 'executable'): | ||
167 | 45 | value_not_set = object() | ||
168 | 46 | value = getattr(utils.windows.sys, attr_name, value_not_set) | ||
169 | 47 | |||
170 | 48 | if self.frozen is not None: | ||
171 | 49 | setattr(utils.windows.sys, attr_name, getattr(self, attr_name)) | ||
172 | 50 | elif self.frozen is None and value is not value_not_set: | ||
173 | 51 | delattr(utils.windows.sys, attr_name) | ||
174 | 52 | |||
175 | 53 | if self.frozen is not None and value is value_not_set: | ||
176 | 54 | self.addCleanup(delattr, utils.windows.sys, attr_name) | ||
177 | 55 | elif value is not value_not_set: | ||
178 | 56 | self.addCleanup(setattr, utils.windows.sys, attr_name, value) | ||
179 | 57 | |||
180 | 31 | 58 | ||
181 | 32 | class AutoupdaterTestCase(TestCase): | 59 | class AutoupdaterTestCase(TestCase): |
182 | 33 | """Test the code that is used for the auto update process.""" | 60 | """Test the code that is used for the auto update process.""" |
183 | @@ -36,7 +63,9 @@ | |||
184 | 36 | def setUp(self): | 63 | def setUp(self): |
185 | 37 | """Prepare for the diff tests.""" | 64 | """Prepare for the diff tests.""" |
186 | 38 | yield super(AutoupdaterTestCase, self).setUp() | 65 | yield super(AutoupdaterTestCase, self).setUp() |
188 | 39 | self.auto_update_path = r'path\to\exe' | 66 | self._base_path = r'path\to\exe' |
189 | 67 | self.auto_update_path = os.path.join(self._base_path, | ||
190 | 68 | utils.windows.AUTOUPDATE_EXE_NAME) | ||
191 | 40 | self.return_from_call = 0 | 69 | self.return_from_call = 0 |
192 | 41 | self.command = None | 70 | self.command = None |
193 | 42 | self.args = [] | 71 | self.args = [] |
194 | @@ -48,8 +77,8 @@ | |||
195 | 48 | return self.return_from_call | 77 | return self.return_from_call |
196 | 49 | 78 | ||
197 | 50 | self.patch(utils.windows, 'getProcessValue', fake_execute_process) | 79 | self.patch(utils.windows, 'getProcessValue', fake_execute_process) |
200 | 51 | self.patch(utils.windows, '_get_update_path', | 80 | self.patch(utils.windows, 'get_exe_path', |
201 | 52 | lambda: self.auto_update_path) | 81 | lambda exe_name: os.path.join(self._base_path, exe_name)) |
202 | 53 | 82 | ||
203 | 54 | @defer.inlineCallbacks | 83 | @defer.inlineCallbacks |
204 | 55 | def test_are_updates_present_true(self): | 84 | def test_are_updates_present_true(self): |
205 | @@ -81,11 +110,9 @@ | |||
206 | 81 | """Test the method that performs the update.""" | 110 | """Test the method that performs the update.""" |
207 | 82 | self.patch(utils.windows.win32api, 'ShellExecute', self._set_called) | 111 | self.patch(utils.windows.win32api, 'ShellExecute', self._set_called) |
208 | 83 | utils.perform_update() | 112 | utils.perform_update() |
214 | 84 | self.assertIn(self.auto_update_path, self._called[0][2]) | 113 | args = (None, 'runas', self.auto_update_path, |
215 | 85 | self.assertEqual('runas', self._called[0][1]) | 114 | '--unattendedmodeui none', '', 0) |
216 | 86 | self.assertEqual('--unattendedmodeui none', self._called[0][3]) | 115 | self.assertEqual(self._called, (args, {})) |
212 | 87 | self.assertEqual('', self._called[0][4]) | ||
213 | 88 | self.assertEqual(0, self._called[0][5]) | ||
217 | 89 | 116 | ||
218 | 90 | 117 | ||
219 | 91 | class FakeOpenKey(object): | 118 | class FakeOpenKey(object): |
220 | @@ -217,15 +244,14 @@ | |||
221 | 217 | self.test_special_folders(names=('PERSONAL', 'MYMUSIC', 'MYPICTURES')) | 244 | self.test_special_folders(names=('PERSONAL', 'MYMUSIC', 'MYPICTURES')) |
222 | 218 | 245 | ||
223 | 219 | 246 | ||
226 | 220 | class GetPathTestCase(TestCase): | 247 | class GetExePathTestCase(FrozenTestCase): |
227 | 221 | """Test the code that is used for the auto update process.""" | 248 | """Test the path calculator when sys is frozen.""" |
228 | 222 | 249 | ||
229 | 223 | @defer.inlineCallbacks | 250 | @defer.inlineCallbacks |
230 | 224 | def setUp(self): | 251 | def setUp(self): |
231 | 225 | """Set the different tests.""" | 252 | """Set the different tests.""" |
233 | 226 | yield super(GetPathTestCase, self).setUp() | 253 | yield super(GetExePathTestCase, self).setUp() |
234 | 227 | self.called = [] | 254 | self.called = [] |
235 | 228 | self.exec_path = 'path/to/current/exe' | ||
236 | 229 | self.exists = True | 255 | self.exists = True |
237 | 230 | 256 | ||
238 | 231 | def fake_abspath(path): | 257 | def fake_abspath(path): |
239 | @@ -248,62 +274,70 @@ | |||
240 | 248 | self.patch(utils.windows.os.path, 'dirname', fake_dirname) | 274 | self.patch(utils.windows.os.path, 'dirname', fake_dirname) |
241 | 249 | self.patch(utils.windows.os.path, 'exists', fake_exists) | 275 | self.patch(utils.windows.os.path, 'exists', fake_exists) |
242 | 250 | 276 | ||
296 | 251 | def _delete_frozen_state(self): | 277 | def test_get_exe_path(self): |
297 | 252 | """Delete the frozen state.""" | 278 | """Test the method used to get the autoupdate.""" |
298 | 253 | del utils.windows.sys.frozen | 279 | path = utils.windows.get_exe_path(exe_name=SOME_EXE_NAME) |
299 | 254 | del utils.windows.sys.executable | 280 | |
300 | 255 | 281 | self.assertEqual(os.path.join(self.executable, SOME_EXE_NAME), path) | |
301 | 256 | def test_get_auto_update_path_frozen(self): | 282 | |
302 | 257 | """Test the method used to get the autoupdate.""" | 283 | expected = ['os.path.abspath', 'os.path.dirname', 'os.path.dirname', |
303 | 258 | # patch the diff parts of sys so that we get fake paths | 284 | 'os.path.exists'] |
304 | 259 | is_frozen = hasattr(utils.windows.sys, 'frozen') | 285 | self.assertEqual(expected, self.called) |
305 | 260 | if not is_frozen: | 286 | |
306 | 261 | utils.windows.sys.frozen = True | 287 | def test_get_exe_path_not_present(self): |
254 | 262 | utils.windows.sys.executable = self.exec_path | ||
255 | 263 | self.addCleanup(self._delete_frozen_state) | ||
256 | 264 | |||
257 | 265 | # called method and assert that we have the correct result | ||
258 | 266 | path = utils.windows._get_update_path() | ||
259 | 267 | self.assertEqual(os.path.join(self.exec_path, | ||
260 | 268 | utils.windows.AUTOUPDATE_EXE_NAME), path) | ||
261 | 269 | self.assertTrue('os.path.abspath' in self.called) | ||
262 | 270 | self.assertTrue('os.path.dirname' in self.called) | ||
263 | 271 | self.assertTrue('os.path.exists' in self.called) | ||
264 | 272 | |||
265 | 273 | def _reset_frozen_state(self, old_frozen, old_exec_path): | ||
266 | 274 | """Reset the frozen state.""" | ||
267 | 275 | utils.windows.sys.frozen = old_frozen | ||
268 | 276 | utils.windows.sys.executable = old_exec_path | ||
269 | 277 | |||
270 | 278 | def _reset__file__(self, path): | ||
271 | 279 | """Reset the value of __file__.""" | ||
272 | 280 | utils.windows.__file__ = path | ||
273 | 281 | |||
274 | 282 | def test_get_auto_update_path_not_frozen(self): | ||
275 | 283 | """Test the method used to get the autoupdate.""" | ||
276 | 284 | is_frozen = hasattr(utils.windows.sys, 'frozen') | ||
277 | 285 | if is_frozen: | ||
278 | 286 | old_frozen = utils.windows.sys.frozen | ||
279 | 287 | old_exec_path = utils.windows.sys.executable | ||
280 | 288 | del utils.windows.sys.frozen | ||
281 | 289 | del utils.windows.sys.executable | ||
282 | 290 | self.addCleanup(self._reset_frozen_state, old_frozen, | ||
283 | 291 | old_exec_path) | ||
284 | 292 | # set a fake __file__ for the module | ||
285 | 293 | old_file = utils.windows.__file__ | ||
286 | 294 | utils.windows.__file__ = self.exec_path | ||
287 | 295 | self.addCleanup(self._reset__file__, old_file) | ||
288 | 296 | |||
289 | 297 | path = utils.windows._get_update_path() | ||
290 | 298 | self.assertEqual(os.path.join(self.exec_path, | ||
291 | 299 | utils.windows.AUTOUPDATE_EXE_NAME), path) | ||
292 | 300 | self.assertEqual(2, self.called.count('os.path.dirname')) | ||
293 | 301 | self.assertTrue('os.path.exists' in self.called) | ||
294 | 302 | |||
295 | 303 | def test_get_auto_update_path_not_present(self): | ||
307 | 304 | """Test the method used to get the autoupdate.""" | 288 | """Test the method used to get the autoupdate.""" |
308 | 305 | self.exists = False | 289 | self.exists = False |
309 | 306 | 290 | ||
310 | 307 | # called method and assert that we have the correct result | 291 | # called method and assert that we have the correct result |
313 | 308 | path = utils.windows._get_update_path() | 292 | path = utils.windows.get_exe_path(exe_name=SOME_EXE_NAME) |
314 | 309 | self.assertEqual(None, path) | 293 | self.assertTrue(path is None) |
315 | 294 | |||
316 | 295 | |||
317 | 296 | class GetExePathNotFrozenTestCase(GetExePathTestCase): | ||
318 | 297 | """Test the path calculator when sys is not frozen.""" | ||
319 | 298 | |||
320 | 299 | frozen = None | ||
321 | 300 | |||
322 | 301 | def test_get_exe_path(self): | ||
323 | 302 | """Test the method used to get the autoupdate.""" | ||
324 | 303 | self.patch(utils.windows, '__file__', self.executable) | ||
325 | 304 | |||
326 | 305 | path = utils.windows.get_exe_path(exe_name=SOME_EXE_NAME) | ||
327 | 306 | self.assertEqual(os.path.join(self.executable, SOME_EXE_NAME), path) | ||
328 | 307 | |||
329 | 308 | expected = ['os.path.dirname', 'os.path.dirname', 'os.path.dirname', | ||
330 | 309 | 'os.path.exists'] | ||
331 | 310 | self.assertEqual(expected, self.called) | ||
332 | 311 | |||
333 | 312 | |||
334 | 313 | class UninstallApplicationTestCase(FrozenTestCase): | ||
335 | 314 | """Test the uninstall_application helper when sys is frozen.""" | ||
336 | 315 | |||
337 | 316 | @defer.inlineCallbacks | ||
338 | 317 | def setUp(self): | ||
339 | 318 | yield super(UninstallApplicationTestCase, self).setUp() | ||
340 | 319 | self.patch(utils.windows.win32api, "ShellExecute", self._set_called) | ||
341 | 320 | self.patch(os.path, "exists", lambda path: True) | ||
342 | 321 | |||
343 | 322 | def test_uninstall(self): | ||
344 | 323 | """The uninstaller is run.""" | ||
345 | 324 | utils.uninstall_application() | ||
346 | 325 | |||
347 | 326 | exe_name = utils.windows.UNINSTALL_EXE_NAME | ||
348 | 327 | uninstall_path = utils.windows.get_exe_path(exe_name=exe_name) | ||
349 | 328 | self.assertEqual(self._called, | ||
350 | 329 | ((None, '', uninstall_path, '--mode win32', '', 0), {})) | ||
351 | 330 | |||
352 | 331 | def test_uninstall_exe_not_present(self): | ||
353 | 332 | """The uninstaller is not run if not available.""" | ||
354 | 333 | self.patch(os.path, "exists", lambda path: False) | ||
355 | 334 | |||
356 | 335 | utils.uninstall_application() | ||
357 | 336 | |||
358 | 337 | self.assertFalse(self._called) | ||
359 | 338 | |||
360 | 339 | |||
361 | 340 | class UninstallApplicationNotFrozenTestCase(UninstallApplicationTestCase): | ||
362 | 341 | """Test the uninstall_application helper when sys is not frozen.""" | ||
363 | 342 | |||
364 | 343 | frozen = None | ||
365 | 310 | 344 | ||
366 | === modified file 'ubuntuone/controlpanel/utils/windows.py' | |||
367 | --- ubuntuone/controlpanel/utils/windows.py 2012-03-23 21:48:53 +0000 | |||
368 | +++ ubuntuone/controlpanel/utils/windows.py 2012-03-30 17:37:31 +0000 | |||
369 | @@ -1,7 +1,6 @@ | |||
370 | 1 | # -*- coding: utf-8 -*- | 1 | # -*- coding: utf-8 -*- |
371 | 2 | |||
372 | 3 | # | 2 | # |
374 | 4 | # Copyright 2011 Canonical Ltd. | 3 | # Copyright 2011-2012 Canonical Ltd. |
375 | 5 | # | 4 | # |
376 | 6 | # This program is free software: you can redistribute it and/or modify it | 5 | # This program is free software: you can redistribute it and/or modify it |
377 | 7 | # under the terms of the GNU General Public License version 3, as published | 6 | # under the terms of the GNU General Public License version 3, as published |
378 | @@ -35,19 +34,41 @@ | |||
379 | 35 | logger = setup_logging('utils.windows') | 34 | logger = setup_logging('utils.windows') |
380 | 36 | AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe' | 35 | AUTOUPDATE_EXE_NAME = 'autoupdate-windows.exe' |
381 | 37 | AUTORUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run" | 36 | AUTORUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run" |
385 | 38 | 37 | UNINSTALL_EXE_NAME = 'uninstall.exe' | |
386 | 39 | 38 | ||
387 | 40 | def _get_update_path(): | 39 | |
388 | 40 | def get_exe_path(exe_name): | ||
389 | 41 | """Return the path in which the autoupdate command is found.""" | 41 | """Return the path in which the autoupdate command is found.""" |
391 | 42 | if hasattr(sys, 'frozen'): | 42 | if getattr(sys, 'frozen', False): |
392 | 43 | exec_path = os.path.abspath(sys.executable) | 43 | exec_path = os.path.abspath(sys.executable) |
393 | 44 | else: | 44 | else: |
394 | 45 | exec_path = os.path.dirname(__file__) | 45 | exec_path = os.path.dirname(__file__) |
400 | 46 | folder = os.path.dirname(exec_path) | 46 | |
401 | 47 | update_path = os.path.join(folder, AUTOUPDATE_EXE_NAME) | 47 | result = None |
402 | 48 | if os.path.exists(update_path): | 48 | folder = os.path.dirname(os.path.dirname(exec_path)) |
403 | 49 | return update_path | 49 | exe_path = os.path.join(folder, exe_name) |
404 | 50 | return None | 50 | if os.path.exists(exe_path): |
405 | 51 | result = exe_path | ||
406 | 52 | |||
407 | 53 | return result | ||
408 | 54 | |||
409 | 55 | |||
410 | 56 | def add_to_autostart(): | ||
411 | 57 | """Add syncdaemon to the session's autostart.""" | ||
412 | 58 | if getattr(sys, "frozen", False): | ||
413 | 59 | sd_path = '"%s"' % os.path.join(os.path.dirname( | ||
414 | 60 | os.path.abspath(sys.executable)), | ||
415 | 61 | "ubuntuone-syncdaemon.exe") | ||
416 | 62 | u1cp_path = '"%s"' % os.path.join(os.path.dirname( | ||
417 | 63 | os.path.abspath(sys.executable)), | ||
418 | 64 | "ubuntuone-control-panel-qt.exe") | ||
419 | 65 | |||
420 | 66 | with _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, AUTORUN_KEY, | ||
421 | 67 | 0, _winreg.KEY_ALL_ACCESS) as key: | ||
422 | 68 | # pylint: disable=E0602 | ||
423 | 69 | _winreg.SetValueEx(key, "Ubuntu One", 0, _winreg.REG_SZ, sd_path) | ||
424 | 70 | _winreg.SetValueEx(key, "Ubuntu One Icon", 0, _winreg.REG_SZ, | ||
425 | 71 | u1cp_path + " --minimized --with-icon") | ||
426 | 51 | 72 | ||
427 | 52 | 73 | ||
428 | 53 | @defer.inlineCallbacks | 74 | @defer.inlineCallbacks |
429 | @@ -55,7 +76,7 @@ | |||
430 | 55 | """Return if there are updates for Ubuntu One.""" | 76 | """Return if there are updates for Ubuntu One.""" |
431 | 56 | result = False | 77 | result = False |
432 | 57 | retcode = None | 78 | retcode = None |
434 | 58 | update_path = _get_update_path() | 79 | update_path = get_exe_path(exe_name=AUTOUPDATE_EXE_NAME) |
435 | 59 | if update_path is not None: | 80 | if update_path is not None: |
436 | 60 | # If there is an update present we will get 0, non-zero otherwise | 81 | # If there is an update present we will get 0, non-zero otherwise |
437 | 61 | retcode = yield getProcessValue(update_path, args=('--mode', | 82 | retcode = yield getProcessValue(update_path, args=('--mode', |
438 | @@ -92,27 +113,15 @@ | |||
439 | 92 | 113 | ||
440 | 93 | def perform_update(): | 114 | def perform_update(): |
441 | 94 | """Spawn the autoupdate process and call the stop function.""" | 115 | """Spawn the autoupdate process and call the stop function.""" |
443 | 95 | update_path = _get_update_path() | 116 | update_path = get_exe_path(exe_name=AUTOUPDATE_EXE_NAME) |
444 | 96 | if update_path is not None: | 117 | if update_path is not None: |
445 | 97 | # lets call the updater with the commands that are required, | 118 | # lets call the updater with the commands that are required, |
467 | 98 | win32api.ShellExecute(None, 'runas', | 119 | win32api.ShellExecute(None, 'runas', update_path, |
468 | 99 | update_path, | 120 | '--unattendedmodeui none', '', 0) |
469 | 100 | '--unattendedmodeui none', '', 0) | 121 | |
470 | 101 | 122 | ||
471 | 102 | 123 | def uninstall_application(): | |
472 | 103 | def add_to_autostart(): | 124 | """Uninstall Ubuntu One.""" |
473 | 104 | """Add syncdaemon to the session's autostart.""" | 125 | uninstall_path = get_exe_path(exe_name=UNINSTALL_EXE_NAME) |
474 | 105 | if getattr(sys, "frozen", False): | 126 | if uninstall_path is not None: |
475 | 106 | sd_path = '"%s"' % os.path.join(os.path.dirname( | 127 | win32api.ShellExecute(None, '', uninstall_path, '--mode win32', '', 0) |
455 | 107 | os.path.abspath(sys.executable)), | ||
456 | 108 | "ubuntuone-syncdaemon.exe") | ||
457 | 109 | u1cp_path = '"%s"' % os.path.join(os.path.dirname( | ||
458 | 110 | os.path.abspath(sys.executable)), | ||
459 | 111 | "ubuntuone-control-panel-qt.exe") | ||
460 | 112 | |||
461 | 113 | with _winreg.OpenKey(_winreg.HKEY_CURRENT_USER, AUTORUN_KEY, | ||
462 | 114 | 0, _winreg.KEY_ALL_ACCESS) as key: | ||
463 | 115 | # pylint: disable=E0602 | ||
464 | 116 | _winreg.SetValueEx(key, "Ubuntu One", 0, _winreg.REG_SZ, sd_path) | ||
465 | 117 | _winreg.SetValueEx(key, "Ubuntu One Icon", 0, _winreg.REG_SZ, | ||
466 | 118 | u1cp_path + " --minimized --with-icon") |
Looks fine, and IRL tests of uninstallation on Windows XP and Windows 7 both function properly with these changes.