Merge lp:~ralsina/ubuntuone-windows-installer/local-folder-fixes into lp:ubuntuone-windows-installer

Proposed by Roberto Alsina
Status: Superseded
Proposed branch: lp:~ralsina/ubuntuone-windows-installer/local-folder-fixes
Merge into: lp:ubuntuone-windows-installer
Diff against target: 657 lines (+356/-98)
3 files modified
data/qt/local_folders.ui (+1/-8)
ubuntuone_installer/gui/qt/local_folders.py (+142/-57)
ubuntuone_installer/gui/qt/tests/test_gui.py (+213/-33)
To merge this branch: bzr merge lp:~ralsina/ubuntuone-windows-installer/local-folder-fixes
Reviewer Review Type Date Requested Status
Ubuntu One hackers Pending
Review via email: mp+71675@code.launchpad.net

Commit message

Implement the "Computer-to-cloud" page of the installer according to spec and discussions.

Description of the change

Implement the "Computer-to-cloud" page of the installer according to spec and discussions.

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

merged

48. By Roberto Alsina

added tests for pre/post initializePage

49. By Roberto Alsina

more tests, lint fixes

50. By Roberto Alsina

added tests for FolderItem

51. By Roberto Alsina

added tests for FolderItem

52. By Roberto Alsina

fixes

53. By Roberto Alsina

added test for special_folders

54. By Roberto Alsina

merged trunk

55. By Roberto Alsina

fixes

56. By Roberto Alsina

add test for 'no folder selected, no quota used'

57. By Roberto Alsina

suggested fix for the while True

58. By Roberto Alsina

Separate tests for local folders

59. By Roberto Alsina

style fixes

60. By Roberto Alsina

added two suggested tests

61. By Roberto Alsina

lint

62. By Roberto Alsina

solve conflict

63. By Roberto Alsina

merge conflict fix

64. By Roberto Alsina

grmbl

65. By Roberto Alsina

