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 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 on 2011-09-07

EOLs

Diego Sarmentero (diegosarmentero) wrote :

+1

review: Approve
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
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 on 2011-09-08

separate tests that need getsize into a separate testcase

63. By Roberto Alsina on 2011-09-08

Make it work right with latest trunk

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

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
Roberto Alsina (ralsina) wrote :

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

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
1=== removed file 'data/qt/sync_now_or_later.ui'
2--- data/qt/sync_now_or_later.ui 2011-09-02 12:58:29 +0000
3+++ data/qt/sync_now_or_later.ui 1970-01-01 00:00:00 +0000
4@@ -1,89 +0,0 @@
5-<?xml version="1.0" encoding="UTF-8"?>
6-<ui version="4.0">
7- <class>Form</class>
8- <widget class="QWidget" name="Form">
9- <property name="geometry">
10- <rect>
11- <x>0</x>
12- <y>0</y>
13- <width>426</width>
14- <height>387</height>
15- </rect>
16- </property>
17- <property name="windowTitle">
18- <string>Form</string>
19- </property>
20- <layout class="QVBoxLayout" name="verticalLayout">
21- <property name="spacing">
22- <number>24</number>
23- </property>
24- <property name="topMargin">
25- <number>0</number>
26- </property>
27- <item>
28- <widget class="QLabel" name="label">
29- <property name="font">
30- <font>
31- <pointsize>14</pointsize>
32- <weight>75</weight>
33- <bold>true</bold>
34- </font>
35- </property>
36- <property name="text">
37- <string>Syncing your computer with the cloud</string>
38- </property>
39- </widget>
40- </item>
41- <item>
42- <widget class="QLabel" name="label_9">
43- <property name="text">
44- <string>It seems that you have already some folders in the cloud.
45-Do you want to sync everything with this computer now?</string>
46- </property>
47- <property name="wordWrap">
48- <bool>true</bool>
49- </property>
50- </widget>
51- </item>
52- <item>
53- <widget class="QRadioButton" name="sync_now">
54- <property name="text">
55- <string>Yes, sync all now</string>
56- </property>
57- <property name="checked">
58- <bool>true</bool>
59- </property>
60- </widget>
61- </item>
62- <item>
63- <widget class="QRadioButton" name="sync_later">
64- <property name="text">
65- <string>No, I'll do it later</string>
66- </property>
67- </widget>
68- </item>
69- <item>
70- <widget class="QRadioButton" name="sync_custom">
71- <property name="text">
72- <string>Yes, but I want to choose what to sync</string>
73- </property>
74- </widget>
75- </item>
76- <item>
77- <spacer name="verticalSpacer">
78- <property name="orientation">
79- <enum>Qt::Vertical</enum>
80- </property>
81- <property name="sizeHint" stdset="0">
82- <size>
83- <width>20</width>
84- <height>54</height>
85- </size>
86- </property>
87- </spacer>
88- </item>
89- </layout>
90- </widget>
91- <resources/>
92- <connections/>
93-</ui>
94
95=== modified file 'ubuntuone_installer/gui/qt/folders.py'
96--- ubuntuone_installer/gui/qt/folders.py 2011-09-01 21:26:50 +0000
97+++ ubuntuone_installer/gui/qt/folders.py 2011-09-08 14:21:18 +0000
98@@ -25,6 +25,7 @@
99 from ubuntu_sso.qt.gui import SSOWizardPage
100 from ubuntuone.controlpanel.gui.qt import folders
101
102+from ubuntuone_installer.gui import NEXT
103 from ubuntuone_installer.gui.qt.ui import folders_ui
104
105 _ = gettext.gettext
106@@ -55,7 +56,9 @@
107 QtGui.QWizard.BackButton,
108 QtGui.QWizard.Stretch,
109 QtGui.QWizard.NextButton])
110- self.wizard()._next_id = self.wizard().CONGRATULATIONS_PAGE
111+ self.wizard().setButtonText(QtGui.QWizard.NextButton,
112+ NEXT)
113+ self.wizard()._next_id = self.wizard().local_folders_page_id
114
115 # pylint: enable=C0103
116
117
118=== modified file 'ubuntuone_installer/gui/qt/gui.py'
119--- ubuntuone_installer/gui/qt/gui.py 2011-09-07 15:51:10 +0000
120+++ ubuntuone_installer/gui/qt/gui.py 2011-09-08 14:21:18 +0000
121@@ -82,7 +82,6 @@
122 TITLE_STYLE = "<span style=\"font-size:24px\">%s</span>"
123 CREDENTIALS_ERROR_TITLE = _("Error getting credentials")
124 CREDENTIALS_ERROR = _('Application will close.\n\n%r')
125-STARTING_CP_ERROR = _('Error starting Ubuntu One')
126 SKIP_TOUR = _("Skip tour, go to Dashboard")
127 START_SETUP = _("Start setup")
128 # Invalid name logger
129@@ -237,12 +236,6 @@
130 self.wizard().setButtonLayout([
131 QtGui.QWizard.Stretch,
132 QtGui.QWizard.FinishButton])
133- if self.field("sync_now").toBool() \
134- or self.field("sync_custom").toBool():
135- self.ui.progressContainer.setVisible(True)
136- else:
137- self.ui.progressContainer.setVisible(False)
138-
139 # Set FinishButton as default when the page is shown.
140 self.wizard().button(QtGui.QWizard.FinishButton).setDefault(True)
141 self.wizard().button(QtGui.QWizard.FinishButton).style().unpolish(
142@@ -372,11 +365,11 @@
143
144 # End of SSO pages
145
146- self.local_folders_page = LocalFoldersPage()
147- self.local_folders_page_id = self.addPage(self.local_folders_page)
148 self.SYNC_NOW_OR_LATER_PAGE = self.addPage(SyncNowOrLaterPage())
149 self.folders_page = FoldersPage()
150 self.folders_page_id = self.addPage(self.folders_page)
151+ self.local_folders_page = LocalFoldersPage()
152+ self.local_folders_page_id = self.addPage(self.local_folders_page)
153 self.preferences_page = PreferencesPage()
154 self.preferences_page_id = self.addPage(self.preferences_page)
155 self.CONGRATULATIONS_PAGE = self.addPage(CongratulationsPage())
156@@ -402,7 +395,8 @@
157 """Show the next page to display and remove the form errors label."""
158 self.overlay.hide()
159 self.form_errors_label.hide()
160- self.currentPage().layout().removeWidget(self.form_errors_label)
161+ if self.currentPage().layout():
162+ self.currentPage().layout().removeWidget(self.form_errors_label)
163 self.form_errors_label.setParent(None)
164 super(MainWindow, self).next()
165
166@@ -417,13 +411,13 @@
167 """Called on successful login."""
168 self._next_id = self.SUCCESS_PAGE
169 self.next()
170- self._next_id = self.local_folders_page_id
171+ self._next_id = self.SYNC_NOW_OR_LATER_PAGE
172
173 def registration_success_slot(self):
174 """Called on successful registration."""
175 self._next_id = self.SUCCESS_PAGE
176 self.next()
177- self._next_id = self.local_folders_page_id
178+ self._next_id = self.SYNC_NOW_OR_LATER_PAGE
179
180 def done(self, result):
181 """The main window is being closed, call any custom callback."""
182@@ -448,7 +442,7 @@
183 if page_id < self.SIGNIN_PAGE:
184 self.sideWidget().ui.states_frame.hide()
185 self.sideWidget().set_stage(0)
186- elif page_id < self.local_folders_page_id:
187+ elif page_id < self.SYNC_NOW_OR_LATER_PAGE:
188 self.sideWidget().ui.states_frame.show()
189 self.sideWidget().set_stage(1)
190 elif page_id < self.CONGRATULATIONS_PAGE:
191
192=== modified file 'ubuntuone_installer/gui/qt/local_folders.py'
193--- ubuntuone_installer/gui/qt/local_folders.py 2011-09-05 21:12:02 +0000
194+++ ubuntuone_installer/gui/qt/local_folders.py 2011-09-08 14:21:18 +0000
195@@ -113,7 +113,7 @@
196 QtGui.QWizard.NextButton])
197 self.wizard().setButtonText(QtGui.QWizard.NextButton,
198 NEXT)
199- self.wizard()._next_id = self.wizard().SYNC_NOW_OR_LATER_PAGE
200+ self.wizard()._next_id = self.wizard().CONGRATULATIONS_PAGE
201 # Start with this invisible
202 self.ui.offer_frame.setVisible(False)
203 # Show overlay until we have server data
204@@ -134,16 +134,16 @@
205 self.folders_info.append(volume)
206 self.ui.folder_list.clear()
207 for folder in self.folders_info:
208- item = yield self.add_folder(
209- os.path.expanduser(folder['path']),
210- validate=False,
211- volume_id=folder['volume_id'],
212- calculate=False,
213- )
214- if item:
215- if folder['subscribed']:
216+ if folder['subscribed']:
217+ item = yield self.add_folder(
218+ os.path.expanduser(folder['path']),
219+ validate=False,
220+ volume_id=folder['volume_id'],
221+ calculate=False,
222+ )
223+ if item:
224 item.setCheckState(0, QtCore.Qt.Checked)
225- item.size = 0
226+ item.size = 0
227 for folder_name in default_folders():
228 item = yield self.add_folder(folder_name, validate=True)
229 self.timer.start(2000)
230
231=== modified file 'ubuntuone_installer/gui/qt/main/windows.py'
232--- ubuntuone_installer/gui/qt/main/windows.py 2011-09-07 11:24:12 +0000
233+++ ubuntuone_installer/gui/qt/main/windows.py 2011-09-08 14:21:18 +0000
234@@ -46,12 +46,8 @@
235 def success_cb(creds, gui):
236 """Handle credentials success."""
237 if creds: # Have credentials already
238- try:
239- from ubuntuone_installer.gui.qt import utils
240- utils.start_control_panel()
241- except OSError:
242- QtGui.QMessageBox.critical(
243- None, "Ubuntu One", gui.STARTING_CP_ERROR)
244+ from ubuntuone_installer.gui.qt import utils
245+ utils.start_control_panel()
246 stop()
247 else: # No credentials
248 window = gui.MainWindow(close_callback=stop)
249
250=== modified file 'ubuntuone_installer/gui/qt/sync_now_or_later.py'
251--- ubuntuone_installer/gui/qt/sync_now_or_later.py 2011-08-10 21:37:30 +0000
252+++ ubuntuone_installer/gui/qt/sync_now_or_later.py 2011-09-08 14:21:18 +0000
253@@ -19,8 +19,16 @@
254 """The user interface for the Ubuntu One Installer."""
255
256 from PyQt4 import QtGui
257-
258-from ubuntuone_installer.gui.qt.ui import sync_now_or_later_ui
259+from twisted.internet.defer import inlineCallbacks
260+from ubuntuone.controlpanel import backend
261+
262+from ubuntuone_installer.gui import NEXT
263+from ubuntuone_installer.logger import setup_logging
264+
265+# Invalid name logger
266+# pylint: disable=C0103
267+logger = setup_logging('qt.sync_now_or_later')
268+# pylint: enable=C0103
269
270
271 class SyncNowOrLaterPage(QtGui.QWizardPage):
272@@ -28,11 +36,8 @@
273
274 def __init__(self, parent=None):
275 QtGui.QWizardPage.__init__(self, parent)
276- self.ui = sync_now_or_later_ui.Ui_Form()
277- self.ui.setupUi(self)
278- self.registerField("sync_now", self.ui.sync_now)
279- self.registerField("sync_later", self.ui.sync_later)
280- self.registerField("sync_custom", self.ui.sync_custom)
281+ self.has_cloud_folders = False
282+ self.cp_backend = None
283
284 # Invalid names of Qt-inherited methods
285 # pylint: disable=C0103
286@@ -42,10 +47,34 @@
287 self.wizard().setOption(QtGui.QWizard.HaveCustomButton1, False)
288 self.wizard().setOption(QtGui.QWizard.NoCancelButton, True)
289 self.wizard()._next_id = None
290+ self.wizard().overlay.show()
291+ self.wizard().setButtonText(QtGui.QWizard.NextButton,
292+ NEXT)
293+ self.get_info()
294
295 def nextId(self):
296 """Go to the next page depending on the select field."""
297- if self.field("sync_custom"):
298+ if self.has_cloud_folders:
299 return self.wizard().folders_page_id
300 else:
301- return self.wizard().CONGRATULATIONS_PAGE
302+ return self.wizard().local_folders_page_id
303+
304+ @inlineCallbacks
305+ def get_info(self):
306+ """Get folder information from CP backend."""
307+ # pylint: disable=W0702
308+ try:
309+ self.cp_backend = backend.ControlBackend()
310+ volumes_info = yield self.cp_backend.volumes_info()
311+ except:
312+ logger.exception("Error getting backend info:")
313+ else:
314+ counter = 0
315+ for _, _, volumes in volumes_info:
316+ counter += len(volumes)
317+ if counter > 1:
318+ # there are UDFs or shares, show cloud-to-computer
319+ self.has_cloud_folders = True
320+ else:
321+ self.has_cloud_folders = False
322+ self.wizard().next()
323
324=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
325--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-09-08 13:41:10 +0000
326+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-09-08 14:21:18 +0000
327@@ -291,7 +291,7 @@
328 tree_folders = folders_page.folders_widget.ui.folders
329 self.assertEqual(tree_folders.isColumnHidden(2), True)
330 # pylint: disable=W0212
331- self.assertEqual(self.ui._next_id, self.ui.CONGRATULATIONS_PAGE)
332+ self.assertEqual(self.ui._next_id, self.ui.local_folders_page_id)
333
334 def test_folders_page_next_id(self):
335 """Check Folders Page UI."""
336@@ -432,7 +432,6 @@
337 @skipIfOS('linux2', 'Windows-specific tests.')
338 def test_start_control_panel_frozen(self):
339 """When frozen, the control-panel has a path."""
340- self.ui.setStartId(self.ui.SYNC_NOW_OR_LATER_PAGE)
341 self.ui.restart()
342 self.ui.show()
343 self.addCleanup(self.ui.hide)
344@@ -476,66 +475,6 @@
345 self.assertEqual(self._called, False)
346 self.assertEqual(FakeAreYouSure.shown, False)
347
348- def test_later_accepts_cancel(self):
349- """Clicking 'Later' accepts cancellation."""
350- self.ui.setStartId(self.ui.SYNC_NOW_OR_LATER_PAGE)
351- self.ui.restart()
352- self.ui.show()
353- self.addCleanup(self.ui.hide)
354- gui.AreYouSure.result = 1
355- self.ui.show()
356- self.addCleanup(self.ui.hide)
357- self.ui.done(result=0)
358- self.assertEqual(self.ui.isVisible(), False)
359-
360- def test_sync_now_shows_message(self):
361- """If the user selects 'Sync Now' the congrats page shows a message."""
362- congrats_page = self.ui.page(self.ui.CONGRATULATIONS_PAGE)
363- congrats_page.setField("sync_now", True)
364-
365- # Show the congrats page
366- self.ui.setStartId(self.ui.CONGRATULATIONS_PAGE)
367- self.ui.restart()
368- self.ui.show()
369- self.addCleanup(self.ui.hide)
370-
371- # Check the properties have the right values
372- self.assertEqual(congrats_page.field("sync_later").toBool(),
373- False)
374- self.assertEqual(
375- congrats_page.ui.progressContainer.isVisible(), True)
376-
377- def test_sync_page_custom_field(self):
378- """If the user selects 'Sync Custom' we move to Folders page."""
379- sync_page = self.ui.page(self.ui.SYNC_NOW_OR_LATER_PAGE)
380- sync_page.setField("sync_custom", True)
381-
382- # Show the Sync Now page
383- self.ui.setStartId(self.ui.SYNC_NOW_OR_LATER_PAGE)
384- self.ui.restart()
385- self.ui.show()
386- self.addCleanup(self.ui.hide)
387-
388- # Check the navigation is correct
389- self.assertEqual(sync_page.nextId(), self.ui.folders_page_id)
390-
391- def test_sync_later_hides_message(self):
392- """Selecting 'Sync Later' the congrats page hides a message."""
393- congrats_page = self.ui.page(self.ui.CONGRATULATIONS_PAGE)
394- congrats_page.setField("sync_later", True)
395-
396- # Show the congrats page
397- self.ui.setStartId(self.ui.CONGRATULATIONS_PAGE)
398- self.ui.restart()
399- self.ui.show()
400- self.addCleanup(self.ui.hide)
401-
402- # Check the properties have the right values
403- self.assertEqual(congrats_page.field("sync_now").toBool(),
404- False)
405- self.assertEqual(
406- congrats_page.ui.progressContainer.isVisible(), False)
407-
408 def test_current_user_controller_parameters(self):
409 """Compare controller parameters with expected values."""
410 self.assertEqual(self.ui.current_user_controller.args,
411@@ -636,17 +575,21 @@
412
413 """A fake MainWindow."""
414
415- overlay = FakeOverlay()
416 currentIdChanged = FakeSignal()
417 loginSuccess = FakeSignal()
418 registrationSuccess = FakeSignal()
419 userCancellation = FakeSignal()
420 shown = False
421 SYNC_NOW_OR_LATER_PAGE = 4
422+ CONGRATULATIONS_PAGE = 5
423+ folders_page_id = 6
424+ local_folders_page_id = 7
425
426 def __init__(self, close_callback=None):
427 self.button_texts = []
428 self.button_layout = None
429+ self.options = []
430+ self.overlay = FakeOverlay()
431
432 def show(self):
433 """Fake method."""
434@@ -661,6 +604,13 @@
435 """Fake setButtonText."""
436 self.button_layout = layout
437
438+ def setOption(self, *args):
439+ """Fake setOption."""
440+ self.options.append(args)
441+
442+ def next(self):
443+ """Fake next."""
444+
445
446 class SuccesPageTestCase(BaseTestCase):
447 """Test the SuccessPage code."""
448
449=== modified file 'ubuntuone_installer/gui/qt/tests/test_local_folders.py'
450--- ubuntuone_installer/gui/qt/tests/test_local_folders.py 2011-09-05 22:00:40 +0000
451+++ ubuntuone_installer/gui/qt/tests/test_local_folders.py 2011-09-08 14:21:18 +0000
452@@ -26,9 +26,7 @@
453 from PyQt4 import QtGui, QtCore
454 from twisted.internet import defer
455
456-from ubuntuone_installer.gui import (
457- NEXT,
458-)
459+from ubuntuone_installer.gui import NEXT
460 from ubuntuone_installer.gui.qt import local_folders
461 from ubuntuone_installer.gui.qt.tests import BaseTestCase, TestCase
462 from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow
463@@ -164,8 +162,8 @@
464 self.assertEqual(item.volume_id, "xyzzy")
465
466
467-class LocalFoldersTestCase(BaseTestCase):
468- """Test the LocalFoldersPage code."""
469+class LocalFoldersWithGetSizeTestCase(BaseTestCase):
470+ """Test the LocalFoldersPage code using the real getsize."""
471
472 class_ui = local_folders.LocalFoldersPage
473
474@@ -183,6 +181,48 @@
475 self.addCleanup(shutil.rmtree, self.tmpdir)
476 self.fake_wizard = FakeMainWindow()
477 self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
478+ super(LocalFoldersWithGetSizeTestCase, self).setUp()
479+ self.patch(self.ui, "wizard", lambda: self.fake_wizard)
480+
481+ @defer.inlineCallbacks
482+ def test_total_size(self):
483+ """Test that the header reflects the change in item sizes."""
484+ self.patch(self.ui, "show_hide_offer", self._set_called)
485+ yield self.ui.get_info()
486+ self.ui.ui.folder_list.clear()
487+ self.ui.items = {}
488+ item = yield self.ui.add_folder(self.tmpdir)
489+ item.thread.run()
490+ item.thread.join()
491+ item.size = 1337
492+ item.setCheckState(0, QtCore.Qt.Checked)
493+ self.ui.update_sizes()
494+ self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
495+ u"Space (1.5 KiB)")
496+ self.assertEqual(self._called, ((1537L,), {}))
497+
498+ def test_size_calculation(self):
499+ """Test the recursive folder size calculation."""
500+ queue = Queue.Queue()
501+ csize = local_folders.CalculateSize(self.tmpdir, queue)
502+ csize.run()
503+ path, size = queue.get()
504+ self.assertEqual(path, self.tmpdir)
505+ self.assertEqual(size, 1337)
506+
507+
508+class LocalFoldersTestCase(BaseTestCase):
509+ """Test the LocalFoldersPage code."""
510+
511+ class_ui = local_folders.LocalFoldersPage
512+
513+ def setUp(self):
514+ """Initialize this test instance."""
515+ self.tmpdir = tempfile.mkdtemp()
516+ self.addCleanup(shutil.rmtree, self.tmpdir)
517+ self.fake_wizard = FakeMainWindow()
518+ self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
519+ self.patch(os.path, 'getsize', lambda *args: 0)
520 super(LocalFoldersTestCase, self).setUp()
521 self.patch(self.ui, "wizard", lambda: self.fake_wizard)
522
523@@ -199,8 +239,8 @@
524 """Test status of page components after initializePage()."""
525 self.patch(self.ui, "get_info", self._set_called)
526 self.ui.initializePage()
527- self.assertTrue(self.ui.wizard().overlay.show_counter, 1)
528- self.assertTrue(self.ui.wizard().overlay.hide_counter, 0)
529+ self.assertEqual(self.ui.wizard().overlay.show_counter, 1)
530+ self.assertEqual(self.ui.wizard().overlay.hide_counter, 0)
531 self.assertFalse(self.ui.ui.offer_frame.isVisible())
532 self.assertEqual(self._called, ((), {}))
533 self.assertEqual(self.ui.wizard().button_texts,
534@@ -211,15 +251,12 @@
535 """Test status of page components after get_info()."""
536 yield self.ui.get_info()
537 self.assertTrue(self.ui.wizard().overlay.hide_counter, 1)
538- self.assertEqual(self.ui.ui.folder_list.topLevelItemCount(), 5)
539+ self.assertEqual(self.ui.ui.folder_list.topLevelItemCount(), 4)
540 self.assertEqual(self.ui.wizard().currentIdChanged.target,
541 self.ui.changed_page)
542 self.assertEqual(
543 self.ui.items[os.path.expanduser('~/xyzzy')].checkState(0),
544 QtCore.Qt.Checked)
545- self.assertEqual(
546- self.ui.items[os.path.expanduser('~/zxyzzy')].checkState(0),
547- QtCore.Qt.Unchecked)
548 check_states = [self.ui.items[item].checkState(0)
549 for item in self.ui.items]
550 self.assertEqual(len([
551@@ -236,22 +273,10 @@
552 self.assertEqual(item.volume_id, 'asdfgh')
553
554 @defer.inlineCallbacks
555- def test_unsubscribed_udf_checked(self):
556- """Check that unsubscribed UDF items are created correctly."""
557+ def test_unsubscribed_udf_not_added(self):
558+ """Check that unsubscribed UDF items are not added."""
559 yield self.ui.get_info()
560- item = self.ui.items[os.path.expanduser(u'~/zxyzzy')]
561- self.assertEqual(item.checkState(0), QtCore.Qt.Unchecked)
562- self.assertEqual(item.size, 0)
563- self.assertEqual(item.volume_id, 'qwerty')
564-
565- def test_size_calculation(self):
566- """Test the recursive folder size calculation."""
567- queue = Queue.Queue()
568- csize = local_folders.CalculateSize(self.tmpdir, queue)
569- csize.run()
570- path, size = queue.get()
571- self.assertEqual(path, self.tmpdir)
572- self.assertEqual(size, 1337)
573+ self.assertNotIn(os.path.expanduser(u'~/zxyzzy'), self.ui.items)
574
575 @defer.inlineCallbacks
576 def test_item_addition(self):
577@@ -293,23 +318,6 @@
578 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
579
580 @defer.inlineCallbacks
581- def test_total_size(self):
582- """Test that the header reflects the change in item sizes."""
583- self.patch(self.ui, "show_hide_offer", self._set_called)
584- yield self.ui.get_info()
585- self.ui.ui.folder_list.clear()
586- self.ui.items = {}
587- item = yield self.ui.add_folder(self.tmpdir)
588- item.thread.run()
589- item.thread.join()
590- item.size = 1337
591- item.setCheckState(0, QtCore.Qt.Checked)
592- self.ui.update_sizes()
593- self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
594- u"Space (1.5 KiB)")
595- self.assertEqual(self._called, ((1537L,), {}))
596-
597- @defer.inlineCallbacks
598 def test_total_size_unchecked(self):
599 """Unchecked items use no space beyond quota_used."""
600 self.patch(self.ui, "show_hide_offer", self._set_called)
601@@ -441,8 +449,7 @@
602 self.ui.changed_page(self.ui.wizard().SYNC_NOW_OR_LATER_PAGE)
603 changes = sorted(self.ui.cp_backend.volume_setings_changes)
604 self.assertEqual(changes,
605- sorted([('asdfgh', {'subscribed': True}),
606- ('qwerty', {'subscribed': False})]))
607+ [('asdfgh', {'subscribed': True})])
608 self.assertEqual(self.ui.wizard().overlay.show_counter,
609 show_counter + 1)
610 self.assertEqual(self.ui.wizard().overlay.hide_counter,
611
612=== added file 'ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py'
613--- ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py 1970-01-01 00:00:00 +0000
614+++ ubuntuone_installer/gui/qt/tests/test_sync_now_or_later.py 2011-09-08 14:21:18 +0000
615@@ -0,0 +1,93 @@
616+# -*- coding: utf-8 -*-
617+
618+# Authors: Roberto Alsina <roberto.alsina@canonical.com>
619+#
620+# Copyright 2011 Canonical Ltd.
621+#
622+# This program is free software: you can redistribute it and/or modify it
623+# under the terms of the GNU General Public License version 3, as published
624+# by the Free Software Foundation.
625+#
626+# This program is distributed in the hope that it will be useful, but
627+# WITHOUT ANY WARRANTY; without even the implied warranties of
628+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
629+# PURPOSE. See the GNU General Public License for more details.
630+#
631+# You should have received a copy of the GNU General Public License along
632+# with this program. If not, see <http://www.gnu.org/licenses/>.
633+
634+"""Tests for the sync_now_or_later page."""
635+
636+import os
637+
638+from PyQt4 import QtGui
639+from twisted.internet import defer
640+
641+from ubuntuone_installer.gui import NEXT
642+from ubuntuone_installer.gui.qt import sync_now_or_later
643+from ubuntuone_installer.gui.qt.tests import BaseTestCase
644+from ubuntuone_installer.gui.qt.tests.test_gui import FakeMainWindow
645+from ubuntuone_installer.gui.qt.tests.test_local_folders import (
646+ FakeCPBackend,
647+)
648+
649+
650+class FakeEmptyCPBackend(FakeCPBackend):
651+ """A CP backend that returns only one folder."""
652+ def volumes_info(self, *args):
653+ """Fake volumes info."""
654+ return defer.succeed(((None, None,
655+ [
656+ {
657+ 'type': u'ROOT',
658+ 'path': os.path.expanduser(u'~/Ubuntu One'),
659+ 'volume_id': 'asdfgh',
660+ 'subscribed': True,
661+ }]),))
662+
663+
664+class SyncNowOrLaterTestCase(BaseTestCase):
665+ """Test the sync_now_or_later page."""
666+
667+ class_ui = sync_now_or_later.SyncNowOrLaterPage
668+
669+ def setUp(self):
670+ """Initialize tests."""
671+ super(SyncNowOrLaterTestCase, self).setUp()
672+ self.main_window = FakeMainWindow()
673+ self.patch(self.ui, "wizard", lambda: self.main_window)
674+ self.patch(sync_now_or_later.backend, "ControlBackend", FakeCPBackend)
675+
676+ @defer.inlineCallbacks
677+ def test_has_folders_in_cloud(self):
678+ """test behaviour when the user has folders in the cloud."""
679+ yield self.ui.get_info()
680+ self.assertTrue(self.ui.has_cloud_folders)
681+
682+ @defer.inlineCallbacks
683+ def test_has_no_folders_in_cloud(self):
684+ """test behaviour when the user has no folders in the cloud."""
685+ self.patch(sync_now_or_later.backend,
686+ "ControlBackend", FakeEmptyCPBackend)
687+ yield self.ui.get_info()
688+ self.assertFalse(self.ui.has_cloud_folders)
689+
690+ def test_has_cloud_folders_next(self):
691+ """With cloud folders, next page is folders."""
692+ self.ui.has_cloud_folders = True
693+ self.assertEqual(self.ui.nextId(), FakeMainWindow.folders_page_id)
694+
695+ def test_has_no_cloud_folders_next(self):
696+ """With cloud folders, next page is folders."""
697+ self.ui.has_cloud_folders = False
698+ self.assertEqual(self.ui.nextId(),
699+ FakeMainWindow.local_folders_page_id)
700+
701+ def test_status_after_initialize(self):
702+ """Test that everything is initialized correctly."""
703+ self.assertEqual(self.ui.wizard().overlay.show_counter, 0)
704+ self.ui.initializePage()
705+ self.assertEqual(self.ui.wizard().overlay.show_counter, 1)
706+ self.assertEqual(self.ui.wizard().overlay.hide_counter, 0)
707+ self.assertEqual(self.ui.wizard().button_texts,
708+ [(QtGui.QWizard.NextButton, NEXT)])

Subscribers

People subscribed via source and target branches