Merge lp:~ralsina/ubuntuone-windows-installer/cloud-to-cloud into lp:ubuntuone-windows-installer

Proposed by Roberto Alsina
Status: Merged
Approved by: Natalia Bidart
Approved revision: 63
Merged at revision: 56
Proposed branch: lp:~ralsina/ubuntuone-windows-installer/cloud-to-cloud
Merge into: lp:ubuntuone-windows-installer
Diff against target: 708 lines (+219/-236)
9 files modified
data/qt/sync_now_or_later.ui (+0/-89)
ubuntuone_installer/gui/qt/folders.py (+4/-1)
ubuntuone_installer/gui/qt/gui.py (+7/-13)
ubuntuone_installer/gui/qt/local_folders.py (+10/-10)
ubuntuone_installer/gui/qt/main/windows.py (+2/-6)
ubuntuone_installer/gui/qt/sync_now_or_later.py (+38/-9)
ubuntuone_installer/gui/qt/tests/test_gui.py (+13/-63)
ubuntuone_installer/gui/qt/tests/test_local_folders.py (+52/-45)
ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py (+93/-0)
To merge this branch: bzr merge lp:~ralsina/ubuntuone-windows-installer/cloud-to-cloud
Reviewer Review Type Date Requested Status
Natalia Bidart (community) Approve
Diego Sarmentero (community) Approve
Review via email: mp+74457@code.launchpad.net

Commit message