resolve further

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/qt/local_folders.ui'
--- data/qt/local_folders.ui 2011-08-08 21:48:11 +0000
+++ data/qt/local_folders.ui 2011-08-17 00:58:24 +0000
@@ -97,7 +97,7 @@
97 </spacer>97 </spacer>
98 </item>98 </item>
99 <item>99 <item>
100 <widget class="AddFolderButton" name="add_folder_button">100 <widget class="QPushButton" name="add_folder_button">
101 <property name="text">101 <property name="text">
102 <string>Add a folder from this computer</string>102 <string>Add a folder from this computer</string>
103 </property>103 </property>
@@ -188,13 +188,6 @@
188 </item>188 </item>
189 </layout>189 </layout>
190 </widget>190 </widget>
191 <customwidgets>
192 <customwidget>
193 <class>AddFolderButton</class>
194 <extends>QPushButton</extends>
195 <header>ubuntuone.controlpanel.gui.qt.addfolder</header>
196 </customwidget>
197 </customwidgets>
198 <resources/>191 <resources/>
199 <connections/>192 <connections/>
200</ui>193</ui>
201194
=== modified file 'ubuntuone_installer/gui/qt/local_folders.py'
--- ubuntuone_installer/gui/qt/local_folders.py 2011-08-17 00:58:24 +0000
+++ ubuntuone_installer/gui/qt/local_folders.py 2011-08-17 00:58:24 +0000
@@ -24,9 +24,14 @@
24import threading24import threading
25import Queue25import Queue
2626
27from twisted.internet.defer import inlineCallbacks27from twisted.internet.defer import inlineCallbacks, returnValue
28from PyQt4 import QtCore, QtGui28from PyQt4 import QtCore, QtGui
29from ubuntuone.controlpanel.gui import humanize, sign_url29from ubuntuone.controlpanel import backend
30from ubuntuone.controlpanel.gui import (
31 humanize,
32 sign_url,
33 FOLDER_INVALID_PATH
34)
30from ubuntuone.platform.credentials import CredentialsManagementTool35from ubuntuone.platform.credentials import CredentialsManagementTool
31from ubuntu_sso.qt.gui import SSOWizardPage36from ubuntu_sso.qt.gui import SSOWizardPage
3237
@@ -49,12 +54,19 @@
4954
50class FolderItem(QtGui.QTreeWidgetItem):55class FolderItem(QtGui.QTreeWidgetItem):
51 """Class representing a folder in the folder list UI."""56 """Class representing a folder in the folder list UI."""
52 def __init__(self, strings, path=None, queue=None):57 def __init__(self, strings, path=None, queue=None,
58 calculate=True, volume_id=None):
53 super(FolderItem, self).__init__(strings)59 super(FolderItem, self).__init__(strings)
54 self.thread = CalculateSize(path, queue)60 if calculate:
55 self.thread.start()61 self.thread = CalculateSize(path, queue)
56 self.size = None62 self.thread.start()
63 self.size = None
64 else:
65 self.thread = CalculateSize(path, queue)
66 self.size = 0
57 self.path = path67 self.path = path
68 self.setCheckState(0, QtCore.Qt.Unchecked)
69 self.volume_id = volume_id
5870
5971
60class CalculateSize(threading.Thread):72class CalculateSize(threading.Thread):
@@ -88,6 +100,9 @@
88 self.queue = Queue.Queue()100 self.queue = Queue.Queue()
89 self.timer = QtCore.QTimer()101 self.timer = QtCore.QTimer()
90 self.items = {}102 self.items = {}
103 self.folders_info = None
104 self.account_info = None
105 self.cp_backend = backend.ControlBackend()
91106
92 # initializePage is inherited107 # initializePage is inherited
93 # pylint: disable=C0103108 # pylint: disable=C0103
@@ -99,16 +114,72 @@
99 self.wizard()._next_id = self.wizard().SYNC_NOW_OR_LATER_PAGE114 self.wizard()._next_id = self.wizard().SYNC_NOW_OR_LATER_PAGE
100 # Start with this invisible115 # Start with this invisible
101 self.ui.offer_frame.setVisible(False)116 self.ui.offer_frame.setVisible(False)
102 if not self.ui.folder_list.topLevelItemCount():117 # Block until we have server data
118 self.wizard().overlay.show()
119 self.get_info()
120
121 @inlineCallbacks
122 def get_info(self):
123 """Get information from CP backend and fill folder list."""
124 try:
125 volumes_info = yield self.cp_backend.volumes_info()
126 self.account_info = yield self.cp_backend.account_info()
127 self.folders_info = []
128 for _, _, volumes in volumes_info:
129 for volume in volumes:
130 if volume[u'type'] == u"UDF":
131 self.folders_info.append(volume)
132 self.ui.folder_list.clear()
133 for folder in self.folders_info:
134 item = yield self.add_folder(
135 os.path.expanduser(folder['path']),
136 validate=False, volume_id=folder['volume_id'])
137 if item:
138 if folder['subscribed']:
139 item.setCheckState(0, QtCore.Qt.Checked)
140 item.thread.join()
141 item.size = 0
103 for folder_name in self.default_folders():142 for folder_name in self.default_folders():
104 self.add_folder(folder_name)143 item = yield self.add_folder(folder_name, validate=True)
105 self.timer.start(2000)144 self.timer.start(2000)
106 self.timer.timeout.connect(self.update_sizes)145 self.timer.timeout.connect(self.update_sizes)
146 self.wizard().overlay.hide()
147 self.wizard().currentIdChanged.connect(self.changed_page)
148 except:
149 logger.exception("Error getting backend info:")
150
151 @QtCore.pyqtSlot("int")
152 @inlineCallbacks
153 def changed_page(self, page_id):
154 """When moving to next page, create/[un]subscribe UDFs."""
155 self.timer.stop()
156 try:
157 self.wizard().currentIdChanged.disconnect(self.changed_page)
158 except KeyError:
159 pass
160 if page_id == self.wizard().SYNC_NOW_OR_LATER_PAGE:
161 # The page following this one
162 self.wizard().overlay.show()
163 for path, item in self.items.items():
164 if item.checkState(0) == QtCore.Qt.Checked:
165 if item.volume_id:
166 yield self.cp_backend.change_volume_settings(
167 item.volume_id,
168 dict(subscribed=True))
169 else:
170 yield self.cp_backend.create_folder(path)
171 else:
172 if item.volume_id:
173 yield self.cp_backend.change_volume_settings(
174 item.volume_id,
175 dict(subscribed=False))
176 self.wizard().overlay.hide()
107177
108 def default_folders(self):178 def default_folders(self):
109 """Return a list of the folders to add by default."""179 """Return a list of the folders to add by default."""
110 if sys.platform == 'win32':180 if sys.platform == 'win32':
111 # Special Folder "My Documents"181 # XXXX to be replaced by calls to xdg_base_directory's
182 # special_folders
112 dll = ctypes.windll.shell32183 dll = ctypes.windll.shell32
113 buf = ctypes.create_string_buffer(300)184 buf = ctypes.create_string_buffer(300)
114 dll.SHGetSpecialFolderPathA(None, buf, 5, False)185 dll.SHGetSpecialFolderPathA(None, buf, 5, False)
@@ -122,61 +193,62 @@
122 result = ['To be implemented']193 result = ['To be implemented']
123 return result194 return result
124195
125 def add_folder(self, path):196 @inlineCallbacks
197 def add_folder(self, path, validate=True, volume_id=False):
126 """Add a folder to the list."""198 """Add a folder to the list."""
127 if path in self.items:199 if path in self.items:
128 return None200 returnValue(None)
129 # FIXME: the path should actually be sent to u1cp to verify as valid201 if validate:
130 item = FolderItem([path, "", "remove"], path=path, queue=self.queue)202 is_valid = yield self.cp_backend.validate_path_for_folder(path)
131 self.ui.folder_list.addTopLevelItem(item)203 else:
132 self.items[path] = item204 is_valid = True
133 return item205 if is_valid:
206 item = FolderItem([path, ""],
207 path=path, queue=self.queue, volume_id=volume_id)
208 self.ui.folder_list.addTopLevelItem(item)
209 self.items[path] = item
210 returnValue(item)
211 returnValue(None)
134212
135 @inlineCallbacks
136 def update_sizes(self):213 def update_sizes(self):
137 """Poll the queue were the threads put the size info."""214 """Poll the queue were the threads put the size info."""
138 try:215 try:
139 path, size = self.queue.get(False)216 while True:
140 item = self.items.get(path)217 path, size = self.queue.get(False)
141 if item:218 item = self.items.get(path)
142 item.size = size219 if item:
143 item.setText(1, humanize(size))220 item.size = size
221 try:
222 item.setText(1, humanize(size))
223 except RuntimeError:
224 del self.items[path]
144 except Queue.Empty:225 except Queue.Empty:
145 pass226 pass
146 total = 0227 total = long(self.account_info['quota_used'])
147 for path, item in self.items.items():228 for path, item in self.items.items():
148 if item.size is None:229 if item.size is None:
149 total = LOCAL_FOLDERS_CALCULATING230 total = LOCAL_FOLDERS_CALCULATING
150 break231 break
151 total += item.size232 if not item.volume_id and item.checkState(0) == QtCore.Qt.Checked:
152233 # Existing UDFs are already accounted for, count if marked.
234 total += item.size
153 if isinstance(total, long):235 if isinstance(total, long):
154 yield self.show_hide_offer(total)236 self.show_hide_offer(total)
155 total = humanize(total)237 total = humanize(total)
156 else:238 else:
157 yield self.show_hide_offer(0)239 self.show_hide_offer(0)
158 self.ui.folder_list.headerItem().setText(240 self.ui.folder_list.headerItem().setText(
159 1, LOCAL_FOLDERS_SPACE_HEADER % total)241 1, LOCAL_FOLDERS_SPACE_HEADER % total)
160242
161 @inlineCallbacks
162 def show_hide_offer(self, cur_size):243 def show_hide_offer(self, cur_size):
163 """Show or hide the offer to buy space according to the total size.244 """Show or hide the offer to buy space according to the total size."""
164245 quota = self.account_info['quota_total']
165 Returns a deferred that is triggered when the update is finished.246 if cur_size > quota:
166247 self.ui.offer_frame.setVisible(True)
167 """248 else:
168 # pylint: disable=W0702249 self.ui.offer_frame.setVisible(False)
169 try:250 self.ui.offer_label.setText(LOCAL_FOLDERS_OFFER_LABEL %
170 user_info = yield self.ui.add_folder_button.backend.account_info()251 {"quota": humanize(quota)})
171 quota = user_info['quota_total']
172 if cur_size > quota:
173 self.ui.offer_frame.setVisible(True)
174 else:
175 self.ui.offer_frame.setVisible(False)
176 self.ui.offer_label.setText(LOCAL_FOLDERS_OFFER_LABEL %
177 {"quota": humanize(quota)})
178 except:
179 logger.exception('Error while trying to update the quota:')
180252
181 def stop_threads(self):253 def stop_threads(self):
182 """Stop all pending threads."""254 """Stop all pending threads."""
@@ -185,31 +257,44 @@
185257
186 # itemClicked is a Qt signal name.258 # itemClicked is a Qt signal name.
187 # pylint: disable=C0103259 # pylint: disable=C0103
188 def on_folder_list_itemClicked(self, item, column):260 def on_folder_list_itemChanged(self, item, column):
189 """Delete folder from the list."""261 """Delete folder from the list."""
190 if column == 2:262 if column == 0:
191 del(self.items[item.path])263 self.update_sizes()
192 item.thread._stop = True
193 self.ui.folder_list.takeTopLevelItem(
194 self.ui.folder_list.indexOfTopLevelItem(item))
195 self.update_sizes()
196264
197 @inlineCallbacks265 @inlineCallbacks
198 @QtCore.pyqtSlot()266 @QtCore.pyqtSlot()
199 def on_add_storage_button_clicked(self):267 def on_add_storage_button_clicked(self):
200 """user clicked on the "Add more storage" button."""268 """user clicked on the "Add more storage" button."""
201269 # Really want to catch everything
202 # pylint: disable=W0702270 # pylint: disable=W0702
203 try:271 try:
204 credtool = CredentialsManagementTool()272 credtool = CredentialsManagementTool()
205 creds = yield credtool.find_credentials()273 creds = yield credtool.find_credentials()
206 except:274 except:
207 logger.exception('Error while trying to update que quota:')275 logger.exception('Error while trying to get credentials:')
208 creds = {}276 creds = {}
209
210 if creds:277 if creds:
211 signed_url = sign_url(278 signed_url = sign_url(
212 "https://one.ubuntu.com/services/#storage_panel", creds)279 "https://one.ubuntu.com/services/#storage_panel", creds)
213 else:280 else:
214 signed_url = "https://one.ubuntu.com/services/#storage_panel"281 signed_url = "https://one.ubuntu.com/services/#storage_panel"
215 QtGui.QDesktopServices.openUrl(QtCore.QUrl(signed_url))282 QtGui.QDesktopServices.openUrl(QtCore.QUrl(signed_url))
283
284 @inlineCallbacks
285 @QtCore.pyqtSlot()
286 def on_add_folder_button_clicked(self):
287 """user clicked on the "Add Folder" button."""
288 folder = QtGui.QFileDialog.getExistingDirectory(parent=self)
289 folder = unicode(folder)
290 if folder == '':
291 return
292
293 is_valid = yield self.cp_backend.validate_path_for_folder(folder)
294 if not is_valid:
295 user_home = os.path.expanduser('~')
296 text = FOLDER_INVALID_PATH % {'folder_path': folder,
297 'home_folder': user_home}
298 QtGui.QMessageBox.warning(self, '', text, QtGui.QMessageBox.Close)
299 return
300 yield self.add_folder(folder, validate=False, volume_id=False)
216301
=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-17 00:58:24 +0000
+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-17 00:58:24 +0000
@@ -529,15 +529,20 @@
529529
530 def __init__(self, *args, **kwargs):530 def __init__(self, *args, **kwargs):
531 """Initialize."""531 """Initialize."""
532 self.target = lambda *args: None532 self.target = None
533533
534 def connect(self, target):534 def connect(self, target):
535 """Fake connect."""535 """Fake connect."""
536 self.target = target536 self.target = target
537537
538 def disconnect(self, *args):
539 """Fake disconnect."""
540 self.target = None
541
538 def emit(self, *args):542 def emit(self, *args):
539 """Fake emit."""543 """Fake emit."""
540 self.target(*args)544 if self.target:
545 self.target(*args)
541546
542547
543class FakeMainWindow(object):548class FakeMainWindow(object):
@@ -548,7 +553,10 @@
548 registrationSuccess = FakeSignal()553 registrationSuccess = FakeSignal()
549 userCancellation = FakeSignal()554 userCancellation = FakeSignal()
550 shown = False555 shown = False
556 _buttonlayout = None
551 SYNC_NOW_OR_LATER_PAGE = 4557 SYNC_NOW_OR_LATER_PAGE = 4
558 overlay = FakeOverlay()
559 currentIdChanged = FakeSignal()
552560
553 def show(self):561 def show(self):
554 """Fake method."""562 """Fake method."""
@@ -563,9 +571,71 @@
563class FakeCPBackend(object):571class FakeCPBackend(object):
564 """Fake Control Panel backend."""572 """Fake Control Panel backend."""
565573
574 def __init__(self):
575 """Initialize."""
576 self._is_valid = True
577 self.volume_setings_changes = []
578 self.folders_created = []
579
566 def account_info(self, *args):580 def account_info(self, *args):
567 """Fake account info."""581 """Fake account info."""
568 return defer.succeed({"quota_total": 1000})582 return defer.succeed({
583 "quota_total": 1000,
584 "quota_used": 200,
585 })
586
587 def volumes_info(self, *args):
588 """"Fake volumes info."""
589 return defer.succeed(((None, None,
590 [
591 {
592 'type': u'UDF',
593 'path': os.path.expanduser(u'~/xyzzy'),
594 'volume_id': 'asdfgh',
595 'subscribed': True
596 },
597 {
598 'type': u'UDF',
599 'path': os.path.expanduser(u'~/zxyzzy'),
600 'volume_id': 'qwerty',
601 'subscribed': False
602 },
603 ],
604 ),))
605
606 def validate_path_for_folder(self, path):
607 """Fake folder validation."""
608 return self._is_valid
609
610 def change_volume_settings(self, *args):
611 """Fake change volume settings."""
612 self.volume_setings_changes.append(args)
613
614 def create_folder(self, *args):
615 """Fake folder creation."""
616 self.folders_created.append(args)
617
618
619class FakeFileDialog(object):
620
621 """A fake QFileDialog class."""
622
623 # pylint: disable=C0103
624 def getExistingDirectory(self, *args, **kwargs):
625 """Fake existing folder name."""
626 return u"whatever"
627
628
629class FakeMessageBox(object):
630
631 """A fake QMessageBox class."""
632
633 Close = 2
634 _warning = None
635
636 def warning(self, *args, **kwargs):
637 """Fake warning."""
638 self._warning = (args, kwargs)
569639
570640
571class FakeFailingCPBackend(object):641class FakeFailingCPBackend(object):
@@ -598,6 +668,7 @@
598 f.write(" " * 737)668 f.write(" " * 737)
599 f.close()669 f.close()
600 self.fake_wizard = FakeMainWindow()670 self.fake_wizard = FakeMainWindow()
671 self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
601 super(LocalFoldersTestCase, self).setUp()672 super(LocalFoldersTestCase, self).setUp()
602 self.patch(self.ui, "wizard", lambda: self.fake_wizard)673 self.patch(self.ui, "wizard", lambda: self.fake_wizard)
603674
@@ -606,6 +677,24 @@
606 shutil.rmtree(self.tmpdir)677 shutil.rmtree(self.tmpdir)
607 BaseTestCase.tearDown(self)678 BaseTestCase.tearDown(self)
608679
680 @defer.inlineCallbacks
681 def test_subscribed_udf_checked(self):
682 """Check that subscribed UDF items are created correctly."""
683 yield self.ui.get_info()
684 item = self.ui.items[os.path.expanduser(u'~/xyzzy')]
685 self.assertEqual(item.checkState(0), QtCore.Qt.Checked)
686 self.assertEqual(item.size, 0)
687 self.assertTrue(item.volume_id)
688
689 @defer.inlineCallbacks
690 def test_unsubscribed_udf_checked(self):
691 """Check that unsubscribed UDF items are created correctly."""
692 yield self.ui.get_info()
693 item = self.ui.items[os.path.expanduser(u'~/zxyzzy')]
694 self.assertEqual(item.checkState(0), QtCore.Qt.Unchecked)
695 self.assertEqual(item.size, 0)
696 self.assertTrue(item.volume_id)
697
609 def test_size_calculation(self):698 def test_size_calculation(self):
610 """Test the recursive folder size calculation."""699 """Test the recursive folder size calculation."""
611 queue = Queue.Queue()700 queue = Queue.Queue()
@@ -615,38 +704,77 @@
615 self.assertEqual(path, self.tmpdir)704 self.assertEqual(path, self.tmpdir)
616 self.assertEqual(size, 1337)705 self.assertEqual(size, 1337)
617706
707 @defer.inlineCallbacks
618 def test_item_addition(self):708 def test_item_addition(self):
619 """Add an item (plus the default one), then remove them."""709 """Add a folder."""
620 self.ui.add_folder(self.tmpdir)710 self.ui.ui.folder_list.clear()
621 self.assertEqual(4, self.ui.ui.folder_list.topLevelItemCount())711 yield self.ui.add_folder(self.tmpdir)
622712 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
713
714 @defer.inlineCallbacks
715 def test_invalid_item_addition(self):
716 """Try to add an invalid folder."""
717 self.ui.ui.folder_list.clear()
718 self.ui.cp_backend._is_valid = False
719 yield self.ui.add_folder(self.tmpdir)
720 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
721
722 @defer.inlineCallbacks
623 def test_total_size(self):723 def test_total_size(self):
624 """Test that the header reflects the change in item sizes."""724 """Test that the header reflects the change in item sizes."""
625 while self.ui.ui.folder_list.topLevelItemCount():725 yield self.ui.get_info()
626 self.ui.on_folder_list_itemClicked(726 self.ui.ui.folder_list.clear()
627 self.ui.ui.folder_list.topLevelItem(0), 2)727 self.ui.items = {}
628 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())728 item = yield self.ui.add_folder(self.tmpdir)
629 item = self.ui.add_folder(self.tmpdir)729 item.thread.run()
630 item.size = 1337730 item.thread.join()
631 item.thread.run()731 item.size = 1337
632 item.thread.join()732 item.setCheckState(0, QtCore.Qt.Checked)
633 self.ui.update_sizes()733 self.ui.update_sizes()
634 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),734 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
635 u"Space (1337)")735 u"Space (1.5 KiB)")
736
737 @defer.inlineCallbacks
738 def test_total_size_unchecked(self):
739 """Unchecked items use no space beyond quota_used."""
740 yield self.ui.get_info()
741 self.ui.ui.folder_list.clear()
742 self.ui.items = {}
743 item = yield self.ui.add_folder(self.tmpdir)
744 item.thread.run()
745 item.thread.join()
746 item.size = 1337
747 item.setCheckState(0, QtCore.Qt.Unchecked)
748 self.ui.update_sizes()
749 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
750 u"Space (200 bytes)")
751
752 @defer.inlineCallbacks
753 def test_total_size_udf(self):
754 """UDFs use no space beyond quota_used."""
755 yield self.ui.get_info()
756 for _, item in self.ui.items.items():
757 item.thread.join()
758 if item.volume_id:
759 item.setCheckState(0, QtCore.Qt.Checked)
760 else:
761 item.setCheckState(0, QtCore.Qt.Unchecked)
762 self.ui.update_sizes()
763 self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
764 u"Space (200 bytes)")
636765
637 def test_add_twice(self):766 def test_add_twice(self):
638 """Behaviour for adding the same folder twice:767 """Behaviour for adding the same folder twice:
639768
640 * It's added only once.769 * It's added only once.
641 """770 """
642 while self.ui.ui.folder_list.topLevelItemCount():771 self.ui.ui.folder_list.clear()
643 self.ui.on_folder_list_itemClicked(
644 self.ui.ui.folder_list.topLevelItem(0), 2)
645 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())772 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
646 self.ui.add_folder(self.tmpdir)773 self.ui.add_folder(self.tmpdir)
647 self.ui.add_folder(self.tmpdir)774 self.ui.add_folder(self.tmpdir)
648 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())775 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
649776
777 @defer.inlineCallbacks
650 def test_add_missing_folder(self):778 def test_add_missing_folder(self):
651 """Behaviour for adding a folder that doesn't exist:779 """Behaviour for adding a folder that doesn't exist:
652780
@@ -654,11 +782,11 @@
654 * Has size 0.782 * Has size 0.
655 """783 """
656784
657 while self.ui.ui.folder_list.topLevelItemCount():785 yield self.ui.get_info()
658 self.ui.on_folder_list_itemClicked(786 self.ui.ui.folder_list.clear()
659 self.ui.ui.folder_list.topLevelItem(0), 2)
660 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())787 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
661 item = self.ui.add_folder(os.path.join("xyzzy", "xyzzy", "xyzzy"))788 item = yield self.ui.add_folder(os.path.join(
789 "xyzzy", "xyzzy", "xyzzy"))
662 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())790 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
663 item.thread.run()791 item.thread.run()
664 item.thread.join()792 item.thread.join()
@@ -672,27 +800,79 @@
672 Push the user over quota, it should be visible.800 Push the user over quota, it should be visible.
673 """801 """
674 self.patch(self.ui.ui.offer_frame, "setVisible", self._set_called)802 self.patch(self.ui.ui.offer_frame, "setVisible", self._set_called)
675 while self.ui.ui.folder_list.topLevelItemCount():803 yield self.ui.get_info()
676 self.ui.on_folder_list_itemClicked(804 self.ui.ui.folder_list.clear()
677 self.ui.ui.folder_list.topLevelItem(0), 2)
678 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
679 self.ui.update_sizes()805 self.ui.update_sizes()
680 self.assertEqual(self._called, ((False,), {}))806 self.assertEqual(self._called, ((False,), {}))
681 self.ui.show_hide_offer(self.ui.quota() + 1)807 self.ui.show_hide_offer(self.ui.quota() + 1)
682 self.assertEqual(self._called, ((True,), {}))808 self.assertEqual(self._called, ((True,), {}))
683809
810 def test_add_folder_valid(self):
811 """Test behaviour when adding a valid folder via the button."""
812 self.patch(QtGui, "QFileDialog", FakeFileDialog())
813 self.patch(self.ui, "add_folder", self._set_called)
814 self.ui.ui.add_folder_button.click()
815 self.assertEqual(self._called,
816 ((u'whatever',), {'validate': False, 'volume_id': False}))
817
818 def test_add_folder_invalid(self):
819 """Test behaviour when adding an invalid folder via the button."""
820 self.patch(QtGui, "QFileDialog", FakeFileDialog())
821 message_box = FakeMessageBox()
822 self.patch(QtGui, "QMessageBox", message_box)
823 self.patch(self.ui, "add_folder", self._set_called)
824 self.ui.cp_backend._is_valid = False
825 self.ui.ui.add_folder_button.click()
826 self.assertEqual(self._called, False)
827 user_home = os.path.expanduser('~')
828 text = local_folders.FOLDER_INVALID_PATH % {
829 'folder_path': "whatever",
830 'home_folder': user_home,
831 }
832 self.assertEqual(message_box._warning,
833 ((self.ui,
834 '', text, 2), {}))
835
836 @defer.inlineCallbacks
837 def test_changed_page_existing_udf_behaviour(self):
838 """If a UDF is checked, subscribe it, if not, unsubscribe it."""
839 yield self.ui.get_info()
840 self.ui.changed_page(self.ui.wizard().SYNC_NOW_OR_LATER_PAGE)
841 self.assertEqual(self.ui.cp_backend.volume_setings_changes,
842 [('asdfgh', {'subscribed': True}),
843 ('qwerty', {'subscribed': False})])
844
845 @defer.inlineCallbacks
846 def test_changed_page_new_udf_behaviour(self):
847 """Create UDFs for non-existing, checked UDFs."""
848 yield self.ui.get_info()
849 self.ui.ui.folder_list.clear()
850 self.ui.items = {}
851 item = yield self.ui.add_folder("whatever")
852 item.setCheckState(0, QtCore.Qt.Checked)
853 item = yield self.ui.add_folder("whatever2")
854 item.setCheckState(0, QtCore.Qt.Unchecked)
855 self.ui.changed_page(self.ui.wizard().SYNC_NOW_OR_LATER_PAGE)
856 self.assertEqual(self.ui.cp_backend.folders_created,
857 [('whatever',)])
858
684 def test_exception_on_account_info(self):859 def test_exception_on_account_info(self):
685 """When account_info fails, nothing should happen."""860 """When account_info fails, nothing should happen."""
686 self.patch(self.ui.ui.add_folder_button,861 self.patch(self.ui,
687 "backend", FakeFailingCPBackend())862 "cp_backend", FakeFailingCPBackend())
688 self.ui.show_hide_offer(1000)863 self.ui.get_info()
689 # Still here864 # Still here
690865
691 def test_timer_is_started(self):866 def test_timer_is_started(self):
692 """ When displaying the page, the timer should start."""867 """When displaying the page, the timer should start."""
693 self.ui.initializePage()868 self.ui.initializePage()
694 self.assertTrue(self.ui.timer.isActive())869 self.assertTrue(self.ui.timer.isActive())
695870
871 def test_timer_is_stopped(self):
872 """When leaving the page, the timer should stop."""
873 self.ui.changed_page(-1)
874 self.assertFalse(self.ui.timer.isActive())
875
696876
697class SetupAccountTestCase(BaseTestCase):877class SetupAccountTestCase(BaseTestCase):
698 """Test the SetupAccountPage code."""878 """Test the SetupAccountPage code."""

Subscribers

People subscribed via source and target branches