Merge lp:~nataliabidart/ubuntuone-control-panel/preferences into lp:ubuntuone-control-panel

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 169
Merged at revision: 163
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/preferences
Merge into: lp:ubuntuone-control-panel
Diff against target: 1391 lines (+839/-131)
13 files modified
data/qt/preferences.ui (+89/-63)
ubuntuone/controlpanel/backend.py (+109/-15)
ubuntuone/controlpanel/gui/qt/folders.py (+3/-2)
ubuntuone/controlpanel/gui/qt/main/linux.py (+8/-0)
ubuntuone/controlpanel/gui/qt/preferences.py (+107/-1)
ubuntuone/controlpanel/gui/qt/tests/__init__.py (+14/-7)
ubuntuone/controlpanel/gui/qt/tests/test_filesyncstatus.py (+1/-1)
ubuntuone/controlpanel/gui/qt/tests/test_folders.py (+2/-2)
ubuntuone/controlpanel/gui/qt/tests/test_preferences.py (+165/-0)
ubuntuone/controlpanel/integrationtests/test_sd_client/test_linux.py (+84/-25)
ubuntuone/controlpanel/sd_client/linux.py (+45/-0)
ubuntuone/controlpanel/tests/__init__.py (+3/-0)
ubuntuone/controlpanel/tests/test_backend.py (+209/-15)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/preferences
Reviewer Review Type Date Requested Status
John Lenton (community) Approve
Review via email: mp+64883@code.launchpad.net

Commit message

- Implemented the "Preferences" tab (LP: #797294).

Description of the change

To test this branch, please run the tests for both widget sets:

./run-tests
./run-tests -qt

To test IRL, please run from within this branch:

DEBUG=True PYTHONPATH=. ./bin/ubuntuone-control-panel-qt

then go to the preferences tab and play with the settings (please note that initial settings are fake). When clicking apply, you should see in the terminal something like:

2011-06-16 15:23:58,688 - ubuntuone.controlpanel.backend - INFO - change_file_sync_settings: args (<ubuntuone.controlpanel.backend.ControlBackend object at 0x29ef950>, {'autoconnect': False, 'max_download_speed': 102400, 'share_autosubscribe': True, 'max_upload_speed': 10240, 'show_all_notifications': False, 'udf_autosubscribe': True}), kwargs {}.

When restoring to defaults, you should get autoconnect and show notifications enabled, autosubscribe disabled x 2 and no limit for throttling.

To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) :
review: Approve
Revision history for this message
Ubuntu One Auto Pilot (otto-pilot) wrote :

Attempt to merge into lp:ubuntuone-control-panel failed due to conflicts:

text conflict in ubuntuone/controlpanel/gui/qt/folders.py

169. By Natalia Bidart

