Merge lp:~nataliabidart/ubuntu/natty/ubuntuone-control-panel/ubuntuone-control-panel-0.9.6 into lp:ubuntu/natty/ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Merged at revision: 21
Proposed branch: lp:~nataliabidart/ubuntu/natty/ubuntuone-control-panel/ubuntuone-control-panel-0.9.6
Merge into: lp:ubuntu/natty/ubuntuone-control-panel
Diff against target: 590 lines (+250/-37)
12 files modified
PKG-INFO (+1/-1)
debian/changelog (+20/-0)
debian/control (+6/-6)
setup.py (+1/-1)
ubuntuone/controlpanel/backend.py (+25/-8)
ubuntuone/controlpanel/gtk/gui.py (+24/-6)
ubuntuone/controlpanel/gtk/tests/__init__.py (+11/-2)
ubuntuone/controlpanel/gtk/tests/test_gui.py (+61/-1)
ubuntuone/controlpanel/gtk/tests/test_gui_basic.py (+1/-1)
ubuntuone/controlpanel/gtk/tests/test_widgets.py (+8/-0)
ubuntuone/controlpanel/gtk/widgets.py (+2/-0)
ubuntuone/controlpanel/tests/test_backend.py (+90/-11)
To merge this branch: bzr merge lp:~nataliabidart/ubuntu/natty/ubuntuone-control-panel/ubuntuone-control-panel-0.9.6
Reviewer Review Type Date Requested Status
Ubuntu Sponsors Pending
Review via email: mp+57347@code.launchpad.net

