Merge lp:~nataliabidart/ubuntuone-windows-installer/stable-3-0-update into lp:ubuntuone-windows-installer/stable-3-0
- stable-3-0-update
- Merge into stable-3-0
Status: | Merged |
---|---|
Approved by: | Natalia Bidart |
Approved revision: | 91 |
Merged at revision: | 91 |
Proposed branch: | lp:~nataliabidart/ubuntuone-windows-installer/stable-3-0-update |
Merge into: | lp:ubuntuone-windows-installer/stable-3-0 |
Diff against target: |
671 lines (+315/-75) 10 files modified
data/qt/congratulations.ui (+5/-16) run-tests.bat (+1/-1) setup.py (+1/-1) ubuntuone_installer/gui/qt/gui.py (+61/-12) ubuntuone_installer/gui/qt/tests/test_gui.py (+149/-34) ubuntuone_installer/gui/qt/utils/__init__.py (+6/-0) ubuntuone_installer/gui/qt/utils/tests/test_common.py (+9/-0) ubuntuone_installer/gui/qt/utils/tests/test_windows.py (+48/-4) ubuntuone_installer/gui/qt/utils/windows.py (+34/-6) ubuntuone_installer/tests/__init__.py (+1/-1) |
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-windows-installer/stable-3-0-update |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Review via email: mp+86297@code.launchpad.net |
Commit message
[ Diego Sarmentero <email address hidden> ]
- Fixed lint issues.
- Fixed: When logging in with an no-yet-validated account, there is no useful
message (LP: #851885).
- Fixed congratulations page (LP: #859711).
[ Manuel de la Pena <email address hidden> ]
- Put all the different pieces of the migration together so that we perform
the uninstall and migtration of the data if the user has the very
old first beta.
- Fixes the code that will call the autoupdate-
in the release the .exe will be in a diff location to avoid dll collisions.
- Changed the import from ubuntuone-dev-tools so that we do not use the
deprecated API.
[ Natalia B. Bidart <email address hidden> ]
- Pass module for test to u1trial properly.
Description of the change
All green in ubuntu, and windows (tested windows 7).
IRL tested on windows.
Preview Diff
1 | === modified file 'data/qt/congratulations.ui' |
2 | --- data/qt/congratulations.ui 2011-09-08 14:49:31 +0000 |
3 | +++ data/qt/congratulations.ui 2011-12-19 21:30:29 +0000 |
4 | @@ -7,7 +7,7 @@ |
5 | <x>0</x> |
6 | <y>0</y> |
7 | <width>622</width> |
8 | - <height>331</height> |
9 | + <height>362</height> |
10 | </rect> |
11 | </property> |
12 | <property name="windowTitle"> |
13 | @@ -21,20 +21,6 @@ |
14 | <number>0</number> |
15 | </property> |
16 | <item> |
17 | - <widget class="QLabel" name="label"> |
18 | - <property name="font"> |
19 | - <font> |
20 | - <pointsize>14</pointsize> |
21 | - <weight>75</weight> |
22 | - <bold>true</bold> |
23 | - </font> |
24 | - </property> |
25 | - <property name="text"> |
26 | - <string>Congratulations!</string> |
27 | - </property> |
28 | - </widget> |
29 | - </item> |
30 | - <item> |
31 | <layout class="QHBoxLayout" name="horizontalLayout_2"> |
32 | <item> |
33 | <spacer name="horizontalSpacer"> |
34 | @@ -50,7 +36,7 @@ |
35 | </spacer> |
36 | </item> |
37 | <item> |
38 | - <widget class="QLabel" name="label_2"> |
39 | + <widget class="QLabel" name="image_label"> |
40 | <property name="text"> |
41 | <string/> |
42 | </property> |
43 | @@ -83,6 +69,9 @@ |
44 | </item> |
45 | <item> |
46 | <widget class="QWidget" name="progressContainer" native="true"> |
47 | + <property name="layoutDirection"> |
48 | + <enum>Qt::RightToLeft</enum> |
49 | + </property> |
50 | <layout class="QHBoxLayout" name="horizontalLayout"> |
51 | <property name="spacing"> |
52 | <number>0</number> |
53 | |
54 | === modified file 'run-tests.bat' |
55 | --- run-tests.bat 2011-08-24 17:04:02 +0000 |
56 | +++ run-tests.bat 2011-12-19 21:30:29 +0000 |
57 | @@ -66,4 +66,4 @@ |
58 | "%PYTHONEXEPATH%\python.exe" setup.py build |
59 | ECHO Running tests |
60 | :: execute the tests with a number of ignored linux only modules |
61 | -"%PYTHONEXEPATH%\python.exe" "%PYTHONEXEPATH%\Scripts\u1trial" -i "test_linux.py" ubuntuone_installer --gui --reactor=qt4 |
62 | +"%PYTHONEXEPATH%\python.exe" "%PYTHONEXEPATH%\Scripts\u1trial" -i "test_linux.py" --gui --reactor=qt4 -c ubuntuone_installer |
63 | |
64 | === modified file 'setup.py' |
65 | --- setup.py 2011-12-01 19:30:38 +0000 |
66 | +++ setup.py 2011-12-19 21:30:29 +0000 |
67 | @@ -228,7 +228,7 @@ |
68 | |
69 | DistUtilsExtra.auto.setup( |
70 | name='ubuntuone-installer', |
71 | - version='2.99', |
72 | + version='2.99.0', |
73 | license='GPL v3', |
74 | author='Roberto Alsina', |
75 | author_email='roberto.alsina@canonical.com', |
76 | |
77 | === modified file 'ubuntuone_installer/gui/qt/gui.py' |
78 | --- ubuntuone_installer/gui/qt/gui.py 2011-11-11 20:36:16 +0000 |
79 | +++ ubuntuone_installer/gui/qt/gui.py 2011-12-19 21:30:29 +0000 |
80 | @@ -1,8 +1,4 @@ |
81 | # -*- coding: utf-8 -*- |
82 | - |
83 | -# Authors: Alejandro J. Cura <alecu@canonical.com> |
84 | -# Roberto Alsina <roberto.alsina@canonical.com> |
85 | -# Diego Sarmentero <diego.sarmentero@canonical.com> |
86 | # |
87 | # Copyright 2011 Canonical Ltd. |
88 | # |
89 | @@ -84,31 +80,71 @@ |
90 | from ubuntuone_installer.gui.qt.side_widget import SideWidget |
91 | |
92 | _ = gettext.gettext |
93 | +CONGRATULATIONS = _("Congratulations") |
94 | +CREDENTIALS_ERROR_TITLE = _("Error getting credentials") |
95 | +CREDENTIALS_ERROR = _('Application will close.\n\n%r') |
96 | SIGN_IN = _("Sign in to Ubuntu One") |
97 | SIGN_IN_SUBTITLE = _("Sign in with your existing Ubuntu One" |
98 | " username and password.") |
99 | -TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>" |
100 | -CREDENTIALS_ERROR_TITLE = _("Error getting credentials") |
101 | -CREDENTIALS_ERROR = _('Application will close.\n\n%r') |
102 | SKIP_TOUR = _("Skip tour, go to Dashboard") |
103 | START_SETUP = _("Start setup") |
104 | SUCCESSFUL_LOGIN = _("Login successful") |
105 | +TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>" |
106 | UPDATE_TITLE = _("Updates are available") |
107 | UPDATE_SOFTWARE = _("There is a new version available. " |
108 | "Do you want perform an upgrade?") |
109 | +REMOVE_OLD_BETA_TITLE = _("Remove old Beta") |
110 | +REMOVE_OLD_BETA = _("The old Ubuntu One Beta is installed in your system. Do " |
111 | + "you want to uninstall it?") |
112 | +REMOVE_OLD_BETA_ERROR = _("There was an error uninstall the old beta. Please " |
113 | + "do this step manually") |
114 | +MIGRATE_OLD_BETA_DATA_TITLE = _("Migrate old data") |
115 | +MIGRATE_OLD_BETA = _("Do you want to migrate the files from the old Ubuntu " |
116 | + "One Beta location to the new one?") |
117 | +MIGRATE_OLD_BETA_DATA_ERROR = _("There was an error migrating your data. " |
118 | + "Please do this step manually.") |
119 | + |
120 | # Invalid name logger |
121 | # pylint: disable=C0103 |
122 | logger = setup_logging('qt.gui') |
123 | # pylint: enable=C0103 |
124 | |
125 | |
126 | +def _ask_user_question(title, question): |
127 | + """Ask the user a Yes/No question.""" |
128 | + result = QtGui.QMessageBox.question(None, title, question, |
129 | + QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) |
130 | + return result == QtGui.QMessageBox.Yes |
131 | + |
132 | + |
133 | def user_wants_to_update(): |
134 | """Ask the user if he really wants to update the software.""" |
135 | - result = QtGui.QMessageBox.question(None, UPDATE_TITLE, UPDATE_SOFTWARE, |
136 | - QtGui.QMessageBox.Yes, QtGui.QMessageBox.No) |
137 | - if result == QtGui.QMessageBox.Yes: |
138 | - return True |
139 | - return False |
140 | + return _ask_user_question(UPDATE_TITLE, UPDATE_SOFTWARE) |
141 | + |
142 | + |
143 | +def user_wants_to_remove_old_beta(): |
144 | + """Ask the user if he really wants to remove the old beta.""" |
145 | + return _ask_user_question(REMOVE_OLD_BETA_TITLE, REMOVE_OLD_BETA) |
146 | + |
147 | + |
148 | +def user_wants_to_migrate_data(): |
149 | + """Ask the user if he really wants to migrate the data.""" |
150 | + return _ask_user_question(MIGRATE_OLD_BETA_DATA_TITLE, MIGRATE_OLD_BETA) |
151 | + |
152 | + |
153 | +def _warn_user(title, message): |
154 | + """Warn the user.""" |
155 | + QtGui.QMessageBox.warning(None, title, message, QtGui.QMessageBox.Ok) |
156 | + |
157 | + |
158 | +def warn_user_beta_not_removed(): |
159 | + """Let the user know that the data was not migrated.""" |
160 | + _warn_user(REMOVE_OLD_BETA_TITLE, REMOVE_OLD_BETA_ERROR) |
161 | + |
162 | + |
163 | +def warn_user_data_not_migrated(): |
164 | + """Let the user know that the data was not migrated.""" |
165 | + _warn_user(MIGRATE_OLD_BETA_DATA_TITLE, MIGRATE_OLD_BETA_DATA_ERROR) |
166 | |
167 | |
168 | class LicensePage(SSOWizardPage): |
169 | @@ -213,6 +249,10 @@ |
170 | self.ui.sign_in_button.style().polish( |
171 | self.ui.sign_in_button) |
172 | |
173 | + def cleanupPage(self): |
174 | + """Reset the state of the wizard if Verification code was visited.""" |
175 | + self.wizard()._next_id = None |
176 | + |
177 | |
178 | class SuccessPage(SSOWizardPage): |
179 | """Shown after SSO login, before setup.""" |
180 | @@ -266,6 +306,7 @@ |
181 | super(CongratulationsPage, self).__init__( |
182 | congratulations_ui.Ui_Form(), None, parent) |
183 | self.setFinalPage(True) |
184 | + self.setTitle(CONGRATULATIONS) |
185 | |
186 | # Invalid names of Qt-inherited methods |
187 | # pylint: disable=C0103 |
188 | @@ -305,6 +346,7 @@ |
189 | # definition of the signals raised by the widget (for SSO) |
190 | recoverableError = QtCore.pyqtSignal('QString', 'QString') |
191 | loginSuccess = QtCore.pyqtSignal('QString', 'QString') |
192 | + registrationIncomplete = QtCore.pyqtSignal('QString', 'QString') |
193 | registrationSuccess = QtCore.pyqtSignal('QString', 'QString') |
194 | userCancellation = QtCore.pyqtSignal('QString') |
195 | |
196 | @@ -412,6 +454,7 @@ |
197 | self.reset_password_page_id = self.addPage(self.reset_password) |
198 | |
199 | self.loginSuccess.connect(self.login_success_slot) |
200 | + self.registrationIncomplete.connect(self.registration_incomplete) |
201 | self.registrationSuccess.connect(self.registration_success_slot) |
202 | |
203 | # End of SSO pages |
204 | @@ -470,6 +513,12 @@ |
205 | self.next() |
206 | self._next_id = self.SYNC_NOW_OR_LATER_PAGE |
207 | |
208 | + def registration_incomplete(self): |
209 | + """Called when registration wasn't completed.""" |
210 | + self._next_id = self.email_verification_page_id |
211 | + self.next() |
212 | + self._next_id = self.SUCCESS_PAGE |
213 | + |
214 | def registration_success_slot(self): |
215 | """Called on successful registration.""" |
216 | self._next_id = self.SUCCESS_PAGE |
217 | |
218 | === modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py' |
219 | --- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-11-11 20:36:16 +0000 |
220 | +++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-12-19 21:30:29 +0000 |
221 | @@ -347,6 +347,36 @@ |
222 | folders_page.on_check_settings_button_clicked() |
223 | self.assertEqual(self.ui.currentId(), self.ui.preferences_page_id) |
224 | |
225 | + def test_current_user_sign_in_page_clenaup(self): |
226 | + """Check CurrentUserSignIn cleanupPage method.""" |
227 | + current_signin_page = self.ui.page(self.ui.current_user_page_id) |
228 | + |
229 | + # Show the current id page |
230 | + self.ui.setStartId(self.ui.current_user_page_id) |
231 | + self.ui.restart() |
232 | + self.ui.show() |
233 | + self.addCleanup(self.ui.hide) |
234 | + |
235 | + self.ui._next_id = self.ui.SUCCESS_PAGE |
236 | + current_signin_page.cleanupPage() |
237 | + # pylint: disable=W0212 |
238 | + self.assertEqual(self.ui._next_id, None) |
239 | + # pylint: enable=W0212 |
240 | + |
241 | + def test_registration_incomplete(self): |
242 | + """Check the registration_incomplete slot.""" |
243 | + self.ui.setStartId(self.ui.current_user_page_id) |
244 | + self.ui.restart() |
245 | + self.ui.show() |
246 | + self.addCleanup(self.ui.hide) |
247 | + |
248 | + self.ui.registration_incomplete() |
249 | + self.assertEqual(self.ui.currentId(), |
250 | + self.ui.email_verification_page_id) |
251 | + # pylint: disable=W0212 |
252 | + self.assertEqual(self.ui._next_id, self.ui.SUCCESS_PAGE) |
253 | + # pylint: enable=W0212 |
254 | + |
255 | def test_critical(self): |
256 | """Show a critical popup, but first hide the overlay.""" |
257 | self.assertEqual(self.ui.overlay.hide_counter, 1) |
258 | @@ -495,6 +525,19 @@ |
259 | self.assertEqual(self._called, False) |
260 | self.assertEqual(FakeAreYouSure.shown, False) |
261 | |
262 | + def test_congratulations_page_title(self): |
263 | + """Check congratulations page title.""" |
264 | + congratulations_page = self.ui.page(self.ui.CONGRATULATIONS_PAGE) |
265 | + self.ui.setStartId(self.ui.CONGRATULATIONS_PAGE) |
266 | + self.ui.restart() |
267 | + self.ui.show() |
268 | + self.addCleanup(self.ui.hide) |
269 | + congratulations_page.initializePage() |
270 | + self.ui.show() |
271 | + self.addCleanup(self.ui.hide) |
272 | + self.assertEqual(congratulations_page.header.title_label.text(), |
273 | + gui.CONGRATULATIONS) |
274 | + |
275 | def test_current_user_controller_parameters(self): |
276 | """Compare controller parameters with expected values.""" |
277 | self.assertEqual(self.ui.current_user_controller.args, |
278 | @@ -615,6 +658,7 @@ |
279 | |
280 | currentIdChanged = FakeSignal() |
281 | loginSuccess = FakeSignal() |
282 | + registrationIncomplete = FakeSignal() |
283 | registrationSuccess = FakeSignal() |
284 | userCancellation = FakeSignal() |
285 | shown = False |
286 | @@ -716,51 +760,122 @@ |
287 | self.assertTrue(self.ui.ui.existing_account_button.isDefault()) |
288 | |
289 | |
290 | -class UpgradeQuestion(BaseTestCase): |
291 | +class MessageBoxTestCase(BaseTestCase): |
292 | """Test the dialog that ask the user if he wants to upgrade.""" |
293 | |
294 | @defer.inlineCallbacks |
295 | def setUp(self): |
296 | """Set the tests.""" |
297 | - yield super(UpgradeQuestion, self).setUp() |
298 | + yield super(MessageBoxTestCase, self).setUp() |
299 | self.answer = 0 |
300 | self.parent = None |
301 | self.title = None |
302 | self.text = None |
303 | self.yes_button = None |
304 | self.no_button = None |
305 | - |
306 | - def fake_question(parent, title, text, yes_button, |
307 | - no_button): |
308 | - """Fake asking a question.""" |
309 | - self.parent = parent |
310 | - self.title = title |
311 | - self.text = text |
312 | - self.yes_button = yes_button |
313 | - self.no_button = no_button |
314 | - return self.answer |
315 | - |
316 | - self.patch(gui.QtGui.QMessageBox, 'question', fake_question) |
317 | - |
318 | - def user_wants_to_update_true(self): |
319 | - """Test the question.""" |
320 | + self.ok_button = None |
321 | + |
322 | + class FakeMessageBox(object): |
323 | + """A fake message box.""" |
324 | + |
325 | + No = 'No' |
326 | + Yes = 'Yes' |
327 | + Ok = 'Ok' |
328 | + |
329 | + @classmethod |
330 | + def question(cls, parent, title, text, yes_button, |
331 | + no_button): |
332 | + """Fake asking a question.""" |
333 | + self.parent = parent |
334 | + self.title = title |
335 | + self.text = text |
336 | + self.yes_button = yes_button |
337 | + self.no_button = no_button |
338 | + return self.answer |
339 | + |
340 | + @classmethod |
341 | + def warning(cls, parent, title, text, ok_button): |
342 | + """Fake warning the user.""" |
343 | + self.parent = parent |
344 | + self.title = title |
345 | + self.text = text |
346 | + self.ok_button = ok_button |
347 | + return self.answer |
348 | + |
349 | + self.patch(gui.QtGui, 'QMessageBox', FakeMessageBox) |
350 | + |
351 | + def _assert_question(self, question_title, question_text): |
352 | + """Assert the execution of a question.""" |
353 | + self.assertEqual(None, self.parent) |
354 | + self.assertEqual(self.title, question_title) |
355 | + self.assertEqual(self.text, question_text) |
356 | + self.assertEqual(self.yes_button, gui.QtGui.QMessageBox.Yes) |
357 | + self.assertEqual(self.no_button, gui.QtGui.QMessageBox.No) |
358 | + |
359 | + def _assert_true_question(self, question_fn, question_title, |
360 | + question_text): |
361 | + """Assert a positive answer to a question.""" |
362 | self.answer = gui.QtGui.QMessageBox.Yes |
363 | - self.assertTrue(gui.user_wants_to_update(), 'User wants to update.') |
364 | - # lets assert the parameters |
365 | - self.assertTrue(None, self.parent) |
366 | - self.assertTrue(self.title, gui.UPDATE_TITLE) |
367 | - self.assertTrue(self.text, gui.UPDATE_SOFTWARE) |
368 | - self.assertTrue(self.yes_button, gui.QtGui.QMessageBox.Yes) |
369 | - self.assertTrue(self.no_button, gui.QtGui.QMessageBox.No) |
370 | + self.assertTrue(question_fn()) |
371 | + self._assert_question(question_title, question_text) |
372 | |
373 | - def user_wants_to_update_false(self): |
374 | - """Test the question.""" |
375 | + def _assert_false_question(self, question_fn, question_title, |
376 | + question_text): |
377 | + """Assert a negative answer to a question.""" |
378 | self.answer = gui.QtGui.QMessageBox.No |
379 | - msg = 'user_wants_to_update must return False when the answer is No.' |
380 | - self.assertFalse(gui.user_wants_to_update(), msg) |
381 | - # lets assert the parameters |
382 | - self.assertTrue(None, self.parent) |
383 | - self.assertTrue(self.title, gui.UPDATE_TITLE) |
384 | - self.assertTrue(self.text, gui.UPDATE_SOFTWARE) |
385 | - self.assertTrue(self.yes_button, gui.QtGui.QMessageBox.Yes) |
386 | - self.assertTrue(self.no_button, gui.QtGui.QMessageBox.No) |
387 | + self.assertFalse(question_fn()) |
388 | + self._assert_question(question_title, question_text) |
389 | + |
390 | + def test_user_wants_to_update_true(self): |
391 | + """Test the question.""" |
392 | + self._assert_true_question(gui.user_wants_to_update, gui.UPDATE_TITLE, |
393 | + gui.UPDATE_SOFTWARE) |
394 | + |
395 | + def test_user_wants_to_update_false(self): |
396 | + """Test the question.""" |
397 | + self._assert_false_question(gui.user_wants_to_update, gui.UPDATE_TITLE, |
398 | + gui.UPDATE_SOFTWARE) |
399 | + |
400 | + def test_user_wants_to_remove_true(self): |
401 | + """Test the question.""" |
402 | + self._assert_true_question(gui.user_wants_to_remove_old_beta, |
403 | + gui.REMOVE_OLD_BETA_TITLE, |
404 | + gui.REMOVE_OLD_BETA) |
405 | + |
406 | + def test_user_wants_to_remove_false(self): |
407 | + """Test the question.""" |
408 | + self._assert_false_question(gui.user_wants_to_remove_old_beta, |
409 | + gui.REMOVE_OLD_BETA_TITLE, |
410 | + gui.REMOVE_OLD_BETA) |
411 | + |
412 | + def test_user_wants_to_migrate_true(self): |
413 | + """Test the question.""" |
414 | + self._assert_true_question(gui.user_wants_to_migrate_data, |
415 | + gui.MIGRATE_OLD_BETA_DATA_TITLE, |
416 | + gui.MIGRATE_OLD_BETA) |
417 | + |
418 | + def test_user_wants_to_migrate_false(self): |
419 | + """Test the question.""" |
420 | + self._assert_false_question(gui.user_wants_to_migrate_data, |
421 | + gui.MIGRATE_OLD_BETA_DATA_TITLE, |
422 | + gui.MIGRATE_OLD_BETA) |
423 | + |
424 | + def _assert_warn_user(self, warn_fn, title, text): |
425 | + """Assert waning a user.""" |
426 | + self.assertEqual(None, warn_fn()) |
427 | + self.assertEqual(None, self.parent) |
428 | + self.assertEqual(self.title, title) |
429 | + self.assertEqual(self.text, text) |
430 | + self.assertEqual(self.ok_button, gui.QtGui.QMessageBox.Ok) |
431 | + |
432 | + def test_warn_user_data_migration(self): |
433 | + """Test warning the user.""" |
434 | + self._assert_warn_user(gui.warn_user_data_not_migrated, |
435 | + gui.MIGRATE_OLD_BETA_DATA_TITLE, |
436 | + gui.MIGRATE_OLD_BETA_DATA_ERROR) |
437 | + |
438 | + def test_warn_user_old_app_removal(self): |
439 | + """Test warning the user.""" |
440 | + self._assert_warn_user(gui.warn_user_beta_not_removed, |
441 | + gui.REMOVE_OLD_BETA_TITLE, |
442 | + gui.REMOVE_OLD_BETA_ERROR) |
443 | |
444 | === modified file 'ubuntuone_installer/gui/qt/utils/__init__.py' |
445 | --- ubuntuone_installer/gui/qt/utils/__init__.py 2011-11-11 19:27:39 +0000 |
446 | +++ ubuntuone_installer/gui/qt/utils/__init__.py 2011-12-19 21:30:29 +0000 |
447 | @@ -42,6 +42,7 @@ |
448 | uninstall_old_beta = windows.uninstall_old_beta |
449 | migrate_old_data = windows.migrate_old_data |
450 | check_updates = windows.check_updates |
451 | + perform_old_beta_data_migration = windows.perform_old_beta_data_migration |
452 | else: |
453 | from ubuntuone_installer.gui.qt.utils import linux |
454 | uninstall_application = linux.uninstall_application |
455 | @@ -54,6 +55,7 @@ |
456 | uninstall_old_beta = lambda *args, **kwargs: None |
457 | migrate_old_data = lambda *args, **kwargs: None |
458 | check_updates = lambda *args, **kwargs: None |
459 | + perform_old_beta_data_migration = lambda *args, **kwargs: None |
460 | # pylint: enable=C0103 |
461 | |
462 | |
463 | @@ -76,6 +78,10 @@ |
464 | logger.info('Updates checked, stopping.') |
465 | stop_cb() |
466 | else: # No credentials |
467 | + # if there are no credentials it usually means that we |
468 | + # are installing the application, before we do anything |
469 | + # lets check if the old beta is present |
470 | + yield perform_old_beta_data_migration(gui) |
471 | logger.info('Got empty credentials, starting wizard app.') |
472 | window = gui.MainWindow(close_callback=stop_cb, |
473 | installing=installing) |
474 | |
475 | === modified file 'ubuntuone_installer/gui/qt/utils/tests/test_common.py' |
476 | --- ubuntuone_installer/gui/qt/utils/tests/test_common.py 2011-11-11 19:28:10 +0000 |
477 | +++ ubuntuone_installer/gui/qt/utils/tests/test_common.py 2011-12-19 21:30:29 +0000 |
478 | @@ -69,11 +69,19 @@ |
479 | |
480 | self.start_cp = lambda with_icon: \ |
481 | self.called.extend(('start_cp', with_icon)) |
482 | + |
483 | self.patch(utils, 'start_control_panel', self.start_cp) |
484 | |
485 | self.check_updates = lambda _: self.called.append('check_updates') |
486 | + |
487 | self.patch(utils, 'check_updates', self.check_updates) |
488 | |
489 | + self.migrate_data_cb = lambda gui: \ |
490 | + self.called.extend(('migrate_data_cb', gui)) |
491 | + |
492 | + self.patch(utils, 'perform_old_beta_data_migration', |
493 | + self.migrate_data_cb) |
494 | + |
495 | self.patch(gui, 'MainWindow', FakeWindow) |
496 | |
497 | @defer.inlineCallbacks |
498 | @@ -110,3 +118,4 @@ |
499 | self.assertTrue(FakeWindow.visible) |
500 | msgs = ('Got empty credentials', 'starting wizard') |
501 | self.assertTrue(self.memento.check_info(*msgs)) |
502 | + self.assertEqual(self.called, ['migrate_data_cb', gui]) |
503 | |
504 | === modified file 'ubuntuone_installer/gui/qt/utils/tests/test_windows.py' |
505 | --- ubuntuone_installer/gui/qt/utils/tests/test_windows.py 2011-11-11 19:27:39 +0000 |
506 | +++ ubuntuone_installer/gui/qt/utils/tests/test_windows.py 2011-12-19 21:30:29 +0000 |
507 | @@ -37,6 +37,9 @@ |
508 | from ubuntuone_installer.gui.qt import utils |
509 | from ubuntuone_installer.gui.qt.tests import BaseTestCase |
510 | |
511 | +# we want to test private methods |
512 | +# pylint:disable=W0212 |
513 | + |
514 | |
515 | class UninstallerTestCase(BaseTestCase): |
516 | |
517 | @@ -395,7 +398,7 @@ |
518 | self.patch(utils.windows, 'deferToThread', |
519 | fake_msi_install_product) |
520 | self.assertFailure(utils.uninstall_old_beta(), |
521 | - utils.windows.MsiException) |
522 | + utils.windows.UninstallException) |
523 | self.assertEqual(self.called['property_uid'], |
524 | utils.windows.OLD_BETA_UID_KEY) |
525 | self.assertEqual(self.called['property_name'], u'LocalPackage') |
526 | @@ -416,7 +419,7 @@ |
527 | self.patch(utils.windows, 'get_property_for_product', |
528 | fake_get_property_for_product) |
529 | self.assertFailure(utils.uninstall_old_beta(), |
530 | - utils.windows.MsiException) |
531 | + utils.windows.UninstallException) |
532 | self.assertEqual(self.called['uid'], utils.windows.OLD_BETA_UID_KEY) |
533 | self.assertEqual(self.called['property_name'], u'LocalPackage') |
534 | |
535 | @@ -527,8 +530,49 @@ |
536 | self.assertEqual('', self._called[0][4]) |
537 | self.assertEqual(0, self._called[0][5]) |
538 | |
539 | - def test_get_auto_update_path(self): |
540 | - """Test the method used to get the autoupdate.""" |
541 | + |
542 | +class UpdatePathTestCase(BaseTestCase): |
543 | + """Test getting the update path.""" |
544 | + |
545 | + @defer.inlineCallbacks |
546 | + def setUp(self): |
547 | + """Set the different tests.""" |
548 | + yield super(UpdatePathTestCase, self).setUp() |
549 | + self.module_path = os.path.join('.', 'root', 'exe', 'dist') |
550 | + self.module_path = os.path.abspath(self.module_path) |
551 | + self.patch(os.path, 'exists', lambda *args: True) |
552 | + |
553 | + def _clean_file(self, module, path): |
554 | + """Set back the correct path.""" |
555 | + module.__file__ = path |
556 | + |
557 | + def _clean_frozen(self, old_executable): |
558 | + """Set back not to be frozen.""" |
559 | + del sys.frozen |
560 | + sys.executable = old_executable |
561 | + |
562 | + def test_get_update_path_not_frozen(self): |
563 | + """Test we return the path to levels up to the dist.""" |
564 | + old_utils_path = utils.windows.__file__ |
565 | + utils.windows.__file__ = os.path.join(self.module_path, 'windows.py') |
566 | + self.addCleanup(self._clean_file, utils.windows, old_utils_path) |
567 | + expected_path = os.path.join('root', |
568 | + utils.windows.AUTO_UPDATE_EXE) |
569 | + expected_path = os.path.abspath(expected_path) |
570 | + path = utils.windows._get_update_path() |
571 | + self.assertEqual(expected_path, path) |
572 | + |
573 | + def test_get_update_path_frozen(self): |
574 | + """Test we return the path to levels up to the dist.""" |
575 | + sys.frozen = True |
576 | + old_exe = sys.executable |
577 | + sys.executable = os.path.join(self.module_path, 'ubuntuone.exe') |
578 | + self.addCleanup(self._clean_frozen, old_exe) |
579 | + expected_path = os.path.join('root', 'exe', |
580 | + utils.windows.AUTO_UPDATE_EXE) |
581 | + expected_path = os.path.abspath(expected_path) |
582 | + path = utils.windows._get_update_path() |
583 | + self.assertEqual(expected_path, path) |
584 | |
585 | |
586 | class CheckUpdatesTestCase(BaseTestCase): |
587 | |
588 | === modified file 'ubuntuone_installer/gui/qt/utils/windows.py' |
589 | --- ubuntuone_installer/gui/qt/utils/windows.py 2011-11-11 19:27:39 +0000 |
590 | +++ ubuntuone_installer/gui/qt/utils/windows.py 2011-12-19 21:30:29 +0000 |
591 | @@ -67,9 +67,10 @@ |
592 | # LONG_PATH_PREFIX will always be appended only to windows paths, |
593 | # which should always be unicode. |
594 | LONG_PATH_PREFIX = u'\\\\?\\' |
595 | - |
596 | - |
597 | -class MsiException(Exception): |
598 | +AUTO_UPDATE_EXE = 'autoupdate-windows.exe' |
599 | + |
600 | + |
601 | +class UninstallException(Exception): |
602 | """Raised when there are msi issues.""" |
603 | |
604 | |
605 | @@ -97,8 +98,12 @@ |
606 | exec_path = os.path.abspath(sys.executable) |
607 | else: |
608 | exec_path = os.path.dirname(__file__) |
609 | + # we take as an axiom that the python code is present in a dist |
610 | + # folder (whatever the path is) and that the autoupdate is |
611 | + # present in a level above it |
612 | + exec_path = os.path.dirname(exec_path) |
613 | folder = os.path.dirname(exec_path) |
614 | - update_path = os.path.join(folder, "autoupdate-windows.exe") |
615 | + update_path = os.path.join(folder, AUTO_UPDATE_EXE) |
616 | if os.path.exists(update_path): |
617 | return update_path |
618 | return None |
619 | @@ -257,10 +262,10 @@ |
620 | result = yield deferToThread(ctypes.windll.msi.MsiInstallProductW, |
621 | uninstall_path, command_line) |
622 | if result != ERROR_SUCCESS: |
623 | - raise MsiException('Could not remove old beta.') |
624 | + raise UninstallException('Could not remove old beta.') |
625 | else: |
626 | # the local file is missing so we cannot un install it :( |
627 | - raise MsiException('Could not remove old beta.') |
628 | + raise UninstallException('Could not remove old beta.') |
629 | |
630 | |
631 | def _append_long_path(path): |
632 | @@ -302,3 +307,26 @@ |
633 | new_full_path = os.path.join(new_location, path) |
634 | yield deferToThread(shutil.move, old_full_path, |
635 | new_full_path) |
636 | + |
637 | + |
638 | +@defer.inlineCallbacks |
639 | +def perform_old_beta_data_migration(gui): |
640 | + """Perform the migration from the old beta.""" |
641 | + if is_old_beta_installed() and \ |
642 | + gui.user_wants_to_remove_old_beta(): |
643 | + logger.debug('Old beta is installed and user wants to remove it.') |
644 | + try: |
645 | + # uninstall the msi and migrate data |
646 | + yield uninstall_old_beta() |
647 | + # ask the user if he wants to move his data |
648 | + if gui.user_wants_to_migrate_data(): |
649 | + yield migrate_old_data() |
650 | + except UninstallException: |
651 | + logger.error('Could not uninstall msi: %s') |
652 | + gui.warn_user_beta_not_removed() |
653 | + except DataMigrationException: |
654 | + # we did uninstall the msi \o/ but failed in the data migration. |
655 | + # This is not a big deal, lets just tell the user that he has to |
656 | + # manually do it |
657 | + logger.error('Could not migrate data: %s') |
658 | + gui.warn_user_data_not_migrated() |
659 | |
660 | === modified file 'ubuntuone_installer/tests/__init__.py' |
661 | --- ubuntuone_installer/tests/__init__.py 2011-10-28 11:00:42 +0000 |
662 | +++ ubuntuone_installer/tests/__init__.py 2011-12-19 21:30:29 +0000 |
663 | @@ -21,7 +21,7 @@ |
664 | |
665 | from twisted.internet import defer |
666 | |
667 | -from ubuntuone.devtools.testcase import TestCase as BaseTestCase |
668 | +from ubuntuone.devtools.testcases import TestCase as BaseTestCase |
669 | |
670 | |
671 | class TestCase(BaseTestCase): |
Looks good!