Merged trunk in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'data/qt/preferences.ui'
--- data/qt/preferences.ui 2011-05-23 21:24:08 +0000
+++ data/qt/preferences.ui 2011-06-17 14:51:05 +0000
@@ -15,64 +15,90 @@
15 </property>15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout_2">16 <layout class="QVBoxLayout" name="verticalLayout_2">
17 <item>17 <item>
18 <widget class="QLabel" name="tab_header_label">18 <widget class="QGroupBox" name="verticalGroupBox">
19 <property name="text">19 <layout class="QVBoxLayout" name="verticalLayout_4">
20 <string>(empty)</string>20 <item>
21 </property>21 <widget class="QGroupBox" name="groupBox">
22 </widget>22 <property name="title">
23 </item>23 <string>Bandwidth settings</string>
24 <item>24 </property>
25 <widget class="QGroupBox" name="groupBox">25 <layout class="QGridLayout" name="gridLayout">
26 <property name="title">26 <item row="0" column="0">
27 <string>Bandwidth settings</string>27 <widget class="QCheckBox" name="limit_uploads_checkbox">
28 </property>28 <property name="text">
29 <layout class="QGridLayout" name="gridLayout">29 <string>Limit upload speed to</string>
30 <item row="0" column="0">30 </property>
31 <widget class="QCheckBox" name="limit_uploads_checkbox">31 </widget>
32 <property name="text">32 </item>
33 <string>Limit upload speed to</string>33 <item row="0" column="1">
34 </property>34 <widget class="QSpinBox" name="upload_speed_spinbox">
35 </widget>35 <property name="minimum">
36 </item>36 <number>-1</number>
37 <item row="0" column="1">37 </property>
38 <widget class="QSpinBox" name="upload_speed_spinbox"/>38 <property name="maximum">
39 </item>39 <number>999999999</number>
40 <item row="0" column="2">40 </property>
41 <widget class="QLabel" name="kbps_label_1">41 </widget>
42 <property name="text">42 </item>
43 <string>Kilobits per second</string>43 <item row="0" column="2">
44 </property>44 <widget class="QLabel" name="kbps_label_1">
45 </widget>45 <property name="text">
46 </item>46 <string>Kilobits per second</string>
47 <item row="1" column="0">47 </property>
48 <widget class="QCheckBox" name="limit_downloads_checkbox">48 </widget>
49 <property name="text">49 </item>
50 <string>Limit download speed to</string>50 <item row="2" column="0">
51 </property>51 <widget class="QCheckBox" name="limit_downloads_checkbox">
52 </widget>52 <property name="text">
53 </item>53 <string>Limit download speed to</string>
54 <item row="1" column="1">54 </property>
55 <widget class="QSpinBox" name="download_speed_spinbox"/>55 </widget>
56 </item>56 </item>
57 <item row="1" column="2">57 <item row="2" column="1">
58 <widget class="QLabel" name="kbps_label_2">58 <widget class="QSpinBox" name="download_speed_spinbox">
59 <property name="text">59 <property name="minimum">
60 <string>Kilobits per second</string>60 <number>-1</number>
61 </property>61 </property>
62 </widget>62 <property name="maximum">
63 </item>63 <number>999999999</number>
64 <item row="0" column="3">64 </property>
65 <spacer name="horizontalSpacer_2">65 </widget>
66 <property name="orientation">66 </item>
67 <enum>Qt::Horizontal</enum>67 <item row="2" column="2">
68 </property>68 <widget class="QLabel" name="kbps_label_2">
69 <property name="sizeHint" stdset="0">69 <property name="text">
70 <size>70 <string>Kilobits per second</string>
71 <width>40</width>71 </property>
72 <height>20</height>72 </widget>
73 </size>73 </item>
74 </property>74 <item row="0" column="3">
75 </spacer>75 <spacer name="horizontalSpacer_2">
76 <property name="orientation">
77 <enum>Qt::Horizontal</enum>
78 </property>
79 <property name="sizeHint" stdset="0">
80 <size>
81 <width>40</width>
82 <height>20</height>
83 </size>
84 </property>
85 </spacer>
86 </item>
87 <item row="3" column="0" colspan="3">
88 <widget class="QLabel" name="label_2">
89 <property name="text">
90 <string>Please note that your files will not sync if you set bandwidth to 0</string>
91 </property>
92 <property name="scaledContents">
93 <bool>false</bool>
94 </property>
95 <property name="wordWrap">
96 <bool>false</bool>
97 </property>
98 </widget>
99 </item>
100 </layout>
101 </widget>
76 </item>102 </item>
77 </layout>103 </layout>
78 </widget>104 </widget>
@@ -80,32 +106,32 @@
80 <item>106 <item>
81 <widget class="QGroupBox" name="groupBox_2">107 <widget class="QGroupBox" name="groupBox_2">
82 <property name="title">108 <property name="title">
83 <string>Application Settings</string>109 <string>File Sync Settings</string>
84 </property>110 </property>
85 <layout class="QVBoxLayout" name="verticalLayout">111 <layout class="QVBoxLayout" name="verticalLayout">
86 <item>112 <item>
87 <widget class="QCheckBox" name="auto_connect_checkbox">113 <widget class="QCheckBox" name="autoconnect_checkbox">
88 <property name="text">114 <property name="text">
89 <string>Connect automatically when computer starts</string>115 <string>Connect automatically when computer starts</string>
90 </property>116 </property>
91 </widget>117 </widget>
92 </item>118 </item>
93 <item>119 <item>
94 <widget class="QCheckBox" name="auto_sync_local_folders_checkbox">120 <widget class="QCheckBox" name="udf_autosubscribe_checkbox">
95 <property name="text">121 <property name="text">
96 <string>Automatically sync all selected folders on this computer to the cloud</string>122 <string>Automatically sync all selected folders on this computer to the cloud</string>
97 </property>123 </property>
98 </widget>124 </widget>
99 </item>125 </item>
100 <item>126 <item>
101 <widget class="QCheckBox" name="auto_sync_shares_to_me_checkbox">127 <widget class="QCheckBox" name="share_autosubscribe_checkbox">
102 <property name="text">128 <property name="text">
103 <string>Automatically sync all folders shared with me by other to this computer</string>129 <string>Automatically sync all folders shared with me by other to this computer</string>
104 </property>130 </property>
105 </widget>131 </widget>
106 </item>132 </item>
107 <item>133 <item>
108 <widget class="QCheckBox" name="show_notifications_checkbox">134 <widget class="QCheckBox" name="show_all_notifications_checkbox">
109 <property name="text">135 <property name="text">
110 <string>Allow all notifications to this device</string>136 <string>Allow all notifications to this device</string>
111 </property>137 </property>
112138
=== modified file 'ubuntuone/controlpanel/backend.py'
--- ubuntuone/controlpanel/backend.py 2011-06-02 03:58:53 +0000
+++ ubuntuone/controlpanel/backend.py 2011-06-17 14:51:05 +0000
@@ -42,6 +42,10 @@
42DEVICE_REMOVE_API = "1.0/devices/remove/%s/%s"42DEVICE_REMOVE_API = "1.0/devices/remove/%s/%s"
43DEVICE_TYPE_PHONE = "Phone"43DEVICE_TYPE_PHONE = "Phone"
44DEVICE_TYPE_COMPUTER = "Computer"44DEVICE_TYPE_COMPUTER = "Computer"
45AUTOCONNECT_KEY = 'autoconnect'
46SHOW_ALL_NOTIFICATIONS_KEY = 'show_all_notifications'
47SHARE_AUTOSUBSCRIBE_KEY = 'share_autosubscribe'
48UDF_AUTOSUBSCRIBE_KEY = 'udf_autosubscribe'
45UPLOAD_KEY = "max_upload_speed"49UPLOAD_KEY = "max_upload_speed"
46DOWNLOAD_KEY = "max_download_speed"50DOWNLOAD_KEY = "max_download_speed"
4751
@@ -99,6 +103,14 @@
99 NAME_NOT_SET = u'ENAMENOTSET'103 NAME_NOT_SET = u'ENAMENOTSET'
100 FREE_BYTES_NOT_AVAILABLE = u'EFREEBYTESNOTAVAILABLE'104 FREE_BYTES_NOT_AVAILABLE = u'EFREEBYTESNOTAVAILABLE'
101 STATUS_DISABLED = {MSG_KEY: '', STATUS_KEY: FILE_SYNC_DISABLED}105 STATUS_DISABLED = {MSG_KEY: '', STATUS_KEY: FILE_SYNC_DISABLED}
106 DEFAULT_FILE_SYNC_SETTINGS = {
107 AUTOCONNECT_KEY: True,
108 SHOW_ALL_NOTIFICATIONS_KEY: True,
109 SHARE_AUTOSUBSCRIBE_KEY: False,
110 UDF_AUTOSUBSCRIBE_KEY: False,
111 DOWNLOAD_KEY: -1, # no limit
112 UPLOAD_KEY: -1, # no limit
113 }
102114
103 def __init__(self, shutdown_func=None):115 def __init__(self, shutdown_func=None):
104 """Initialize the web_client."""116 """Initialize the web_client."""
@@ -180,7 +192,8 @@
180192
181 @inlineCallbacks193 @inlineCallbacks
182 def _process_device_web_info(self, devices, enabled, limit_bw, limits,194 def _process_device_web_info(self, devices, enabled, limit_bw, limits,
183 show_notifs):195 autoconnect, show_notifs,
196 share_autosubscribe, udf_autosubscribe):
184 """Return a lis of processed devices."""197 """Return a lis of processed devices."""
185 result = []198 result = []
186 for d in devices:199 for d in devices:
@@ -202,7 +215,10 @@
202215
203 if di["configurable"]:216 if di["configurable"]:
204 di["limit_bandwidth"] = limit_bw217 di["limit_bandwidth"] = limit_bw
205 di["show_all_notifications"] = show_notifs218 di[AUTOCONNECT_KEY] = autoconnect
219 di[SHOW_ALL_NOTIFICATIONS_KEY] = show_notifs
220 di[SHARE_AUTOSUBSCRIBE_KEY] = share_autosubscribe
221 di[UDF_AUTOSUBSCRIBE_KEY] = udf_autosubscribe
206 di[UPLOAD_KEY] = limits["upload"]222 di[UPLOAD_KEY] = limits["upload"]
207 di[DOWNLOAD_KEY] = limits["download"]223 di[DOWNLOAD_KEY] = limits["download"]
208224
@@ -273,19 +289,35 @@
273 @inlineCallbacks289 @inlineCallbacks
274 def devices_info(self):290 def devices_info(self):
275 """Get the user devices info."""291 """Get the user devices info."""
276 result = limit_bw = limits = show_notifs = None292 result = limit_bw = limits = None
293 autoconnect = show_notifs = None
294 share_autosubscribe = udf_autosubscribe = None
295
277 enabled = yield sd_client.files_sync_enabled()296 enabled = yield sd_client.files_sync_enabled()
278 enabled = bool(enabled)297 enabled = bool(enabled)
279 if enabled:298 if enabled:
280 limit_bw = yield sd_client.bandwidth_throttling_enabled()299 sd_res = yield sd_client.autoconnect_enabled()
281 limit_bw = bool(limit_bw)300 autoconnect = bool(sd_res)
282 show_notifs = yield sd_client.show_all_notifications_enabled()301
283 show_notifs = bool(show_notifs)302 sd_res = yield sd_client.show_all_notifications_enabled()
303 show_notifs = bool(sd_res)
304
305 sd_res = yield sd_client.share_autosubscribe_enabled()
306 share_autosubscribe = bool(sd_res)
307
308 sd_res = yield sd_client.udf_autosubscribe_enabled()
309 udf_autosubscribe = bool(sd_res)
310
311 sd_res = yield sd_client.bandwidth_throttling_enabled()
312 limit_bw = bool(sd_res)
313
284 limits = yield sd_client.get_throttling_limits()314 limits = yield sd_client.get_throttling_limits()
285315
286 logger.debug('devices_info: file sync enabled? %s limit_bw %s, limits '316 logger.debug('devices_info: file sync enabled? %s limit_bw %s, limits '
287 '%s, show_notifs %s',317 '%s, autoconnect %s, show_notifs %s, '
288 enabled, limit_bw, limits, show_notifs)318 'share_autosubscribe %s, udf_autosubscribe %s',
319 enabled, limit_bw, limits, autoconnect, show_notifs,
320 share_autosubscribe, udf_autosubscribe)
289321
290 try:322 try:
291 devices = yield self.wc.call_api(DEVICES_API)323 devices = yield self.wc.call_api(DEVICES_API)
@@ -295,8 +327,8 @@
295 logger.exception('devices_info: web client failure:')327 logger.exception('devices_info: web client failure:')
296 else:328 else:
297 result = yield self._process_device_web_info(devices, enabled,329 result = yield self._process_device_web_info(devices, enabled,
298 limit_bw, limits,330 limit_bw, limits, autoconnect, show_notifs,
299 show_notifs)331 share_autosubscribe, udf_autosubscribe)
300 if result is None:332 if result is None:
301 logger.info('devices_info: result is None after calling '333 logger.info('devices_info: result is None after calling '
302 'devices/ API, building the local device.')334 'devices/ API, building the local device.')
@@ -310,12 +342,15 @@
310 local_device["configurable"] = enabled342 local_device["configurable"] = enabled
311 if local_device["configurable"]:343 if local_device["configurable"]:
312 local_device["limit_bandwidth"] = limit_bw344 local_device["limit_bandwidth"] = limit_bw
313 show_notifs = show_notifs345 local_device[AUTOCONNECT_KEY] = autoconnect
314 local_device["show_all_notifications"] = show_notifs346 local_device[SHOW_ALL_NOTIFICATIONS_KEY] = show_notifs
347 local_device[SHARE_AUTOSUBSCRIBE_KEY] = share_autosubscribe
348 local_device[UDF_AUTOSUBSCRIBE_KEY] = udf_autosubscribe
315 upload = limits["upload"]349 upload = limits["upload"]
316 download = limits["download"]350 download = limits["download"]
317 local_device[UPLOAD_KEY] = upload351 local_device[UPLOAD_KEY] = upload
318 local_device[DOWNLOAD_KEY] = download352 local_device[DOWNLOAD_KEY] = download
353 logger.debug('devices_info: local device built: %r.', local_device)
319 result = [local_device]354 result = [local_device]
320 else:355 else:
321 logger.info('devices_info: result is not None after calling '356 logger.info('devices_info: result is not None after calling '
@@ -338,8 +373,8 @@
338 """Change the settings for the given device."""373 """Change the settings for the given device."""
339 is_local = yield self.device_is_local(device_id)374 is_local = yield self.device_is_local(device_id)
340375
341 if is_local and "show_all_notifications" in settings:376 if is_local and SHOW_ALL_NOTIFICATIONS_KEY in settings:
342 if not settings["show_all_notifications"]:377 if not settings[SHOW_ALL_NOTIFICATIONS_KEY]:
343 yield sd_client.disable_show_all_notifications()378 yield sd_client.disable_show_all_notifications()
344 else:379 else:
345 yield sd_client.enable_show_all_notifications()380 yield sd_client.enable_show_all_notifications()
@@ -597,6 +632,65 @@
597 # still pending (LP: #673673)632 # still pending (LP: #673673)
598 returnValue(None)633 returnValue(None)
599634
635 @log_call(logger.debug)
636 @inlineCallbacks
637 def file_sync_settings_info(self):
638 """Get the file sync settings info."""
639 result = {}
640
641 for name in (AUTOCONNECT_KEY, SHOW_ALL_NOTIFICATIONS_KEY,
642 SHARE_AUTOSUBSCRIBE_KEY, UDF_AUTOSUBSCRIBE_KEY):
643 sd_method = getattr(sd_client, '%s_enabled' % name)
644 value = yield sd_method()
645 result[name] = bool(value)
646
647 limits = yield sd_client.get_throttling_limits()
648 result[DOWNLOAD_KEY] = limits['download']
649 result[UPLOAD_KEY] = limits['upload']
650
651 returnValue(result)
652
653 @inlineCallbacks
654 def _change_boolean_file_sync_setting(self, setting_name, settings):
655 """Change the value for 'setting_name' to be 'new_value'."""
656 if setting_name in settings:
657 new_value = settings[setting_name]
658 sd_method_name = 'enable_%s' if new_value else 'disable_%s'
659 sd_method = getattr(sd_client, sd_method_name % setting_name)
660 yield sd_method()
661
662 @log_call(logger.info)
663 @inlineCallbacks
664 def change_file_sync_settings(self, settings):
665 """Change the file sync settings."""
666 for name in (AUTOCONNECT_KEY, SHOW_ALL_NOTIFICATIONS_KEY,
667 SHARE_AUTOSUBSCRIBE_KEY, UDF_AUTOSUBSCRIBE_KEY):
668 yield self._change_boolean_file_sync_setting(name, settings)
669
670 if DOWNLOAD_KEY in settings or UPLOAD_KEY in settings:
671 current_limits = yield sd_client.get_throttling_limits()
672 limits = {
673 "download": current_limits["download"],
674 "upload": current_limits["upload"],
675 }
676 if UPLOAD_KEY in settings:
677 limits["upload"] = settings[UPLOAD_KEY]
678 if DOWNLOAD_KEY in settings:
679 limits["download"] = settings[DOWNLOAD_KEY]
680 yield sd_client.set_throttling_limits(limits)
681
682 throttling_disabled = sum(limits.itervalues()) == -2
683 if throttling_disabled:
684 yield sd_client.disable_bandwidth_throttling()
685 else:
686 yield sd_client.enable_bandwidth_throttling()
687
688 @log_call(logger.info)
689 @inlineCallbacks
690 def restore_file_sync_settings(self):
691 """Restore the file sync settings."""
692 yield self.change_file_sync_settings(self.DEFAULT_FILE_SYNC_SETTINGS)
693
600 @log_call(logger.info)694 @log_call(logger.info)
601 def shutdown(self):695 def shutdown(self):
602 """Stop this service."""696 """Stop this service."""
603697
=== modified file 'ubuntuone/controlpanel/gui/qt/folders.py'
--- ubuntuone/controlpanel/gui/qt/folders.py 2011-06-16 20:33:39 +0000
+++ ubuntuone/controlpanel/gui/qt/folders.py 2011-06-17 14:51:05 +0000
@@ -34,6 +34,7 @@
34 FILE_URI_PREFIX,34 FILE_URI_PREFIX,
35 FOLDER_ICON_NAME,35 FOLDER_ICON_NAME,
36 FOLDERS_CONFIRM_MERGE,36 FOLDERS_CONFIRM_MERGE,
37 KILOBYTES,
37 MANAGE_FILES_LINK,38 MANAGE_FILES_LINK,
38 MUSIC_ICON_NAME,39 MUSIC_ICON_NAME,
39 MUSIC_DISPLAY_NAME,40 MUSIC_DISPLAY_NAME,
@@ -102,8 +103,8 @@
102 units = {0: 'bytes', 1: 'KiB', 2: 'MiB', 3: 'GiB', 4: 'TiB',103 units = {0: 'bytes', 1: 'KiB', 2: 'MiB', 3: 'GiB', 4: 'TiB',
103 5: 'PiB', 6: 'Eib', 7: 'ZiB', 8: 'YiB'}104 5: 'PiB', 6: 'Eib', 7: 'ZiB', 8: 'YiB'}
104 unit = 0105 unit = 0
105 while int_bytes >= 1024:106 while int_bytes >= KILOBYTES:
106 int_bytes = int_bytes / 1024107 int_bytes = int_bytes / KILOBYTES
107 unit += 1108 unit += 1
108 return '%.1f %s' % (int_bytes, units[unit])109 return '%.1f %s' % (int_bytes, units[unit])
109110
110111
=== modified file 'ubuntuone/controlpanel/gui/qt/main/linux.py'
--- ubuntuone/controlpanel/gui/qt/main/linux.py 2011-06-14 11:41:11 +0000
+++ ubuntuone/controlpanel/gui/qt/main/linux.py 2011-06-17 14:51:05 +0000
@@ -55,6 +55,14 @@
55 class SDTool(FakedSyncDaemonTool):55 class SDTool(FakedSyncDaemonTool):
56 """A custom SDTool."""56 """A custom SDTool."""
5757
58 settings = {
59 'autoconnect': True,
60 'show_all_notifications': True,
61 'share_autosubscribe': False,
62 'udf_autosubscribe': False,
63 'throttling_enabled': True,
64 'limits': {'download': 100000, 'upload': 1000},
65 }
58 shares = [66 shares = [
59 {u'accepted': u'True',67 {u'accepted': u'True',
60 u'access_level': u'Modify',68 u'access_level': u'Modify',
6169
=== modified file 'ubuntuone/controlpanel/gui/qt/preferences.py'
--- ubuntuone/controlpanel/gui/qt/preferences.py 2011-05-24 14:20:18 +0000
+++ ubuntuone/controlpanel/gui/qt/preferences.py 2011-06-17 14:51:05 +0000
@@ -18,10 +18,24 @@
1818
19"""The user interface for the control panel for Ubuntu One."""19"""The user interface for the control panel for Ubuntu One."""
2020
21from PyQt4 import QtGui21from PyQt4 import QtGui, QtCore
22from twisted.internet import defer
2223
24from ubuntuone.controlpanel import backend
25from ubuntuone.controlpanel.logger import setup_logging, log_call
26from ubuntuone.controlpanel.gui import KILOBYTES
23from ubuntuone.controlpanel.gui.qt.ui import preferences_ui27from ubuntuone.controlpanel.gui.qt.ui import preferences_ui
2428
29logger = setup_logging('qt.preferences')
30
31CHECKED = QtCore.Qt.Checked
32UNCHECKED = QtCore.Qt.Unchecked
33
34
35def check_state(checked):
36 """Return the QCheckBox check state according the value of 'checked'."""
37 return CHECKED if checked else UNCHECKED
38
2539
26class PreferencesPanel(QtGui.QWidget):40class PreferencesPanel(QtGui.QWidget):
27 """The Preferences Tab Panel widget"""41 """The Preferences Tab Panel widget"""
@@ -31,3 +45,95 @@
31 QtGui.QWidget.__init__(self, *args)45 QtGui.QWidget.__init__(self, *args)
32 self.ui = preferences_ui.Ui_Form()46 self.ui = preferences_ui.Ui_Form()
33 self.ui.setupUi(self)47 self.ui.setupUi(self)
48
49 self.backend = backend.ControlBackend()
50 logger.debug('%s: started.', self.__class__.__name__)
51
52 # Invalid name "showEvent"
53 # pylint: disable=C0103
54
55 def showEvent(self, event):
56 """Load info."""
57 d = defer.maybeDeferred(self.backend.file_sync_settings_info)
58 d.addCallback(self.process_settings)
59 event.accept()
60
61 @log_call(logger.debug)
62 def process_settings(self, info):
63 """Load settings info into the view."""
64 if not info:
65 return
66
67 autoconnect = check_state(info[backend.AUTOCONNECT_KEY])
68 show_all_notifs = \
69 check_state(info[backend.SHOW_ALL_NOTIFICATIONS_KEY])
70 share_autosubscribe = \
71 check_state(info[backend.SHARE_AUTOSUBSCRIBE_KEY])
72 udf_autosubscribe = \
73 check_state(info[backend.UDF_AUTOSUBSCRIBE_KEY])
74 download_speed = info[backend.DOWNLOAD_KEY] // KILOBYTES
75 upload_speed = info[backend.UPLOAD_KEY] // KILOBYTES
76
77 self.ui.autoconnect_checkbox.setCheckState(autoconnect)
78 self.ui.show_all_notifications_checkbox.setCheckState(show_all_notifs)
79 self.ui.share_autosubscribe_checkbox.setCheckState(share_autosubscribe)
80 self.ui.udf_autosubscribe_checkbox.setCheckState(udf_autosubscribe)
81 self.ui.download_speed_spinbox.setValue(download_speed)
82 self.ui.upload_speed_spinbox.setValue(upload_speed)
83
84 def process_speed_settings(self, new_value, checkbox):
85 """A new speed limit was set."""
86 if new_value < 0:
87 checkbox.setCheckState(UNCHECKED)
88 else:
89 checkbox.setCheckState(CHECKED)
90
91 @QtCore.pyqtSlot(int)
92 def on_download_speed_spinbox_valueChanged(self, new_value):
93 """A new download speed was set."""
94 self.process_speed_settings(new_value,
95 self.ui.limit_downloads_checkbox)
96
97 @QtCore.pyqtSlot(int)
98 def on_upload_speed_spinbox_valueChanged(self, new_value):
99 """A new upload speed was set."""
100 self.process_speed_settings(new_value,
101 self.ui.limit_uploads_checkbox)
102
103 @QtCore.pyqtSlot()
104 @defer.inlineCallbacks
105 def on_apply_changes_button_clicked(self):
106 """The apply changes button was clicked."""
107 autoconnect = self.ui.autoconnect_checkbox.checkState()
108 notifications = self.ui.show_all_notifications_checkbox.checkState()
109 share_autosubscribe = self.ui.share_autosubscribe_checkbox.checkState()
110 udf_autosubscribe = self.ui.udf_autosubscribe_checkbox.checkState()
111 download_speed = self.ui.download_speed_spinbox.value() * KILOBYTES
112 upload_speed = self.ui.upload_speed_spinbox.value() * KILOBYTES
113
114 settings = {
115 backend.AUTOCONNECT_KEY: autoconnect == CHECKED,
116 backend.SHOW_ALL_NOTIFICATIONS_KEY: notifications == CHECKED,
117 backend.SHARE_AUTOSUBSCRIBE_KEY: share_autosubscribe == CHECKED,
118 backend.UDF_AUTOSUBSCRIBE_KEY: udf_autosubscribe == CHECKED,
119 backend.DOWNLOAD_KEY: download_speed,
120 backend.UPLOAD_KEY: upload_speed,
121 }
122
123 # set is_processing
124 # TODO: handle errors
125 yield self.backend.change_file_sync_settings(settings)
126 # unset is_processing
127
128 @QtCore.pyqtSlot()
129 @defer.inlineCallbacks
130 def on_restore_defaults_button_clicked(self):
131 """The restore defaults button was clicked."""
132 # set is_processing
133 # TODO: handle errors
134 yield self.backend.restore_file_sync_settings()
135 settings = yield self.backend.file_sync_settings_info()
136
137 self.process_settings(settings)
138
139 # unset is_processing
34140
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/__init__.py'
--- ubuntuone/controlpanel/gui/qt/tests/__init__.py 2011-06-16 20:31:27 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/__init__.py 2011-06-17 14:51:05 +0000
@@ -93,6 +93,14 @@
93 SHARE_TYPE = u'SHARE'93 SHARE_TYPE = u'SHARE'
94 NAME_NOT_SET = u'ENAMENOTSET'94 NAME_NOT_SET = u'ENAMENOTSET'
95 FREE_BYTES_NOT_AVAILABLE = u'EFREEBYTESNOTAVAILABLE'95 FREE_BYTES_NOT_AVAILABLE = u'EFREEBYTESNOTAVAILABLE'
96 DEFAULT_FILE_SYNC_SETTINGS = {
97 backend.AUTOCONNECT_KEY: True,
98 backend.SHOW_ALL_NOTIFICATIONS_KEY: True,
99 backend.SHARE_AUTOSUBSCRIBE_KEY: False,
100 backend.UDF_AUTOSUBSCRIBE_KEY: False,
101 backend.DOWNLOAD_KEY: -1, # no limit
102 backend.UPLOAD_KEY: -1, # no limit
103 }
96104
97 exposed_methods = [105 exposed_methods = [
98 'account_info', # account106 'account_info', # account
@@ -101,7 +109,11 @@
101 'replications_info', 'change_replication_settings', # replications109 'replications_info', 'change_replication_settings', # replications
102 'file_sync_status', 'enable_files', 'disable_files', # files110 'file_sync_status', 'enable_files', 'disable_files', # files
103 'connect_files', 'disconnect_files',111 'connect_files', 'disconnect_files',
104 'restart_files', 'start_files', 'stop_files', 'shutdown',112 'restart_files', 'start_files', 'stop_files',
113 'file_sync_settings_info',
114 'change_file_sync_settings',
115 'restore_file_sync_settings',
116 'shutdown',
105 ]117 ]
106118
107119
@@ -140,13 +152,8 @@
140152
141 self.ui.show()153 self.ui.show()
142154
143 def assert_backend_called(self, method_name, args=None, kwargs=None):155 def assert_backend_called(self, method_name, *args, **kwargs):
144 """Check that the control panel backend 'method_name' was called."""156 """Check that the control panel backend 'method_name' was called."""
145 if args is None:
146 args = ()
147 if kwargs is None:
148 kwargs = {}
149
150 self.assertIn(method_name, self.ui.backend._called)157 self.assertIn(method_name, self.ui.backend._called)
151 self.assertEqual(self.ui.backend._called[method_name], (args, kwargs))158 self.assertEqual(self.ui.backend._called[method_name], (args, kwargs))
152159
153160
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_filesyncstatus.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_filesyncstatus.py 2011-06-01 18:10:22 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_filesyncstatus.py 2011-06-17 14:51:05 +0000
@@ -87,7 +87,7 @@
8787
88 def test_file_sync_status_is_requested_on_show(self):88 def test_file_sync_status_is_requested_on_show(self):
89 """The file sync status is requested to the backend."""89 """The file sync status is requested to the backend."""
90 self.assert_backend_called('file_sync_status', ())90 self.assert_backend_called('file_sync_status')
9191
92 def test_process_status_disabled(self):92 def test_process_status_disabled(self):
93 """File sync status disabled update the label."""93 """File sync status disabled update the label."""
9494
=== modified file 'ubuntuone/controlpanel/gui/qt/tests/test_folders.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2011-06-16 20:33:39 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_folders.py 2011-06-17 14:51:05 +0000
@@ -77,7 +77,7 @@
7777
78 def test_volumes_info_is_requested_on_show(self):78 def test_volumes_info_is_requested_on_show(self):
79 """The volumes info is requested to the backend."""79 """The volumes info is requested to the backend."""
80 self.assert_backend_called('volumes_info', ())80 self.assert_backend_called('volumes_info')
8181
82 def test_process_folders(self):82 def test_process_folders(self):
83 """The volumes info is processed when ready."""83 """The volumes info is processed when ready."""
@@ -333,7 +333,7 @@
333333
334 # backend was called334 # backend was called
335 self.assert_backend_called('change_volume_settings',335 self.assert_backend_called('change_volume_settings',
336 (fid, {'subscribed': subscribed}))336 fid, {'subscribed': subscribed})
337337
338 value = self.item.checkState(gui.SUBSCRIPTION_COL) == gui.CHECKED338 value = self.item.checkState(gui.SUBSCRIPTION_COL) == gui.CHECKED
339 self.assertEqual(value, bool(subscribed))339 self.assertEqual(value, bool(subscribed))
340340
=== added file 'ubuntuone/controlpanel/gui/qt/tests/test_preferences.py'
--- ubuntuone/controlpanel/gui/qt/tests/test_preferences.py 1970-01-01 00:00:00 +0000
+++ ubuntuone/controlpanel/gui/qt/tests/test_preferences.py 2011-06-17 14:51:05 +0000
@@ -0,0 +1,165 @@
1# -*- coding: utf-8 -*-
2
3# Authors: Natalia B Bidart <natalia.bidart@canonical.com>
4#
5# Copyright 2011 Canonical Ltd.
6#
7# This program is free software: you can redistribute it and/or modify it
8# under the terms of the GNU General Public License version 3, as published
9# by the Free Software Foundation.
10#
11# This program is distributed in the hope that it will be useful, but
12# WITHOUT ANY WARRANTY; without even the implied warranties of
13# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
14# PURPOSE. See the GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License along
17# with this program. If not, see <http://www.gnu.org/licenses/>.
18
19"""Tests for the Control Panel."""
20
21from __future__ import division
22
23from ubuntuone.controlpanel.gui.qt import preferences as gui
24from ubuntuone.controlpanel.gui.qt.tests import BaseTestCase
25
26# Access to a protected member
27# pylint: disable=W0212
28
29
30class PreferencesPanelTestCase(BaseTestCase):
31 """Test the qt cloud preferences tab."""
32
33 innerclass_ui = gui.preferences_ui
34 innerclass_name = "Ui_Form"
35 class_ui = gui.PreferencesPanel
36
37 def test_backend(self):
38 """Backend is created."""
39 self.assertIsInstance(self.ui.backend,
40 gui.backend.ControlBackend)
41
42 def test_file_sync_settings_info_is_requested(self):
43 """The file_sync_settings info is requested to the backend."""
44 self.assert_backend_called('file_sync_settings_info')
45
46 def _test_update_ui_from_settings_info(self, settings):
47 """The ui is correctly updated when the backend info is received."""
48 autoconnect = self.ui.ui.autoconnect_checkbox.checkState()
49 self.assertEqual(autoconnect == gui.CHECKED,
50 settings[gui.backend.AUTOCONNECT_KEY])
51
52 show_all_notifications = \
53 self.ui.ui.show_all_notifications_checkbox.checkState()
54 self.assertEqual(show_all_notifications == gui.CHECKED,
55 settings[gui.backend.SHOW_ALL_NOTIFICATIONS_KEY])
56
57 share_autosubscribe = \
58 self.ui.ui.share_autosubscribe_checkbox.checkState()
59 self.assertEqual(share_autosubscribe == gui.CHECKED,
60 settings[gui.backend.SHARE_AUTOSUBSCRIBE_KEY])
61
62 udf_autosubscribe = self.ui.ui.udf_autosubscribe_checkbox.checkState()
63 self.assertEqual(udf_autosubscribe == gui.CHECKED,
64 settings[gui.backend.UDF_AUTOSUBSCRIBE_KEY])
65
66 download_speed = self.ui.ui.download_speed_spinbox.value()
67 self.assertEqual(download_speed,
68 settings[gui.backend.DOWNLOAD_KEY] // gui.KILOBYTES)
69
70 upload_speed = self.ui.ui.upload_speed_spinbox.value()
71 self.assertEqual(upload_speed,
72 settings[gui.backend.UPLOAD_KEY] // gui.KILOBYTES)
73
74 def test_update_ui_from_backed_info(self):
75 """The ui is correctly updated when the backend info is received."""
76 settings = {
77 gui.backend.AUTOCONNECT_KEY: True,
78 gui.backend.SHOW_ALL_NOTIFICATIONS_KEY: True,
79 gui.backend.SHARE_AUTOSUBSCRIBE_KEY: True,
80 gui.backend.UDF_AUTOSUBSCRIBE_KEY: True,
81 gui.backend.DOWNLOAD_KEY: 20480,
82 gui.backend.UPLOAD_KEY: 2048,
83 }
84 self.ui.process_settings(settings)
85 self._test_update_ui_from_settings_info(settings)
86
87 def _test_speed_checkbox_value_changed_to_positive(self, speed_spinbox,
88 limit_checkbox):
89 """When the speed is set to a positive value, enable the checkbox."""
90 limit_checkbox.setCheckState(gui.UNCHECKED)
91 speed_spinbox.setValue(33)
92
93 self.assertEqual(gui.CHECKED, limit_checkbox.checkState())
94
95 def _test_speed_checkbox_value_changed_to_negative(self, speed_spinbox,
96 limit_checkbox):
97 """When the speed is set to a negative value, disable the checkbox."""
98 limit_checkbox.setCheckState(gui.UNCHECKED)
99 speed_spinbox.setValue(-1)
100
101 self.assertEqual(gui.UNCHECKED, limit_checkbox.checkState())
102
103 def test_download_speed_checkbox_value_changed_to_positive(self):
104 """When the download speed is set, enable the checkbox."""
105 self._test_speed_checkbox_value_changed_to_positive(
106 self.ui.ui.download_speed_spinbox,
107 self.ui.ui.limit_downloads_checkbox)
108
109 def test_download_speed_checkbox_value_changed_to_negative(self):
110 """When the download speed is set, enable the checkbox."""
111 self._test_speed_checkbox_value_changed_to_negative(
112 self.ui.ui.download_speed_spinbox,
113 self.ui.ui.limit_downloads_checkbox)
114
115 def test_upload_speed_checkbox_value_changed_to_positive(self):
116 """When the upload speed is set, enable the checkbox."""
117 self._test_speed_checkbox_value_changed_to_positive(
118 self.ui.ui.upload_speed_spinbox,
119 self.ui.ui.limit_uploads_checkbox)
120
121 def test_upload_speed_checkbox_value_changed_to_negative(self):
122 """When the upload speed is set, enable the checkbox."""
123 self._test_speed_checkbox_value_changed_to_negative(
124 self.ui.ui.upload_speed_spinbox,
125 self.ui.ui.limit_uploads_checkbox)
126
127 def test_apply_changes_button_clicked(self):
128 """When the apply button is clicked, the backend is called."""
129 self.ui.ui.autoconnect_checkbox.setCheckState(gui.CHECKED)
130 self.ui.ui.show_all_notifications_checkbox.setCheckState(gui.CHECKED)
131 self.ui.ui.share_autosubscribe_checkbox.setCheckState(gui.CHECKED)
132 self.ui.ui.udf_autosubscribe_checkbox.setCheckState(gui.CHECKED)
133 self.ui.ui.download_speed_spinbox.setValue(20)
134 self.ui.ui.upload_speed_spinbox.setValue(2)
135
136 self.ui.ui.apply_changes_button.click()
137
138 expected_dict = {
139 gui.backend.AUTOCONNECT_KEY: True,
140 gui.backend.SHOW_ALL_NOTIFICATIONS_KEY: True,
141 gui.backend.SHARE_AUTOSUBSCRIBE_KEY: True,
142 gui.backend.UDF_AUTOSUBSCRIBE_KEY: True,
143 gui.backend.DOWNLOAD_KEY: 20 * gui.KILOBYTES,
144 gui.backend.UPLOAD_KEY: 2 * gui.KILOBYTES,
145 }
146 self.assert_backend_called('change_file_sync_settings', expected_dict)
147
148 def test_restore_defaults_button_clicked(self):
149 """When the restore button is clicked, the backend is called."""
150 settings = gui.backend.ControlBackend.DEFAULT_FILE_SYNC_SETTINGS
151 self.patch(self.ui.backend, 'file_sync_settings_info',
152 lambda: settings)
153 # modify the state a bit to ensure defaults are applied
154 self.ui.ui.autoconnect_checkbox.setCheckState(gui.UNCHECKED)
155 self.ui.ui.show_all_notifications_checkbox.setCheckState(gui.UNCHECKED)
156 self.ui.ui.share_autosubscribe_checkbox.setCheckState(gui.CHECKED)
157 self.ui.ui.udf_autosubscribe_checkbox.setCheckState(gui.CHECKED)
158 self.ui.ui.download_speed_spinbox.setValue(20)
159 self.ui.ui.upload_speed_spinbox.setValue(2)
160
161 self.ui.ui.restore_defaults_button.click()
162
163 self.assert_backend_called('restore_file_sync_settings')
164
165 self._test_update_ui_from_settings_info(settings)
0166
=== modified file 'ubuntuone/controlpanel/integrationtests/test_sd_client/test_linux.py'
--- ubuntuone/controlpanel/integrationtests/test_sd_client/test_linux.py 2011-06-02 17:19:37 +0000
+++ ubuntuone/controlpanel/integrationtests/test_sd_client/test_linux.py 2011-06-17 14:51:05 +0000
@@ -51,7 +51,10 @@
51 """Fake the SyncDaemonTool."""51 """Fake the SyncDaemonTool."""
5252
53 settings = {53 settings = {
54 'autoconnect': True,
54 'show_all_notifications': True,55 'show_all_notifications': True,
56 'share_autosubscribe': True,
57 'udf_autosubscribe': True,
55 'file_sync_enabled': True,58 'file_sync_enabled': True,
56 'throttling_enabled': False,59 'throttling_enabled': False,
57 'limits': {'download': -1, 'upload': -1},60 'limits': {'download': -1, 'upload': -1},
@@ -264,6 +267,14 @@
264 """Enable/disable file sync."""267 """Enable/disable file sync."""
265 self.settings['file_sync_enabled'] = enabled268 self.settings['file_sync_enabled'] = enabled
266269
270 def is_autoconnect_enabled(self):
271 """Check if autoconnect is enabled."""
272 return self.settings['autoconnect']
273
274 def enable_autoconnect(self, enabled):
275 """Enable/disable autoconnect."""
276 self.settings['autoconnect'] = enabled
277
267 def is_show_all_notifications_enabled(self):278 def is_show_all_notifications_enabled(self):
268 """Check if show_all_notifications is enabled."""279 """Check if show_all_notifications is enabled."""
269 return self.settings['show_all_notifications']280 return self.settings['show_all_notifications']
@@ -272,6 +283,22 @@
272 """Enable/disable show_all_notifications."""283 """Enable/disable show_all_notifications."""
273 self.settings['show_all_notifications'] = enabled284 self.settings['show_all_notifications'] = enabled
274285
286 def is_share_autosubscribe_enabled(self):
287 """Check if share_autosubscribe is enabled."""
288 return self.settings['share_autosubscribe']
289
290 def enable_share_autosubscribe(self, enabled):
291 """Enable/disable share_autosubscribe."""
292 self.settings['share_autosubscribe'] = enabled
293
294 def is_udf_autosubscribe_enabled(self):
295 """Check if udf_autosubscribe is enabled."""
296 return self.settings['udf_autosubscribe']
297
298 def enable_udf_autosubscribe(self, enabled):
299 """Enable/disable udf_autosubscribe."""
300 self.settings['udf_autosubscribe'] = enabled
301
275 def refresh_volumes(self):302 def refresh_volumes(self):
276 """Request the volumes list to the server."""303 """Request the volumes list to the server."""
277 self.called['refresh_volumes'] = None304 self.called['refresh_volumes'] = None
@@ -393,54 +420,86 @@
393class NotificationsTestCase(BaseTestCase):420class NotificationsTestCase(BaseTestCase):
394 """Test for the show_all_notifications syncdaemon client methods."""421 """Test for the show_all_notifications syncdaemon client methods."""
395422
423 # No value passed for parameter '_' in function call
424 # pylint: disable=E1120
425
426 name = 'show_all_notifications'
427 getter = lambda _: sd_client.show_all_notifications_enabled()
428 enabler = lambda _: sd_client.enable_show_all_notifications()
429 disabler = lambda _: sd_client.disable_show_all_notifications()
430
396 @inlineCallbacks431 @inlineCallbacks
397 def test_notifications_get(self):432 def test_get_value(self):
398 """Getting the show_all_notifications state."""433 """Getting the show_all_notifications state."""
399 FakedSyncDaemonTool.settings['show_all_notifications'] = False434 FakedSyncDaemonTool.settings[self.name] = False
400 state = yield sd_client.show_all_notifications_enabled()435 state = yield self.getter()
401 self.assertEqual(state, False)436 self.assertEqual(state, False)
402 FakedSyncDaemonTool.settings['show_all_notifications'] = True437 FakedSyncDaemonTool.settings[self.name] = True
403 state = yield sd_client.show_all_notifications_enabled()438 state = yield self.getter()
404 self.assertEqual(state, True)439 self.assertEqual(state, True)
405440
406 @inlineCallbacks441 @inlineCallbacks
407 def test_notifications_get_throws_an_error(self):442 def test_get_value_throws_an_error(self):
408 """Handle error when getting the show_all_notifications state."""443 """Handle error when getting the show_all_notifications state."""
409 self.patch(FakedSyncDaemonTool, 'is_show_all_notifications_enabled',444 self.patch(FakedSyncDaemonTool, 'is_%s_enabled' % self.name,
410 self.fake_fail)445 self.fake_fail)
411 yield self.assertFailure(sd_client.show_all_notifications_enabled(),446 yield self.assertFailure(self.getter(), CustomError)
412 CustomError)
413447
414 @inlineCallbacks448 @inlineCallbacks
415 def test_notifications_enable(self):449 def test_enable(self):
416 """Enabling show_all_notifications."""450 """Enabling show_all_notifications."""
417 FakedSyncDaemonTool.settings['show_all_notifications'] = False451 FakedSyncDaemonTool.settings[self.name] = False
418 yield sd_client.enable_show_all_notifications()452 yield self.enabler()
419 self.assertTrue(FakedSyncDaemonTool.settings['show_all_notifications'])453 self.assertTrue(FakedSyncDaemonTool.settings[self.name])
420454
421 @inlineCallbacks455 @inlineCallbacks
422 def test_notifications_enable_throws_an_error(self):456 def test_enable_throws_an_error(self):
423 """Handle error when enabling show_all_notifications."""457 """Handle error when enabling show_all_notifications."""
424 self.patch(FakedSyncDaemonTool, 'enable_show_all_notifications',458 self.patch(FakedSyncDaemonTool, 'enable_%s' % self.name,
425 self.fake_fail)459 self.fake_fail)
426 yield self.assertFailure(sd_client.enable_show_all_notifications(),460 yield self.assertFailure(self.enabler(), CustomError)
427 CustomError)
428461
429 @inlineCallbacks462 @inlineCallbacks
430 def test_notifications_disable(self):463 def test_disable(self):
431 """Disabling show_all_notifications."""464 """Disabling show_all_notifications."""
432 FakedSyncDaemonTool.settings['show_all_notifications'] = True465 FakedSyncDaemonTool.settings[self.name] = True
433 yield sd_client.disable_show_all_notifications()466 yield self.disabler()
434 value = FakedSyncDaemonTool.settings['show_all_notifications']467 value = FakedSyncDaemonTool.settings[self.name]
435 self.assertFalse(value)468 self.assertFalse(value)
436469
437 @inlineCallbacks470 @inlineCallbacks
438 def test_notifications_disable_throws_an_error(self):471 def test_disable_throws_an_error(self):
439 """Handle error when disabling show_all_notifications."""472 """Handle error when disabling show_all_notifications."""
440 self.patch(FakedSyncDaemonTool, 'enable_show_all_notifications',473 self.patch(FakedSyncDaemonTool, 'enable_%s' % self.name,
441 self.fake_fail)474 self.fake_fail)
442 yield self.assertFailure(sd_client.disable_show_all_notifications(),475 yield self.assertFailure(self.disabler(), CustomError)
443 CustomError)476
477
478class AutoconnectTestCase(NotificationsTestCase):
479 """Test for the autoconnect syncdaemon client methods."""
480
481 name = 'autoconnect'
482 getter = lambda _: sd_client.autoconnect_enabled()
483 enabler = lambda _: sd_client.enable_autoconnect()
484 disabler = lambda _: sd_client.disable_autoconnect()
485
486
487class ShareAutosubscribeTestCase(NotificationsTestCase):
488 """Test for the share_autosubscribe syncdaemon client methods."""
489
490 name = 'share_autosubscribe'
491 getter = lambda _: sd_client.share_autosubscribe_enabled()
492 enabler = lambda _: sd_client.enable_share_autosubscribe()
493 disabler = lambda _: sd_client.disable_share_autosubscribe()
494
495
496class UDFAutosubscribeTestCase(NotificationsTestCase):
497 """Test for the udf_autosubscribe syncdaemon client methods."""
498
499 name = 'udf_autosubscribe'
500 getter = lambda _: sd_client.udf_autosubscribe_enabled()
501 enabler = lambda _: sd_client.enable_udf_autosubscribe()
502 disabler = lambda _: sd_client.disable_udf_autosubscribe()
444503
445504
446class FoldersTestCase(BaseTestCase):505class FoldersTestCase(BaseTestCase):
447506
=== modified file 'ubuntuone/controlpanel/sd_client/linux.py'
--- ubuntuone/controlpanel/sd_client/linux.py 2011-05-26 22:08:32 +0000
+++ ubuntuone/controlpanel/sd_client/linux.py 2011-06-17 14:51:05 +0000
@@ -77,6 +77,21 @@
77 return get_syncdaemon_tool().enable_throttling(False)77 return get_syncdaemon_tool().enable_throttling(False)
7878
7979
80def autoconnect_enabled():
81 """Get the state of autoconnect in the syncdaemon."""
82 return get_syncdaemon_tool().is_autoconnect_enabled()
83
84
85def enable_autoconnect():
86 """Enable autoconnect in the syncdaemon."""
87 return get_syncdaemon_tool().enable_autoconnect(True)
88
89
90def disable_autoconnect():
91 """Disable autoconnect in the syncdaemon."""
92 return get_syncdaemon_tool().enable_autoconnect(False)
93
94
80def show_all_notifications_enabled():95def show_all_notifications_enabled():
81 """Get the state of show_all_notifications in the syncdaemon."""96 """Get the state of show_all_notifications in the syncdaemon."""
82 return get_syncdaemon_tool().is_show_all_notifications_enabled()97 return get_syncdaemon_tool().is_show_all_notifications_enabled()
@@ -92,6 +107,36 @@
92 return get_syncdaemon_tool().enable_show_all_notifications(False)107 return get_syncdaemon_tool().enable_show_all_notifications(False)
93108
94109
110def share_autosubscribe_enabled():
111 """Get the state of share_autosubscribe in the syncdaemon."""
112 return get_syncdaemon_tool().is_share_autosubscribe_enabled()
113
114
115def enable_share_autosubscribe():
116 """Enable share_autosubscribe in the syncdaemon."""
117 return get_syncdaemon_tool().enable_share_autosubscribe(True)
118
119
120def disable_share_autosubscribe():
121 """Disable share_autosubscribe in the syncdaemon."""
122 return get_syncdaemon_tool().enable_share_autosubscribe(False)
123
124
125def udf_autosubscribe_enabled():
126 """Get the state of udf_autosubscribe in the syncdaemon."""
127 return get_syncdaemon_tool().is_udf_autosubscribe_enabled()
128
129
130def enable_udf_autosubscribe():
131 """Enable udf_autosubscribe in the syncdaemon."""
132 return get_syncdaemon_tool().enable_udf_autosubscribe(True)
133
134
135def disable_udf_autosubscribe():
136 """Disable udf_autosubscribe in the syncdaemon."""
137 return get_syncdaemon_tool().enable_udf_autosubscribe(False)
138
139
95def get_root_dir():140def get_root_dir():
96 """Retrieve the root information from syncdaemon."""141 """Retrieve the root information from syncdaemon."""
97 return get_syncdaemon_tool().get_root_dir()142 return get_syncdaemon_tool().get_root_dir()
98143
=== modified file 'ubuntuone/controlpanel/tests/__init__.py'
--- ubuntuone/controlpanel/tests/__init__.py 2011-05-19 17:57:56 +0000
+++ ubuntuone/controlpanel/tests/__init__.py 2011-06-17 14:51:05 +0000
@@ -125,7 +125,10 @@
125 'configurable': True,125 'configurable': True,
126 'device_id': 'ComputerABCDEF01234-localtoken',126 'device_id': 'ComputerABCDEF01234-localtoken',
127 'limit_bandwidth': False,127 'limit_bandwidth': False,
128 'autoconnect': True,
128 'show_all_notifications': True,129 'show_all_notifications': True,
130 'share_autosubscribe': False,
131 'udf_autosubscribe': False,
129 'max_download_speed': -1,132 'max_download_speed': -1,
130 'max_upload_speed': -1,133 'max_upload_speed': -1,
131 'name': 'Ubuntu One @ localhost',134 'name': 'Ubuntu One @ localhost',
132135
=== modified file 'ubuntuone/controlpanel/tests/test_backend.py'
--- ubuntuone/controlpanel/tests/test_backend.py 2011-06-02 03:58:53 +0000
+++ ubuntuone/controlpanel/tests/test_backend.py 2011-06-17 14:51:05 +0000
@@ -63,6 +63,9 @@
63)63)
6464
6565
66# pylint: disable=E1101
67
68
66class MockWebClient(object):69class MockWebClient(object):
67 """A mock webclient."""70 """A mock webclient."""
6871
@@ -104,6 +107,9 @@
104107
105 throttling = False108 throttling = False
106 show_all_notifications = True109 show_all_notifications = True
110 autoconnect = True
111 udf_autosubscribe = False
112 share_autosubscribe = False
107 limits = {"download": -1, "upload": -1}113 limits = {"download": -1, "upload": -1}
108 file_sync = True114 file_sync = True
109 status = {115 status = {
@@ -151,6 +157,42 @@
151 """Disable show_all_notifications."""157 """Disable show_all_notifications."""
152 self.show_all_notifications = False158 self.show_all_notifications = False
153159
160 def autoconnect_enabled(self):
161 """Return the state of autoconnect."""
162 return self.autoconnect
163
164 def enable_autoconnect(self):
165 """Enable autoconnect."""
166 self.autoconnect = True
167
168 def disable_autoconnect(self):
169 """Disable autoconnect."""
170 self.autoconnect = False
171
172 def udf_autosubscribe_enabled(self):
173 """Return the state of udf_autosubscribe."""
174 return self.udf_autosubscribe
175
176 def enable_udf_autosubscribe(self):
177 """Enable udf_autosubscribe."""
178 self.udf_autosubscribe = True
179
180 def disable_udf_autosubscribe(self):
181 """Disable udf_autosubscribe."""
182 self.udf_autosubscribe = False
183
184 def share_autosubscribe_enabled(self):
185 """Return the state of share_autosubscribe."""
186 return self.share_autosubscribe
187
188 def enable_share_autosubscribe(self):
189 """Enable share_autosubscribe."""
190 self.share_autosubscribe = True
191
192 def disable_share_autosubscribe(self):
193 """Disable share_autosubscribe."""
194 self.share_autosubscribe = False
195
154 def files_sync_enabled(self):196 def files_sync_enabled(self):
155 """Get if file sync service is enabled."""197 """Get if file sync service is enabled."""
156 return MockSDClient.file_sync198 return MockSDClient.file_sync
@@ -319,7 +361,6 @@
319 @inlineCallbacks361 @inlineCallbacks
320 def test_account_info(self):362 def test_account_info(self):
321 """The account_info method exercises its callback."""363 """The account_info method exercises its callback."""
322 # pylint: disable=E1101
323 self.be.wc.results[ACCOUNT_API] = SAMPLE_ACCOUNT_NO_CURRENT_PLAN364 self.be.wc.results[ACCOUNT_API] = SAMPLE_ACCOUNT_NO_CURRENT_PLAN
324 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON365 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON
325 result = yield self.be.account_info()366 result = yield self.be.account_info()
@@ -328,7 +369,6 @@
328 @inlineCallbacks369 @inlineCallbacks
329 def test_account_info_with_current_plan(self):370 def test_account_info_with_current_plan(self):
330 """The account_info method exercises its callback."""371 """The account_info method exercises its callback."""
331 # pylint: disable=E1101
332 self.be.wc.results[ACCOUNT_API] = SAMPLE_ACCOUNT_WITH_CURRENT_PLAN372 self.be.wc.results[ACCOUNT_API] = SAMPLE_ACCOUNT_WITH_CURRENT_PLAN
333 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON373 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON
334 result = yield self.be.account_info()374 result = yield self.be.account_info()
@@ -359,7 +399,6 @@
359 @inlineCallbacks399 @inlineCallbacks
360 def test_devices_info(self):400 def test_devices_info(self):
361 """The devices_info method exercises its callback."""401 """The devices_info method exercises its callback."""
362 # pylint: disable=E1101
363 self.be.wc.results[DEVICES_API] = SAMPLE_DEVICES_JSON402 self.be.wc.results[DEVICES_API] = SAMPLE_DEVICES_JSON
364 result = yield self.be.devices_info()403 result = yield self.be.devices_info()
365 self.assertEqual(result, EXPECTED_DEVICES_INFO)404 self.assertEqual(result, EXPECTED_DEVICES_INFO)
@@ -402,23 +441,24 @@
402 status = yield self.be.file_sync_status()441 status = yield self.be.file_sync_status()
403 assert status['status'] == backend.FILE_SYNC_DISABLED, status442 assert status['status'] == backend.FILE_SYNC_DISABLED, status
404443
405 # pylint: disable=E1101
406 self.be.wc.results[DEVICES_API] = SAMPLE_DEVICES_JSON444 self.be.wc.results[DEVICES_API] = SAMPLE_DEVICES_JSON
407 result = yield self.be.devices_info()445 result = yield self.be.devices_info()
408446
409 expected = EXPECTED_DEVICES_INFO[:]447 expected = EXPECTED_DEVICES_INFO[:]
410 for device in expected:448 for device in expected:
411 device.pop('limit_bandwidth', None)449 device.pop('limit_bandwidth', None)
412 device.pop('max_download_speed', None)450 device.pop(backend.DOWNLOAD_KEY, None)
413 device.pop('max_upload_speed', None)451 device.pop(backend.UPLOAD_KEY, None)
414 device.pop('show_all_notifications', None)452 device.pop(backend.AUTOCONNECT_KEY, None)
453 device.pop(backend.SHOW_ALL_NOTIFICATIONS_KEY, None)
454 device.pop(backend.SHARE_AUTOSUBSCRIBE_KEY, None)
455 device.pop(backend.UDF_AUTOSUBSCRIBE_KEY, None)
415 device['configurable'] = False456 device['configurable'] = False
416 self.assertEqual(result, expected)457 self.assertEqual(result, expected)
417458
418 @inlineCallbacks459 @inlineCallbacks
419 def test_devices_info_when_token_name_is_empty(self):460 def test_devices_info_when_token_name_is_empty(self):
420 """The devices_info can handle empty token names."""461 """The devices_info can handle empty token names."""
421 # pylint: disable=E1101
422 self.be.wc.results[DEVICES_API] = EMPTY_DESCRIPTION_JSON462 self.be.wc.results[DEVICES_API] = EMPTY_DESCRIPTION_JSON
423 result = yield self.be.devices_info()463 result = yield self.be.devices_info()
424 expected = {'configurable': False,464 expected = {'configurable': False,
@@ -430,7 +470,6 @@
430 @inlineCallbacks470 @inlineCallbacks
431 def test_devices_info_does_not_log_device_id(self):471 def test_devices_info_does_not_log_device_id(self):
432 """The devices_info does not log the device_id."""472 """The devices_info does not log the device_id."""
433 # pylint: disable=E1101
434 self.be.wc.results[DEVICES_API] = SAMPLE_DEVICES_JSON473 self.be.wc.results[DEVICES_API] = SAMPLE_DEVICES_JSON
435 yield self.be.devices_info()474 yield self.be.devices_info()
436475
@@ -446,7 +485,6 @@
446 dtype, did = DEVICE_TYPE_COMPUTER, "SAMPLE-TOKEN"485 dtype, did = DEVICE_TYPE_COMPUTER, "SAMPLE-TOKEN"
447 device_id = dtype + did486 device_id = dtype + did
448 apiurl = DEVICE_REMOVE_API % (dtype.lower(), did)487 apiurl = DEVICE_REMOVE_API % (dtype.lower(), did)
449 # pylint: disable=E1101
450 self.be.wc.results[apiurl] = SAMPLE_DEVICES_JSON488 self.be.wc.results[apiurl] = SAMPLE_DEVICES_JSON
451 result = yield self.be.remove_device(device_id)489 result = yield self.be.remove_device(device_id)
452 self.assertEqual(result, device_id)490 self.assertEqual(result, device_id)
@@ -457,7 +495,6 @@
457 def test_remove_device_clear_credentials_if_local_device(self):495 def test_remove_device_clear_credentials_if_local_device(self):
458 """The remove_device method clears the credentials if is local."""496 """The remove_device method clears the credentials if is local."""
459 apiurl = DEVICE_REMOVE_API % ('computer', TOKEN['token'])497 apiurl = DEVICE_REMOVE_API % ('computer', TOKEN['token'])
460 # pylint: disable=E1101
461 self.be.wc.results[apiurl] = SAMPLE_DEVICES_JSON498 self.be.wc.results[apiurl] = SAMPLE_DEVICES_JSON
462 yield self.be.remove_device(self.local_token)499 yield self.be.remove_device(self.local_token)
463 # credentials were cleared500 # credentials were cleared
@@ -496,10 +533,10 @@
496 """The device settings are updated."""533 """The device settings are updated."""
497 backend.sd_client.show_all_notifications = False534 backend.sd_client.show_all_notifications = False
498 yield self.be.change_device_settings(self.local_token,535 yield self.be.change_device_settings(self.local_token,
499 {"show_all_notifications": True})536 {backend.SHOW_ALL_NOTIFICATIONS_KEY: True})
500 self.assertEqual(backend.sd_client.show_all_notifications, True)537 self.assertEqual(backend.sd_client.show_all_notifications, True)
501 yield self.be.change_device_settings(self.local_token,538 yield self.be.change_device_settings(self.local_token,
502 {"show_all_notifications": False})539 {backend.SHOW_ALL_NOTIFICATIONS_KEY: False})
503 self.assertEqual(backend.sd_client.show_all_notifications, False)540 self.assertEqual(backend.sd_client.show_all_notifications, False)
504541
505 @inlineCallbacks542 @inlineCallbacks
@@ -566,7 +603,6 @@
566 def setUp(self):603 def setUp(self):
567 super(BackendVolumesTestCase, self).setUp()604 super(BackendVolumesTestCase, self).setUp()
568 # fake quota info and calculate free bytes605 # fake quota info and calculate free bytes
569 # pylint: disable=E1101
570 self.be.wc.results[ACCOUNT_API] = SAMPLE_ACCOUNT_NO_CURRENT_PLAN606 self.be.wc.results[ACCOUNT_API] = SAMPLE_ACCOUNT_NO_CURRENT_PLAN
571 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON607 self.be.wc.results[QUOTA_API] = SAMPLE_QUOTA_JSON
572608
@@ -1009,7 +1045,6 @@
1009 self.be.status_changed_handler = self._set_called1045 self.be.status_changed_handler = self._set_called
1010 status = {'name': 'foo', 'description': 'bar', 'is_error': '',1046 status = {'name': 'foo', 'description': 'bar', 'is_error': '',
1011 'is_connected': '', 'is_online': '', 'queues': ''}1047 'is_connected': '', 'is_online': '', 'queues': ''}
1012 # pylint: disable=E1101
1013 backend.sd_client.status_changed_handler(status)1048 backend.sd_client.status_changed_handler(status)
10141049
1015 # pylint: disable=W02121050 # pylint: disable=W0212
@@ -1158,3 +1193,162 @@
1158 yield self.be.change_replication_settings(rid, {})1193 yield self.be.change_replication_settings(rid, {})
11591194
1160 self.assertEqual(MockReplicationClient.exclusions, prior)1195 self.assertEqual(MockReplicationClient.exclusions, prior)
1196
1197
1198class BackendFileSyncSettingsTestCase(BackendBasicTestCase):
1199 """File Sync Settings tests for the backend."""
1200
1201 default_settings = backend.ControlBackend.DEFAULT_FILE_SYNC_SETTINGS
1202
1203 @inlineCallbacks
1204 def setUp(self):
1205 yield super(BackendFileSyncSettingsTestCase, self).setUp()
1206 # restore default settings
1207 yield self.be.change_file_sync_settings(self.default_settings)
1208
1209 @inlineCallbacks
1210 def assert_boolean_setting_is_correct(self, setting_name):
1211 """The 'setting_name' can be successfully changed."""
1212 new_value = not self.default_settings[setting_name]
1213 yield self.be.change_file_sync_settings({setting_name: new_value})
1214
1215 self.assertEqual(getattr(backend.sd_client, setting_name), new_value)
1216
1217 actual = yield self.be.file_sync_settings_info()
1218 expected = self.default_settings.copy()
1219 expected[setting_name] = new_value
1220 self.assertEqual(expected, actual)
1221
1222 @inlineCallbacks
1223 def test_file_sync_settings_info(self):
1224 """The settings_info method exercises its callback."""
1225 backend.sd_client.limits = {"download": 1000, "upload": 100}
1226 expected = {
1227 backend.AUTOCONNECT_KEY: backend.sd_client.autoconnect,
1228 backend.SHOW_ALL_NOTIFICATIONS_KEY:
1229 backend.sd_client.show_all_notifications,
1230 backend.SHARE_AUTOSUBSCRIBE_KEY:
1231 backend.sd_client.share_autosubscribe,
1232 backend.UDF_AUTOSUBSCRIBE_KEY:
1233 backend.sd_client.udf_autosubscribe,
1234 backend.DOWNLOAD_KEY: backend.sd_client.limits['download'],
1235 backend.UPLOAD_KEY: backend.sd_client.limits['upload'],
1236 }
1237 result = yield self.be.file_sync_settings_info()
1238 self.assertEqual(expected, result)
1239
1240 @inlineCallbacks
1241 def test_change_file_sync_setting_autoconnect(self):
1242 """The settings can be changed for autoconnect."""
1243 yield self.assert_boolean_setting_is_correct(backend.AUTOCONNECT_KEY)
1244
1245 @inlineCallbacks
1246 def test_change_file_sync_setting_show_all_notifications(self):
1247 """The settings can be changed for show_all_notifications."""
1248 yield self.assert_boolean_setting_is_correct(
1249 backend.SHOW_ALL_NOTIFICATIONS_KEY)
1250
1251 @inlineCallbacks
1252 def test_change_file_sync_setting_share_autosubscribe(self):
1253 """The settings can be changed for share_autosubscribe."""
1254 yield self.assert_boolean_setting_is_correct(
1255 backend.SHARE_AUTOSUBSCRIBE_KEY)
1256
1257 @inlineCallbacks
1258 def test_change_file_sync_setting_udf_autosubscribe(self):
1259 """The settings can be changed for udf_autosubscribe."""
1260 yield self.assert_boolean_setting_is_correct(
1261 backend.UDF_AUTOSUBSCRIBE_KEY)
1262
1263 @inlineCallbacks
1264 def test_change_file_sync_setting_download_bandwidth_limit(self):
1265 """The settings can be changed for download_bandwidth_limit."""
1266 new_value = 834
1267 setting_name = backend.DOWNLOAD_KEY
1268 yield self.be.change_file_sync_settings({setting_name: new_value})
1269
1270 self.assertEqual(backend.sd_client.throttling, True)
1271 self.assertEqual(backend.sd_client.limits,
1272 {'download': new_value, 'upload': -1})
1273
1274 @inlineCallbacks
1275 def test_change_file_sync_setting_upload_bandwidth_limit(self):
1276 """The settings can be changed for upload_bandwidth_limit."""
1277 new_value = 932
1278 setting_name = backend.UPLOAD_KEY
1279 yield self.be.change_file_sync_settings({setting_name: new_value})
1280
1281 self.assertEqual(backend.sd_client.throttling, True)
1282 self.assertEqual(backend.sd_client.limits,
1283 {'download': -1, 'upload': new_value})
1284
1285 @inlineCallbacks
1286 def test_no_download_limit_and_upload_change_to_no_limit(self):
1287 """The settings can be changed for download_bandwidth_limit.
1288
1289 If the download limit was not set and the upload was set, when
1290 unsetting the upload limit the bandwidth_throttling_enabled is False.
1291
1292 """
1293 only_one_limit_set = {
1294 backend.DOWNLOAD_KEY: -1,
1295 backend.UPLOAD_KEY: 52,
1296 }
1297 yield self.be.change_file_sync_settings(only_one_limit_set)
1298
1299 # unset upload_bandwidth_limit
1300 setting_name = backend.UPLOAD_KEY
1301 yield self.be.change_file_sync_settings({setting_name: -1})
1302
1303 self.assertEqual(backend.sd_client.throttling, False)
1304 self.assertEqual(backend.sd_client.limits,
1305 {'download': -1, 'upload': -1})
1306
1307 @inlineCallbacks
1308 def test_no_upload_limit_and_download_change_to_no_limit(self):
1309 """The settings can be changed for upload_bandwidth_limit.
1310
1311 If the upload limit was not set and the download was set, when
1312 unsetting the download limit the bandwidth_throttling_enabled is False.
1313
1314 """
1315 only_one_limit_set = {
1316 backend.DOWNLOAD_KEY: 33,
1317 backend.UPLOAD_KEY: -1,
1318 }
1319 yield self.be.change_file_sync_settings(only_one_limit_set)
1320
1321 # unset download_bandwidth_limit
1322 setting_name = backend.DOWNLOAD_KEY
1323 yield self.be.change_file_sync_settings({setting_name: -1})
1324
1325 self.assertEqual(backend.sd_client.throttling, False)
1326 self.assertEqual(backend.sd_client.limits,
1327 {'download': -1, 'upload': -1})
1328
1329 @inlineCallbacks
1330 def test_restore_defaults(self):
1331 """The defaults can be restored."""
1332 not_defaults = {
1333 backend.AUTOCONNECT_KEY: False,
1334 backend.SHOW_ALL_NOTIFICATIONS_KEY: False,
1335 backend.SHARE_AUTOSUBSCRIBE_KEY: True,
1336 backend.UDF_AUTOSUBSCRIBE_KEY: True,
1337 backend.DOWNLOAD_KEY: 204800,
1338 backend.UPLOAD_KEY: 2048,
1339 }
1340 yield self.be.change_file_sync_settings(not_defaults)
1341
1342 # the call we want to test
1343 yield self.be.restore_file_sync_settings()
1344
1345 self.assertEqual(backend.sd_client.autoconnect, True)
1346 self.assertEqual(backend.sd_client.show_all_notifications, True)
1347 self.assertEqual(backend.sd_client.share_autosubscribe, False)
1348 self.assertEqual(backend.sd_client.udf_autosubscribe, False)
1349 self.assertEqual(backend.sd_client.throttling, False)
1350 self.assertEqual(backend.sd_client.limits,
1351 {'download': -1, 'upload': -1})
1352
1353 result = yield self.be.file_sync_settings_info()
1354 self.assertEqual(self.default_settings, result)

Subscribers

People subscribed via source and target branches