- Improve the folder sync selection workflow (LP: #843865).

Description of the change

Improve the sync selection workflow.

To test IRL:

Start the installer. Login with an account that has UDFs or shares. After the "login successful" screen, you should get an overlay over an empty page for a bit, and then the "Folders" page. After that, the "Local folders" page, containing only subscribed UDFs and suggested ones.

Start the installer. Login with an account that has no UDFs or shares. After the "login successful" screen, you should get an overlay over an empty page for a bit, and then the "Local folders" page, containing only suggested UDFs.

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

EOLs

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

+1

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

Question:

when entering the SyncNowOrLaterPage, where its initializePage calls get_info and the overlay is shown, where is the overlay hid?

* Can you please move the self.patch(os.path, 'getsize', lambda *args: 0) to the testcase setup?
I'm getting this for test_status_after_get_info:

    test_status_after_get_info ... Exception in thread Thread-19:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "/home/nessita/canonical/u1/windows-installer/review_cloud-to-cloud/ubuntuone_installer/gui/qt/local_folders.py", line 86, in run
    total_size += os.path.getsize(fp)
  File "/usr/lib/python2.7/genericpath.py", line 49, in getsize
    return os.stat(filename).st_size
OSError: [Errno 2] No such file or directory: '/tmp/tmp5i98v9/test_file'

* When testing IRL, right after the SSO's "Congratulations" page, I got an empty page with a loading overlay. A few seconds later, the overlay went away, but the page remained empty (I have a screenshot if you need it).
I had to click next on the empty page to get the cloud to computer page.

* And I never for the computer to cloud page :-/.

review: Needs Fixing
Revision history for this message
Roberto Alsina (ralsina) wrote :

> Question:
>
> when entering the SyncNowOrLaterPage, where its initializePage calls get_info
> and the overlay is shown, where is the overlay hid?

In the wizard's next()

> * Can you please move the self.patch(os.path, 'getsize', lambda *args: 0) to
> the testcase setup?
> I'm getting this for test_status_after_get_info:
>
> test_status_after_get_info ... Exception in thread Thread-19:
> Traceback (most recent call last):
> File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
> self.run()
> File "/home/nessita/canonical/u1/windows-installer/review_cloud-to-
> cloud/ubuntuone_installer/gui/qt/local_folders.py", line 86, in run
> total_size += os.path.getsize(fp)
> File "/usr/lib/python2.7/genericpath.py", line 49, in getsize
> return os.stat(filename).st_size
> OSError: [Errno 2] No such file or directory: '/tmp/tmp5i98v9/test_file'

Sure. I am not sure if that won't break some other test that actually uses getsize though. Will check it.

>
> * When testing IRL, right after the SSO's "Congratulations" page, I got an
> empty page with a loading overlay. A few seconds later, the overlay went away,
> but the page remained empty (I have a screenshot if you need it).
> I had to click next on the empty page to get the cloud to computer page.

I believe you!

> * And I never for the computer to cloud page :-/.

That one should always be there, even if you get the "cloud to computer" page, it should after that.

62. By Roberto Alsina

separate tests that need getsize into a separate testcase

63. By Roberto Alsina

Make it work right with latest trunk

Revision history for this message
Roberto Alsina (ralsina) wrote :

The white page problem was caused by something that merged into trunk interacting badly with this branch. Fixed in revno 63

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

The white page problem is indeed fixed but I still don't get the computer-to-cloud page.

So, after I login successfully, I get the congratulations page. Then, the loading overlay (when I click on setup now). Then, the cloud to computer screen, and then, zás, the last page with the "IMAGE GOES HERE" legend.

Am I missing something?

review: Needs Fixing
Revision history for this message
Roberto Alsina (ralsina) wrote :

I can't reproduce it. I included it in the build I just uploaded, let's see if it works?

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

I tested with a fresh account and it worked, so approving.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file 'data/qt/sync_now_or_later.ui'
--- data/qt/sync_now_or_later.ui 2011-09-02 12:58:29 +0000
+++ data/qt/sync_now_or_later.ui 1970-01-01 00:00:00 +0000
@@ -1,89 +0,0 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>Form</class>
4 <widget class="QWidget" name="Form">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>426</width>
10 <height>387</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Form</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout">
17 <property name="spacing">
18 <number>24</number>
19 </property>
20 <property name="topMargin">
21 <number>0</number>
22 </property>
23 <item>
24 <widget class="QLabel" name="label">
25 <property name="font">
26 <font>
27 <pointsize>14</pointsize>
28 <weight>75</weight>
29 <bold>true</bold>
30 </font>
31 </property>
32 <property name="text">
33 <string>Syncing your computer with the cloud</string>
34 </property>
35 </widget>
36 </item>
37 <item>
38 <widget class="QLabel" name="label_9">
39 <property name="text">
40 <string>It seems that you have already some folders in the cloud.
41Do you want to sync everything with this computer now?</string>
42 </property>
43 <property name="wordWrap">
44 <bool>true</bool>
45 </property>
46 </widget>
47 </item>
48 <item>
49 <widget class="QRadioButton" name="sync_now">
50 <property name="text">
51 <string>Yes, sync all now</string>
52 </property>
53 <property name="checked">
54 <bool>true</bool>
55 </property>
56 </widget>
57 </item>
58 <item>
59 <widget class="QRadioButton" name="sync_later">
60 <property name="text">
61 <string>No, I'll do it later</string>
62 </property>
63 </widget>
64 </item>
65 <item>
66 <widget class="QRadioButton" name="sync_custom">
67 <property name="text">
68 <string>Yes, but I want to choose what to sync</string>
69 </property>
70 </widget>
71 </item>
72 <item>
73 <spacer name="verticalSpacer">
74 <property name="orientation">
75 <enum>Qt::Vertical</enum>
76 </property>
77 <property name="sizeHint" stdset="0">
78 <size>
79 <width>20</width>
80 <height>54</height>
81 </size>
82 </property>
83 </spacer>
84 </item>
85 </layout>
86 </widget>
87 <resources/>
88 <connections/>
89</ui>
900
=== modified file 'ubuntuone_installer/gui/qt/folders.py'
--- ubuntuone_installer/gui/qt/folders.py 2011-09-01 21:26:50 +0000
+++ ubuntuone_installer/gui/qt/folders.py 2011-09-08 14:21:18 +0000
@@ -25,6 +25,7 @@
25from ubuntu_sso.qt.gui import SSOWizardPage25from ubuntu_sso.qt.gui import SSOWizardPage
26from ubuntuone.controlpanel.gui.qt import folders26from ubuntuone.controlpanel.gui.qt import folders
2727
28from ubuntuone_installer.gui import NEXT
28from ubuntuone_installer.gui.qt.ui import folders_ui29from ubuntuone_installer.gui.qt.ui import folders_ui
2930
30_ = gettext.gettext31_ = gettext.gettext
@@ -55,7 +56,9 @@
55 QtGui.QWizard.BackButton,56 QtGui.QWizard.BackButton,
56 QtGui.QWizard.Stretch,57 QtGui.QWizard.Stretch,
57 QtGui.QWizard.NextButton])58 QtGui.QWizard.NextButton])
58 self.wizard()._next_id = self.wizard().CONGRATULATIONS_PAGE59 self.wizard().setButtonText(QtGui.QWizard.NextButton,
60 NEXT)
61 self.wizard()._next_id = self.wizard().local_folders_page_id
5962
60 # pylint: enable=C010363 # pylint: enable=C0103
6164
6265
=== modified file 'ubuntuone_installer/gui/qt/gui.py'
--- ubuntuone_installer/gui/qt/gui.py 2011-09-07 15:51:10 +0000
+++ ubuntuone_installer/gui/qt/gui.py 2011-09-08 14:21:18 +0000
@@ -82,7 +82,6 @@
82TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"82TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
83CREDENTIALS_ERROR_TITLE = _("Error getting credentials")83CREDENTIALS_ERROR_TITLE = _("Error getting credentials")
84CREDENTIALS_ERROR = _('Application will close.\n\n%r')84CREDENTIALS_ERROR = _('Application will close.\n\n%r')
85STARTING_CP_ERROR = _('Error starting Ubuntu One')
86SKIP_TOUR = _("Skip tour, go to Dashboard")85SKIP_TOUR = _("Skip tour, go to Dashboard")
87START_SETUP = _("Start setup")86START_SETUP = _("Start setup")
88# Invalid name logger87# Invalid name logger
@@ -237,12 +236,6 @@
237 self.wizard().setButtonLayout([236 self.wizard().setButtonLayout([
238 QtGui.QWizard.Stretch,237 QtGui.QWizard.Stretch,
239 QtGui.QWizard.FinishButton])238 QtGui.QWizard.FinishButton])
240 if self.field("sync_now").toBool() \
241 or self.field("sync_custom").toBool():
242 self.ui.progressContainer.setVisible(True)
243 else:
244 self.ui.progressContainer.setVisible(False)
245
246 # Set FinishButton as default when the page is shown.239 # Set FinishButton as default when the page is shown.
247 self.wizard().button(QtGui.QWizard.FinishButton).setDefault(True)240 self.wizard().button(QtGui.QWizard.FinishButton).setDefault(True)
248 self.wizard().button(QtGui.QWizard.FinishButton).style().unpolish(241 self.wizard().button(QtGui.QWizard.FinishButton).style().unpolish(
@@ -372,11 +365,11 @@
372365
373 # End of SSO pages366 # End of SSO pages
374367
375 self.local_folders_page = LocalFoldersPage()
376 self.local_folders_page_id = self.addPage(self.local_folders_page)
377 self.SYNC_NOW_OR_LATER_PAGE = self.addPage(SyncNowOrLaterPage())368 self.SYNC_NOW_OR_LATER_PAGE = self.addPage(SyncNowOrLaterPage())
378 self.folders_page = FoldersPage()369 self.folders_page = FoldersPage()
379 self.folders_page_id = self.addPage(self.folders_page)370 self.folders_page_id = self.addPage(self.folders_page)
371 self.local_folders_page = LocalFoldersPage()
372 self.local_folders_page_id = self.addPage(self.local_folders_page)
380 self.preferences_page = PreferencesPage()373 self.preferences_page = PreferencesPage()
381 self.preferences_page_id = self.addPage(self.preferences_page)374 self.preferences_page_id = self.addPage(self.preferences_page)
382 self.CONGRATULATIONS_PAGE = self.addPage(CongratulationsPage())375 self.CONGRATULATIONS_PAGE = self.addPage(CongratulationsPage())
@@ -402,7 +395,8 @@
402 """Show the next page to display and remove the form errors label."""395 """Show the next page to display and remove the form errors label."""
403 self.overlay.hide()396 self.overlay.hide()
404 self.form_errors_label.hide()397 self.form_errors_label.hide()
405 self.currentPage().layout().removeWidget(self.form_errors_label)398 if self.currentPage().layout():
399 self.currentPage().layout().removeWidget(self.form_errors_label)
406 self.form_errors_label.setParent(None)400 self.form_errors_label.setParent(None)
407 super(MainWindow, self).next()401 super(MainWindow, self).next()
408402
@@ -417,13 +411,13 @@
417 """Called on successful login."""411 """Called on successful login."""
418 self._next_id = self.SUCCESS_PAGE412 self._next_id = self.SUCCESS_PAGE
419 self.next()413 self.next()
420 self._next_id = self.local_folders_page_id414 self._next_id = self.SYNC_NOW_OR_LATER_PAGE
421415
422 def registration_success_slot(self):416 def registration_success_slot(self):
423 """Called on successful registration."""417 """Called on successful registration."""
424 self._next_id = self.SUCCESS_PAGE418 self._next_id = self.SUCCESS_PAGE
425 self.next()419 self.next()
426 self._next_id = self.local_folders_page_id420 self._next_id = self.SYNC_NOW_OR_LATER_PAGE
427421
428 def done(self, result):422 def done(self, result):
429 """The main window is being closed, call any custom callback."""423 """The main window is being closed, call any custom callback."""
@@ -448,7 +442,7 @@
448 if page_id < self.SIGNIN_PAGE:442 if page_id < self.SIGNIN_PAGE:
449 self.sideWidget().ui.states_frame.hide()443 self.sideWidget().ui.states_frame.hide()
450 self.sideWidget().set_stage(0)444 self.sideWidget().set_stage(0)
451 elif page_id < self.local_folders_page_id:445 elif page_id < self.SYNC_NOW_OR_LATER_PAGE:
452 self.sideWidget().ui.states_frame.show()446 self.sideWidget().ui.states_frame.show()
453 self.sideWidget().set_stage(1)447 self.sideWidget().set_stage(1)
454 elif page_id < self.CONGRATULATIONS_PAGE:448 elif page_id < self.CONGRATULATIONS_PAGE:
455449
=== modified file 'ubuntuone_installer/gui/qt/local_folders.py'
--- ubuntuone_installer/gui/qt/local_folders.py 2011-09-05 21:12:02 +0000
+++ ubuntuone_installer/gui/qt/local_folders.py 2011-09-08 14:21:18 +0000
@@ -113,7 +113,7 @@
113 QtGui.QWizard.NextButton])113 QtGui.QWizard.NextButton])
114 self.wizard().setButtonText(QtGui.QWizard.NextButton,114 self.wizard().setButtonText(QtGui.QWizard.NextButton,
115 NEXT)115 NEXT)
116 self.wizard()._next_id = self.wizard().SYNC_NOW_OR_LATER_PAGE116 self.wizard()._next_id = self.wizard().CONGRATULATIONS_PAGE
117 # Start with this invisible117 # Start with this invisible
118 self.ui.offer_frame.setVisible(False)118 self.ui.offer_frame.setVisible(False)
119 # Show overlay until we have server data119 # Show overlay until we have server data
@@ -134,16 +134,16 @@
134 self.folders_info.append(volume)134 self.folders_info.append(volume)
135 self.ui.folder_list.clear()135 self.ui.folder_list.clear()
136 for folder in self.folders_info:136 for folder in self.folders_info:
137 item = yield self.add_folder(137 if folder['subscribed']:
138 os.path.expanduser(folder['path']),138 item = yield self.add_folder(
139 validate=False,139 os.path.expanduser(folder['path']),
140 volume_id=folder['volume_id'],140 validate=False,
141 calculate=False,141 volume_id=folder['volume_id'],
142 )142 calculate=False,
143 if item:143 )
144 if folder['subscribed']:144 if item:
145 item.setCheckState(0, QtCore.Qt.Checked)145 item.setCheckState(0, QtCore.Qt.Checked)
146 item.size = 0146 item.size = 0
147 for folder_name in default_folders():147 for folder_name in default_folders():
148 item = yield self.add_folder(folder_name, validate=True)148 item = yield self.add_folder(folder_name, validate=True)
149 self.timer.start(2000)149 self.timer.start(2000)
150150
=== modified file 'ubuntuone_installer/gui/qt/main/windows.py'
--- ubuntuone_installer/gui/qt/main/windows.py 2011-09-07 11:24:12 +0000
+++ ubuntuone_installer/gui/qt/main/windows.py 2011-09-08 14:21:18 +0000
@@ -46,12 +46,8 @@
46def success_cb(creds, gui):46def success_cb(creds, gui):
47 """Handle credentials success."""47 """Handle credentials success."""
48 if creds: # Have credentials already48 if creds: # Have credentials already
49 try:49 from ubuntuone_installer.gui.qt import utils
50 from ubuntuone_installer.gui.qt import utils50 utils.start_control_panel()
51 utils.start_control_panel()
52 except OSError:
53 QtGui.QMessageBox.critical(
54 None, "Ubuntu One", gui.STARTING_CP_ERROR)
55 stop()51 stop()
56 else: # No credentials52 else: # No credentials
57 window = gui.MainWindow(close_callback=stop)53 window = gui.MainWindow(close_callback=stop)
5854
=== modified file 'ubuntuone_installer/gui/qt/sync_now_or_later.py'
--- ubuntuone_installer/gui/qt/sync_now_or_later.py 2011-08-10 21:37:30 +0000
+++ ubuntuone_installer/gui/qt/sync_now_or_later.py 2011-09-08 14:21:18 +0000
@@ -19,8 +19,16 @@
19"""The user interface for the Ubuntu One Installer."""19"""The user interface for the Ubuntu One Installer."""
2020
21from PyQt4 import QtGui21from PyQt4 import QtGui
2222from twisted.internet.defer import inlineCallbacks
23from ubuntuone_installer.gui.qt.ui import sync_now_or_later_ui23from ubuntuone.controlpanel import backend
24
25from ubuntuone_installer.gui import NEXT
26from ubuntuone_installer.logger import setup_logging
27
28# Invalid name logger
29# pylint: disable=C0103
30logger = setup_logging('qt.sync_now_or_later')
31# pylint: enable=C0103
2432
2533
26class SyncNowOrLaterPage(QtGui.QWizardPage):34class SyncNowOrLaterPage(QtGui.QWizardPage):
@@ -28,11 +36,8 @@
2836
29 def __init__(self, parent=None):37 def __init__(self, parent=None):
30 QtGui.QWizardPage.__init__(self, parent)38 QtGui.QWizardPage.__init__(self, parent)
31 self.ui = sync_now_or_later_ui.Ui_Form()39 self.has_cloud_folders = False
32 self.ui.setupUi(self)40 self.cp_backend = None
33 self.registerField("sync_now", self.ui.sync_now)
34 self.registerField("sync_later", self.ui.sync_later)
35 self.registerField("sync_custom", self.ui.sync_custom)
3641
37 # Invalid names of Qt-inherited methods42 # Invalid names of Qt-inherited methods
38 # pylint: disable=C010343 # pylint: disable=C0103
@@ -42,10 +47,34 @@
42 self.wizard().setOption(QtGui.QWizard.HaveCustomButton1, False)47 self.wizard().setOption(QtGui.QWizard.HaveCustomButton1, False)
43 self.wizard().setOption(QtGui.QWizard.NoCancelButton, True)48 self.wizard().setOption(QtGui.QWizard.NoCancelButton, True)
44 self.wizard()._next_id = None49 self.wizard()._next_id = None
50 self.wizard().overlay.show()
51 self.wizard().setButtonText(QtGui.QWizard.NextButton,
52 NEXT)
53 self.get_info()
4554
46 def nextId(self):55 def nextId(self):
47 """Go to the next page depending on the select field."""56 """Go to the next page depending on the select field."""
48 if self.field("sync_custom"):57 if self.has_cloud_folders:
49 return self.wizard().folders_page_id58 return self.wizard().folders_page_id
50 else:59 else:
51 return self.wizard().CONGRATULATIONS_PAGE60 return self.wizard().local_folders_page_id
61
62 @inlineCallbacks
63 def get_info(self):
64 """Get folder information from CP backend."""
65 # pylint: disable=W0702
66 try:
67 self.cp_backend = backend.ControlBackend()
68 volumes_info = yield self.cp_backend.volumes_info()
69 except:
70 logger.exception("Error getting backend info:")
71 else:
72 counter = 0
73 for _, _, volumes in volumes_info:
74 counter += len(volumes)
75 if counter > 1:
76 # there are UDFs or shares, show cloud-to-computer
77 self.has_cloud_folders = True
78 else:
79 self.has_cloud_folders = False
80 self.wizard().next()
5281
=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-09-08 13:41:10 +0000
+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-09-08 14:21:18 +0000
@@ -291,7 +291,7 @@
291 tree_folders = folders_page.folders_widget.ui.folders291 tree_folders = folders_page.folders_widget.ui.folders
292 self.assertEqual(tree_folders.isColumnHidden(2), True)292 self.assertEqual(tree_folders.isColumnHidden(2), True)
293 # pylint: disable=W0212293 # pylint: disable=W0212
294 self.assertEqual(self.ui._next_id, self.ui.CONGRATULATIONS_PAGE)294 self.assertEqual(self.ui._next_id, self.ui.local_folders_page_id)
295295
296 def test_folders_page_next_id(self):296 def test_folders_page_next_id(self):
297 """Check Folders Page UI."""297 """Check Folders Page UI."""
@@ -432,7 +432,6 @@
432 @skipIfOS('linux2', 'Windows-specific tests.')432 @skipIfOS('linux2', 'Windows-specific tests.')
433 def test_start_control_panel_frozen(self):433 def test_start_control_panel_frozen(self):
434 """When frozen, the control-panel has a path."""434 """When frozen, the control-panel has a path."""
435 self.ui.setStartId(self.ui.SYNC_NOW_OR_LATER_PAGE)
436 self.ui.restart()435 self.ui.restart()
437 self.ui.show()436 self.ui.show()
438 self.addCleanup(self.ui.hide)437 self.addCleanup(self.ui.hide)
@@ -476,66 +475,6 @@
476 self.assertEqual(self._called, False)475 self.assertEqual(self._called, False)
477 self.assertEqual(FakeAreYouSure.shown, False)476 self.assertEqual(FakeAreYouSure.shown, False)
478477
479 def test_later_accepts_cancel(self):
480 """Clicking 'Later' accepts cancellation."""
481 self.ui.setStartId(self.ui.SYNC_NOW_OR_LATER_PAGE)
482 self.ui.restart()
483 self.ui.show()
484 self.addCleanup(self.ui.hide)
485 gui.AreYouSure.result = 1
486 self.ui.show()
487 self.addCleanup(self.ui.hide)
488 self.ui.done(result=0)
489 self.assertEqual(self.ui.isVisible(), False)
490
491 def test_sync_now_shows_message(self):
492 """If the user selects 'Sync Now' the congrats page shows a message."""
493 congrats_page = self.ui.page(self.ui.CONGRATULATIONS_PAGE)
494 congrats_page.setField("sync_now", True)
495
496 # Show the congrats page
497 self.ui.setStartId(self.ui.CONGRATULATIONS_PAGE)
498 self.ui.restart()
499 self.ui.show()
500 self.addCleanup(self.ui.hide)
501
502 # Check the properties have the right values
503 self.assertEqual(congrats_page.field("sync_later").toBool(),
504 False)
505 self.assertEqual(
506 congrats_page.ui.progressContainer.isVisible(), True)
507
508 def test_sync_page_custom_field(self):
509 """If the user selects 'Sync Custom' we move to Folders page."""
510 sync_page = self.ui.page(self.ui.SYNC_NOW_OR_LATER_PAGE)
511 sync_page.setField("sync_custom", True)
512
513 # Show the Sync Now page
514 self.ui.setStartId(self.ui.SYNC_NOW_OR_LATER_PAGE)
515 self.ui.restart()
516 self.ui.show()
517 self.addCleanup(self.ui.hide)
518
519 # Check the navigation is correct
520 self.assertEqual(sync_page.nextId(), self.ui.folders_page_id)
521
522 def test_sync_later_hides_message(self):
523 """Selecting 'Sync Later' the congrats page hides a message."""
524 congrats_page = self.ui.page(self.ui.CONGRATULATIONS_PAGE)
525 congrats_page.setField("sync_later", True)
526
527 # Show the congrats page
528 self.ui.setStartId(self.ui.CONGRATULATIONS_PAGE)
529 self.ui.restart()
530 self.ui.show()
531 self.addCleanup(self.ui.hide)
532
533 # Check the properties have the right values
534 self.assertEqual(congrats_page.field("sync_now").toBool(),
535 False)
536 self.assertEqual(
537 congrats_page.ui.progressContainer.isVisible(), False)
538
539 def test_current_user_controller_parameters(self):478 def test_current_user_controller_parameters(self):
540 """Compare controller parameters with expected values."""479 """Compare controller parameters with expected values."""
541 self.assertEqual(self.ui.current_user_controller.args,480 self.assertEqual(self.ui.current_user_controller.args,
@@ -636,17 +575,21 @@
636575
637 """A fake MainWindow."""576 """A fake MainWindow."""
638577
639 overlay = FakeOverlay()
640 currentIdChanged = FakeSignal()578 currentIdChanged = FakeSignal()
641 loginSuccess = FakeSignal()579 loginSuccess = FakeSignal()
642 registrationSuccess = FakeSignal()580 registrationSuccess = FakeSignal()
643 userCancellation = FakeSignal()581 userCancellation = FakeSignal()
644 shown = False582 shown = False
645 SYNC_NOW_OR_LATER_PAGE = 4583 SYNC_NOW_OR_LATER_PAGE = 4
584 CONGRATULATIONS_PAGE = 5
585 folders_page_id = 6
586 local_folders_page_id = 7
646587
647 def __init__(self, close_callback=None):588 def __init__(self, close_callback=None):
648 self.button_texts = []589 self.button_texts = []
649 self.button_layout = None590 self.button_layout = None
591 self.options = []
592 self.overlay = FakeOverlay()
650593
651 def show(self):594 def show(self):
652 """Fake method."""595 """Fake method."""
@@ -661,6 +604,13 @@
661 """Fake setButtonText."""604 """Fake setButtonText."""
662 self.button_layout = layout605 self.button_layout = layout
663606
607 def setOption(self, *args):
608 """Fake setOption."""
609 self.options.append(args)
610
611 def next(self):
612 """Fake next."""
613
664614
665class SuccesPageTestCase(BaseTestCase):615class SuccesPageTestCase(BaseTestCase):
666 """Test the SuccessPage code."""616 """Test the SuccessPage code."""
667617
=== modified file 'ubuntuone_installer/gui/qt/tests/test_local_folders.py'
--- ubuntuone_installer/gui/qt/tests/test_local_folders.py 2011-09-05 22:00:40 +0000
+++ ubuntuone_installer/gui/qt/tests/test_local_folders.py 2011-09-08 14:21:18 +0000
@@ -26,9 +26,7 @@
26from PyQt4 import QtGui, QtCore26from PyQt4 import QtGui, QtCore
27from twisted.internet import defer27from twisted.internet import defer
2828
29from ubuntuone_installer.gui import (29from ubuntuone_installer.gui import NEXT
30 NEXT,
31)
32from ubuntuone_installer.gui.qt import local_folders30from ubuntuone_installer.gui.qt import local_folders
33from ubuntuone_installer.gui.qt.tests import BaseTestCase, TestCase31from ubuntuone_installer.gui.qt.tests import BaseTestCase, TestCase
34from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow32from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow
@@ -164,8 +162,8 @@
164 self.assertEqual(item.volume_id, "xyzzy")162 self.assertEqual(item.volume_id, "xyzzy")
165163
166164
167class LocalFoldersTestCase(BaseTestCase):165class LocalFoldersWithGetSizeTestCase(BaseTestCase):
168 """Test the LocalFoldersPage code."""166 """Test the LocalFoldersPage code using the real getsize."""
169167
170 class_ui = local_folders.LocalFoldersPage168 class_ui = local_folders.LocalFoldersPage
171169
@@ -183,6 +181,48 @@
183 self.addCleanup(shutil.rmtree, self.tmpdir)181 self.addCleanup(shutil.rmtree, self.tmpdir)
184 self.fake_wizard = FakeMainWindow()182 self.fake_wizard = FakeMainWindow()
185 self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)183 self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
184 super(LocalFoldersWithGetSizeTestCase, self).setUp()
185 self.patch(self.ui, "wizard", lambda: self.fake_wizard)
186
187 @defer.inlineCallbacks
188 def test_total_size(self):
189 """Test that the header reflects the change in item sizes."""
190 self.patch(self.ui, "show_hide_offer", self._set_called)
191 yield self.ui.get_info()
192 self.ui.ui.folder_list.clear()
193 self.ui.items = {}
194 item = yield self.ui.add_folder(self.tmpdir)
195 item.thread.run()
196 item.thread.join()
197 item.size = 1337
198 item.setCheckState(0, QtCore.Qt.Checked)
199 self.ui.update_sizes()
200 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
201 u"Space (1.5 KiB)")
202 self.assertEqual(self._called, ((1537L,), {}))
203
204 def test_size_calculation(self):
205 """Test the recursive folder size calculation."""
206 queue = Queue.Queue()
207 csize = local_folders.CalculateSize(self.tmpdir, queue)
208 csize.run()
209 path, size = queue.get()
210 self.assertEqual(path, self.tmpdir)
211 self.assertEqual(size, 1337)
212
213
214class LocalFoldersTestCase(BaseTestCase):
215 """Test the LocalFoldersPage code."""
216
217 class_ui = local_folders.LocalFoldersPage
218
219 def setUp(self):
220 """Initialize this test instance."""
221 self.tmpdir = tempfile.mkdtemp()
222 self.addCleanup(shutil.rmtree, self.tmpdir)
223 self.fake_wizard = FakeMainWindow()
224 self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
225 self.patch(os.path, 'getsize', lambda *args: 0)
186 super(LocalFoldersTestCase, self).setUp()226 super(LocalFoldersTestCase, self).setUp()
187 self.patch(self.ui, "wizard", lambda: self.fake_wizard)227 self.patch(self.ui, "wizard", lambda: self.fake_wizard)
188228
@@ -199,8 +239,8 @@
199 """Test status of page components after initializePage()."""239 """Test status of page components after initializePage()."""
200 self.patch(self.ui, "get_info", self._set_called)240 self.patch(self.ui, "get_info", self._set_called)
201 self.ui.initializePage()241 self.ui.initializePage()
202 self.assertTrue(self.ui.wizard().overlay.show_counter, 1)242 self.assertEqual(self.ui.wizard().overlay.show_counter, 1)
203 self.assertTrue(self.ui.wizard().overlay.hide_counter, 0)243 self.assertEqual(self.ui.wizard().overlay.hide_counter, 0)
204 self.assertFalse(self.ui.ui.offer_frame.isVisible())244 self.assertFalse(self.ui.ui.offer_frame.isVisible())
205 self.assertEqual(self._called, ((), {}))245 self.assertEqual(self._called, ((), {}))
206 self.assertEqual(self.ui.wizard().button_texts,246 self.assertEqual(self.ui.wizard().button_texts,
@@ -211,15 +251,12 @@
211 """Test status of page components after get_info()."""251 """Test status of page components after get_info()."""
212 yield self.ui.get_info()252 yield self.ui.get_info()
213 self.assertTrue(self.ui.wizard().overlay.hide_counter, 1)253 self.assertTrue(self.ui.wizard().overlay.hide_counter, 1)
214 self.assertEqual(self.ui.ui.folder_list.topLevelItemCount(), 5)254 self.assertEqual(self.ui.ui.folder_list.topLevelItemCount(), 4)
215 self.assertEqual(self.ui.wizard().currentIdChanged.target,255 self.assertEqual(self.ui.wizard().currentIdChanged.target,
216 self.ui.changed_page)256 self.ui.changed_page)
217 self.assertEqual(257 self.assertEqual(
218 self.ui.items[os.path.expanduser('~/xyzzy')].checkState(0),258 self.ui.items[os.path.expanduser('~/xyzzy')].checkState(0),
219 QtCore.Qt.Checked)259 QtCore.Qt.Checked)
220 self.assertEqual(
221 self.ui.items[os.path.expanduser('~/zxyzzy')].checkState(0),
222 QtCore.Qt.Unchecked)
223 check_states = [self.ui.items[item].checkState(0)260 check_states = [self.ui.items[item].checkState(0)
224 for item in self.ui.items]261 for item in self.ui.items]
225 self.assertEqual(len([262 self.assertEqual(len([
@@ -236,22 +273,10 @@
236 self.assertEqual(item.volume_id, 'asdfgh')273 self.assertEqual(item.volume_id, 'asdfgh')
237274
238 @defer.inlineCallbacks275 @defer.inlineCallbacks
239 def test_unsubscribed_udf_checked(self):276 def test_unsubscribed_udf_not_added(self):
240 """Check that unsubscribed UDF items are created correctly."""277 """Check that unsubscribed UDF items are not added."""
241 yield self.ui.get_info()278 yield self.ui.get_info()
242 item = self.ui.items[os.path.expanduser(u'~/zxyzzy')]279 self.assertNotIn(os.path.expanduser(u'~/zxyzzy'), self.ui.items)
243 self.assertEqual(item.checkState(0), QtCore.Qt.Unchecked)
244 self.assertEqual(item.size, 0)
245 self.assertEqual(item.volume_id, 'qwerty')
246
247 def test_size_calculation(self):
248 """Test the recursive folder size calculation."""
249 queue = Queue.Queue()
250 csize = local_folders.CalculateSize(self.tmpdir, queue)
251 csize.run()
252 path, size = queue.get()
253 self.assertEqual(path, self.tmpdir)
254 self.assertEqual(size, 1337)
255280
256 @defer.inlineCallbacks281 @defer.inlineCallbacks
257 def test_item_addition(self):282 def test_item_addition(self):
@@ -293,23 +318,6 @@
293 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())318 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
294319
295 @defer.inlineCallbacks320 @defer.inlineCallbacks
296 def test_total_size(self):
297 """Test that the header reflects the change in item sizes."""
298 self.patch(self.ui, "show_hide_offer", self._set_called)
299 yield self.ui.get_info()
300 self.ui.ui.folder_list.clear()
301 self.ui.items = {}
302 item = yield self.ui.add_folder(self.tmpdir)
303 item.thread.run()
304 item.thread.join()
305 item.size = 1337
306 item.setCheckState(0, QtCore.Qt.Checked)
307 self.ui.update_sizes()
308 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
309 u"Space (1.5 KiB)")
310 self.assertEqual(self._called, ((1537L,), {}))
311
312 @defer.inlineCallbacks
313 def test_total_size_unchecked(self):321 def test_total_size_unchecked(self):
314 """Unchecked items use no space beyond quota_used."""322 """Unchecked items use no space beyond quota_used."""
315 self.patch(self.ui, "show_hide_offer", self._set_called)323 self.patch(self.ui, "show_hide_offer", self._set_called)
@@ -441,8 +449,7 @@
441 self.ui.changed_page(self.ui.wizard().SYNC_NOW_OR_LATER_PAGE)449 self.ui.changed_page(self.ui.wizard().SYNC_NOW_OR_LATER_PAGE)
442 changes = sorted(self.ui.cp_backend.volume_setings_changes)450 changes = sorted(self.ui.cp_backend.volume_setings_changes)
443 self.assertEqual(changes,451 self.assertEqual(changes,
444 sorted([('asdfgh', {'subscribed': True}),452 [('asdfgh', {'subscribed': True})])
445 ('qwerty', {'subscribed': False})]))
446 self.assertEqual(self.ui.wizard().overlay.show_counter,453 self.assertEqual(self.ui.wizard().overlay.show_counter,
447 show_counter + 1)454 show_counter + 1)
448 self.assertEqual(self.ui.wizard().overlay.hide_counter,455 self.assertEqual(self.ui.wizard().overlay.hide_counter,
449456
=== added file 'ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py'
--- ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py 1970-01-01 00:00:00 +0000
+++ ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py 2011-09-08 14:21:18 +0000
@@ -0,0 +1,93 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Roberto Alsina <roberto.alsina@canonical.com>
4#
5# Copyright 2011 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Tests for the sync_now_or_later page."""
20
21import os
22
23from PyQt4 import QtGui
24from twisted.internet import defer
25
26from ubuntuone_installer.gui import NEXT
27from ubuntuone_installer.gui.qt import sync_now_or_later
28from ubuntuone_installer.gui.qt.tests import BaseTestCase
29from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow
30from ubuntuone_installer.gui.qt.tests.test_local_folders import (
31 FakeCPBackend,
32)
33
34
35class FakeEmptyCPBackend(FakeCPBackend):
36 """A CP backend that returns only one folder."""
37 def volumes_info(self, *args):
38 """Fake volumes info."""
39 return defer.succeed(((None, None,
40 [
41 {
42 'type': u'ROOT',
43 'path': os.path.expanduser(u'~/Ubuntu One'),
44 'volume_id': 'asdfgh',
45 'subscribed': True,
46 }]),))
47
48
49class SyncNowOrLaterTestCase(BaseTestCase):
50 """Test the sync_now_or_later page."""
51
52 class_ui = sync_now_or_later.SyncNowOrLaterPage
53
54 def setUp(self):
55 """Initialize tests."""
56 super(SyncNowOrLaterTestCase, self).setUp()
57 self.main_window = FakeMainWindow()
58 self.patch(self.ui, "wizard", lambda: self.main_window)
59 self.patch(sync_now_or_later.backend, "ControlBackend", FakeCPBackend)
60
61 @defer.inlineCallbacks
62 def test_has_folders_in_cloud(self):
63 """test behaviour when the user has folders in the cloud."""
64 yield self.ui.get_info()
65 self.assertTrue(self.ui.has_cloud_folders)
66
67 @defer.inlineCallbacks
68 def test_has_no_folders_in_cloud(self):
69 """test behaviour when the user has no folders in the cloud."""
70 self.patch(sync_now_or_later.backend,
71 "ControlBackend", FakeEmptyCPBackend)
72 yield self.ui.get_info()
73 self.assertFalse(self.ui.has_cloud_folders)
74
75 def test_has_cloud_folders_next(self):
76 """With cloud folders, next page is folders."""
77 self.ui.has_cloud_folders = True
78 self.assertEqual(self.ui.nextId(), FakeMainWindow.folders_page_id)
79
80 def test_has_no_cloud_folders_next(self):
81 """With cloud folders, next page is folders."""
82 self.ui.has_cloud_folders = False
83 self.assertEqual(self.ui.nextId(),
84 FakeMainWindow.local_folders_page_id)
85
86 def test_status_after_initialize(self):
87 """Test that everything is initialized correctly."""
88 self.assertEqual(self.ui.wizard().overlay.show_counter, 0)
89 self.ui.initializePage()
90 self.assertEqual(self.ui.wizard().overlay.show_counter, 1)
91 self.assertEqual(self.ui.wizard().overlay.hide_counter, 0)
92 self.assertEqual(self.ui.wizard().button_texts,
93 [(QtGui.QWizard.NextButton, NEXT)])

Subscribers

People subscribed via source and target branches