Description of the change

  * New upstream release.
    [ Natalia B. Bidart <email address hidden> ]
      - Free bytes will not be displayed in the UI for read-only shares.
      Also, backend now handles quota info not available for the root folder
      (LP: #726580).
      - Setting the unity's urgent prop only if available (LP: #755185).
      - Made panel title selectable. Tab messages are now also selectable
      (LP: #757543).
      - Highlight with red and bold when free space available is very little
      (either in own volumes or shares) (LP: #753989).

  * debian/control:
    - bump depends versions for ubuntuone-client (>= 1.6.0) and
    ubuntu-sso-client (>= 1.2.0).

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'PKG-INFO'
--- PKG-INFO 2011-04-08 16:07:22 +0000
+++ PKG-INFO 2011-04-12 16:04:35 +0000
@@ -1,6 +1,6 @@
1Metadata-Version: 1.11Metadata-Version: 1.1
2Name: ubuntuone-control-panel2Name: ubuntuone-control-panel
3Version: 0.9.53Version: 0.9.6
4Summary: Ubuntu One Control Panel4Summary: Ubuntu One Control Panel
5Home-page: https://launchpad.net/ubuntuone-control-panel5Home-page: https://launchpad.net/ubuntuone-control-panel
6Author: Natalia Bidart6Author: Natalia Bidart
77
=== modified file 'debian/changelog'
--- debian/changelog 2011-04-08 20:23:32 +0000
+++ debian/changelog 2011-04-12 16:04:35 +0000
@@ -1,3 +1,23 @@
1ubuntuone-control-panel (0.9.6-0ubuntu1) UNRELEASED; urgency=low
2
3 * New upstream release.
4
5 [ Natalia B. Bidart <natalia.bidart@canonical.com> ]
6 - Free bytes will not be displayed in the UI for read-only shares.
7 Also, backend now handles quota info not available for the root folder
8 (LP: #726580).
9 - Setting the unity's urgent prop only if available (LP: #755185).
10 - Made panel title selectable. Tab messages are now also selectable
11 (LP: #757543).
12 - Highlight with red and bold when free space available is very little
13 (either in own volumes or shares) (LP: #753989).
14
15 * debian/control:
16 - bump depends versions for ubuntuone-client (>= 1.6.0) and
17 ubuntu-sso-client (>= 1.2.0).
18
19 -- Natalia Bidart (nessita) <nataliabidart@gmail.com> Tue, 12 Apr 2011 12:11:11 -0300
20
1ubuntuone-control-panel (0.9.5-0ubuntu1) natty; urgency=low21ubuntuone-control-panel (0.9.5-0ubuntu1) natty; urgency=low
222
3 * New upstream release:23 * New upstream release:
424
=== modified file 'debian/control'
--- debian/control 2011-03-10 03:09:16 +0000
+++ debian/control 2011-04-12 16:04:35 +0000
@@ -17,7 +17,7 @@
17 ${python:Depends},17 ${python:Depends},
18 python,18 python,
19 python-ubuntuone-control-panel (= ${binary:Version}),19 python-ubuntuone-control-panel (= ${binary:Version}),
20 ubuntuone-client (>= 1.5.6),20 ubuntuone-client (>= 1.6.0),
21Recommends: ubuntuone-control-panel-gui21Recommends: ubuntuone-control-panel-gui
22Description: Ubuntu One Control Panel22Description: Ubuntu One Control Panel
23 Desktop application to manage a Ubuntu One account.23 Desktop application to manage a Ubuntu One account.
@@ -37,8 +37,8 @@
37 python-simplejson,37 python-simplejson,
38 python-twisted-core,38 python-twisted-core,
39 python-twisted-web,39 python-twisted-web,
40 python-ubuntuone-client (>= 1.5.6),40 python-ubuntuone-client (>= 1.6.0),
41 ubuntu-sso-client (>= 1.1.11),41 ubuntu-sso-client (>= 1.2.0),
42Description: Ubuntu One Control Panel Python Libraries42Description: Ubuntu One Control Panel Python Libraries
43 Ubuntu One Control Panel provides a Python library to manage an Ubuntu One43 Ubuntu One Control Panel provides a Python library to manage an Ubuntu One
44 account.44 account.
@@ -54,9 +54,9 @@
54 python-defer,54 python-defer,
55 python-gobject,55 python-gobject,
56 python-gtk2,56 python-gtk2,
57 python-ubuntuone-client (>= 1.5.6),57 python-ubuntuone-client (>= 1.6.0),
58 ubuntu-sso-client (>= 1.1.11),58 ubuntu-sso-client (>= 1.2.0),
59 ubuntuone-client (>= 1.5.6),59 ubuntuone-client (>= 1.6.0),
60 ubuntuone-control-panel (= ${binary:Version}),60 ubuntuone-control-panel (= ${binary:Version}),
61Provides: ubuntuone-control-panel-gui61Provides: ubuntuone-control-panel-gui
62Description: Ubuntu One Control Panel62Description: Ubuntu One Control Panel
6363
=== modified file 'setup.py'
--- setup.py 2011-04-08 16:07:22 +0000
+++ setup.py 2011-04-12 16:04:35 +0000
@@ -79,7 +79,7 @@
7979
80DistUtilsExtra.auto.setup(80DistUtilsExtra.auto.setup(
81 name='ubuntuone-control-panel',81 name='ubuntuone-control-panel',
82 version='0.9.5',82 version='0.9.6',
83 license='GPL v3',83 license='GPL v3',
84 author='Natalia Bidart',84 author='Natalia Bidart',
85 author_email='natalia.bidart@canonical.com',85 author_email='natalia.bidart@canonical.com',
8686
=== modified file 'ubuntuone/controlpanel/backend.py'
--- ubuntuone/controlpanel/backend.py 2011-04-08 16:07:22 +0000
+++ ubuntuone/controlpanel/backend.py 2011-04-12 16:04:35 +0000
@@ -100,6 +100,7 @@
100 FOLDER_TYPE = u'UDF'100 FOLDER_TYPE = u'UDF'
101 SHARE_TYPE = u'SHARE'101 SHARE_TYPE = u'SHARE'
102 NAME_NOT_SET = u'ENAMENOTSET'102 NAME_NOT_SET = u'ENAMENOTSET'
103 FREE_BYTES_NOT_AVAILABLE = u'EFREEBYTESNOTAVAILABLE'
103 STATUS_DISABLED = {MSG_KEY: '', STATUS_KEY: FILE_SYNC_DISABLED}104 STATUS_DISABLED = {MSG_KEY: '', STATUS_KEY: FILE_SYNC_DISABLED}
104105
105 def __init__(self, shutdown_func=None):106 def __init__(self, shutdown_func=None):
@@ -450,14 +451,21 @@
450 """Get the volumes info."""451 """Get the volumes info."""
451 self._volumes = {}452 self._volumes = {}
452453
453 account = yield self.account_info()454 try:
455 account = yield self.account_info()
456 except Exception: # pylint: disable=W0703
457 logger.exception('volumes_info: quota could not be retrieved:')
458 free_bytes = self.FREE_BYTES_NOT_AVAILABLE
459 else:
460 free_bytes = int(account['quota_total']) - \
461 int(account['quota_used'])
462
454 root_dir = yield dbus_client.get_root_dir()463 root_dir = yield dbus_client.get_root_dir()
455 shares_dir = yield dbus_client.get_shares_dir()464 shares_dir = yield dbus_client.get_shares_dir()
456 shares_dir_link = yield dbus_client.get_shares_dir_link()465 shares_dir_link = yield dbus_client.get_shares_dir_link()
457 folders = yield dbus_client.get_folders()466 folders = yield dbus_client.get_folders()
458 shares = yield dbus_client.get_shares()467 shares = yield dbus_client.get_shares()
459468
460 free_bytes = int(account['quota_total']) - int(account['quota_used'])
461 root_volume = {u'volume_id': u'', u'path': root_dir,469 root_volume = {u'volume_id': u'', u'path': root_dir,
462 u'subscribed': 'True', u'type': self.ROOT_TYPE}470 u'subscribed': 'True', u'type': self.ROOT_TYPE}
463 self._volumes[u''] = root_volume471 self._volumes[u''] = root_volume
@@ -465,15 +473,17 @@
465 # group shares by the offering user473 # group shares by the offering user
466 shares_result = defaultdict(list)474 shares_result = defaultdict(list)
467 for share in shares:475 for share in shares:
476 if not bool(share['accepted']):
477 continue
478
468 share[u'type'] = self.SHARE_TYPE479 share[u'type'] = self.SHARE_TYPE
469480
470 vid = share['volume_id']481 vid = share['volume_id']
471 assert vid not in self._volumes482 if vid in self._volumes:
483 logger.warning('volumes_info: share %r already in the volumes '
484 'list (%r).', vid, self._volumes[vid])
472 self._volumes[vid] = share485 self._volumes[vid] = share
473486
474 if not bool(share['accepted']):
475 continue
476
477 nicer_path = share[u'path'].replace(shares_dir, shares_dir_link)487 nicer_path = share[u'path'].replace(shares_dir, shares_dir_link)
478 share[u'path'] = nicer_path488 share[u'path'] = nicer_path
479489
@@ -488,13 +498,20 @@
488 folder[u'type'] = self.FOLDER_TYPE498 folder[u'type'] = self.FOLDER_TYPE
489499
490 vid = folder['volume_id']500 vid = folder['volume_id']
491 assert vid not in self._volumes501 if vid in self._volumes:
502 logger.warning('volumes_info: udf %r already in the volumes '
503 'list (%r).', vid, self._volumes[vid])
492 self._volumes[vid] = folder504 self._volumes[vid] = folder
493505
494 result = [(u'', unicode(free_bytes), [root_volume] + folders)]506 result = [(u'', unicode(free_bytes), [root_volume] + folders)]
495507
496 for other_username, shares in shares_result.iteritems():508 for other_username, shares in shares_result.iteritems():
497 result.append((other_username, shares[0][u'free_bytes'], shares))509 send_freebytes = any(s['access_level'] == 'Modify' for s in shares)
510 if send_freebytes:
511 free_bytes = shares[0][u'free_bytes']
512 else:
513 free_bytes = self.FREE_BYTES_NOT_AVAILABLE
514 result.append((other_username, free_bytes, shares))
498515
499 returnValue(result)516 returnValue(result)
500517
501518
=== modified file 'ubuntuone/controlpanel/gtk/gui.py'
--- ubuntuone/controlpanel/gtk/gui.py 2011-04-08 16:07:22 +0000
+++ ubuntuone/controlpanel/gtk/gui.py 2011-04-12 16:04:35 +0000
@@ -456,7 +456,7 @@
456 'this computer')456 'this computer')
457 MY_FOLDERS = _('My folders')457 MY_FOLDERS = _('My folders')
458 ALWAYS_SUBSCRIBED = _('Always in sync!')458 ALWAYS_SUBSCRIBED = _('Always in sync!')
459 FREE_SPACE = _('%(free_space)s available storage')459 FREE_SPACE_TEXT = _('%(free_space)s available storage')
460 NO_VOLUMES = _('No folders to show.')460 NO_VOLUMES = _('No folders to show.')
461 NAME_NOT_SET = _('[unknown user name]')461 NAME_NOT_SET = _('[unknown user name]')
462 CONFIRM_MERGE = _('The contents of your cloud folder will be merged with '462 CONFIRM_MERGE = _('The contents of your cloud folder will be merged with '
@@ -466,13 +466,15 @@
466 MUSIC_REAL_PATH = '~/.ubuntuone/Purchased from Ubuntu One'466 MUSIC_REAL_PATH = '~/.ubuntuone/Purchased from Ubuntu One'
467467
468 MAX_COLS = 8468 MAX_COLS = 8
469 MIN_SIZE_FULL = 1048576
469470
470 CONTACT_ICON_NAME = 'avatar-default'471 CONTACT_ICON_NAME = 'avatar-default'
471 FOLDER_ICON_NAME = 'folder'472 FOLDER_ICON_NAME = 'folder'
472 SHARE_ICON_NAME = 'folder-remote'473 SHARE_ICON_NAME = 'folder-remote'
473 MUSIC_ICON_NAME = 'audio-x-generic'474 MUSIC_ICON_NAME = 'audio-x-generic'
474 ROW_HEADER = '<span font_size="large"><b>%s</b></span> ' \475 FREE_SPACE = '<span foreground="grey">%s</span>' % FREE_SPACE_TEXT
475 '<span foreground="grey">%s</span>'476 NO_FREE_SPACE = '<span foreground="red"><b>%s</b></span>' % FREE_SPACE_TEXT
477 ROW_HEADER = '<span font_size="large"><b>%s</b></span> %s'
476 ROOT = '%s - <span foreground="%s" font_size="small">%s</span>'478 ROOT = '%s - <span foreground="%s" font_size="small">%s</span>'
477479
478 def __init__(self, main_window=None):480 def __init__(self, main_window=None):
@@ -534,12 +536,28 @@
534 else:536 else:
535 name = self.MY_FOLDERS537 name = self.MY_FOLDERS
536538
537 free_bytes_args = {'free_space': self.humanize(int(free_bytes))}539 scroll_to_cell = False
538 row = (self.ROW_HEADER % (name, self.FREE_SPACE % free_bytes_args),540 if free_bytes == backend.ControlBackend.FREE_BYTES_NOT_AVAILABLE:
541 free_bytes = ''
542 else:
543 free_bytes = int(free_bytes)
544 if free_bytes < self.MIN_SIZE_FULL:
545 free_bytes_str = self.NO_FREE_SPACE
546 scroll_to_cell = True
547 else:
548 free_bytes_str = self.FREE_SPACE
549 free_bytes_args = {'free_space': self.humanize(free_bytes)}
550 free_bytes = free_bytes_str % free_bytes_args
551
552 row = (self.ROW_HEADER % (name, free_bytes),
539 True, self.CONTACT_ICON_NAME, False, False,553 True, self.CONTACT_ICON_NAME, False, False,
540 gtk.ICON_SIZE_LARGE_TOOLBAR, None, None)554 gtk.ICON_SIZE_LARGE_TOOLBAR, None, None)
541 treeiter = self.volumes_store.append(None, row)555 treeiter = self.volumes_store.append(None, row)
542556
557 if scroll_to_cell:
558 path = self.volumes_store.get_string_from_iter(treeiter)
559 self.volumes_view.scroll_to_cell(path)
560
543 volumes.sort(key=operator.itemgetter('path'))561 volumes.sort(key=operator.itemgetter('path'))
544 for volume in volumes:562 for volume in volumes:
545 sensitive = True563 sensitive = True
@@ -1722,7 +1740,7 @@
1722 if not USE_LIBUNITY:1740 if not USE_LIBUNITY:
1723 return1741 return
1724 entry = Unity.LauncherEntry.get_for_desktop_id(U1_DOTDESKTOP)1742 entry = Unity.LauncherEntry.get_for_desktop_id(U1_DOTDESKTOP)
1725 if entry.props.urgent:1743 if getattr(entry.props, 'urgent', False):
1726 self.switch_to('volumes')1744 self.switch_to('volumes')
1727 entry.props.urgent = False1745 entry.props.urgent = False
17281746
17291747
=== modified file 'ubuntuone/controlpanel/gtk/tests/__init__.py'
--- ubuntuone/controlpanel/gtk/tests/__init__.py 2011-04-08 16:07:22 +0000
+++ ubuntuone/controlpanel/gtk/tests/__init__.py 2011-04-12 16:04:35 +0000
@@ -68,7 +68,6 @@
68 {u'volume_id': u'1234', u'name': u'do',68 {u'volume_id': u'1234', u'name': u'do',
69 u'path': u'/home/tester/.local/share/ubuntuone/shares/do from Other User',69 u'path': u'/home/tester/.local/share/ubuntuone/shares/do from Other User',
70 u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE},70 u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE},
71
72 {u'volume_id': u'5678', u'name': u're',71 {u'volume_id': u'5678', u'name': u're',
73 u'path': u'/home/tester/.local/share/ubuntuone/shares/re from Other User',72 u'path': u'/home/tester/.local/share/ubuntuone/shares/re from Other User',
74 u'subscribed': u'True', u'type': ControlBackend.SHARE_TYPE},73 u'subscribed': u'True', u'type': ControlBackend.SHARE_TYPE},
@@ -76,7 +75,17 @@
7675
77FAKE_VOLUMES_INFO = [76FAKE_VOLUMES_INFO = [
78 (u'', u'147852369', [ROOT] + FAKE_FOLDERS_INFO),77 (u'', u'147852369', [ROOT] + FAKE_FOLDERS_INFO),
79 (u'Other User', u'985674', FAKE_SHARES_INFO),78 (u'Other User', gui.VolumesPanel.MIN_SIZE_FULL, FAKE_SHARES_INFO),
79]
80
81FAKE_VOLUMES_NO_FREE_SPACE_INFO = [
82 (u'', u'500', [ROOT]),
83 (u'No free space', u'0',
84 [{u'volume_id': u'0', u'name': u'full', u'path': u'full-share',
85 u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE}]),
86 (u'Almost no free space', gui.VolumesPanel.MIN_SIZE_FULL - 1,
87 [{u'volume_id': u'1', u'name': u'almostfull', u'path': u'almost-full',
88 u'subscribed': u'', u'type': ControlBackend.SHARE_TYPE}]),
80]89]
8190
82FAKE_DEVICE_INFO = {91FAKE_DEVICE_INFO = {
8392
=== modified file 'ubuntuone/controlpanel/gtk/tests/test_gui.py'
--- ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-04-08 16:07:22 +0000
+++ ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-04-12 16:04:35 +0000
@@ -23,7 +23,7 @@
23from ubuntuone.controlpanel.gtk import gui23from ubuntuone.controlpanel.gtk import gui
24from ubuntuone.controlpanel.gtk.tests import (FAKE_ACCOUNT_INFO,24from ubuntuone.controlpanel.gtk.tests import (FAKE_ACCOUNT_INFO,
25 FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, FAKE_FOLDERS_INFO,25 FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, FAKE_FOLDERS_INFO,
26 FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO,26 FAKE_VOLUMES_INFO, FAKE_VOLUMES_NO_FREE_SPACE_INFO, FAKE_REPLICATIONS_INFO,
27 MUSIC_FOLDER, ROOT, USER_HOME,27 MUSIC_FOLDER, ROOT, USER_HOME,
28 FakedConfirmDialog,28 FakedConfirmDialog,
29)29)
@@ -260,6 +260,66 @@
260260
261 self.assertEqual(len(self.ui.volumes_store), 0)261 self.assertEqual(len(self.ui.volumes_store), 0)
262262
263 def test_on_volumes_info_ready_highlights_little_free_space(self):
264 """The free space is red if is zero (or close to 0)."""
265 self.ui.on_volumes_info_ready(FAKE_VOLUMES_NO_FREE_SPACE_INFO)
266
267 treeiter = self.ui.volumes_store.get_iter_root()
268 for name, free_bytes, volumes in FAKE_VOLUMES_NO_FREE_SPACE_INFO:
269 name = "%s's" % name if name else self.ui.MY_FOLDERS
270 free_bytes = self.ui.humanize(int(free_bytes))
271 free_bytes = self.ui.NO_FREE_SPACE % {'free_space': free_bytes}
272
273 # check parent row
274 row = self.ui.volumes_store.get(treeiter,
275 *xrange(self.ui.MAX_COLS))
276
277 self.assertEqual(row[0], self.ui.ROW_HEADER % (name, free_bytes))
278
279 treeiter = self.ui.volumes_store.iter_next(treeiter)
280
281 if treeiter is not None:
282 # skip the empty row
283 row = self.ui.volumes_store.get(treeiter,
284 *xrange(self.ui.MAX_COLS))
285 self.assertEqual(row, self.ui._empty_row)
286
287 # grab next non-empty row
288 treeiter = self.ui.volumes_store.iter_next(treeiter)
289
290 def test_on_volumes_info_ready_handles_no_quota_info(self):
291 """The lack of free space is handled."""
292 info = [
293 (u'', gui.backend.ControlBackend.FREE_BYTES_NOT_AVAILABLE, [ROOT]),
294 (u'No free space available',
295 gui.backend.ControlBackend.FREE_BYTES_NOT_AVAILABLE,
296 [{u'volume_id': u'0', u'name': u'full',
297 u'path': u'full-share', u'subscribed': u'',
298 u'type': gui.backend.ControlBackend.SHARE_TYPE}]),
299 ]
300 self.ui.on_volumes_info_ready(info)
301
302 treeiter = self.ui.volumes_store.get_iter_root()
303 for name, free_bytes, volumes in info:
304 name = "%s's" % name if name else self.ui.MY_FOLDERS
305
306 # check parent row
307 row = self.ui.volumes_store.get(treeiter,
308 *xrange(self.ui.MAX_COLS))
309
310 self.assertEqual(row[0], self.ui.ROW_HEADER % (name, ''))
311
312 treeiter = self.ui.volumes_store.iter_next(treeiter)
313
314 if treeiter is not None:
315 # skip the empty row
316 row = self.ui.volumes_store.get(treeiter,
317 *xrange(self.ui.MAX_COLS))
318 self.assertEqual(row, self.ui._empty_row)
319
320 # grab next non-empty row
321 treeiter = self.ui.volumes_store.iter_next(treeiter)
322
263 def test_on_volumes_info_error(self):323 def test_on_volumes_info_error(self):
264 """The volumes info couldn't be retrieved."""324 """The volumes info couldn't be retrieved."""
265 self.ui.on_volumes_info_error()325 self.ui.on_volumes_info_error()
266326
=== modified file 'ubuntuone/controlpanel/gtk/tests/test_gui_basic.py'
--- ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 2011-04-08 16:07:22 +0000
+++ ubuntuone/controlpanel/gtk/tests/test_gui_basic.py 2011-04-12 16:04:35 +0000
@@ -143,7 +143,7 @@
143 THE_FLEP.urgent = True143 THE_FLEP.urgent = True
144 self.patch(gui.Unity, "LauncherEntry", FakeLauncherEntry)144 self.patch(gui.Unity, "LauncherEntry", FakeLauncherEntry)
145 cp = gui.ControlPanelWindow()145 cp = gui.ControlPanelWindow()
146 cp.emit('focus-in-event', None)146 cp.emit('focus-in-event', gui.gtk.gdk.Event(gui.gtk.gdk.FOCUS_CHANGE))
147 self.assertEqual(147 self.assertEqual(
148 False, THE_FLEP.urgent, 'remove_urgency should have been called.')148 False, THE_FLEP.urgent, 'remove_urgency should have been called.')
149149
150150
=== modified file 'ubuntuone/controlpanel/gtk/tests/test_widgets.py'
--- ubuntuone/controlpanel/gtk/tests/test_widgets.py 2011-03-23 16:06:41 +0000
+++ ubuntuone/controlpanel/gtk/tests/test_widgets.py 2011-04-12 16:04:35 +0000
@@ -148,6 +148,10 @@
148 actual = widget.loading.spinner.style.fg[widgets.gtk.STATE_NORMAL]148 actual = widget.loading.spinner.style.fg[widgets.gtk.STATE_NORMAL]
149 self.assertEqual(actual, widgets.gtk.gdk.Color(expected))149 self.assertEqual(actual, widgets.gtk.gdk.Color(expected))
150150
151 def test_selectable(self):
152 """The widget is selectable."""
153 self.assertTrue(self.widget.label.get_selectable())
154
151155
152class PanelTitleTestCase(TestCase):156class PanelTitleTestCase(TestCase):
153 """Tets case for a special title for each management panel."""157 """Tets case for a special title for each management panel."""
@@ -186,3 +190,7 @@
186 """The label padding is correct."""190 """The label padding is correct."""
187 self.assertEqual(self.widget.get_padding(),191 self.assertEqual(self.widget.get_padding(),
188 widgets.DEFAULT_PADDING)192 widgets.DEFAULT_PADDING)
193
194 def test_selectable(self):
195 """The widget is selectable."""
196 self.assertTrue(self.widget.get_selectable())
189197
=== modified file 'ubuntuone/controlpanel/gtk/widgets.py'
--- ubuntuone/controlpanel/gtk/widgets.py 2011-03-23 16:06:41 +0000
+++ ubuntuone/controlpanel/gtk/widgets.py 2011-04-12 16:04:35 +0000
@@ -55,6 +55,7 @@
55 self.loading = Loading(loading_label, fg_color=fg_color)55 self.loading = Loading(loading_label, fg_color=fg_color)
5656
57 self.label = gtk.Label()57 self.label = gtk.Label()
58 self.label.set_selectable(True)
58 self.label.show()59 self.label.show()
59 if fg_color is not None:60 if fg_color is not None:
60 self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(fg_color))61 self.label.modify_fg(gtk.STATE_NORMAL, gtk.gdk.Color(fg_color))
@@ -113,6 +114,7 @@
113 self.set_property('xalign', 0.0)114 self.set_property('xalign', 0.0)
114 self.set_line_wrap(True)115 self.set_line_wrap(True)
115 self.set_line_wrap_mode(pango.WRAP_WORD)116 self.set_line_wrap_mode(pango.WRAP_WORD)
117 self.set_selectable(True)
116 self.show_all()118 self.show_all()
117119
118120
119121
=== modified file 'ubuntuone/controlpanel/tests/test_backend.py'
--- ubuntuone/controlpanel/tests/test_backend.py 2011-04-08 16:07:22 +0000
+++ ubuntuone/controlpanel/tests/test_backend.py 2011-04-12 16:04:35 +0000
@@ -24,7 +24,7 @@
24import simplejson24import simplejson
2525
26from twisted.internet import defer26from twisted.internet import defer
27from twisted.internet.defer import inlineCallbacks27from twisted.internet.defer import inlineCallbacks, returnValue
28from ubuntuone.devtools.handlers import MementoHandler28from ubuntuone.devtools.handlers import MementoHandler
2929
30from ubuntuone.controlpanel import backend, replication_client30from ubuntuone.controlpanel import backend, replication_client
@@ -98,6 +98,8 @@
98 subscribed_folders = []98 subscribed_folders = []
99 subscribed_shares = []99 subscribed_shares = []
100 actions = []100 actions = []
101 shares = []
102 folders = []
101103
102 def get_credentials(self):104 def get_credentials(self):
103 """Return the mock credentials."""105 """Return the mock credentials."""
@@ -179,7 +181,7 @@
179181
180 def get_folders(self):182 def get_folders(self):
181 """Grab list of folders."""183 """Grab list of folders."""
182 return SAMPLE_FOLDERS184 return MockDBusClient.folders
183185
184 def subscribe_folder(self, volume_id):186 def subscribe_folder(self, volume_id):
185 """Subcribe to 'volume_id'."""187 """Subcribe to 'volume_id'."""
@@ -191,7 +193,7 @@
191193
192 def get_shares(self):194 def get_shares(self):
193 """Grab list of shares."""195 """Grab list of shares."""
194 return SAMPLE_SHARES196 return MockDBusClient.shares
195197
196 def subscribe_share(self, volume_id):198 def subscribe_share(self, volume_id):
197 """Subcribe to 'volume_id'."""199 """Subcribe to 'volume_id'."""
@@ -563,10 +565,14 @@
563 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON565 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON
564566
565 @inlineCallbacks567 @inlineCallbacks
566 def test_volumes_info(self):568 def expected_volumes(self, sample_shares, sample_folders):
567 """The volumes_info method exercises its callback."""569 """Get shares and group by sharing user, get folders and free space."""
568 result = yield self.be.account_info()570 try:
569 free_bytes = int(result['quota_total']) - int(result['quota_used'])571 result = yield self.be.account_info()
572 except Exception: # pylint: disable=W0703
573 free_bytes = self.be.FREE_BYTES_NOT_AVAILABLE
574 else:
575 free_bytes = int(result['quota_total']) - int(result['quota_used'])
570576
571 # get root dir info577 # get root dir info
572 root_volume = {u'volume_id': u'', u'path': ROOT_PATH,578 root_volume = {u'volume_id': u'', u'path': ROOT_PATH,
@@ -574,7 +580,7 @@
574580
575 # get shares and group by sharing user581 # get shares and group by sharing user
576 shares = defaultdict(list)582 shares = defaultdict(list)
577 for share in SAMPLE_SHARES:583 for share in sample_shares:
578 # filter out non accepted values584 # filter out non accepted values
579 if not bool(share['accepted']):585 if not bool(share['accepted']):
580 continue586 continue
@@ -593,15 +599,29 @@
593 shares[username].append(share)599 shares[username].append(share)
594600
595 folders = []601 folders = []
596 for folder in SAMPLE_FOLDERS:602 for folder in sample_folders:
597 folder = folder.copy()603 folder = folder.copy()
598 folder[u'type'] = self.be.FOLDER_TYPE604 folder[u'type'] = self.be.FOLDER_TYPE
599 folders.append(folder)605 folders.append(folder)
600606
601 expected = [(u'', unicode(free_bytes), [root_volume] + folders)]607 expected = [(u'', unicode(free_bytes), [root_volume] + folders)]
602 for other_user, data in shares.iteritems():608 for other_user, data in shares.iteritems():
603 expected.append((other_user, data[0][u'free_bytes'], data))609 send_freebytes = any(d['access_level'] == 'Modify' for d in data)
604610 if send_freebytes:
611 free_bytes = data[0][u'free_bytes']
612 else:
613 free_bytes = self.be.FREE_BYTES_NOT_AVAILABLE
614 expected.append((other_user, free_bytes, data))
615
616 returnValue(expected)
617
618 @inlineCallbacks
619 def test_volumes_info(self):
620 """The volumes_info method exercises its callback."""
621 self.patch(MockDBusClient, 'shares', SAMPLE_SHARES)
622 self.patch(MockDBusClient, 'folders', SAMPLE_FOLDERS)
623
624 expected = yield self.expected_volumes(SAMPLE_SHARES, SAMPLE_FOLDERS)
605 result = yield self.be.volumes_info()625 result = yield self.be.volumes_info()
606 self.assertEqual(result, expected)626 self.assertEqual(result, expected)
607627
@@ -614,14 +634,23 @@
614 @inlineCallbacks634 @inlineCallbacks
615 def test_volumes_are_cached(self):635 def test_volumes_are_cached(self):
616 """The volume list is cached."""636 """The volume list is cached."""
637 self.patch(MockDBusClient, 'shares', SAMPLE_SHARES)
638 self.patch(MockDBusClient, 'folders', SAMPLE_FOLDERS)
639
617 # get root dir info640 # get root dir info
618 root_volume = {u'volume_id': u'', u'path': ROOT_PATH,641 root_volume = {u'volume_id': u'', u'path': ROOT_PATH,
619 u'subscribed': 'True', u'type': self.be.ROOT_TYPE}642 u'subscribed': 'True', u'type': self.be.ROOT_TYPE}
620 expected = {u'': root_volume}643 expected = {u'': root_volume}
621 for volume in SAMPLE_SHARES + SAMPLE_FOLDERS:644 for volume in SAMPLE_SHARES + SAMPLE_FOLDERS:
645 volume = volume.copy()
622 if volume[u'type'] == u'UDF':646 if volume[u'type'] == u'UDF':
623 volume[u'type'] = self.be.FOLDER_TYPE647 volume[u'type'] = self.be.FOLDER_TYPE
624 else:648 else:
649 if not bool(volume[u'accepted']):
650 continue
651 path = volume[u'path']
652 nicer_path = path.replace(SHARES_PATH, SHARES_PATH_LINK)
653 volume[u'path'] = nicer_path
625 volume[u'type'] = self.be.SHARE_TYPE654 volume[u'type'] = self.be.SHARE_TYPE
626655
627 sid = volume['volume_id']656 sid = volume['volume_id']
@@ -639,6 +668,56 @@
639 yield self.test_volumes_are_cached()668 yield self.test_volumes_are_cached()
640669
641 @inlineCallbacks670 @inlineCallbacks
671 def test_volumes_info_no_quota_for_read_onlys(self):
672 """The volumes_info does not send qupota info for RO shares."""
673 read_only_shares = [
674 {u'accepted': u'True',
675 u'subscribed': u'True',
676 u'access_level': u'View',
677 u'free_bytes': u'39892622746',
678 u'generation': u'2704',
679 u'name': u're',
680 u'node_id': u'c483f419-ed28-490a-825d-a8c074e2d795',
681 u'other_username': u'otheruser',
682 u'other_visible_name': u'Other User',
683 u'path': SHARES_PATH + u'/re from Other User',
684 u'type': u'Share',
685 u'volume_id': u'4a1b263b-a2b3-4f66-9e66-4cd18050810d'},
686 {u'accepted': u'True',
687 u'subscribed': u'True',
688 u'access_level': u'View',
689 u'free_bytes': u'39892622746',
690 u'generation': u'2704',
691 u'name': u'do',
692 u'node_id': u'84544ea4-aefe-4f91-9bb9-ed7b0a805baf',
693 u'other_username': u'otheruser',
694 u'other_visible_name': u'Other User',
695 u'path': SHARES_PATH + u'/do from Other User',
696 u'type': u'Share',
697 u'volume_id': u'7d130dfe-98b2-4bd5-8708-9eeba9838ac0'},
698 ]
699
700 self.patch(MockDBusClient, 'shares', read_only_shares)
701 self.patch(MockDBusClient, 'folders', SAMPLE_FOLDERS)
702
703 expected = yield self.expected_volumes(read_only_shares,
704 SAMPLE_FOLDERS)
705 result = yield self.be.volumes_info()
706 self.assertEqual(result, expected)
707
708 @inlineCallbacks
709 def test_volumes_info_no_quota_for_root(self):
710 """The volumes_info returns info even if quota call fails."""
711 # pylint: disable=E1101
712 self.be.wc.failure = 500
713 self.patch(MockDBusClient, 'shares', SAMPLE_SHARES)
714 self.patch(MockDBusClient, 'folders', SAMPLE_FOLDERS)
715
716 expected = yield self.expected_volumes(SAMPLE_SHARES, SAMPLE_FOLDERS)
717 result = yield self.be.volumes_info()
718 self.assertEqual(result, expected)
719
720 @inlineCallbacks
642 def test_subscribe_volume_folder(self):721 def test_subscribe_volume_folder(self):
643 """The subscribe_volume method subscribes a folder."""722 """The subscribe_volume method subscribes a folder."""
644 fid = '0123-4567'723 fid = '0123-4567'

Subscribers

People subscribed via source and target branches