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
1=== modified file 'data/qt/local_folders.ui'
2--- data/qt/local_folders.ui 2011-08-08 21:48:11 +0000
3+++ data/qt/local_folders.ui 2011-08-17 00:58:24 +0000
4@@ -97,7 +97,7 @@
5 </spacer>
6 </item>
7 <item>
8- <widget class="AddFolderButton" name="add_folder_button">
9+ <widget class="QPushButton" name="add_folder_button">
10 <property name="text">
11 <string>Add a folder from this computer</string>
12 </property>
13@@ -188,13 +188,6 @@
14 </item>
15 </layout>
16 </widget>
17- <customwidgets>
18- <customwidget>
19- <class>AddFolderButton</class>
20- <extends>QPushButton</extends>
21- <header>ubuntuone.controlpanel.gui.qt.addfolder</header>
22- </customwidget>
23- </customwidgets>
24 <resources/>
25 <connections/>
26 </ui>
27
28=== modified file 'ubuntuone_installer/gui/qt/local_folders.py'
29--- ubuntuone_installer/gui/qt/local_folders.py 2011-08-17 00:58:24 +0000
30+++ ubuntuone_installer/gui/qt/local_folders.py 2011-08-17 00:58:24 +0000
31@@ -24,9 +24,14 @@
32 import threading
33 import Queue
34
35-from twisted.internet.defer import inlineCallbacks
36+from twisted.internet.defer import inlineCallbacks, returnValue
37 from PyQt4 import QtCore, QtGui
38-from ubuntuone.controlpanel.gui import humanize, sign_url
39+from ubuntuone.controlpanel import backend
40+from ubuntuone.controlpanel.gui import (
41+ humanize,
42+ sign_url,
43+ FOLDER_INVALID_PATH
44+)
45 from ubuntuone.platform.credentials import CredentialsManagementTool
46 from ubuntu_sso.qt.gui import SSOWizardPage
47
48@@ -49,12 +54,19 @@
49
50 class FolderItem(QtGui.QTreeWidgetItem):
51 """Class representing a folder in the folder list UI."""
52- def __init__(self, strings, path=None, queue=None):
53+ def __init__(self, strings, path=None, queue=None,
54+ calculate=True, volume_id=None):
55 super(FolderItem, self).__init__(strings)
56- self.thread = CalculateSize(path, queue)
57- self.thread.start()
58- self.size = None
59+ if calculate:
60+ self.thread = CalculateSize(path, queue)
61+ self.thread.start()
62+ self.size = None
63+ else:
64+ self.thread = CalculateSize(path, queue)
65+ self.size = 0
66 self.path = path
67+ self.setCheckState(0, QtCore.Qt.Unchecked)
68+ self.volume_id = volume_id
69
70
71 class CalculateSize(threading.Thread):
72@@ -88,6 +100,9 @@
73 self.queue = Queue.Queue()
74 self.timer = QtCore.QTimer()
75 self.items = {}
76+ self.folders_info = None
77+ self.account_info = None
78+ self.cp_backend = backend.ControlBackend()
79
80 # initializePage is inherited
81 # pylint: disable=C0103
82@@ -99,16 +114,72 @@
83 self.wizard()._next_id = self.wizard().SYNC_NOW_OR_LATER_PAGE
84 # Start with this invisible
85 self.ui.offer_frame.setVisible(False)
86- if not self.ui.folder_list.topLevelItemCount():
87+ # Block until we have server data
88+ self.wizard().overlay.show()
89+ self.get_info()
90+
91+ @inlineCallbacks
92+ def get_info(self):
93+ """Get information from CP backend and fill folder list."""
94+ try:
95+ volumes_info = yield self.cp_backend.volumes_info()
96+ self.account_info = yield self.cp_backend.account_info()
97+ self.folders_info = []
98+ for _, _, volumes in volumes_info:
99+ for volume in volumes:
100+ if volume[u'type'] == u"UDF":
101+ self.folders_info.append(volume)
102+ self.ui.folder_list.clear()
103+ for folder in self.folders_info:
104+ item = yield self.add_folder(
105+ os.path.expanduser(folder['path']),
106+ validate=False, volume_id=folder['volume_id'])
107+ if item:
108+ if folder['subscribed']:
109+ item.setCheckState(0, QtCore.Qt.Checked)
110+ item.thread.join()
111+ item.size = 0
112 for folder_name in self.default_folders():
113- self.add_folder(folder_name)
114- self.timer.start(2000)
115- self.timer.timeout.connect(self.update_sizes)
116+ item = yield self.add_folder(folder_name, validate=True)
117+ self.timer.start(2000)
118+ self.timer.timeout.connect(self.update_sizes)
119+ self.wizard().overlay.hide()
120+ self.wizard().currentIdChanged.connect(self.changed_page)
121+ except:
122+ logger.exception("Error getting backend info:")
123+
124+ @QtCore.pyqtSlot("int")
125+ @inlineCallbacks
126+ def changed_page(self, page_id):
127+ """When moving to next page, create/[un]subscribe UDFs."""
128+ self.timer.stop()
129+ try:
130+ self.wizard().currentIdChanged.disconnect(self.changed_page)
131+ except KeyError:
132+ pass
133+ if page_id == self.wizard().SYNC_NOW_OR_LATER_PAGE:
134+ # The page following this one
135+ self.wizard().overlay.show()
136+ for path, item in self.items.items():
137+ if item.checkState(0) == QtCore.Qt.Checked:
138+ if item.volume_id:
139+ yield self.cp_backend.change_volume_settings(
140+ item.volume_id,
141+ dict(subscribed=True))
142+ else:
143+ yield self.cp_backend.create_folder(path)
144+ else:
145+ if item.volume_id:
146+ yield self.cp_backend.change_volume_settings(
147+ item.volume_id,
148+ dict(subscribed=False))
149+ self.wizard().overlay.hide()
150
151 def default_folders(self):
152 """Return a list of the folders to add by default."""
153 if sys.platform == 'win32':
154- # Special Folder "My Documents"
155+ # XXXX to be replaced by calls to xdg_base_directory's
156+ # special_folders
157 dll = ctypes.windll.shell32
158 buf = ctypes.create_string_buffer(300)
159 dll.SHGetSpecialFolderPathA(None, buf, 5, False)
160@@ -122,61 +193,62 @@
161 result = ['To be implemented']
162 return result
163
164- def add_folder(self, path):
165+ @inlineCallbacks
166+ def add_folder(self, path, validate=True, volume_id=False):
167 """Add a folder to the list."""
168 if path in self.items:
169- return None
170- # FIXME: the path should actually be sent to u1cp to verify as valid
171- item = FolderItem([path, "", "remove"], path=path, queue=self.queue)
172- self.ui.folder_list.addTopLevelItem(item)
173- self.items[path] = item
174- return item
175+ returnValue(None)
176+ if validate:
177+ is_valid = yield self.cp_backend.validate_path_for_folder(path)
178+ else:
179+ is_valid = True
180+ if is_valid:
181+ item = FolderItem([path, ""],
182+ path=path, queue=self.queue, volume_id=volume_id)
183+ self.ui.folder_list.addTopLevelItem(item)
184+ self.items[path] = item
185+ returnValue(item)
186+ returnValue(None)
187
188- @inlineCallbacks
189 def update_sizes(self):
190 """Poll the queue were the threads put the size info."""
191 try:
192- path, size = self.queue.get(False)
193- item = self.items.get(path)
194- if item:
195- item.size = size
196- item.setText(1, humanize(size))
197+ while True:
198+ path, size = self.queue.get(False)
199+ item = self.items.get(path)
200+ if item:
201+ item.size = size
202+ try:
203+ item.setText(1, humanize(size))
204+ except RuntimeError:
205+ del self.items[path]
206 except Queue.Empty:
207 pass
208- total = 0
209+ total = long(self.account_info['quota_used'])
210 for path, item in self.items.items():
211 if item.size is None:
212 total = LOCAL_FOLDERS_CALCULATING
213 break
214- total += item.size
215-
216+ if not item.volume_id and item.checkState(0) == QtCore.Qt.Checked:
217+ # Existing UDFs are already accounted for, count if marked.
218+ total += item.size
219 if isinstance(total, long):
220- yield self.show_hide_offer(total)
221+ self.show_hide_offer(total)
222 total = humanize(total)
223 else:
224- yield self.show_hide_offer(0)
225+ self.show_hide_offer(0)
226 self.ui.folder_list.headerItem().setText(
227 1, LOCAL_FOLDERS_SPACE_HEADER % total)
228
229- @inlineCallbacks
230 def show_hide_offer(self, cur_size):
231- """Show or hide the offer to buy space according to the total size.
232-
233- Returns a deferred that is triggered when the update is finished.
234-
235- """
236- # pylint: disable=W0702
237- try:
238- user_info = yield self.ui.add_folder_button.backend.account_info()
239- quota = user_info['quota_total']
240- if cur_size > quota:
241- self.ui.offer_frame.setVisible(True)
242- else:
243- self.ui.offer_frame.setVisible(False)
244- self.ui.offer_label.setText(LOCAL_FOLDERS_OFFER_LABEL %
245- {"quota": humanize(quota)})
246- except:
247- logger.exception('Error while trying to update the quota:')
248+ """Show or hide the offer to buy space according to the total size."""
249+ quota = self.account_info['quota_total']
250+ if cur_size > quota:
251+ self.ui.offer_frame.setVisible(True)
252+ else:
253+ self.ui.offer_frame.setVisible(False)
254+ self.ui.offer_label.setText(LOCAL_FOLDERS_OFFER_LABEL %
255+ {"quota": humanize(quota)})
256
257 def stop_threads(self):
258 """Stop all pending threads."""
259@@ -185,31 +257,44 @@
260
261 # itemClicked is a Qt signal name.
262 # pylint: disable=C0103
263- def on_folder_list_itemClicked(self, item, column):
264+ def on_folder_list_itemChanged(self, item, column):
265 """Delete folder from the list."""
266- if column == 2:
267- del(self.items[item.path])
268- item.thread._stop = True
269- self.ui.folder_list.takeTopLevelItem(
270- self.ui.folder_list.indexOfTopLevelItem(item))
271- self.update_sizes()
272+ if column == 0:
273+ self.update_sizes()
274
275 @inlineCallbacks
276 @QtCore.pyqtSlot()
277 def on_add_storage_button_clicked(self):
278 """user clicked on the "Add more storage" button."""
279-
280+ # Really want to catch everything
281 # pylint: disable=W0702
282 try:
283 credtool = CredentialsManagementTool()
284 creds = yield credtool.find_credentials()
285 except:
286- logger.exception('Error while trying to update que quota:')
287+ logger.exception('Error while trying to get credentials:')
288 creds = {}
289-
290 if creds:
291 signed_url = sign_url(
292 "https://one.ubuntu.com/services/#storage_panel", creds)
293 else:
294 signed_url = "https://one.ubuntu.com/services/#storage_panel"
295 QtGui.QDesktopServices.openUrl(QtCore.QUrl(signed_url))
296+
297+ @inlineCallbacks
298+ @QtCore.pyqtSlot()
299+ def on_add_folder_button_clicked(self):
300+ """user clicked on the "Add Folder" button."""
301+ folder = QtGui.QFileDialog.getExistingDirectory(parent=self)
302+ folder = unicode(folder)
303+ if folder == '':
304+ return
305+
306+ is_valid = yield self.cp_backend.validate_path_for_folder(folder)
307+ if not is_valid:
308+ user_home = os.path.expanduser('~')
309+ text = FOLDER_INVALID_PATH % {'folder_path': folder,
310+ 'home_folder': user_home}
311+ QtGui.QMessageBox.warning(self, '', text, QtGui.QMessageBox.Close)
312+ return
313+ yield self.add_folder(folder, validate=False, volume_id=False)
314
315=== modified file 'ubuntuone_installer/gui/qt/tests/test_gui.py'
316--- ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-17 00:58:24 +0000
317+++ ubuntuone_installer/gui/qt/tests/test_gui.py 2011-08-17 00:58:24 +0000
318@@ -529,15 +529,20 @@
319
320 def __init__(self, *args, **kwargs):
321 """Initialize."""
322- self.target = lambda *args: None
323+ self.target = None
324
325 def connect(self, target):
326 """Fake connect."""
327 self.target = target
328
329+ def disconnect(self, *args):
330+ """Fake disconnect."""
331+ self.target = None
332+
333 def emit(self, *args):
334 """Fake emit."""
335- self.target(*args)
336+ if self.target:
337+ self.target(*args)
338
339
340 class FakeMainWindow(object):
341@@ -548,7 +553,10 @@
342 registrationSuccess = FakeSignal()
343 userCancellation = FakeSignal()
344 shown = False
345+ _buttonlayout = None
346 SYNC_NOW_OR_LATER_PAGE = 4
347+ overlay = FakeOverlay()
348+ currentIdChanged = FakeSignal()
349
350 def show(self):
351 """Fake method."""
352@@ -563,9 +571,71 @@
353 class FakeCPBackend(object):
354 """Fake Control Panel backend."""
355
356+ def __init__(self):
357+ """Initialize."""
358+ self._is_valid = True
359+ self.volume_setings_changes = []
360+ self.folders_created = []
361+
362 def account_info(self, *args):
363 """Fake account info."""
364- return defer.succeed({"quota_total": 1000})
365+ return defer.succeed({
366+ "quota_total": 1000,
367+ "quota_used": 200,
368+ })
369+
370+ def volumes_info(self, *args):
371+ """"Fake volumes info."""
372+ return defer.succeed(((None, None,
373+ [
374+ {
375+ 'type': u'UDF',
376+ 'path': os.path.expanduser(u'~/xyzzy'),
377+ 'volume_id': 'asdfgh',
378+ 'subscribed': True
379+ },
380+ {
381+ 'type': u'UDF',
382+ 'path': os.path.expanduser(u'~/zxyzzy'),
383+ 'volume_id': 'qwerty',
384+ 'subscribed': False
385+ },
386+ ],
387+ ),))
388+
389+ def validate_path_for_folder(self, path):
390+ """Fake folder validation."""
391+ return self._is_valid
392+
393+ def change_volume_settings(self, *args):
394+ """Fake change volume settings."""
395+ self.volume_setings_changes.append(args)
396+
397+ def create_folder(self, *args):
398+ """Fake folder creation."""
399+ self.folders_created.append(args)
400+
401+
402+class FakeFileDialog(object):
403+
404+ """A fake QFileDialog class."""
405+
406+ # pylint: disable=C0103
407+ def getExistingDirectory(self, *args, **kwargs):
408+ """Fake existing folder name."""
409+ return u"whatever"
410+
411+
412+class FakeMessageBox(object):
413+
414+ """A fake QMessageBox class."""
415+
416+ Close = 2
417+ _warning = None
418+
419+ def warning(self, *args, **kwargs):
420+ """Fake warning."""
421+ self._warning = (args, kwargs)
422
423
424 class FakeFailingCPBackend(object):
425@@ -598,6 +668,7 @@
426 f.write(" " * 737)
427 f.close()
428 self.fake_wizard = FakeMainWindow()
429+ self.patch(local_folders.backend, "ControlBackend", FakeCPBackend)
430 super(LocalFoldersTestCase, self).setUp()
431 self.patch(self.ui, "wizard", lambda: self.fake_wizard)
432
433@@ -606,6 +677,24 @@
434 shutil.rmtree(self.tmpdir)
435 BaseTestCase.tearDown(self)
436
437+ @defer.inlineCallbacks
438+ def test_subscribed_udf_checked(self):
439+ """Check that subscribed UDF items are created correctly."""
440+ yield self.ui.get_info()
441+ item = self.ui.items[os.path.expanduser(u'~/xyzzy')]
442+ self.assertEqual(item.checkState(0), QtCore.Qt.Checked)
443+ self.assertEqual(item.size, 0)
444+ self.assertTrue(item.volume_id)
445+
446+ @defer.inlineCallbacks
447+ def test_unsubscribed_udf_checked(self):
448+ """Check that unsubscribed UDF items are created correctly."""
449+ yield self.ui.get_info()
450+ item = self.ui.items[os.path.expanduser(u'~/zxyzzy')]
451+ self.assertEqual(item.checkState(0), QtCore.Qt.Unchecked)
452+ self.assertEqual(item.size, 0)
453+ self.assertTrue(item.volume_id)
454+
455 def test_size_calculation(self):
456 """Test the recursive folder size calculation."""
457 queue = Queue.Queue()
458@@ -615,38 +704,77 @@
459 self.assertEqual(path, self.tmpdir)
460 self.assertEqual(size, 1337)
461
462+ @defer.inlineCallbacks
463 def test_item_addition(self):
464- """Add an item (plus the default one), then remove them."""
465- self.ui.add_folder(self.tmpdir)
466- self.assertEqual(4, self.ui.ui.folder_list.topLevelItemCount())
467-
468+ """Add a folder."""
469+ self.ui.ui.folder_list.clear()
470+ yield self.ui.add_folder(self.tmpdir)
471+ self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
472+
473+ @defer.inlineCallbacks
474+ def test_invalid_item_addition(self):
475+ """Try to add an invalid folder."""
476+ self.ui.ui.folder_list.clear()
477+ self.ui.cp_backend._is_valid = False
478+ yield self.ui.add_folder(self.tmpdir)
479+ self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
480+
481+ @defer.inlineCallbacks
482 def test_total_size(self):
483 """Test that the header reflects the change in item sizes."""
484- while self.ui.ui.folder_list.topLevelItemCount():
485- self.ui.on_folder_list_itemClicked(
486- self.ui.ui.folder_list.topLevelItem(0), 2)
487- self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
488- item = self.ui.add_folder(self.tmpdir)
489- item.size = 1337
490- item.thread.run()
491- item.thread.join()
492- self.ui.update_sizes()
493- self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
494- u"Space (1337)")
495+ yield self.ui.get_info()
496+ self.ui.ui.folder_list.clear()
497+ self.ui.items = {}
498+ item = yield self.ui.add_folder(self.tmpdir)
499+ item.thread.run()
500+ item.thread.join()
501+ item.size = 1337
502+ item.setCheckState(0, QtCore.Qt.Checked)
503+ self.ui.update_sizes()
504+ self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
505+ u"Space (1.5 KiB)")
506+
507+ @defer.inlineCallbacks
508+ def test_total_size_unchecked(self):
509+ """Unchecked items use no space beyond quota_used."""
510+ yield self.ui.get_info()
511+ self.ui.ui.folder_list.clear()
512+ self.ui.items = {}
513+ item = yield self.ui.add_folder(self.tmpdir)
514+ item.thread.run()
515+ item.thread.join()
516+ item.size = 1337
517+ item.setCheckState(0, QtCore.Qt.Unchecked)
518+ self.ui.update_sizes()
519+ self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
520+ u"Space (200 bytes)")
521+
522+ @defer.inlineCallbacks
523+ def test_total_size_udf(self):
524+ """UDFs use no space beyond quota_used."""
525+ yield self.ui.get_info()
526+ for _, item in self.ui.items.items():
527+ item.thread.join()
528+ if item.volume_id:
529+ item.setCheckState(0, QtCore.Qt.Checked)
530+ else:
531+ item.setCheckState(0, QtCore.Qt.Unchecked)
532+ self.ui.update_sizes()
533+ self.assertEqual(unicode(self.ui.ui.folder_list.headerItem().text(1)),
534+ u"Space (200 bytes)")
535
536 def test_add_twice(self):
537 """Behaviour for adding the same folder twice:
538
539 * It's added only once.
540 """
541- while self.ui.ui.folder_list.topLevelItemCount():
542- self.ui.on_folder_list_itemClicked(
543- self.ui.ui.folder_list.topLevelItem(0), 2)
544+ self.ui.ui.folder_list.clear()
545 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
546 self.ui.add_folder(self.tmpdir)
547 self.ui.add_folder(self.tmpdir)
548 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
549
550+ @defer.inlineCallbacks
551 def test_add_missing_folder(self):
552 """Behaviour for adding a folder that doesn't exist:
553
554@@ -654,11 +782,11 @@
555 * Has size 0.
556 """
557
558- while self.ui.ui.folder_list.topLevelItemCount():
559- self.ui.on_folder_list_itemClicked(
560- self.ui.ui.folder_list.topLevelItem(0), 2)
561+ yield self.ui.get_info()
562+ self.ui.ui.folder_list.clear()
563 self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
564- item = self.ui.add_folder(os.path.join("xyzzy", "xyzzy", "xyzzy"))
565+ item = yield self.ui.add_folder(os.path.join(
566+ "xyzzy", "xyzzy", "xyzzy"))
567 self.assertEqual(1, self.ui.ui.folder_list.topLevelItemCount())
568 item.thread.run()
569 item.thread.join()
570@@ -672,27 +800,79 @@
571 Push the user over quota, it should be visible.
572 """
573 self.patch(self.ui.ui.offer_frame, "setVisible", self._set_called)
574- while self.ui.ui.folder_list.topLevelItemCount():
575- self.ui.on_folder_list_itemClicked(
576- self.ui.ui.folder_list.topLevelItem(0), 2)
577- self.assertEqual(0, self.ui.ui.folder_list.topLevelItemCount())
578+ yield self.ui.get_info()
579+ self.ui.ui.folder_list.clear()
580 self.ui.update_sizes()
581 self.assertEqual(self._called, ((False,), {}))
582 self.ui.show_hide_offer(self.ui.quota() + 1)
583 self.assertEqual(self._called, ((True,), {}))
584
585+ def test_add_folder_valid(self):
586+ """Test behaviour when adding a valid folder via the button."""
587+ self.patch(QtGui, "QFileDialog", FakeFileDialog())
588+ self.patch(self.ui, "add_folder", self._set_called)
589+ self.ui.ui.add_folder_button.click()
590+ self.assertEqual(self._called,
591+ ((u'whatever',), {'validate': False, 'volume_id': False}))
592+
593+ def test_add_folder_invalid(self):
594+ """Test behaviour when adding an invalid folder via the button."""
595+ self.patch(QtGui, "QFileDialog", FakeFileDialog())
596+ message_box = FakeMessageBox()
597+ self.patch(QtGui, "QMessageBox", message_box)
598+ self.patch(self.ui, "add_folder", self._set_called)
599+ self.ui.cp_backend._is_valid = False
600+ self.ui.ui.add_folder_button.click()
601+ self.assertEqual(self._called, False)
602+ user_home = os.path.expanduser('~')
603+ text = local_folders.FOLDER_INVALID_PATH % {
604+ 'folder_path': "whatever",
605+ 'home_folder': user_home,
606+ }
607+ self.assertEqual(message_box._warning,
608+ ((self.ui,
609+ '', text, 2), {}))
610+
611+ @defer.inlineCallbacks
612+ def test_changed_page_existing_udf_behaviour(self):
613+ """If a UDF is checked, subscribe it, if not, unsubscribe it."""
614+ yield self.ui.get_info()
615+ self.ui.changed_page(self.ui.wizard().SYNC_NOW_OR_LATER_PAGE)
616+ self.assertEqual(self.ui.cp_backend.volume_setings_changes,
617+ [('asdfgh', {'subscribed': True}),
618+ ('qwerty', {'subscribed': False})])
619+
620+ @defer.inlineCallbacks
621+ def test_changed_page_new_udf_behaviour(self):
622+ """Create UDFs for non-existing, checked UDFs."""
623+ yield self.ui.get_info()
624+ self.ui.ui.folder_list.clear()
625+ self.ui.items = {}
626+ item = yield self.ui.add_folder("whatever")
627+ item.setCheckState(0, QtCore.Qt.Checked)
628+ item = yield self.ui.add_folder("whatever2")
629+ item.setCheckState(0, QtCore.Qt.Unchecked)
630+ self.ui.changed_page(self.ui.wizard().SYNC_NOW_OR_LATER_PAGE)
631+ self.assertEqual(self.ui.cp_backend.folders_created,
632+ [('whatever',)])
633+
634 def test_exception_on_account_info(self):
635 """When account_info fails, nothing should happen."""
636- self.patch(self.ui.ui.add_folder_button,
637- "backend", FakeFailingCPBackend())
638- self.ui.show_hide_offer(1000)
639+ self.patch(self.ui,
640+ "cp_backend", FakeFailingCPBackend())
641+ self.ui.get_info()
642 # Still here
643
644 def test_timer_is_started(self):
645- """ When displaying the page, the timer should start."""
646+ """When displaying the page, the timer should start."""
647 self.ui.initializePage()
648 self.assertTrue(self.ui.timer.isActive())
649
650+ def test_timer_is_stopped(self):
651+ """When leaving the page, the timer should stop."""
652+ self.ui.changed_page(-1)
653+ self.assertFalse(self.ui.timer.isActive())
654+
655
656 class SetupAccountTestCase(BaseTestCase):
657 """Test the SetupAccountPage code."""

Subscribers

People subscribed via source and target branches