Merge lp:~nataliabidart/ubuntuone-control-panel/start-dc-on-backend into lp:ubuntuone-control-panel
- start-dc-on-backend
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Natalia Bidart |
Approved revision: | 56 |
Merged at revision: | 45 |
Proposed branch: | lp:~nataliabidart/ubuntuone-control-panel/start-dc-on-backend |
Merge into: | lp:ubuntuone-control-panel |
Prerequisite: | lp:~nataliabidart/ubuntuone-control-panel/replication-to-the-backend |
Diff against target: |
932 lines (+326/-242) 7 files modified
data/install.ui (+7/-2) po/POTFILES.in (+2/-1) pylintrc (+1/-1) ubuntuone/controlpanel/gtk/gui.py (+114/-81) ubuntuone/controlpanel/gtk/tests/__init__.py (+14/-13) ubuntuone/controlpanel/gtk/tests/test_gui.py (+187/-140) ubuntuone/controlpanel/logger.py (+1/-4) |
To merge this branch: | bzr merge lp:~nataliabidart/ubuntuone-control-panel/start-dc-on-backend |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Roberto Alsina (community) | Approve | ||
Eric Casteleijn (community) | Approve | ||
Review via email: mp+45448@code.launchpad.net |
This proposal supersedes a proposal from 2011-01-06.
Commit message
Desktopcouch replication service is accessed through the backend using its DBus service (LP: #696782).
Description of the change
To test, first check that all the desktopcouch related packages are uninstalled, and that no desktopcouch nor couchdb process is running. This meaning:
sudo apt-cache search couch
should show no package installed, and:
ps aux | grep couch
should return no results. Then, from this branch, run:
terminal 1: DEBUG=True PYTHONPATH=. ./bin/ubuntuone
terminal 2: DEBUG=True PYTHONPATH=. ./bin/ubuntuone
And go to the third tab and install dc-u1 from there, and keep playing. You should get no hangs at all in the UI.
- 55. By Natalia Bidart
-
Avoiding conflicts.
- 56. By Natalia Bidart
-
Merged dependency branch in.
Roberto Alsina (ralsina) wrote : | # |
Does what it says. +1
Preview Diff
1 | === modified file 'data/install.ui' | |||
2 | --- data/install.ui 2010-12-24 14:53:03 +0000 | |||
3 | +++ data/install.ui 2011-01-06 21:03:06 +0000 | |||
4 | @@ -23,11 +23,12 @@ | |||
5 | 23 | <property name="visible">True</property> | 23 | <property name="visible">True</property> |
6 | 24 | <child> | 24 | <child> |
7 | 25 | <object class="GtkButton" id="install_button"> | 25 | <object class="GtkButton" id="install_button"> |
9 | 26 | <property name="label">gtk-ok</property> | 26 | <property name="label" translatable="yes">_Install now</property> |
10 | 27 | <property name="visible">True</property> | 27 | <property name="visible">True</property> |
11 | 28 | <property name="can_focus">True</property> | 28 | <property name="can_focus">True</property> |
12 | 29 | <property name="receives_default">True</property> | 29 | <property name="receives_default">True</property> |
14 | 30 | <property name="use_stock">True</property> | 30 | <property name="image">image1</property> |
15 | 31 | <property name="use_underline">True</property> | ||
16 | 31 | <signal name="clicked" handler="on_install_button_clicked"/> | 32 | <signal name="clicked" handler="on_install_button_clicked"/> |
17 | 32 | </object> | 33 | </object> |
18 | 33 | <packing> | 34 | <packing> |
19 | @@ -43,4 +44,8 @@ | |||
20 | 43 | </packing> | 44 | </packing> |
21 | 44 | </child> | 45 | </child> |
22 | 45 | </object> | 46 | </object> |
23 | 47 | <object class="GtkImage" id="image1"> | ||
24 | 48 | <property name="visible">True</property> | ||
25 | 49 | <property name="stock">gtk-ok</property> | ||
26 | 50 | </object> | ||
27 | 46 | </interface> | 51 | </interface> |
28 | 47 | 52 | ||
29 | === modified file 'po/POTFILES.in' | |||
30 | --- po/POTFILES.in 2011-01-04 16:12:56 +0000 | |||
31 | +++ po/POTFILES.in 2011-01-06 21:03:06 +0000 | |||
32 | @@ -1,8 +1,9 @@ | |||
33 | 1 | ubuntuone-control-panel-gtk.desktop.in | 1 | ubuntuone-control-panel-gtk.desktop.in |
34 | 2 | ubuntuone/controlpanel/gtk/gui.py | 2 | ubuntuone/controlpanel/gtk/gui.py |
35 | 3 | [type: gettext/glade] data/dashboard.ui | 3 | [type: gettext/glade] data/dashboard.ui |
36 | 4 | [type: gettext/glade] data/services.ui | ||
37 | 5 | [type: gettext/glade] data/device.ui | 4 | [type: gettext/glade] data/device.ui |
38 | 6 | [type: gettext/glade] data/devices.ui | 5 | [type: gettext/glade] data/devices.ui |
39 | 6 | [type: gettext/glade] data/install.ui | ||
40 | 7 | [type: gettext/glade] data/management.ui | 7 | [type: gettext/glade] data/management.ui |
41 | 8 | [type: gettext/glade] data/overview.ui | 8 | [type: gettext/glade] data/overview.ui |
42 | 9 | [type: gettext/glade] data/services.ui | ||
43 | 9 | 10 | ||
44 | === modified file 'pylintrc' | |||
45 | --- pylintrc 2010-10-13 18:55:23 +0000 | |||
46 | +++ pylintrc 2011-01-06 21:03:06 +0000 | |||
47 | @@ -272,7 +272,7 @@ | |||
48 | 272 | max-line-length=79 | 272 | max-line-length=79 |
49 | 273 | 273 | ||
50 | 274 | # Maximum number of lines in a module | 274 | # Maximum number of lines in a module |
52 | 275 | max-module-lines=2000 | 275 | max-module-lines=2500 |
53 | 276 | 276 | ||
54 | 277 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 | 277 | # String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 |
55 | 278 | # tab). | 278 | # tab). |
56 | 279 | 279 | ||
57 | === modified file 'ubuntuone/controlpanel/gtk/gui.py' | |||
58 | --- ubuntuone/controlpanel/gtk/gui.py 2010-12-26 15:02:52 +0000 | |||
59 | +++ ubuntuone/controlpanel/gtk/gui.py 2011-01-06 21:03:06 +0000 | |||
60 | @@ -78,6 +78,12 @@ | |||
61 | 78 | VALUE_ERROR = _('Value could not be retrieved.') | 78 | VALUE_ERROR = _('Value could not be retrieved.') |
62 | 79 | WARNING_MARKUP = '<span foreground="%s"><b>%%s</b></span>' % ORANGE | 79 | WARNING_MARKUP = '<span foreground="%s"><b>%%s</b></span>' % ORANGE |
63 | 80 | KILOBYTES = 1024 | 80 | KILOBYTES = 1024 |
64 | 81 | NO_OP = lambda *a, **kw: None | ||
65 | 82 | |||
66 | 83 | |||
67 | 84 | def error_handler(*args, **kwargs): | ||
68 | 85 | """Log errors when calling D-Bus methods in a async way.""" | ||
69 | 86 | logger.error('Error handler received: %r, %r', args, kwargs) | ||
70 | 81 | 87 | ||
71 | 82 | 88 | ||
72 | 83 | def filter_by_app_name(f): | 89 | def filter_by_app_name(f): |
73 | @@ -352,7 +358,8 @@ | |||
74 | 352 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, | 358 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, |
75 | 353 | WINDOW_ID_KEY: str(self._window_id), | 359 | WINDOW_ID_KEY: str(self._window_id), |
76 | 354 | PING_URL_KEY: U1_PING_URL} | 360 | PING_URL_KEY: U1_PING_URL} |
78 | 355 | self.sso_backend.register(U1_APP_NAME, settings) | 361 | self.sso_backend.register(U1_APP_NAME, settings, |
79 | 362 | reply_handler=NO_OP, error_handler=error_handler) | ||
80 | 356 | self.set_property('greyed', True) | 363 | self.set_property('greyed', True) |
81 | 357 | self.warning_label.set_text('') | 364 | self.warning_label.set_text('') |
82 | 358 | 365 | ||
83 | @@ -361,7 +368,8 @@ | |||
84 | 361 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, | 368 | settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION, |
85 | 362 | WINDOW_ID_KEY: str(self._window_id), | 369 | WINDOW_ID_KEY: str(self._window_id), |
86 | 363 | PING_URL_KEY: U1_PING_URL} | 370 | PING_URL_KEY: U1_PING_URL} |
88 | 364 | self.sso_backend.login(U1_APP_NAME, settings) | 371 | self.sso_backend.login(U1_APP_NAME, settings, |
89 | 372 | reply_handler=NO_OP, error_handler=error_handler) | ||
90 | 365 | self.set_property('greyed', True) | 373 | self.set_property('greyed', True) |
91 | 366 | self.warning_label.set_text('') | 374 | self.warning_label.set_text('') |
92 | 367 | 375 | ||
93 | @@ -408,7 +416,8 @@ | |||
94 | 408 | else: | 416 | else: |
95 | 409 | self.set_sensitive(True) | 417 | self.set_sensitive(True) |
96 | 410 | self.warning_label.set_text('') | 418 | self.warning_label.set_text('') |
98 | 411 | self.sso_backend.find_credentials(U1_APP_NAME, {}) | 419 | self.sso_backend.find_credentials(U1_APP_NAME, {}, |
99 | 420 | reply_handler=NO_OP, error_handler=error_handler) | ||
100 | 412 | 421 | ||
101 | 413 | 422 | ||
102 | 414 | class DashboardPanel(UbuntuOneBin, ControlPanelMixin): | 423 | class DashboardPanel(UbuntuOneBin, ControlPanelMixin): |
103 | @@ -516,11 +525,13 @@ | |||
104 | 516 | volume_id = checkbutton.get_label() | 525 | volume_id = checkbutton.get_label() |
105 | 517 | subscribed = bool_str(checkbutton.get_active()) | 526 | subscribed = bool_str(checkbutton.get_active()) |
106 | 518 | self.backend.change_volume_settings(volume_id, | 527 | self.backend.change_volume_settings(volume_id, |
108 | 519 | {'subscribed': subscribed}) | 528 | {'subscribed': subscribed}, |
109 | 529 | reply_handler=NO_OP, error_handler=error_handler) | ||
110 | 520 | 530 | ||
111 | 521 | def load(self): | 531 | def load(self): |
112 | 522 | """Load the volume list.""" | 532 | """Load the volume list.""" |
114 | 523 | self.backend.volumes_info() | 533 | self.backend.volumes_info(reply_handler=NO_OP, |
115 | 534 | error_handler=error_handler) | ||
116 | 524 | self.message.start() | 535 | self.message.start() |
117 | 525 | 536 | ||
118 | 526 | 537 | ||
119 | @@ -565,7 +576,8 @@ | |||
120 | 565 | # Not disabling the GUI to avoid annyong twitchings | 576 | # Not disabling the GUI to avoid annyong twitchings |
121 | 566 | #self.set_sensitive(False) | 577 | #self.set_sensitive(False) |
122 | 567 | self.warning_label.set_text('') | 578 | self.warning_label.set_text('') |
124 | 568 | self.backend.change_device_settings(self.id, self.__dict__) | 579 | self.backend.change_device_settings(self.id, self.__dict__, |
125 | 580 | reply_handler=NO_OP, error_handler=error_handler) | ||
126 | 569 | 581 | ||
127 | 570 | def _block_signals(f): | 582 | def _block_signals(f): |
128 | 571 | """Execute 'f' while having the _updating flag set.""" | 583 | """Execute 'f' while having the _updating flag set.""" |
129 | @@ -591,7 +603,8 @@ | |||
130 | 591 | 603 | ||
131 | 592 | def on_remove_clicked(self, widget): | 604 | def on_remove_clicked(self, widget): |
132 | 593 | """Remove button was clicked or activated.""" | 605 | """Remove button was clicked or activated.""" |
134 | 594 | self.backend.remove_device(self.id) | 606 | self.backend.remove_device(self.id, |
135 | 607 | reply_handler=NO_OP, error_handler=error_handler) | ||
136 | 595 | self.set_sensitive(False) | 608 | self.set_sensitive(False) |
137 | 596 | 609 | ||
138 | 597 | @_block_signals | 610 | @_block_signals |
139 | @@ -747,7 +760,8 @@ | |||
140 | 747 | 760 | ||
141 | 748 | def load(self): | 761 | def load(self): |
142 | 749 | """Load the device list.""" | 762 | """Load the device list.""" |
144 | 750 | self.backend.devices_info() | 763 | self.backend.devices_info(reply_handler=NO_OP, |
145 | 764 | error_handler=error_handler) | ||
146 | 751 | self.message.start() | 765 | self.message.start() |
147 | 752 | 766 | ||
148 | 753 | 767 | ||
149 | @@ -818,12 +832,18 @@ | |||
150 | 818 | class Service(gtk.VBox, ControlPanelMixin): | 832 | class Service(gtk.VBox, ControlPanelMixin): |
151 | 819 | """A service.""" | 833 | """A service.""" |
152 | 820 | 834 | ||
154 | 821 | def __init__(self, name, localized_name, *args, **kwargs): | 835 | CHANGE_ERROR = _('The settings could not be changed,\n' |
155 | 836 | 'previous values were restored.') | ||
156 | 837 | |||
157 | 838 | def __init__(self, service_id, name, *args, **kwargs): | ||
158 | 822 | gtk.VBox.__init__(self) | 839 | gtk.VBox.__init__(self) |
159 | 823 | ControlPanelMixin.__init__(self) | 840 | ControlPanelMixin.__init__(self) |
163 | 824 | self.service_name = name | 841 | self.id = service_id |
164 | 825 | 842 | ||
165 | 826 | self.button = gtk.CheckButton(label=localized_name) | 843 | self.warning_label = gtk.Label() |
166 | 844 | self.pack_start(self.warning_label, expand=False) | ||
167 | 845 | |||
168 | 846 | self.button = gtk.CheckButton(label=name) | ||
169 | 827 | self.pack_start(self.button, expand=False) | 847 | self.pack_start(self.button, expand=False) |
170 | 828 | 848 | ||
171 | 829 | self.show_all() | 849 | self.show_all() |
172 | @@ -835,15 +855,18 @@ | |||
173 | 835 | FILES_SERVICE_NAME = _('Files') | 855 | FILES_SERVICE_NAME = _('Files') |
174 | 836 | 856 | ||
175 | 837 | def __init__(self): | 857 | def __init__(self): |
178 | 838 | Service.__init__(self, name='files', | 858 | Service.__init__(self, service_id='files', |
179 | 839 | localized_name=self.FILES_SERVICE_NAME) | 859 | name=self.FILES_SERVICE_NAME) |
180 | 840 | 860 | ||
181 | 841 | self.set_sensitive(False) | 861 | self.set_sensitive(False) |
182 | 862 | |||
183 | 842 | self.backend.connect_to_signal('FileSyncStatusChanged', | 863 | self.backend.connect_to_signal('FileSyncStatusChanged', |
184 | 843 | self.on_file_sync_status_changed) | 864 | self.on_file_sync_status_changed) |
185 | 844 | self.backend.connect_to_signal('FilesEnabled', self.on_files_enabled) | 865 | self.backend.connect_to_signal('FilesEnabled', self.on_files_enabled) |
186 | 845 | self.backend.connect_to_signal('FilesDisabled', self.on_files_disabled) | 866 | self.backend.connect_to_signal('FilesDisabled', self.on_files_disabled) |
188 | 846 | self.backend.file_sync_status() | 867 | |
189 | 868 | self.backend.file_sync_status(reply_handler=NO_OP, | ||
190 | 869 | error_handler=error_handler) | ||
191 | 847 | 870 | ||
192 | 848 | @log_call(logger.debug) | 871 | @log_call(logger.debug) |
193 | 849 | def on_file_sync_status_changed(self, status): | 872 | def on_file_sync_status_changed(self, status): |
194 | @@ -869,19 +892,24 @@ | |||
195 | 869 | """Button was toggled, exclude/replicate the service properly.""" | 892 | """Button was toggled, exclude/replicate the service properly.""" |
196 | 870 | logger.info('File sync enabled? %r', self.button.get_active()) | 893 | logger.info('File sync enabled? %r', self.button.get_active()) |
197 | 871 | if self.button.get_active(): | 894 | if self.button.get_active(): |
199 | 872 | self.backend.enable_files() | 895 | self.backend.enable_files(reply_handler=NO_OP, |
200 | 896 | error_handler=error_handler) | ||
201 | 873 | else: | 897 | else: |
203 | 874 | self.backend.disable_files() | 898 | self.backend.disable_files(reply_handler=NO_OP, |
204 | 899 | error_handler=error_handler) | ||
205 | 875 | 900 | ||
206 | 876 | 901 | ||
207 | 877 | class DesktopcouchService(Service): | 902 | class DesktopcouchService(Service): |
208 | 878 | """A desktopcouch service.""" | 903 | """A desktopcouch service.""" |
209 | 879 | 904 | ||
215 | 880 | def __init__(self, name, localized_name, | 905 | def __init__(self, service_id, name, enabled, dependency=None): |
216 | 881 | replication_service, dependency=None): | 906 | Service.__init__(self, service_id, name) |
217 | 882 | Service.__init__(self, name, localized_name) | 907 | |
218 | 883 | self.replication_service = replication_service | 908 | self.backend.connect_to_signal('ReplicationSettingsChanged', |
219 | 884 | enabled = name not in self.replication_service.all_exclusions() | 909 | self.on_replication_settings_changed) |
220 | 910 | self.backend.connect_to_signal('ReplicationSettingsChangeError', | ||
221 | 911 | self.on_replication_settings_change_error) | ||
222 | 912 | |||
223 | 885 | self.button.set_active(enabled) | 913 | self.button.set_active(enabled) |
224 | 886 | 914 | ||
225 | 887 | self.dependency = None | 915 | self.dependency = None |
226 | @@ -903,11 +931,27 @@ | |||
227 | 903 | def on_button_toggled(self, button): | 931 | def on_button_toggled(self, button): |
228 | 904 | """Button was toggled, exclude/replicate the service properly.""" | 932 | """Button was toggled, exclude/replicate the service properly.""" |
229 | 905 | logger.info('Starting replication for %r? %r', | 933 | logger.info('Starting replication for %r? %r', |
235 | 906 | self.service_name, self.button.get_active()) | 934 | self.id, self.button.get_active()) |
236 | 907 | if self.button.get_active(): | 935 | |
237 | 908 | self.replication_service.replicate(self.service_name) | 936 | args = {'enabled': bool_str(self.button.get_active())} |
238 | 909 | else: | 937 | self.backend.change_replication_settings(self.id, args, |
239 | 910 | self.replication_service.exclude(self.service_name) | 938 | reply_handler=NO_OP, error_handler=error_handler) |
240 | 939 | |||
241 | 940 | @log_call(logger.info) | ||
242 | 941 | def on_replication_settings_changed(self, replication_id): | ||
243 | 942 | """The change of settings for this replication succeded.""" | ||
244 | 943 | if replication_id != self.id: | ||
245 | 944 | return | ||
246 | 945 | self.warning_label.set_text('') | ||
247 | 946 | |||
248 | 947 | @log_call(logger.error) | ||
249 | 948 | def on_replication_settings_change_error(self, replication_id, | ||
250 | 949 | error_dict=None): | ||
251 | 950 | """The change of settings for this replication failed.""" | ||
252 | 951 | if replication_id != self.id: | ||
253 | 952 | return | ||
254 | 953 | self.button.set_active(not self.button.get_active()) | ||
255 | 954 | self._set_warning(self.CHANGE_ERROR, self.warning_label) | ||
256 | 911 | 955 | ||
257 | 912 | 956 | ||
258 | 913 | class ServicesPanel(UbuntuOneBin, ControlPanelMixin): | 957 | class ServicesPanel(UbuntuOneBin, ControlPanelMixin): |
259 | @@ -916,32 +960,33 @@ | |||
260 | 916 | TITLE = _('Ubuntu One services including data sync are enabled for the ' | 960 | TITLE = _('Ubuntu One services including data sync are enabled for the ' |
261 | 917 | 'data types and services listed below.') | 961 | 'data types and services listed below.') |
262 | 918 | CHOOSE_SERVICES = _('Choose services to synchronize with this computer:') | 962 | CHOOSE_SERVICES = _('Choose services to synchronize with this computer:') |
266 | 919 | DESKTOPCOUCH_PKG = 'desktopcouch' | 963 | DESKTOPCOUCH_PKG = 'desktopcouch-ubuntuone' |
264 | 920 | BINDWOOD_PKG = 'xul-ext-bindwood' | ||
265 | 921 | EVOCOUCH_PKG = 'evolution-couchdb' | ||
267 | 922 | BOOKMARKS = _('Bookmarks (Firefox)') | 964 | BOOKMARKS = _('Bookmarks (Firefox)') |
268 | 923 | CONTACTS = _('Contacts (Evolution)') | 965 | CONTACTS = _('Contacts (Evolution)') |
269 | 924 | NO_PAIRING_RECORD = _('There is no Ubuntu One pairing record.') | 966 | NO_PAIRING_RECORD = _('There is no Ubuntu One pairing record.') |
270 | 925 | 967 | ||
272 | 926 | def __init__(self, replication_exclusion_class=None): | 968 | def __init__(self): |
273 | 927 | UbuntuOneBin.__init__(self) | 969 | UbuntuOneBin.__init__(self) |
274 | 928 | ControlPanelMixin.__init__(self, filename='services.ui') | 970 | ControlPanelMixin.__init__(self, filename='services.ui') |
275 | 929 | self.add(self.itself) | 971 | self.add(self.itself) |
276 | 930 | 972 | ||
277 | 931 | self.replication_exclusion_class = replication_exclusion_class | ||
278 | 932 | self.replication_service = None | ||
279 | 933 | self.has_desktopcouch = False | ||
280 | 934 | self.has_bindwood = False | ||
281 | 935 | self.has_evocouch = False | ||
282 | 936 | self.package_manager = package_manager.PackageManager() | 973 | self.package_manager = package_manager.PackageManager() |
283 | 937 | self.install_box = None | 974 | self.install_box = None |
286 | 938 | self.bookmarks = None | 975 | |
287 | 939 | self.contacts = None | 976 | self.backend.connect_to_signal('ReplicationsInfoReady', |
288 | 977 | self.on_replications_info_ready) | ||
289 | 978 | self.backend.connect_to_signal('ReplicationsInfoError', | ||
290 | 979 | self.on_replications_info_error) | ||
291 | 940 | 980 | ||
292 | 941 | self.files.pack_start(FilesService(), expand=False) | 981 | self.files.pack_start(FilesService(), expand=False) |
293 | 942 | 982 | ||
294 | 943 | self.show() | 983 | self.show() |
295 | 944 | 984 | ||
296 | 985 | @property | ||
297 | 986 | def has_desktopcouch(self): | ||
298 | 987 | """Is desktopcouch installed?""" | ||
299 | 988 | return self.package_manager.is_installed(self.DESKTOPCOUCH_PKG) | ||
300 | 989 | |||
301 | 945 | @log_call(logger.debug) | 990 | @log_call(logger.debug) |
302 | 946 | def load(self): | 991 | def load(self): |
303 | 947 | """Load info.""" | 992 | """Load info.""" |
304 | @@ -949,16 +994,7 @@ | |||
305 | 949 | self.itself.remove(self.install_box) | 994 | self.itself.remove(self.install_box) |
306 | 950 | self.install_box = None | 995 | self.install_box = None |
307 | 951 | 996 | ||
318 | 952 | self.has_desktopcouch = \ | 997 | logger.info('load: has_desktopcouch? %r', self.has_desktopcouch) |
309 | 953 | self.package_manager.is_installed(self.DESKTOPCOUCH_PKG) | ||
310 | 954 | self.has_bindwood = \ | ||
311 | 955 | self.package_manager.is_installed(self.BINDWOOD_PKG) | ||
312 | 956 | self.has_evocouch = \ | ||
313 | 957 | self.package_manager.is_installed(self.EVOCOUCH_PKG) | ||
314 | 958 | |||
315 | 959 | logger.info('load: has_desktopcouch? %r has_bindwood? %s ' | ||
316 | 960 | 'has_evocouch? %s', self.has_desktopcouch, | ||
317 | 961 | self.has_bindwood, self.has_evocouch) | ||
319 | 962 | if not self.has_desktopcouch: | 998 | if not self.has_desktopcouch: |
320 | 963 | self.message.set_text('') | 999 | self.message.set_text('') |
321 | 964 | self.replications.hide() | 1000 | self.replications.hide() |
322 | @@ -975,46 +1011,41 @@ | |||
323 | 975 | @log_call(logger.debug) | 1011 | @log_call(logger.debug) |
324 | 976 | def load_replications(self, *args): | 1012 | def load_replications(self, *args): |
325 | 977 | """Load replications info.""" | 1013 | """Load replications info.""" |
326 | 1014 | # ask replications to the backend | ||
327 | 1015 | self.message.start() | ||
328 | 1016 | self.backend.replications_info(reply_handler=NO_OP, | ||
329 | 1017 | error_handler=error_handler) | ||
330 | 1018 | |||
331 | 1019 | @log_call(logger.debug) | ||
332 | 1020 | def on_replications_info_ready(self, info): | ||
333 | 1021 | """The replication info is ready.""" | ||
334 | 1022 | self.on_success(self.CHOOSE_SERVICES) | ||
335 | 1023 | |||
336 | 978 | self.replications.show() | 1024 | self.replications.show() |
337 | 979 | 1025 | ||
338 | 980 | if self.install_box is not None: | 1026 | if self.install_box is not None: |
339 | 981 | self.itself.remove(self.install_box) | 1027 | self.itself.remove(self.install_box) |
340 | 982 | self.install_box = None | 1028 | self.install_box = None |
341 | 983 | 1029 | ||
342 | 984 | self.message.set_text(self.CHOOSE_SERVICES) | ||
343 | 985 | for child in self.replications.get_children(): | 1030 | for child in self.replications.get_children(): |
344 | 986 | self.replications.remove(child) | 1031 | self.replications.remove(child) |
345 | 987 | 1032 | ||
376 | 988 | # Unable to import 'desktopcouch.application.replication_services' | 1033 | for item in info: |
377 | 989 | # pylint: disable=F0401 | 1034 | pkg = item['dependency'] |
378 | 990 | if self.replication_exclusion_class is None: | 1035 | child = DesktopcouchService(service_id=item['replication_id'], |
379 | 991 | from desktopcouch.application.replication_services import \ | 1036 | name=item['name'], # self.BOOKMARKS, |
380 | 992 | ubuntuone as u1rep | 1037 | enabled=bool(item['enabled']), |
381 | 993 | self.replication_exclusion_class = u1rep.ReplicationExclusion | 1038 | dependency=pkg if pkg else None) |
382 | 994 | 1039 | self.replications.pack_start(child, expand=False) | |
383 | 995 | if self.replication_service is None: | 1040 | |
384 | 996 | try: | 1041 | @log_call(logger.error) |
385 | 997 | self.replication_service = self.replication_exclusion_class() | 1042 | def on_replications_info_error(self, error_dict=None): |
386 | 998 | except ValueError: | 1043 | """The replication info can not be retrieved.""" |
387 | 999 | logger.exception('Can not load replications:') | 1044 | if error_dict is not None and \ |
388 | 1000 | self._set_warning(self.NO_PAIRING_RECORD, self.message) | 1045 | error_dict.get('error_type', None) == 'NoPairingRecord': |
389 | 1001 | return | 1046 | self.on_error(self.NO_PAIRING_RECORD) |
390 | 1002 | 1047 | else: | |
391 | 1003 | pkg = None | 1048 | self.on_error() |
362 | 1004 | if not self.has_bindwood: | ||
363 | 1005 | pkg = self.BINDWOOD_PKG | ||
364 | 1006 | self.bookmarks = DesktopcouchService('bookmarks', self.BOOKMARKS, | ||
365 | 1007 | self.replication_service, | ||
366 | 1008 | dependency=pkg) | ||
367 | 1009 | self.replications.pack_start(self.bookmarks, expand=False) | ||
368 | 1010 | |||
369 | 1011 | pkg = None | ||
370 | 1012 | if not self.has_evocouch: | ||
371 | 1013 | pkg = self.EVOCOUCH_PKG | ||
372 | 1014 | self.contacts = DesktopcouchService('contacts', self.CONTACTS, | ||
373 | 1015 | self.replication_service, | ||
374 | 1016 | dependency=pkg) | ||
375 | 1017 | self.replications.pack_start(self.contacts, expand=False) | ||
392 | 1018 | 1049 | ||
393 | 1019 | 1050 | ||
394 | 1020 | class ManagementPanel(gtk.VBox, ControlPanelMixin): | 1051 | class ManagementPanel(gtk.VBox, ControlPanelMixin): |
395 | @@ -1107,8 +1138,10 @@ | |||
396 | 1107 | 1138 | ||
397 | 1108 | def load(self): | 1139 | def load(self): |
398 | 1109 | """Load the account info and file sync status list.""" | 1140 | """Load the account info and file sync status list.""" |
401 | 1110 | self.backend.account_info() | 1141 | self.backend.account_info(reply_handler=NO_OP, |
402 | 1111 | self.backend.file_sync_status() | 1142 | error_handler=error_handler) |
403 | 1143 | self.backend.file_sync_status(reply_handler=NO_OP, | ||
404 | 1144 | error_handler=error_handler) | ||
405 | 1112 | self.dashboard_button.clicked() | 1145 | self.dashboard_button.clicked() |
406 | 1113 | 1146 | ||
407 | 1114 | @log_call(logger.debug) | 1147 | @log_call(logger.debug) |
408 | 1115 | 1148 | ||
409 | === modified file 'ubuntuone/controlpanel/gtk/tests/__init__.py' | |||
410 | --- ubuntuone/controlpanel/gtk/tests/__init__.py 2010-12-23 19:17:53 +0000 | |||
411 | +++ ubuntuone/controlpanel/gtk/tests/__init__.py 2011-01-06 21:03:06 +0000 | |||
412 | @@ -53,6 +53,15 @@ | |||
413 | 53 | 'max_upload_speed': '1000', 'max_download_speed': '72548'}, # local | 53 | 'max_upload_speed': '1000', 'max_download_speed': '72548'}, # local |
414 | 54 | ] | 54 | ] |
415 | 55 | 55 | ||
416 | 56 | FAKE_REPLICATIONS_INFO = [ | ||
417 | 57 | {'replication_id': 'foo', 'name': 'Bar', | ||
418 | 58 | 'enabled': 'True', 'dependency': ''}, | ||
419 | 59 | {'replication_id': 'yadda', 'name': 'Foo', | ||
420 | 60 | 'enabled': '', 'dependency': 'a very weird one'}, | ||
421 | 61 | {'replication_id': 'yoda', 'name': 'Figthers', | ||
422 | 62 | 'enabled': 'True', 'dependency': 'other dep'}, | ||
423 | 63 | ] | ||
424 | 64 | |||
425 | 56 | 65 | ||
426 | 57 | class FakedObject(object): | 66 | class FakedObject(object): |
427 | 58 | """Fake an object, record every call.""" | 67 | """Fake an object, record every call.""" |
428 | @@ -117,9 +126,11 @@ | |||
429 | 117 | object_path = gui.DBUS_PREFERENCES_PATH | 126 | object_path = gui.DBUS_PREFERENCES_PATH |
430 | 118 | iface = gui.DBUS_PREFERENCES_IFACE | 127 | iface = gui.DBUS_PREFERENCES_IFACE |
431 | 119 | exposed_methods = [ | 128 | exposed_methods = [ |
435 | 120 | 'account_info', 'devices_info', 'change_device_settings', | 129 | 'account_info', # account |
436 | 121 | 'volumes_info', 'change_volume_settings', 'file_sync_status', | 130 | 'devices_info', 'change_device_settings', 'remove_device', # devices |
437 | 122 | 'remove_device', 'enable_files', 'disable_files', | 131 | 'volumes_info', 'change_volume_settings', # volumes |
438 | 132 | 'replications_info', 'change_replication_settings', # replications | ||
439 | 133 | 'file_sync_status', 'enable_files', 'disable_files', # files | ||
440 | 123 | ] | 134 | ] |
441 | 124 | 135 | ||
442 | 125 | 136 | ||
443 | @@ -157,13 +168,3 @@ | |||
444 | 157 | yield | 168 | yield |
445 | 158 | self._installed[package_name] = True | 169 | self._installed[package_name] = True |
446 | 159 | gui.package_manager.return_value(FakedTransaction([package_name])) | 170 | gui.package_manager.return_value(FakedTransaction([package_name])) |
447 | 160 | |||
448 | 161 | |||
449 | 162 | class FakedReplication(object): | ||
450 | 163 | """Faked a DC replication exclusion.""" | ||
451 | 164 | |||
452 | 165 | def __init__(self): | ||
453 | 166 | self._exclusions = set() | ||
454 | 167 | self.all_exclusions = lambda: self._exclusions | ||
455 | 168 | self.replicate = self._exclusions.remove | ||
456 | 169 | self.exclude = self._exclusions.add | ||
457 | 170 | 171 | ||
458 | === modified file 'ubuntuone/controlpanel/gtk/tests/test_gui.py' | |||
459 | --- ubuntuone/controlpanel/gtk/tests/test_gui.py 2010-12-26 15:02:52 +0000 | |||
460 | +++ ubuntuone/controlpanel/gtk/tests/test_gui.py 2011-01-06 21:03:06 +0000 | |||
461 | @@ -26,9 +26,10 @@ | |||
462 | 26 | 26 | ||
463 | 27 | from ubuntuone.controlpanel.gtk import gui | 27 | from ubuntuone.controlpanel.gtk import gui |
464 | 28 | from ubuntuone.controlpanel.gtk.tests import (FAKE_ACCOUNT_INFO, | 28 | from ubuntuone.controlpanel.gtk.tests import (FAKE_ACCOUNT_INFO, |
466 | 29 | FAKE_VOLUMES_INFO, FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, | 29 | FAKE_DEVICE_INFO, FAKE_DEVICES_INFO, |
467 | 30 | FAKE_VOLUMES_INFO, FAKE_REPLICATIONS_INFO, | ||
468 | 30 | FakedNMState, FakedSSOBackend, FakedSessionBus, FakedInterface, | 31 | FakedNMState, FakedSSOBackend, FakedSessionBus, FakedInterface, |
470 | 31 | FakedPackageManager, FakedReplication, | 32 | FakedPackageManager, |
471 | 32 | ) | 33 | ) |
472 | 33 | from ubuntuone.controlpanel.tests import TOKEN, TestCase | 34 | from ubuntuone.controlpanel.tests import TOKEN, TestCase |
473 | 34 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( | 35 | from ubuntuone.controlpanel.gtk.tests.test_package_manager import ( |
474 | @@ -37,6 +38,8 @@ | |||
475 | 37 | 38 | ||
476 | 38 | # Attribute 'yyy' defined outside __init__, access to a protected member | 39 | # Attribute 'yyy' defined outside __init__, access to a protected member |
477 | 39 | # pylint: disable=W0201, W0212 | 40 | # pylint: disable=W0201, W0212 |
478 | 41 | # Too many lines in module | ||
479 | 42 | # pylint: disable=C0302 | ||
480 | 40 | 43 | ||
481 | 41 | 44 | ||
482 | 42 | class BaseTestCase(TestCase): | 45 | class BaseTestCase(TestCase): |
483 | @@ -96,7 +99,9 @@ | |||
484 | 96 | if backend is None: | 99 | if backend is None: |
485 | 97 | backend = self.ui.backend | 100 | backend = self.ui.backend |
486 | 98 | self.assertIn(method_name, backend._called) | 101 | self.assertIn(method_name, backend._called) |
488 | 99 | self.assertEqual(backend._called[method_name], (args, {})) | 102 | kwargs = {'reply_handler': gui.NO_OP, |
489 | 103 | 'error_handler': gui.error_handler} | ||
490 | 104 | self.assertEqual(backend._called[method_name], (args, kwargs)) | ||
491 | 100 | 105 | ||
492 | 101 | def assert_warning_correct(self, warning, text): | 106 | def assert_warning_correct(self, warning, text): |
493 | 102 | """Check that 'warning' is visible, showing 'text'.""" | 107 | """Check that 'warning' is visible, showing 'text'.""" |
494 | @@ -1361,9 +1366,9 @@ | |||
495 | 1361 | """The test suite for a service.""" | 1366 | """The test suite for a service.""" |
496 | 1362 | 1367 | ||
497 | 1363 | klass = gui.Service | 1368 | klass = gui.Service |
501 | 1364 | name = 'dc_test' | 1369 | service_id = 'dc_test' |
502 | 1365 | localized_name = u'Qué lindo test!' | 1370 | name = u'Qué lindo test!' |
503 | 1366 | kwargs = {'name': 'dc_test', 'localized_name': u'Qué lindo test!'} | 1371 | kwargs = {'service_id': service_id, 'name': name} |
504 | 1367 | 1372 | ||
505 | 1368 | def test_is_an_box(self): | 1373 | def test_is_an_box(self): |
506 | 1369 | """Inherits from gtk.VBox.""" | 1374 | """Inherits from gtk.VBox.""" |
507 | @@ -1373,30 +1378,35 @@ | |||
508 | 1373 | """Is visible.""" | 1378 | """Is visible.""" |
509 | 1374 | self.assertTrue(self.ui.get_visible()) | 1379 | self.assertTrue(self.ui.get_visible()) |
510 | 1375 | 1380 | ||
511 | 1381 | def test_warning_label_is_cleared(self): | ||
512 | 1382 | """The warning label is cleared.""" | ||
513 | 1383 | self.assertEqual(self.ui.warning_label.get_text(), '') | ||
514 | 1384 | |||
515 | 1385 | def test_warning_label_packed(self): | ||
516 | 1386 | """The warning label is packed as child.""" | ||
517 | 1387 | self.assertIn(self.ui.warning_label, self.ui.get_children()) | ||
518 | 1388 | |||
519 | 1376 | def test_check_button_packed(self): | 1389 | def test_check_button_packed(self): |
521 | 1377 | """A check button is packed as only child.""" | 1390 | """A check button is packed as child.""" |
522 | 1378 | self.assertIn(self.ui.button, self.ui.get_children()) | 1391 | self.assertIn(self.ui.button, self.ui.get_children()) |
523 | 1379 | 1392 | ||
524 | 1380 | def test_label(self): | 1393 | def test_label(self): |
525 | 1381 | """The label is set.""" | 1394 | """The label is set.""" |
527 | 1382 | self.assertEqual(self.localized_name, self.ui.button.get_label()) | 1395 | self.assertEqual(self.name, self.ui.button.get_label()) |
528 | 1383 | 1396 | ||
532 | 1384 | def test_service_name(self): | 1397 | def test_service_id(self): |
533 | 1385 | """The service_name is set.""" | 1398 | """The service id is set.""" |
534 | 1386 | self.assertEqual(self.name, self.ui.service_name) | 1399 | self.assertEqual(self.service_id, self.ui.id) |
535 | 1387 | 1400 | ||
536 | 1388 | 1401 | ||
537 | 1389 | class FilesServiceTestCase(ServiceTestCase): | 1402 | class FilesServiceTestCase(ServiceTestCase): |
538 | 1390 | """The test suite for the file sync service.""" | 1403 | """The test suite for the file sync service.""" |
539 | 1391 | 1404 | ||
540 | 1392 | klass = gui.FilesService | 1405 | klass = gui.FilesService |
541 | 1406 | service_id = 'files' | ||
542 | 1407 | name = gui.FilesService.FILES_SERVICE_NAME | ||
543 | 1393 | kwargs = {} | 1408 | kwargs = {} |
544 | 1394 | 1409 | ||
545 | 1395 | def setUp(self): | ||
546 | 1396 | self.name = 'files' | ||
547 | 1397 | self.localized_name = gui.FilesService.FILES_SERVICE_NAME | ||
548 | 1398 | super(FilesServiceTestCase, self).setUp() | ||
549 | 1399 | |||
550 | 1400 | def test_backend_account_signals(self): | 1410 | def test_backend_account_signals(self): |
551 | 1401 | """The proper signals are connected to the backend.""" | 1411 | """The proper signals are connected to the backend.""" |
552 | 1402 | self.assertEqual(self.ui.backend._signals['FileSyncStatusChanged'], | 1412 | self.assertEqual(self.ui.backend._signals['FileSyncStatusChanged'], |
553 | @@ -1461,35 +1471,36 @@ | |||
554 | 1461 | """The test suite for a desktopcouch service.""" | 1471 | """The test suite for a desktopcouch service.""" |
555 | 1462 | 1472 | ||
556 | 1463 | klass = gui.DesktopcouchService | 1473 | klass = gui.DesktopcouchService |
557 | 1474 | enabled = True | ||
558 | 1464 | 1475 | ||
559 | 1465 | def setUp(self): | 1476 | def setUp(self): |
563 | 1466 | self.replication = FakedReplication() | 1477 | self.kwargs['enabled'] = self.enabled |
561 | 1467 | self.name = self.kwargs['name'] | ||
562 | 1468 | self.kwargs['replication_service'] = self.replication | ||
564 | 1469 | super(DesktopcouchServiceTestCase, self).setUp() | 1478 | super(DesktopcouchServiceTestCase, self).setUp() |
565 | 1470 | 1479 | ||
566 | 1480 | def modify_settings(self): | ||
567 | 1481 | """Modify settings so values actually change.""" | ||
568 | 1482 | self.ui.button.set_active(not self.ui.button.get_active()) | ||
569 | 1483 | |||
570 | 1484 | def test_backend_account_signals(self): | ||
571 | 1485 | """The proper signals are connected to the backend.""" | ||
572 | 1486 | self.assertEqual( | ||
573 | 1487 | self.ui.backend._signals['ReplicationSettingsChanged'], | ||
574 | 1488 | [self.ui.on_replication_settings_changed]) | ||
575 | 1489 | self.assertEqual( | ||
576 | 1490 | self.ui.backend._signals['ReplicationSettingsChangeError'], | ||
577 | 1491 | [self.ui.on_replication_settings_change_error]) | ||
578 | 1492 | |||
579 | 1471 | def test_active(self): | 1493 | def test_active(self): |
588 | 1472 | """Is active since replication has an empty database.""" | 1494 | """Is active if enabled.""" |
589 | 1473 | self.assertTrue(self.ui.button.get_active()) | 1495 | self.assertEqual(self.enabled, self.ui.button.get_active()) |
582 | 1474 | |||
583 | 1475 | def test_not_active(self): | ||
584 | 1476 | """Is not active since 'name' is excluded on replication database.""" | ||
585 | 1477 | self.replication.exclude(self.name) | ||
586 | 1478 | self.ui = self.klass(**self.kwargs) | ||
587 | 1479 | self.assertFalse(self.ui.button.get_active()) | ||
590 | 1480 | 1496 | ||
591 | 1481 | def test_on_button_toggled(self): | 1497 | def test_on_button_toggled(self): |
592 | 1482 | """When toggling the button, the DC exclude list is updated.""" | 1498 | """When toggling the button, the DC exclude list is updated.""" |
593 | 1483 | assert self.ui.button.get_active() | ||
594 | 1484 | self.ui.button.set_active(not self.ui.button.get_active()) | 1499 | self.ui.button.set_active(not self.ui.button.get_active()) |
595 | 1485 | self.assertEqual(set([self.name]), self.replication.all_exclusions()) | ||
596 | 1486 | 1500 | ||
603 | 1487 | def test_on_button_toggled_twice(self): | 1501 | args = (self.service_id, |
604 | 1488 | """When toggling the button twice, the DC exclude list is updated.""" | 1502 | {'enabled': gui.bool_str(self.ui.button.get_active())}) |
605 | 1489 | assert self.ui.button.get_active() | 1503 | self.assert_backend_called('change_replication_settings', args) |
600 | 1490 | self.ui.button.set_active(not self.ui.button.get_active()) | ||
601 | 1491 | self.ui.button.set_active(not self.ui.button.get_active()) | ||
602 | 1492 | self.assertEqual(set(), self.replication.all_exclusions()) | ||
606 | 1493 | 1504 | ||
607 | 1494 | def test_dependency(self): | 1505 | def test_dependency(self): |
608 | 1495 | """The dependency box is None.""" | 1506 | """The dependency box is None.""" |
609 | @@ -1499,6 +1510,72 @@ | |||
610 | 1499 | """The check button is sensitive.""" | 1510 | """The check button is sensitive.""" |
611 | 1500 | self.assertTrue(self.ui.button.get_sensitive()) | 1511 | self.assertTrue(self.ui.button.get_sensitive()) |
612 | 1501 | 1512 | ||
613 | 1513 | def test_on_replication_settings_changed(self): | ||
614 | 1514 | """When settings were changed for this replication, enable it.""" | ||
615 | 1515 | new_val = not self.ui.button.get_active() | ||
616 | 1516 | self.ui.button.set_active(new_val) | ||
617 | 1517 | |||
618 | 1518 | self.ui.on_replication_settings_changed(replication_id=self.ui.id) | ||
619 | 1519 | |||
620 | 1520 | self.assertEqual(self.ui.warning_label.get_text(), '') | ||
621 | 1521 | self.assertEqual(new_val, self.ui.button.get_active()) | ||
622 | 1522 | |||
623 | 1523 | def test_on_replication_settings_changed_after_error(self): | ||
624 | 1524 | """Change success after error.""" | ||
625 | 1525 | self.ui.button.set_active(not self.ui.button.get_active()) | ||
626 | 1526 | self.ui.on_replication_settings_change_error(replication_id=self.ui.id) | ||
627 | 1527 | |||
628 | 1528 | self.test_on_replication_settings_changed() | ||
629 | 1529 | |||
630 | 1530 | def test_on_replication_settings_changed_different_id(self): | ||
631 | 1531 | """When settings were changed for other rep, nothing changes.""" | ||
632 | 1532 | self.ui.button.set_active(not self.ui.button.get_active()) | ||
633 | 1533 | self.ui.on_replication_settings_changed(replication_id='yadda') | ||
634 | 1534 | |||
635 | 1535 | self.assertEqual(self.ui.warning_label.get_text(), '') | ||
636 | 1536 | |||
637 | 1537 | def test_on_replication_settings_changed_different_id_after_error(self): | ||
638 | 1538 | """When settings were changed for other + error, nothing changes.""" | ||
639 | 1539 | self.ui.on_replication_settings_change_error(replication_id=self.ui.id) | ||
640 | 1540 | self.ui.on_replication_settings_changed(replication_id='yadda') | ||
641 | 1541 | |||
642 | 1542 | self.assert_warning_correct(self.ui.warning_label, | ||
643 | 1543 | self.ui.CHANGE_ERROR) | ||
644 | 1544 | |||
645 | 1545 | def test_on_replication_settings_change_error(self): | ||
646 | 1546 | """When settings were not changed, notify the user. | ||
647 | 1547 | |||
648 | 1548 | Also, confirm that old value was restored. | ||
649 | 1549 | |||
650 | 1550 | """ | ||
651 | 1551 | old_val = self.ui.button.get_active() | ||
652 | 1552 | self.ui.button.set_active(not old_val) | ||
653 | 1553 | self.ui.on_replication_settings_change_error(replication_id=self.ui.id) | ||
654 | 1554 | |||
655 | 1555 | self.assert_warning_correct(self.ui.warning_label, | ||
656 | 1556 | self.ui.CHANGE_ERROR) | ||
657 | 1557 | self.assertEqual(old_val, self.ui.button.get_active()) | ||
658 | 1558 | |||
659 | 1559 | def test_on_replication_settings_change_error_after_success(self): | ||
660 | 1560 | """Change error after success.""" | ||
661 | 1561 | self.ui.button.set_active(not self.ui.button.get_active()) | ||
662 | 1562 | self.ui.on_replication_settings_changed(replication_id=self.ui.id) | ||
663 | 1563 | |||
664 | 1564 | self.test_on_replication_settings_change_error() | ||
665 | 1565 | |||
666 | 1566 | def test_on_replication_settings_change_error_different_id(self): | ||
667 | 1567 | """When settings were not changed for other replication, do nothing.""" | ||
668 | 1568 | self.ui.button.set_active(not self.ui.button.get_active()) | ||
669 | 1569 | self.ui.on_replication_settings_change_error(replication_id='yudo') | ||
670 | 1570 | |||
671 | 1571 | self.assertEqual(self.ui.warning_label.get_text(), '') | ||
672 | 1572 | |||
673 | 1573 | |||
674 | 1574 | class DesktopcouchServiceDisabledAtStartupTestCase(ServiceTestCase): | ||
675 | 1575 | """The test suite for a desktopcouch service when enabled=False.""" | ||
676 | 1576 | |||
677 | 1577 | enabled = False | ||
678 | 1578 | |||
679 | 1502 | 1579 | ||
680 | 1503 | class DesktopcouchServiceWithDependencyTestCase(DesktopcouchServiceTestCase): | 1580 | class DesktopcouchServiceWithDependencyTestCase(DesktopcouchServiceTestCase): |
681 | 1504 | """The test suite for a desktopcouch service when it needs a dependency.""" | 1581 | """The test suite for a desktopcouch service when it needs a dependency.""" |
682 | @@ -1532,7 +1609,8 @@ | |||
683 | 1532 | self.ui.dependency.emit('finished') | 1609 | self.ui.dependency.emit('finished') |
684 | 1533 | 1610 | ||
685 | 1534 | self.assertTrue(self.ui.dependency is None) | 1611 | self.assertTrue(self.ui.dependency is None) |
687 | 1535 | self.assertEqual(self.ui.get_children(), [self.ui.button]) | 1612 | self.assertEqual(sorted(self.ui.get_children()), |
688 | 1613 | sorted([self.ui.button, self.ui.warning_label])) | ||
689 | 1536 | 1614 | ||
690 | 1537 | 1615 | ||
691 | 1538 | class ServicesTestCase(ControlPanelMixinTestCase): | 1616 | class ServicesTestCase(ControlPanelMixinTestCase): |
692 | @@ -1562,6 +1640,13 @@ | |||
693 | 1562 | """The install box is None.""" | 1640 | """The install box is None.""" |
694 | 1563 | self.assertTrue(self.ui.install_box is None) | 1641 | self.assertTrue(self.ui.install_box is None) |
695 | 1564 | 1642 | ||
696 | 1643 | def test_backend_signals(self): | ||
697 | 1644 | """The proper signals are connected to the backend.""" | ||
698 | 1645 | self.assertEqual(self.ui.backend._signals['ReplicationsInfoReady'], | ||
699 | 1646 | [self.ui.on_replications_info_ready]) | ||
700 | 1647 | self.assertEqual(self.ui.backend._signals['ReplicationsInfoError'], | ||
701 | 1648 | [self.ui.on_replications_info_error]) | ||
702 | 1649 | |||
703 | 1565 | 1650 | ||
704 | 1566 | class ServicesFilesTestCase(ServicesTestCase): | 1651 | class ServicesFilesTestCase(ServicesTestCase): |
705 | 1567 | """The test suite for the services panel (files section).""" | 1652 | """The test suite for the services panel (files section).""" |
706 | @@ -1589,22 +1674,10 @@ | |||
707 | 1589 | self.assertFalse(self.ui.message.active) | 1674 | self.assertFalse(self.ui.message.active) |
708 | 1590 | self.assertEqual(self.ui.message.get_text(), '') | 1675 | self.assertEqual(self.ui.message.get_text(), '') |
709 | 1591 | 1676 | ||
710 | 1592 | def test_replication_service(self): | ||
711 | 1593 | """Has a replication service.""" | ||
712 | 1594 | self.assertEqual(self.ui.replication_service, None) | ||
713 | 1595 | |||
714 | 1596 | def test_has_desktopcouch(self): | 1677 | def test_has_desktopcouch(self): |
715 | 1597 | """Has desktopcouch installed?""" | 1678 | """Has desktopcouch installed?""" |
716 | 1598 | self.assertFalse(self.ui.has_desktopcouch) | 1679 | self.assertFalse(self.ui.has_desktopcouch) |
717 | 1599 | 1680 | ||
718 | 1600 | def test_has_bindwood(self): | ||
719 | 1601 | """Has bindwood installed?""" | ||
720 | 1602 | self.assertFalse(self.ui.has_bindwood) | ||
721 | 1603 | |||
722 | 1604 | def test_has_evocouch(self): | ||
723 | 1605 | """Has evocouch installed?""" | ||
724 | 1606 | self.assertFalse(self.ui.has_evocouch) | ||
725 | 1607 | |||
726 | 1608 | def test_install_box_is_hidden(self): | 1681 | def test_install_box_is_hidden(self): |
727 | 1609 | """The install box is not hidden.""" | 1682 | """The install box is not hidden.""" |
728 | 1610 | self.assertTrue(self.ui.install_box.get_visible()) | 1683 | self.assertTrue(self.ui.install_box.get_visible()) |
729 | @@ -1629,41 +1702,27 @@ | |||
730 | 1629 | 1702 | ||
731 | 1630 | self.assertEqual(self._called, ((self.ui.install_box,), {})) | 1703 | self.assertEqual(self._called, ((self.ui.install_box,), {})) |
732 | 1631 | 1704 | ||
733 | 1705 | def test_load_replications(self): | ||
734 | 1706 | """The load_replications starts the spinner and calls the backend.""" | ||
735 | 1707 | self.ui.load_replications() | ||
736 | 1708 | |||
737 | 1709 | self.assertTrue(self.ui.message.active) | ||
738 | 1710 | self.assert_backend_called('replications_info', ()) | ||
739 | 1711 | |||
740 | 1632 | 1712 | ||
741 | 1633 | class ServicesWithDesktopcouchTestCase(ServicesTestCase): | 1713 | class ServicesWithDesktopcouchTestCase(ServicesTestCase): |
742 | 1634 | """The test suite for the services panel.""" | 1714 | """The test suite for the services panel.""" |
743 | 1635 | 1715 | ||
744 | 1636 | kwargs = {'replication_exclusion_class': FakedReplication} | ||
745 | 1637 | |||
746 | 1638 | def setUp(self): | 1716 | def setUp(self): |
747 | 1639 | super(ServicesWithDesktopcouchTestCase, self).setUp() | 1717 | super(ServicesWithDesktopcouchTestCase, self).setUp() |
748 | 1640 | self.ui.package_manager._installed[self.ui.DESKTOPCOUCH_PKG] = True | 1718 | self.ui.package_manager._installed[self.ui.DESKTOPCOUCH_PKG] = True |
750 | 1641 | self.ui.load() | 1719 | self.ui.on_replications_info_ready(info=FAKE_REPLICATIONS_INFO) |
751 | 1642 | 1720 | ||
752 | 1643 | def test_message(self): | 1721 | def test_message(self): |
753 | 1644 | """Global load message is stopped and proper test is shown.""" | 1722 | """Global load message is stopped and proper test is shown.""" |
754 | 1645 | self.assertFalse(self.ui.message.active) | 1723 | self.assertFalse(self.ui.message.active) |
755 | 1646 | self.assertEqual(self.ui.message.get_text(), self.ui.CHOOSE_SERVICES) | 1724 | self.assertEqual(self.ui.message.get_text(), self.ui.CHOOSE_SERVICES) |
756 | 1647 | 1725 | ||
757 | 1648 | def test_replication_service(self): | ||
758 | 1649 | """Has a replication service.""" | ||
759 | 1650 | self.assertIsInstance(self.ui.replication_service, FakedReplication) | ||
760 | 1651 | |||
761 | 1652 | def test_no_pairing_record(self): | ||
762 | 1653 | """The pairing record is not in place.""" | ||
763 | 1654 | |||
764 | 1655 | def no_pairing_record(*a): | ||
765 | 1656 | """Fake a ReplicationExclusion with no pairing record.""" | ||
766 | 1657 | raise ValueError("No pairing record for ubuntuone.") | ||
767 | 1658 | |||
768 | 1659 | self.ui.replication_exclusion_class = no_pairing_record | ||
769 | 1660 | self.ui.replication_service = None | ||
770 | 1661 | self.ui.load() | ||
771 | 1662 | |||
772 | 1663 | self.assertEqual(self.ui.replications.get_children(), []) | ||
773 | 1664 | self.assertFalse(self.ui.message.active) | ||
774 | 1665 | self.assert_warning_correct(self.ui.message, self.ui.NO_PAIRING_RECORD) | ||
775 | 1666 | |||
776 | 1667 | def test_has_desktopcouch(self): | 1726 | def test_has_desktopcouch(self): |
777 | 1668 | """Has desktopcouch installed?""" | 1727 | """Has desktopcouch installed?""" |
778 | 1669 | self.assertTrue(self.ui.has_desktopcouch) | 1728 | self.assertTrue(self.ui.has_desktopcouch) |
779 | @@ -1673,79 +1732,67 @@ | |||
780 | 1673 | self.assertTrue(self.ui.replications.get_visible()) | 1732 | self.assertTrue(self.ui.replications.get_visible()) |
781 | 1674 | 1733 | ||
782 | 1675 | children = self.ui.replications.get_children() | 1734 | children = self.ui.replications.get_children() |
785 | 1676 | self.assertEqual(len(children), 2) | 1735 | self.assertEqual(len(children), len(FAKE_REPLICATIONS_INFO)) |
786 | 1677 | for child in children: | 1736 | for expected, child in zip(FAKE_REPLICATIONS_INFO, children): |
787 | 1678 | self.assertIsInstance(child, gui.DesktopcouchService) | 1737 | self.assertIsInstance(child, gui.DesktopcouchService) |
795 | 1679 | 1738 | self.assertEqual(expected['replication_id'], child.id) | |
796 | 1680 | self.assertTrue(self.ui.bookmarks is children[0]) | 1739 | self.assertEqual(expected['name'], child.button.get_label()) |
797 | 1681 | self.assertTrue(self.ui.contacts is children[1]) | 1740 | self.assertEqual(bool(expected['enabled']), |
798 | 1682 | 1741 | child.button.get_active()) | |
799 | 1683 | def test_replications_after_loading_twice(self): | 1742 | |
800 | 1684 | """Has proper child after loading twice.""" | 1743 | if expected['dependency']: |
801 | 1685 | self.ui.load() | 1744 | self.assertTrue(child.dependency is not None) |
802 | 1745 | self.assertEqual(expected['dependency'], | ||
803 | 1746 | child.dependency.package_name) | ||
804 | 1747 | else: | ||
805 | 1748 | self.assertTrue(child.dependency is None) | ||
806 | 1749 | |||
807 | 1750 | def test_replications_after_getting_info_twice(self): | ||
808 | 1751 | """Has proper child after getting backend info twice.""" | ||
809 | 1752 | self.ui.on_replications_info_ready(info=FAKE_REPLICATIONS_INFO) | ||
810 | 1686 | self.test_replications() | 1753 | self.test_replications() |
811 | 1687 | 1754 | ||
873 | 1688 | def test_bookmarks(self): | 1755 | |
874 | 1689 | """The bookmarks is correct.""" | 1756 | class ServicesWithDesktopcouchErrorTestCase(ServicesTestCase): |
875 | 1690 | self.assertEqual(self.ui.bookmarks.service_name, 'bookmarks') | 1757 | """The test suite for the services panel.""" |
876 | 1691 | self.assertEqual(self.ui.bookmarks.button.get_label(), | 1758 | |
877 | 1692 | self.ui.BOOKMARKS) | 1759 | def setUp(self): |
878 | 1693 | self.assertTrue(self.ui.bookmarks.replication_service is | 1760 | super(ServicesWithDesktopcouchErrorTestCase, self).setUp() |
879 | 1694 | self.ui.replication_service) | 1761 | self.ui.package_manager._installed[self.ui.DESKTOPCOUCH_PKG] = True |
880 | 1695 | 1762 | ||
881 | 1696 | def test_bookmarks_dependency(self): | 1763 | def test_no_pairing_record(self): |
882 | 1697 | """The bookmarks dependency is correct.""" | 1764 | """The pairing record is not in place.""" |
883 | 1698 | self.assertTrue(self.ui.bookmarks.dependency is not None) | 1765 | error_dict = {'error_type': 'NoPairingRecord'} |
884 | 1699 | self.assertEqual(self.ui.bookmarks.dependency.package_name, | 1766 | self.ui.on_replications_info_error(error_dict) |
885 | 1700 | self.ui.BINDWOOD_PKG) | 1767 | |
886 | 1701 | 1768 | self.assertEqual(self.ui.replications.get_children(), []) | |
887 | 1702 | def test_contacts(self): | 1769 | self.assertFalse(self.ui.message.active) |
888 | 1703 | """The contacts is correct.""" | 1770 | self.assert_warning_correct(self.ui.message, self.ui.NO_PAIRING_RECORD) |
889 | 1704 | self.assertEqual(self.ui.contacts.service_name, 'contacts') | 1771 | |
890 | 1705 | self.assertEqual(self.ui.contacts.button.get_label(), | 1772 | def test_other_error(self): |
891 | 1706 | self.ui.CONTACTS) | 1773 | """There was an error other than no pairing record.""" |
892 | 1707 | self.assertTrue(self.ui.contacts.replication_service is | 1774 | error_dict = {'error_type': 'OtherError'} |
893 | 1708 | self.ui.replication_service) | 1775 | self.ui.on_replications_info_error(error_dict) |
894 | 1709 | 1776 | ||
895 | 1710 | def test_contacts_dependency(self): | 1777 | self.assertEqual(self.ui.replications.get_children(), []) |
896 | 1711 | """The contacts dependency is correct.""" | 1778 | self.assertFalse(self.ui.message.active) |
897 | 1712 | self.assertTrue(self.ui.contacts.dependency is not None) | 1779 | self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
898 | 1713 | self.assertEqual(self.ui.contacts.dependency.package_name, | 1780 | |
899 | 1714 | self.ui.EVOCOUCH_PKG) | 1781 | def test_empty_dict(self): |
900 | 1715 | 1782 | """Handle empty dicts errors.""" | |
901 | 1716 | 1783 | self.ui.on_replications_info_error(error_dict={}) | |
902 | 1717 | class ServicesWithDCAndBindwoodTestCase(ServicesWithDesktopcouchTestCase): | 1784 | |
903 | 1718 | """The test suite for the services panel.""" | 1785 | self.assertEqual(self.ui.replications.get_children(), []) |
904 | 1719 | 1786 | self.assertFalse(self.ui.message.active) | |
905 | 1720 | def setUp(self): | 1787 | self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) |
906 | 1721 | super(ServicesWithDCAndBindwoodTestCase, self).setUp() | 1788 | |
907 | 1722 | self.ui.package_manager._installed[self.ui.BINDWOOD_PKG] = True | 1789 | def test_error_dict_none(self): |
908 | 1723 | self.ui.load() | 1790 | """HGandle empty dicts errors.""" |
909 | 1724 | 1791 | self.ui.on_replications_info_error(error_dict=None) | |
910 | 1725 | def test_has_bindwood(self): | 1792 | |
911 | 1726 | """Has bindwood installed?""" | 1793 | self.assertEqual(self.ui.replications.get_children(), []) |
912 | 1727 | self.assertTrue(self.ui.has_bindwood) | 1794 | self.assertFalse(self.ui.message.active) |
913 | 1728 | 1795 | self.assert_warning_correct(self.ui.message, gui.VALUE_ERROR) | |
853 | 1729 | def test_bookmarks_dependency(self): | ||
854 | 1730 | """The bookmarks dependency is correct.""" | ||
855 | 1731 | self.assertTrue(self.ui.bookmarks.dependency is None) | ||
856 | 1732 | |||
857 | 1733 | |||
858 | 1734 | class ServicesWithDCAndEvocouchTestCase(ServicesWithDesktopcouchTestCase): | ||
859 | 1735 | """The test suite for the services panel.""" | ||
860 | 1736 | |||
861 | 1737 | def setUp(self): | ||
862 | 1738 | super(ServicesWithDCAndEvocouchTestCase, self).setUp() | ||
863 | 1739 | self.ui.package_manager._installed[self.ui.EVOCOUCH_PKG] = True | ||
864 | 1740 | self.ui.load() | ||
865 | 1741 | |||
866 | 1742 | def test_has_evocouch(self): | ||
867 | 1743 | """Has evocoucg installed?""" | ||
868 | 1744 | self.assertTrue(self.ui.has_evocouch) | ||
869 | 1745 | |||
870 | 1746 | def test_contacts_dependency(self): | ||
871 | 1747 | """The bookmarks dependency is correct.""" | ||
872 | 1748 | self.assertTrue(self.ui.contacts.dependency is None) | ||
914 | 1749 | 1796 | ||
915 | 1750 | 1797 | ||
916 | 1751 | class ManagementPanelTestCase(ControlPanelMixinTestCase): | 1798 | class ManagementPanelTestCase(ControlPanelMixinTestCase): |
917 | 1752 | 1799 | ||
918 | === modified file 'ubuntuone/controlpanel/logger.py' | |||
919 | --- ubuntuone/controlpanel/logger.py 2010-12-23 18:20:56 +0000 | |||
920 | +++ ubuntuone/controlpanel/logger.py 2011-01-06 21:03:06 +0000 | |||
921 | @@ -53,10 +53,7 @@ | |||
922 | 53 | logger.addHandler(MAIN_HANDLER) | 53 | logger.addHandler(MAIN_HANDLER) |
923 | 54 | if os.environ.get('DEBUG'): | 54 | if os.environ.get('DEBUG'): |
924 | 55 | debug_handler = logging.StreamHandler(sys.stderr) | 55 | debug_handler = logging.StreamHandler(sys.stderr) |
929 | 56 | if prefix is not None: | 56 | debug_handler.setFormatter(basic_formatter) |
926 | 57 | fmt = prefix + "%(name)s - %(levelname)s\n%(message)s\n" | ||
927 | 58 | formatter = logging.Formatter(fmt) | ||
928 | 59 | debug_handler.setFormatter(formatter) | ||
930 | 60 | logger.addHandler(debug_handler) | 57 | logger.addHandler(debug_handler) |
931 | 61 | 58 | ||
932 | 62 | return logger | 59 | return logger |
Works as advertised, code looks good. I don't like the desktopcouch pairing functionality as it stands, but that's in the design, so we'll discuss elsewhere.