Merge lp:~nataliabidart/ubuntuone-control-panel/new-creds into lp:ubuntuone-control-panel

Proposed by Natalia Bidart on 2011-08-18
Status: Merged
Approved by: Natalia Bidart on 2011-08-19
Approved revision: 203
Merged at revision: 201
Proposed branch: lp:~nataliabidart/ubuntuone-control-panel/new-creds
Merge into: lp:ubuntuone-control-panel
Diff against target: 996 lines (+285/-203)
8 files modified
run-tests (+4/-2)
setup.py (+12/-6)
ubuntuone/controlpanel/gui/gtk/gui.py (+46/-70)
ubuntuone/controlpanel/gui/gtk/tests/__init__.py (+12/-14)
ubuntuone/controlpanel/gui/gtk/tests/test_gui.py (+19/-19)
ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py (+126/-81)
ubuntuone/controlpanel/login_client.py (+18/-5)
ubuntuone/controlpanel/tests/test_login_client.py (+48/-6)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-control-panel/new-creds
Reviewer Review Type Date Requested Status
John Lenton Approve on 2011-08-18
Roberto Alsina (community) 2011-08-18 Approve on 2011-08-18
Review via email: mp+72077@code.launchpad.net

Commit message

- Using CredentialsManagementTool instead of SSO dbus backend (LP: #828805).

To post a comment you must log in.
Roberto Alsina (ralsina) wrote :

+1

review: Approve
John Lenton (chipaca) wrote :

Good.

What does GTK_MODULES break?

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'run-tests'
2--- run-tests 2011-07-15 17:50:50 +0000
3+++ run-tests 2011-08-18 17:23:16 +0000
4@@ -37,14 +37,16 @@
5 fi
6
7 style_check() {
8- u1lint --ignore ubuntuone/controlpanel/gui/qt/ui ubuntuone/
9+ u1lint --ignore ubuntuone/controlpanel/gui/qt/ui
10 if [ -x `which pep8` ]; then
11- pep8 --exclude '.svn,CVS,.bzr,.hg,.git,*_ui.py,*_rc.py' --repeat bin/ $MODULE
12+ pep8 --exclude '.svn,CVS,.bzr,.hg,.git,*_ui.py,*_rc.py' --repeat .
13 else
14 echo "Please install the 'pep8' package."
15 fi
16 }
17
18+unset GTK_MODULES
19+
20 ./setup.py build
21 echo "Running test suite for ""$MODULE"
22 if [ "$USE_QT" -eq 0 ]; then
23
24=== modified file 'setup.py'
25--- setup.py 2011-08-12 19:09:02 +0000
26+++ setup.py 2011-08-18 17:23:16 +0000
27@@ -46,6 +46,7 @@
28 CLEANFILES = [
29 SERVICE_FILE, GUI_SERVICE_FILE, MESSAGE_ENTRY, CONSTANTS, POT_FILE,
30 'MANIFEST']
31+QT_UI_DIR = os.path.join('ubuntuone', 'controlpanel', 'gui', 'qt', 'ui')
32
33
34 def replace_prefix(prefix):
35@@ -64,7 +65,7 @@
36 def run(self):
37 """Do the install.
38
39- Read from *.service.in and generate .service files with reeplacing
40+ Read from *.service.in and generate .service files by replacing
41 @prefix@ by self.prefix.
42
43 """
44@@ -75,7 +76,6 @@
45 class ControlPanelBuild(build_extra.build_extra):
46 """Build PyQt (.ui) files and resources."""
47
48- QT_UI_DIR = os.path.join('ubuntuone', 'controlpanel', 'gui', 'qt', 'ui')
49 description = "build PyQt GUIs (.ui) and resources (.qrc)"
50
51 def compile_ui(self, ui_file, py_file=None):
52@@ -86,7 +86,7 @@
53 # python file in the qt moodule
54 py_file = os.path.split(ui_file)[1]
55 py_file = os.path.splitext(py_file)[0] + '_ui.py'
56- py_file = os.path.join(self.QT_UI_DIR, py_file)
57+ py_file = os.path.join(QT_UI_DIR, py_file)
58 # we indeed want to catch Exception, is ugly but we need it
59 # pylint: disable=W0703
60 try:
61@@ -112,7 +112,7 @@
62 if py_file is None:
63 py_file = os.path.split(qrc_file)[1]
64 py_file = os.path.splitext(py_file)[0] + '_rc.py'
65- py_file = os.path.join(self.QT_UI_DIR, py_file)
66+ py_file = os.path.join(QT_UI_DIR, py_file)
67 path = os.getenv('PATH')
68 os.putenv('PATH', path + os.path.pathsep + os.path.join(
69 os.path.dirname(PyQt4.__file__), 'bin'))
70@@ -218,6 +218,12 @@
71 if os.path.exists(built_file):
72 os.unlink(built_file)
73
74+ for dirpath, _, filenames in os.walk(os.path.join(QT_UI_DIR)):
75+ for current_file in filenames:
76+ if current_file.endswith('_ui.py') or\
77+ current_file.endswith('_rc.py'):
78+ os.unlink(os.path.join(dirpath, current_file))
79+
80 DistUtilsExtra.auto.clean_build_tree.run(self)
81
82
83@@ -228,8 +234,8 @@
84 author='Natalia Bidart',
85 author_email='natalia.bidart@canonical.com',
86 description='Ubuntu One Control Panel',
87- long_description='Application to manage a Ubuntu One account. Provides a'\
88- 'DBus service to query/modify all the Ubuntu One bits.',
89+ long_description='Application to manage a Ubuntu One account. Provides' \
90+ ' a DBus service to query/modify all the Ubuntu One bits.',
91 url='https://launchpad.net/ubuntuone-control-panel',
92 packages=[
93 'ubuntuone', 'ubuntuone.controlpanel', 'ubuntuone.controlpanel.gui',
94
95=== modified file 'ubuntuone/controlpanel/gui/gtk/gui.py'
96--- ubuntuone/controlpanel/gui/gtk/gui.py 2011-06-01 18:10:22 +0000
97+++ ubuntuone/controlpanel/gui/gtk/gui.py 2011-08-18 17:23:16 +0000
98@@ -28,17 +28,15 @@
99 import dbus
100 import gtk
101 import gobject
102-import ubuntu_sso
103
104 from dbus.mainloop.glib import DBusGMainLoop
105 from ubuntu_sso import networkstate
106-from ubuntu_sso.credentials import (TC_URL_KEY, HELP_TEXT_KEY, WINDOW_ID_KEY,
107- PING_URL_KEY)
108-# No name 'clientdefs' in module 'ubuntuone'
109 # pylint: disable=E0611,F0401
110 from gi.repository import GLib
111-from ubuntuone.clientdefs import (APP_NAME as U1_APP_NAME, TC_URL as U1_TC_URL,
112- PING_URL as U1_PING_URL, DESCRIPTION as U1_DESCRIPTION)
113+from ubuntuone.platform.credentials import (
114+ APP_NAME as U1_APP_NAME,
115+ CredentialsManagementTool,
116+)
117 # pylint: enable=E0611,F0401
118
119 # Wildcard import ubuntuone.controlpanel.gui
120@@ -123,21 +121,6 @@
121 gtk.main()
122
123
124-def filter_by_app_name(f):
125- """Excecute 'f' filtering by app_name."""
126-
127- @wraps(f)
128- def filter_by_app_name_inner(instance, app_name, *args, **kwargs):
129- """Execute 'f' only if 'app_name' matches 'U1_APP_NAME'."""
130- if app_name == U1_APP_NAME:
131- return f(instance, app_name, *args, **kwargs)
132- else:
133- logger.info('%s: ignoring call since received app_name '\
134- '"%s" (expected "%s")',
135- f.__name__, app_name, U1_APP_NAME)
136- return filter_by_app_name_inner
137-
138-
139 def on_size_allocate(widget, allocation, label):
140 """Resize labels according to who 'widget' is being resized."""
141 label.set_size_request(allocation.width - 2, -1)
142@@ -272,23 +255,9 @@
143
144 def __init__(self, main_window):
145 GreyableBin.__init__(self)
146-
147- sso_backend = None
148- bus = dbus.SessionBus()
149- try:
150- obj = bus.get_object(ubuntu_sso.DBUS_BUS_NAME,
151- ubuntu_sso.DBUS_CREDENTIALS_PATH,
152- follow_name_owner_changes=True)
153- iface = ubuntu_sso.DBUS_CREDENTIALS_IFACE
154- sso_backend = dbus.Interface(obj, dbus_interface=iface)
155- except dbus.exceptions.DBusException:
156- logger.exception('Can not connect to DBus at %r',
157- (ubuntu_sso.DBUS_BUS_NAME,
158- ubuntu_sso.DBUS_CREDENTIALS_PATH))
159- raise
160-
161+ creds_backend = CredentialsManagementTool()
162 ControlPanelMixin.__init__(self, filename='overview.ui',
163- backend_instance=sso_backend)
164+ backend_instance=creds_backend)
165 self.add(self.itself)
166 self.banner.set_from_file(get_data_file(OVERVIEW_BANNER))
167 self.files_icon.set_from_file(get_data_file(FILES_ICON))
168@@ -305,15 +274,6 @@
169 self._credentials_are_new = False
170 self.show()
171
172- self.backend.connect_to_signal('CredentialsFound',
173- self.on_credentials_found)
174- self.backend.connect_to_signal('CredentialsNotFound',
175- self.on_credentials_not_found)
176- self.backend.connect_to_signal('CredentialsError',
177- self.on_credentials_error)
178- self.backend.connect_to_signal('AuthorizationDenied',
179- self.on_authorization_denied)
180-
181 kw = dict(result_cb=self.on_network_state_changed)
182 self.network_manager_state = networkstate.NetworkManagerState(**kw)
183 self.network_manager_state.find_online_state()
184@@ -323,6 +283,14 @@
185 ControlPanelMixin._set_warning(self, message,
186 label=self.warning_label)
187
188+ def _window_xid(self):
189+ """Return settings for credentials backend."""
190+ if self.main_window.window is not None:
191+ settings = {'window_id': str(self.main_window.window.xid)}
192+ else:
193+ settings = {}
194+ return settings
195+
196 def set_property(self, prop_name, new_value):
197 """Override 'set_property' to disable buttons if prop is 'greyed'."""
198 if prop_name == 'greyed':
199@@ -342,21 +310,17 @@
200
201 def on_join_now_button_clicked(self, *a, **kw):
202 """User wants to join now."""
203- settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION,
204- WINDOW_ID_KEY: str(self.main_window.window.xid),
205- PING_URL_KEY: U1_PING_URL}
206- self.backend.register(U1_APP_NAME, settings,
207- reply_handler=NO_OP, error_handler=error_handler)
208+ d = self.backend.register(**self._window_xid())
209+ d.addCallback(self.on_credentials_result)
210+ d.addErrback(self.on_credentials_error)
211 self.set_property('greyed', True)
212 self.warning_label.set_text('')
213
214 def on_connect_button_clicked(self, *a, **kw):
215 """User wants to connect now."""
216- settings = {TC_URL_KEY: U1_TC_URL, HELP_TEXT_KEY: U1_DESCRIPTION,
217- WINDOW_ID_KEY: str(self.main_window.window.xid),
218- PING_URL_KEY: U1_PING_URL}
219- self.backend.login(U1_APP_NAME, settings,
220- reply_handler=NO_OP, error_handler=error_handler)
221+ d = self.backend.login(**self._window_xid())
222+ d.addCallback(self.on_credentials_result)
223+ d.addErrback(self.on_credentials_error)
224 self.set_property('greyed', True)
225 self.warning_label.set_text('')
226
227@@ -364,31 +328,42 @@
228 """User wants to learn more."""
229 uri_hook(self.learn_more_button, LEARN_MORE_LINK)
230
231- @filter_by_app_name
232+ def on_credentials_result(self, result):
233+ """Process the credentials response.
234+
235+ If 'result' is a non empty dict, they were found.
236+ If 'result' is an empty dict, they were not found.
237+ If 'result' is None, the user cancelled the process.
238+
239+ """
240+ if result is None:
241+ self.on_authorization_denied()
242+ elif result == {}:
243+ self.on_credentials_not_found()
244+ else:
245+ self.on_credentials_found(result)
246+
247 @log_call(logger.info, with_args=False)
248- def on_credentials_found(self, app_name, credentials):
249- """SSO backend notifies of credentials found."""
250+ def on_credentials_found(self, credentials):
251+ """Credentials backend notifies of credentials found."""
252 self.set_property('greyed', False)
253 self.emit('credentials-found', self._credentials_are_new, credentials)
254
255- @filter_by_app_name
256 @log_call(logger.info)
257- def on_credentials_not_found(self, app_name):
258- """SSO backend notifies of credentials not found."""
259+ def on_credentials_not_found(self):
260+ """Creds backend notifies of credentials not found."""
261 self._credentials_are_new = True
262 self.set_property('greyed', False)
263
264- @filter_by_app_name
265 @log_call(logger.error)
266- def on_credentials_error(self, app_name, error_dict):
267- """SSO backend notifies of an error when fetching credentials."""
268+ def on_credentials_error(self, error_dict):
269+ """Creds backend notifies of an error when fetching credentials."""
270 self.set_property('greyed', False)
271 self._set_warning(CREDENTIALS_ERROR)
272
273- @filter_by_app_name
274 @log_call(logger.info)
275- def on_authorization_denied(self, app_name):
276- """SSO backend notifies that user refused auth for 'app_name'."""
277+ def on_authorization_denied(self):
278+ """Creds backend notifies that user refused auth for 'app_name'."""
279 self.set_property('greyed', False)
280
281 @log_call(logger.info)
282@@ -402,8 +377,9 @@
283 else:
284 self.set_sensitive(True)
285 self.warning_label.set_text(msg)
286- self.backend.find_credentials(U1_APP_NAME, {},
287- reply_handler=NO_OP, error_handler=error_handler)
288+ d = self.backend.find_credentials()
289+ d.addCallback(self.on_credentials_result)
290+ d.addErrback(self.on_credentials_error)
291
292
293 class DashboardPanel(UbuntuOneBin, ControlPanelMixin):
294
295=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/__init__.py'
296--- ubuntuone/controlpanel/gui/gtk/tests/__init__.py 2011-05-26 22:18:04 +0000
297+++ ubuntuone/controlpanel/gui/gtk/tests/__init__.py 2011-08-18 17:23:16 +0000
298@@ -22,6 +22,7 @@
299
300 from collections import defaultdict
301
302+from twisted.internet import defer
303 from ubuntuone.devtools.handlers import MementoHandler
304
305 from ubuntuone.controlpanel.gui.gtk import gui
306@@ -83,14 +84,12 @@
307 self._signals[signal].append(handler)
308
309
310-class FakedSSOBackend(FakedDBusBackend):
311- """Fake a SSO Backend, act as a dbus.Interface."""
312+class FakedCredentialsBackend(FakedObject):
313+ """Fake a credentials backend."""
314
315- bus_name = gui.ubuntu_sso.DBUS_BUS_NAME
316- object_path = gui.ubuntu_sso.DBUS_CREDENTIALS_PATH
317- iface = gui.ubuntu_sso.DBUS_CREDENTIALS_IFACE
318 exposed_methods = ['find_credentials', 'clear_credentials',
319 'login', 'register']
320+ next_result = defer.succeed(None)
321
322
323 class FakedControlPanelBackend(FakedDBusBackend):
324@@ -135,8 +134,6 @@
325 if dbus_interface == gui.DBUS_PREFERENCES_IFACE:
326 return FakedControlPanelBackend(obj, dbus_interface,
327 *args, **kwargs)
328- if dbus_interface == gui.ubuntu_sso.DBUS_CREDENTIALS_IFACE:
329- return FakedSSOBackend(obj, dbus_interface, *args, **kwargs)
330 if dbus_interface == gui.DBUS_IFACE_GUI:
331 return FakeControlPanelBackend(
332 obj, dbus_interface, *args, **kwargs)
333@@ -188,9 +185,11 @@
334 # pylint: disable=E1102
335 klass = None
336 kwargs = {}
337+ backend_is_dbus = True
338
339 def setUp(self):
340 super(BaseTestCase, self).setUp()
341+ self.patch(gui, 'CredentialsManagementTool', FakedCredentialsBackend)
342 self.patch(gui.os.path, 'expanduser',
343 lambda path: path.replace('~', USER_HOME))
344 self.patch(gui.gtk, 'main', lambda: None)
345@@ -221,14 +220,13 @@
346 pb = gui.gtk.gdk.pixbuf_new_from_file(gui.get_data_file(filename))
347 self.assertEqual(image.get_pixbuf().get_pixels(), pb.get_pixels())
348
349- def assert_backend_called(self, method_name, args, backend=None):
350+ def assert_backend_called(self, method_name, *args, **kwargs):
351 """Check that the control panel backend 'method_name' was called."""
352- if backend is None:
353- backend = self.ui.backend
354- self.assertIn(method_name, backend._called)
355- kwargs = {'reply_handler': gui.NO_OP,
356- 'error_handler': gui.error_handler}
357- self.assertEqual(backend._called[method_name], (args, kwargs))
358+ if self.backend_is_dbus:
359+ kwargs = {'reply_handler': gui.NO_OP,
360+ 'error_handler': gui.error_handler}
361+ self.assertIn(method_name, self.ui.backend._called)
362+ self.assertEqual(self.ui.backend._called[method_name], (args, kwargs))
363
364 def assert_warning_correct(self, warning, text):
365 """Check that 'warning' is visible, showing 'text'."""
366
367=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/test_gui.py'
368--- ubuntuone/controlpanel/gui/gtk/tests/test_gui.py 2011-06-01 21:18:46 +0000
369+++ ubuntuone/controlpanel/gui/gtk/tests/test_gui.py 2011-08-18 17:23:16 +0000
370@@ -159,7 +159,7 @@
371 self.ui.backend._called.pop('volumes_info', None)
372 self.ui.load()
373
374- self.assert_backend_called('volumes_info', ())
375+ self.assert_backend_called('volumes_info')
376
377 def test_is_processing_after_load(self):
378 """The ui is processing when contents are load."""
379@@ -440,7 +440,7 @@
380 subscribed = gui.bool_str(not bool(volume['subscribed']))
381 # backend was called
382 self.assert_backend_called('change_volume_settings',
383- (fid, {'subscribed': subscribed}))
384+ fid, {'subscribed': subscribed})
385 # store was updated
386 it = self.ui.volumes_store.get_iter(path)
387 value = self.ui.volumes_store.get_value(it, 1)
388@@ -572,7 +572,7 @@
389 """Changing throttling settings updates the backend properly."""
390 expected = self.ui.__dict__
391 self.assert_backend_called('change_device_settings',
392- (self.ui.id, expected))
393+ self.ui.id, expected)
394 self.assertEqual(self.ui.warning_label.get_text(), '')
395
396 limit_enabled = self.ui.throttling_limits.get_sensitive()
397@@ -806,7 +806,7 @@
398 self.ui.is_local = False
399 self.ui.remove.clicked()
400
401- self.assert_backend_called('remove_device', (self.ui.id,))
402+ self.assert_backend_called('remove_device', self.ui.id)
403 self.assertFalse(self.ui.get_sensitive(),
404 'Must be disabled while removing.')
405
406@@ -936,7 +936,7 @@
407 self.ui.backend._called.pop('devices_info', None)
408 self.ui.load()
409
410- self.assert_backend_called('devices_info', ())
411+ self.assert_backend_called('devices_info')
412
413 def test_is_processing_after_load(self):
414 """The ui is processing when contents are load."""
415@@ -1246,7 +1246,7 @@
416
417 def test_file_sync_status_is_requested(self):
418 """The file sync status is requested to the backend."""
419- self.assert_backend_called('file_sync_status', ())
420+ self.assert_backend_called('file_sync_status')
421
422 def test_is_disabled(self):
423 """Until file sync status is given, the widget is disabled."""
424@@ -1273,10 +1273,10 @@
425 assert self.ui.button.get_active()
426
427 self.ui.button.set_active(not self.ui.button.get_active())
428- self.assert_backend_called('disable_files', ())
429+ self.assert_backend_called('disable_files')
430
431 self.ui.button.set_active(not self.ui.button.get_active())
432- self.assert_backend_called('enable_files', ())
433+ self.assert_backend_called('enable_files')
434
435 def test_on_file_sync_enabled(self):
436 """When file sync is enabled, the button is active."""
437@@ -1330,7 +1330,7 @@
438
439 args = (self.service_id,
440 {'enabled': gui.bool_str(self.ui.button.get_active())})
441- self.assert_backend_called('change_replication_settings', args)
442+ self.assert_backend_called('change_replication_settings', *args)
443
444 def test_dependency(self):
445 """The dependency box is None."""
446@@ -1543,7 +1543,7 @@
447 self.ui.load_replications()
448
449 self.assertTrue(self.ui.message.active)
450- self.assert_backend_called('replications_info', ())
451+ self.assert_backend_called('replications_info')
452
453
454 class ServicesWithDesktopcouchTestCase(ServicesTestCase):
455@@ -1750,7 +1750,7 @@
456 def test_file_sync_status_is_requested_on_load(self):
457 """The file sync status is requested to the backend."""
458 self.ui.load()
459- self.assert_backend_called('file_sync_status', ())
460+ self.assert_backend_called('file_sync_status')
461
462 def test_on_file_sync_status_disabled(self):
463 """The file sync is disabled.
464@@ -1862,43 +1862,43 @@
465 self.ui.backend._called.clear()
466 self.ui.on_files_start_error({'error_msg': 'error msg'})
467
468- self.assert_backend_called('file_sync_status', ())
469+ self.assert_backend_called('file_sync_status')
470
471 def test_on_connect_clicked(self):
472 """User requested connection."""
473 self.ui.on_connect_clicked(self.ui.button)
474
475- self.assert_backend_called('connect_files', ())
476+ self.assert_backend_called('connect_files')
477
478 def test_on_disconnect_clicked(self):
479 """User requested disconnection."""
480 self.ui.on_disconnect_clicked(self.ui.button)
481
482- self.assert_backend_called('disconnect_files', ())
483+ self.assert_backend_called('disconnect_files')
484
485 def test_on_enable_clicked(self):
486 """User requested enable the service."""
487 self.ui.on_enable_clicked(self.ui.button)
488
489- self.assert_backend_called('enable_files', ())
490+ self.assert_backend_called('enable_files')
491
492 def test_on_restart_clicked(self):
493 """User requested restart the service."""
494 self.ui.on_restart_clicked(self.ui.button)
495
496- self.assert_backend_called('restart_files', ())
497+ self.assert_backend_called('restart_files')
498
499 def test_on_start_clicked(self):
500 """User requested start the service."""
501 self.ui.on_start_clicked(self.ui.button)
502
503- self.assert_backend_called('start_files', ())
504+ self.assert_backend_called('start_files')
505
506 def test_on_stop_clicked(self):
507 """User requested stop the service."""
508 self.ui.on_stop_clicked(self.ui.button)
509
510- self.assert_backend_called('stop_files', ())
511+ self.assert_backend_called('stop_files')
512
513
514 class ManagementPanelTestCase(ControlPanelMixinTestCase):
515@@ -1992,7 +1992,7 @@
516 def test_account_info_is_requested_on_load(self):
517 """The account info is requested to the backend."""
518 self.ui.load()
519- self.assert_backend_called('account_info', ())
520+ self.assert_backend_called('account_info')
521
522 def test_file_sync_status_info_is_requested_on_load(self):
523 """The file sync status info is requested to the backend."""
524
525=== modified file 'ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py'
526--- ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py 2011-05-24 16:05:30 +0000
527+++ ubuntuone/controlpanel/gui/gtk/tests/test_gui_basic.py 2011-08-18 17:23:16 +0000
528@@ -20,9 +20,14 @@
529
530 from __future__ import division
531
532+from twisted.internet import defer
533+from twisted.python.failure import Failure
534
535 from ubuntuone.controlpanel.gui.gtk import gui
536-from ubuntuone.controlpanel.gui.gtk.tests import BaseTestCase, FakedSSOBackend
537+from ubuntuone.controlpanel.gui.gtk.tests import (
538+ BaseTestCase,
539+ FakedCredentialsBackend,
540+)
541 from ubuntuone.controlpanel.tests import TOKEN
542
543 from ubuntuone.devtools.testcase import skipIf
544@@ -287,7 +292,7 @@
545 """On 'credentials-found' signal, ask syncdaemon to connect."""
546 # credentials are new
547 self.ui.overview.emit('credentials-found', True, object())
548- self.assert_backend_called('connect_files', ())
549+ self.assert_backend_called('connect_files')
550
551 def test_local_device_removed_shows_overview_panel(self):
552 """On 'local-device-removed' signal, the overview panel is shown."""
553@@ -306,7 +311,7 @@
554 def test_backend_is_shutdown_on_close(self):
555 """When the control panel is closed, the backend is shutdown."""
556 self.ui.emit('destroy')
557- self.assert_backend_called('shutdown', ())
558+ self.assert_backend_called('shutdown')
559
560
561 class UbuntuOneBinTestCase(BaseTestCase):
562@@ -437,6 +442,11 @@
563 klass = gui.OverviewPanel
564 kwargs = {'main_window': gui.gtk.Window()}
565 ui_filename = 'overview.ui'
566+ backend_is_dbus = False
567+
568+ def setUp(self):
569+ super(OverwiewPanelTestCase, self).setUp()
570+ gui.gtk.link_button_set_uri_hook(lambda *a: None)
571
572 def test_is_a_greyable_bin(self):
573 """Inherits from GreyableBin."""
574@@ -450,20 +460,102 @@
575 """The 'join_now' button is the default widget."""
576 self.assertTrue(self.ui.join_now_button.get_property('can-default'))
577
578- def test_sso_backend(self):
579- """Has a correct SSO backend."""
580- self.assertIsInstance(self.ui.backend, FakedSSOBackend)
581-
582- def test_sso_backend_signals(self):
583- """The proper signals are connected to the backend."""
584- self.assertEqual(self.ui.backend._signals['CredentialsFound'],
585- [self.ui.on_credentials_found])
586- self.assertEqual(self.ui.backend._signals['CredentialsNotFound'],
587- [self.ui.on_credentials_not_found])
588- self.assertEqual(self.ui.backend._signals['CredentialsError'],
589- [self.ui.on_credentials_error])
590- self.assertEqual(self.ui.backend._signals['AuthorizationDenied'],
591- [self.ui.on_authorization_denied])
592+ def test_backend(self):
593+ """Has a correct backend."""
594+ self.assertIsInstance(self.ui.backend, FakedCredentialsBackend)
595+
596+
597+class OverwiewPanelBackendCallbacksTestCase(OverwiewPanelTestCase):
598+ """Proper callbacks are chained to the credentials backend methods."""
599+
600+ failure = Exception()
601+
602+ def test_find_credentials_fired_with_credentials(self):
603+ """Test that on_credentials_found is called."""
604+ self.ui.backend.next_result = defer.succeed(TOKEN)
605+ self.patch(self.ui, 'on_credentials_found', self._set_called)
606+
607+ self.ui.on_network_state_changed(gui.networkstate.ONLINE)
608+
609+ self.assertEqual(self._called, ((TOKEN,), {}))
610+
611+ def test_find_credentials_fired_without_credentials(self):
612+ """Test that on_credentials_not_found is called."""
613+ self.ui.backend.next_result = defer.succeed({})
614+ self.patch(self.ui, 'on_credentials_not_found', self._set_called)
615+
616+ self.ui.on_network_state_changed(gui.networkstate.ONLINE)
617+
618+ self.assertEqual(self._called, ((), {}))
619+
620+ def test_find_credentials_errback(self):
621+ """Test that on_credentials_error is called."""
622+ self.ui.backend.next_result = defer.fail(self.failure)
623+ self.patch(self.ui, 'on_credentials_error', self._set_called)
624+
625+ self.ui.on_network_state_changed(gui.networkstate.ONLINE)
626+
627+ failure = self._called[0][0]
628+ self.assertIsInstance(failure, Failure)
629+ self.assertEqual(failure.value, self.failure)
630+
631+ def test_register_fired_with_credentials(self):
632+ """Test that on_credentials_found is called."""
633+ self.ui.backend.next_result = defer.succeed(TOKEN)
634+ self.patch(self.ui, 'on_credentials_found', self._set_called)
635+
636+ self.ui.join_now_button.clicked()
637+
638+ self.assertEqual(self._called, ((TOKEN,), {}))
639+
640+ def test_register_fired_with_credentials_none(self):
641+ """Test that on_authorization_denied is called."""
642+ self.ui.backend.next_result = defer.succeed(None)
643+ self.patch(self.ui, 'on_authorization_denied', self._set_called)
644+
645+ self.ui.join_now_button.clicked()
646+
647+ self.assertEqual(self._called, ((), {}))
648+
649+ def test_register_errback(self):
650+ """Test that on_credentials_error is called."""
651+ self.ui.backend.next_result = defer.fail(self.failure)
652+ self.patch(self.ui, 'on_credentials_error', self._set_called)
653+
654+ self.ui.join_now_button.clicked()
655+
656+ failure = self._called[0][0]
657+ self.assertIsInstance(failure, Failure)
658+ self.assertEqual(failure.value, self.failure)
659+
660+ def test_login_fired_with_credentials(self):
661+ """Test that on_credentials_found is called."""
662+ self.ui.backend.next_result = defer.succeed(TOKEN)
663+ self.patch(self.ui, 'on_credentials_found', self._set_called)
664+
665+ self.ui.connect_button.clicked()
666+
667+ self.assertEqual(self._called, ((TOKEN,), {}))
668+
669+ def test_login_fired_with_credentials_none(self):
670+ """Test that on_authorization_denied is called."""
671+ self.ui.backend.next_result = defer.succeed(None)
672+ self.patch(self.ui, 'on_authorization_denied', self._set_called)
673+
674+ self.ui.connect_button.clicked()
675+
676+ self.assertEqual(self._called, ((), {}))
677+
678+ def test_login_errback(self):
679+ """Test that on_credentials_error is called."""
680+ self.ui.backend.next_result = defer.fail(self.failure)
681+ self.patch(self.ui, 'on_credentials_error', self._set_called)
682+
683+ self.ui.connect_button.clicked()
684+
685+ failure = self._called[0][0]
686+ self.assertIsInstance(failure, Failure)
687+ self.assertEqual(failure.value, self.failure)
688
689
690 class OverwiewNetworkStatePanelTestCase(OverwiewPanelTestCase):
691@@ -514,13 +606,13 @@
692 def test_find_credentials_is_called(self):
693 """Credentials are asked to SSO backend."""
694 self.assertFalse(self.ui._credentials_are_new)
695- self.assert_backend_called('find_credentials', (gui.U1_APP_NAME, {}))
696+ self.assert_backend_called('find_credentials')
697
698 def test_on_credentials_found(self):
699 """Callback 'on_credentials_found' is correct."""
700 self.ui.connect('credentials-found', self._set_called)
701
702- self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN)
703+ self.ui.on_credentials_found(TOKEN)
704
705 self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.')
706 # assume credentials were in local keyring
707@@ -531,9 +623,9 @@
708 self.ui.connect('credentials-found', self._set_called)
709
710 # credentials weren't in the system
711- self.ui.on_credentials_not_found(gui.U1_APP_NAME)
712+ self.ui.on_credentials_not_found()
713 # now they are!
714- self.ui.on_credentials_found(gui.U1_APP_NAME, TOKEN)
715+ self.ui.on_credentials_found(TOKEN)
716
717 self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.')
718 # assume credentials were not in local keyring
719@@ -541,70 +633,31 @@
720
721 def test_on_credentials_not_found(self):
722 """Callback 'on_credentials_not_found' is correct."""
723- self.ui.on_credentials_not_found(gui.U1_APP_NAME)
724+ self.ui.on_credentials_not_found()
725 self.assertTrue(self.ui.get_visible())
726 self.assertTrue(self.ui._credentials_are_new)
727
728 def test_on_credentials_error(self):
729 """Callback 'on_credentials_error' is correct."""
730- self.ui.on_credentials_error(gui.U1_APP_NAME, {})
731+ self.ui.on_credentials_error({})
732 self.assertTrue(self.ui.get_visible())
733 self.assert_warning_correct(self.ui.warning_label,
734 gui.CREDENTIALS_ERROR)
735
736 def test_on_authorization_denied(self):
737 """Callback 'on_authorization_denied' is correct."""
738- self.ui.on_authorization_denied(gui.U1_APP_NAME)
739+ self.ui.on_authorization_denied()
740 self.assertTrue(self.ui.get_visible())
741 self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.')
742 self.assertEqual(self.ui.warning_label.get_text(), '')
743
744
745-class OverwiewPanelAppNameMismatchTestCase(OverwiewPanelTestCase):
746- """The test suite for the overview panel when the app_name won't match."""
747-
748- NOT_U1_APP = 'Not ' + gui.U1_APP_NAME
749-
750- def test_filter_by_app_name(self):
751- """The filter_by_app_name decorator is correct."""
752- f = gui.filter_by_app_name(self._set_called)
753- f(self.ui, self.NOT_U1_APP)
754- self.assertFalse(self._called)
755- self.assertTrue(self.memento.check_info('ignoring', self.NOT_U1_APP))
756-
757- args = ('test', object())
758- kwargs = {'really': 'AWESOME'}
759- f(self.ui, gui.U1_APP_NAME, *args, **kwargs)
760- self.assertEqual(self._called,
761- ((self.ui, gui.U1_APP_NAME,) + args, kwargs))
762-
763- def test_on_credentials_found(self):
764- """Callback 'on_credentials_found' is not executed."""
765- self.assert_function_decorated(gui.filter_by_app_name,
766- self.ui.on_credentials_found)
767-
768- def test_on_credentials_not_found(self):
769- """Callback 'on_credentials_not_found' is not executed."""
770- self.assert_function_decorated(gui.filter_by_app_name,
771- self.ui.on_credentials_not_found)
772-
773- def test_on_credentials_error(self):
774- """Callback 'on_credentials_error' is not executed."""
775- self.assert_function_decorated(gui.filter_by_app_name,
776- self.ui.on_credentials_error)
777-
778- def test_on_authorization_denied(self):
779- """Callback 'on_authorization_denied' is not executed."""
780- self.assert_function_decorated(gui.filter_by_app_name,
781- self.ui.on_authorization_denied)
782-
783-
784 class OverwiewPanelNoCredsTestCase(OverwiewPanelTestCase):
785 """The test suite for the overview panel when no credentials are found."""
786
787 def setUp(self):
788 super(OverwiewPanelNoCredsTestCase, self).setUp()
789- self.ui.on_credentials_not_found(gui.U1_APP_NAME)
790+ self.ui.on_credentials_not_found()
791
792 def test_startup_visibility(self):
793 """The widget is visible at startup."""
794@@ -631,12 +684,8 @@
795 self.ui.join_now_button.clicked()
796
797 window_id = self.kwargs['main_window'].window.xid
798- args = (gui.U1_APP_NAME,
799- {gui.TC_URL_KEY: gui.U1_TC_URL,
800- gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION,
801- gui.WINDOW_ID_KEY: str(window_id),
802- gui.PING_URL_KEY: gui.U1_PING_URL})
803- self.assert_backend_called('register', args)
804+ kwargs = {'window_id': str(window_id)}
805+ self.assert_backend_called('register', **kwargs)
806
807 def test_connect_button_clicked(self):
808 """Test the 'join now' button callback."""
809@@ -646,12 +695,8 @@
810 self.ui.connect_button.clicked()
811
812 window_id = self.kwargs['main_window'].window.xid
813- args = (gui.U1_APP_NAME,
814- {gui.TC_URL_KEY: gui.U1_TC_URL,
815- gui.HELP_TEXT_KEY: gui.U1_DESCRIPTION,
816- gui.WINDOW_ID_KEY: str(window_id),
817- gui.PING_URL_KEY: gui.U1_PING_URL})
818- self.assert_backend_called('login', args)
819+ kwargs = {'window_id': str(window_id)}
820+ self.assert_backend_called('login', **kwargs)
821
822 def test_join_now_button_clicked_set_greyed(self):
823 """Clicking on 'join_now' self is greyed."""
824@@ -660,7 +705,7 @@
825
826 def test_join_now_button_clicked_removes_warning(self):
827 """Clicking on 'join_now' the warnings are removed."""
828- self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning
829+ self.ui.on_authorization_denied() # show warning
830 self.ui.join_now_button.clicked()
831
832 self.assertEqual(self.ui.warning_label.get_text(), '')
833@@ -672,7 +717,7 @@
834
835 def test_connect_button_clicked_removes_warning(self):
836 """Clicking on 'connect' the warnings are removed."""
837- self.ui.on_authorization_denied(gui.U1_APP_NAME) # show warning
838+ self.ui.on_authorization_denied() # show warning
839 self.ui.connect_button.clicked()
840
841 self.assertEqual(self.ui.warning_label.get_text(), '')
842@@ -688,21 +733,21 @@
843 def test_on_credentials_not_found_unset_greyed(self):
844 """Callback 'on_credentials_not_found' unsets the 'greyed' prop."""
845 self.ui.connect_button.clicked()
846- self.ui.on_credentials_not_found(gui.U1_APP_NAME)
847+ self.ui.on_credentials_not_found()
848
849 self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.')
850
851 def test_on_credentials_error_unset_greyed(self):
852 """Callback 'on_credentials_error' unsets the 'greyed' prop."""
853 self.ui.connect_button.clicked()
854- self.ui.on_credentials_error(gui.U1_APP_NAME, {})
855+ self.ui.on_credentials_error({})
856
857 self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.')
858
859 def test_on_authorization_denied_unset_greyed(self):
860 """Callback 'on_authorization_denied' unsets the 'greyed' prop."""
861 self.ui.connect_button.clicked()
862- self.ui.on_authorization_denied(gui.U1_APP_NAME)
863+ self.ui.on_authorization_denied()
864
865 self.assertFalse(self.ui.get_property('greyed'), 'Must not be greyed.')
866
867
868=== modified file 'ubuntuone/controlpanel/login_client.py'
869--- ubuntuone/controlpanel/login_client.py 2011-06-17 15:56:54 +0000
870+++ ubuntuone/controlpanel/login_client.py 2011-08-18 17:23:16 +0000
871@@ -18,14 +18,15 @@
872
873 """Client to access Ubuntu One credentials."""
874
875+# pylint: disable=E0611, F0401
876+from ubuntuone.platform.credentials import CredentialsManagementTool
877+# pylint: enable=E0611, F0401
878+
879
880 def get_sso_proxy():
881 """Return a login client."""
882- # No name 'credentials' in module 'ubuntuone.platform'
883- # Reimport 'credentials' (imported line 22)
884- # pylint: disable=E0611,W0404
885- from ubuntuone.platform import credentials
886- return credentials.CredentialsManagementTool()
887+ result = CredentialsManagementTool()
888+ return result
889
890
891 def get_credentials():
892@@ -38,3 +39,15 @@
893 """Clear the credentials for Ubuntu One."""
894 proxy = get_sso_proxy()
895 return proxy.clear_credentials()
896+
897+
898+def login(*args, **kwargs):
899+ """Get the credentials for Ubuntu One offering the user to login."""
900+ proxy = get_sso_proxy()
901+ return proxy.login(*args, **kwargs)
902+
903+
904+def register(*args, **kwargs):
905+ """Get the credentials for Ubuntu One offering the user to register."""
906+ proxy = get_sso_proxy()
907+ return proxy.register(*args, **kwargs)
908
909=== modified file 'ubuntuone/controlpanel/tests/test_login_client.py'
910--- ubuntuone/controlpanel/tests/test_login_client.py 2011-06-17 15:56:54 +0000
911+++ ubuntuone/controlpanel/tests/test_login_client.py 2011-08-18 17:23:16 +0000
912@@ -19,10 +19,6 @@
913 """Tests for the service when accessing the login client."""
914
915 from twisted.internet import defer
916-# No name 'credentials' in module 'ubuntuone.platform'
917-# pylint: disable=E0611
918-from ubuntuone.platform import credentials
919-# pylint: enable=E0611
920
921 from ubuntuone.controlpanel import login_client
922 from ubuntuone.controlpanel.tests import TestCase, TOKEN
923@@ -49,13 +45,23 @@
924 FakedCredentialsManagementTool.credentials = None
925 yield
926
927+ @defer.inlineCallbacks
928+ def login(self):
929+ """Create credentials for Ubuntu One by logging in."""
930+ yield defer.succeed(FakedCredentialsManagementTool.credentials)
931+
932+ @defer.inlineCallbacks
933+ def register(self):
934+ """Create credentials for Ubuntu One by registering."""
935+ yield defer.succeed(FakedCredentialsManagementTool.credentials)
936+
937
938 class BaseTestCase(TestCase):
939 """Base TestCase for the login client methods."""
940
941 def setUp(self):
942 super(BaseTestCase, self).setUp()
943- self.patch(credentials, 'CredentialsManagementTool',
944+ self.patch(login_client, 'CredentialsManagementTool',
945 FakedCredentialsManagementTool)
946 FakedCredentialsManagementTool.credentials = TOKEN
947
948@@ -87,7 +93,7 @@
949
950 @defer.inlineCallbacks
951 def test_clear_credentials(self):
952- """The credentials are properly retrieved."""
953+ """The credentials are properly cleared."""
954 yield login_client.clear_credentials()
955 self.assertEqual(None, FakedCredentialsManagementTool.credentials)
956
957@@ -98,3 +104,39 @@
958 self.fake_fail)
959 yield self.assertFailure(login_client.clear_credentials(),
960 CustomError)
961+
962+
963+class LoginTestCase(BaseTestCase):
964+ """Test for the login method."""
965+
966+ @defer.inlineCallbacks
967+ def test_login(self):
968+ """The credentials are properly retrieved."""
969+ yield login_client.login()
970+ self.assertEqual(TOKEN, FakedCredentialsManagementTool.credentials)
971+
972+ @defer.inlineCallbacks
973+ def test_login_throws_an_error(self):
974+ """If login fails, the error is propagated."""
975+ self.patch(FakedCredentialsManagementTool, 'login',
976+ self.fake_fail)
977+ yield self.assertFailure(login_client.login(),
978+ CustomError)
979+
980+
981+class RegisterTestCase(BaseTestCase):
982+ """Test for the register method."""
983+
984+ @defer.inlineCallbacks
985+ def test_register(self):
986+ """The credentials are properly retrieved."""
987+ yield login_client.register()
988+ self.assertEqual(TOKEN, FakedCredentialsManagementTool.credentials)
989+
990+ @defer.inlineCallbacks
991+ def test_register_throws_an_error(self):
992+ """If register fails, the error is propagated."""
993+ self.patch(FakedCredentialsManagementTool, 'register',
994+ self.fake_fail)
995+ yield self.assertFailure(login_client.register(),
996+ CustomError)

Subscribers

People subscribed via source and target branches