Merge lp:~mandel/ubuntu-sso-client/implement_windows_main_1 into lp:ubuntu-sso-client

Proposed by Manuel de la Peña on 2011-03-09
Status: Merged
Approved by: Manuel de la Peña on 2011-03-17
Approved revision: 696
Merged at revision: 680
Proposed branch: lp:~mandel/ubuntu-sso-client/implement_windows_main_1
Merge into: lp:ubuntu-sso-client
Prerequisite: lp:~mandel/ubuntu-sso-client/implement_windows_networkstatus
Diff against target: 1267 lines (+741/-187)
9 files modified
run-tests (+1/-1)
run-tests.bat (+1/-1)
ubuntu_sso/main/__init__.py (+375/-0)
ubuntu_sso/main/linux.py (+48/-166)
ubuntu_sso/main/windows.py (+17/-0)
ubuntu_sso/tests/main/__init__.py (+17/-0)
ubuntu_sso/tests/main/test_common.py (+244/-0)
ubuntu_sso/tests/main/test_linux.py (+21/-19)
ubuntu_sso/tests/main/test_windows.py (+17/-0)
To merge this branch: bzr merge lp:~mandel/ubuntu-sso-client/implement_windows_main_1
Reviewer Review Type Date Requested Status
Alejandro J. Cura (community) Approve on 2011-03-16
Roberto Alsina (community) 2011-03-09 Approve on 2011-03-16
Review via email: mp+52707@code.launchpad.net

Commit message

First step of implementing the code in main on windows.

Description of the change

First step of implementing the code in main on windows.

To post a comment you must log in.
689. By Manuel de la Peña on 2011-03-09

Merged implement_windows_networkstatus into implement_windows_main_1.

690. By Manuel de la Peña on 2011-03-10

Merged implement_windows_networkstatus into implement_windows_main_1.

691. By Manuel de la Peña on 2011-03-10

Merged implement_windows_networkstatus into implement_windows_main_1.

692. By Manuel de la Peña on 2011-03-16

Renamed test files so they are correctly ignored.

693. By Manuel de la Peña on 2011-03-16

Renamed test files so they are correctly ignored.

Roberto Alsina (ralsina) wrote :

+1 on windows

review: Approve
Alejandro J. Cura (alecu) wrote :

When running the tests on natty:

alecu@breetai:~/canonical/ubuntu-sso-client/review_implement_windows_main_1$ ./run-tests
Running test suite for ubuntu_sso
Xlib: extension "RANDR" missing on display ":99".
Traceback (most recent call last):
  File "/usr/bin/u1trial", line 246, in <module>
    main()
  File "/usr/bin/u1trial", line 243, in main
    TestRunner(force_gc=options.force_gc).run(testpath, options)
  File "/usr/bin/u1trial", line 181, in run
    options.ignored_modules, options.ignored_paths)
  File "/usr/bin/u1trial", line 160, in _collect_tests
    module_suite = self._load_unittest(filepath)
  File "/usr/bin/u1trial", line 88, in _load_unittest
    module = __import__(modpath, None, None, [""])
  File "/home/alecu/canonical/ubuntu-sso-client/review_implement_windows_main_1/ubuntu_sso/tests/networkstate/test_windows.py", line 20, in <module>
    from ubuntu_sso.networkstate.windows import (
  File "/home/alecu/canonical/ubuntu-sso-client/review_implement_windows_main_1/ubuntu_sso/networkstate/windows.py", line 23, in <module>
    import pythoncom
ImportError: No module named pythoncom

review: Needs Fixing
694. By Manuel de la Peña on 2011-03-16

Added the correct ignore to the runt-test script.

695. By Manuel de la Peña on 2011-03-16

Fixed style issues.

Alejandro J. Cura (alecu) wrote :

Great branch!

A couple of minor nitpicks:

 * a small typo: "Object object"
 * and a weird name for a test method: CredentialsManagementMockedTestCase.login (looks like it should be named test_login)

review: Approve
Manuel de la Peña (mandel) wrote :

Alecu,

Thanks for the comments, I'll fix those two thing you mentioned, better now than never :)

696. By Manuel de la Peña on 2011-03-16

Fixed test name and small typo.

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-02-24 02:46:19 +0000
3+++ run-tests 2011-03-17 08:43:34 +0000
4@@ -33,5 +33,5 @@
5 }
6
7 echo "Running test suite for ""$MODULE"
8-`which xvfb-run` u1trial "$MODULE" -i "test_windows_networkstate.py" && style_check
9+`which xvfb-run` u1trial "$MODULE" -i "test_windows.py" && style_check
10 rm -rf _trial_temp
11
12=== modified file 'run-tests.bat'
13--- run-tests.bat 2011-03-15 08:27:10 +0000
14+++ run-tests.bat 2011-03-17 08:43:34 +0000
15@@ -51,7 +51,7 @@
16 :PYTHONPRESENT
17 ECHO Python found, executing the tests...
18 :: execute the tests with a number of ignored linux only modules
19-"%PYTHONPATH%\python.exe" "%PYTHONPATH%\Scripts\u1trial" -c ubuntu_sso -i "test_gui.py, test_linux_keyring.py, test_linux_network_state.py"
20+"%PYTHONPATH%\python.exe" "%PYTHONPATH%\Scripts\u1trial" -c ubuntu_sso -i "test_gui.py, test_linux.py, test_txsecrets.py"
21 "%PYTHONPATH%\python.exe" "%PYTHONPATH%\Scripts\u1lint" ubuntu_sso
22 :: test for style if we can, if pep8 is not present, move to the end
23 IF EXIST "%PYTHONPATH%Scripts\pep8.exe"
24
25=== added directory 'ubuntu_sso/main'
26=== added file 'ubuntu_sso/main/__init__.py'
27--- ubuntu_sso/main/__init__.py 1970-01-01 00:00:00 +0000
28+++ ubuntu_sso/main/__init__.py 2011-03-17 08:43:34 +0000
29@@ -0,0 +1,375 @@
30+# -*- coding: utf-8 -*-
31+#
32+# Author: Natalia Bidart <natalia.bidart@canonical.com>
33+# Author: Alejandro J. Cura <alecu@canonical.com>
34+# Author: Manuel de la Pena <manuel@canonical.com>
35+#
36+# Copyright 2011 Canonical Ltd.
37+#
38+# This program is free software: you can redistribute it and/or modify it
39+# under the terms of the GNU General Public License version 3, as published
40+# by the Free Software Foundation.
41+#
42+# This program is distributed in the hope that it will be useful, but
43+# WITHOUT ANY WARRANTY; without even the implied warranties of
44+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
45+# PURPOSE. See the GNU General Public License for more details.
46+#
47+# You should have received a copy of the GNU General Public License along
48+# with this program. If not, see <http://www.gnu.org/licenses/>.
49+"""Main object implementations."""
50+
51+import os
52+import sys
53+import warnings
54+
55+from ubuntu_sso import NO_OP
56+from ubuntu_sso.account import Account
57+from ubuntu_sso.credentials import (Credentials, HELP_TEXT_KEY, PING_URL_KEY,
58+ TC_URL_KEY, UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY,
59+ SUCCESS_CB_KEY, ERROR_CB_KEY, DENIAL_CB_KEY)
60+from ubuntu_sso.keyring import get_token_name, U1_APP_NAME, Keyring
61+from ubuntu_sso.logger import setup_logging
62+
63+logger = setup_logging("ubuntu_sso.main")
64+U1_PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/"
65+
66+
67+class SSOLoginProcessor(Account):
68+ """Login and register users using the Ubuntu Single Sign On service.
69+
70+ Alias classname to maintain backwards compatibility. DO NOT USE, use
71+ ubuntu_sso.account.Account instead.
72+ """
73+
74+ def __init__(self, sso_service_class=None):
75+ """Create a new SSO Account manager."""
76+ msg = 'Use ubuntu_sso.account.Account instead.'
77+ warnings.warn(msg, DeprecationWarning)
78+ super(SSOLoginProcessor, self).__init__(sso_service_class)
79+
80+
81+def except_to_errdict(e):
82+ """Turn an exception into a dictionary to return thru DBus."""
83+ result = {
84+ "errtype": e.__class__.__name__,
85+ }
86+ if len(e.args) == 0:
87+ result["message"] = e.__class__.__doc__
88+ elif isinstance(e.args[0], dict):
89+ result.update(e.args[0])
90+ elif isinstance(e.args[0], basestring):
91+ result["message"] = e.args[0]
92+
93+ return result
94+
95+
96+class SSOLoginRoot(object):
97+ """Login thru the Single Sign On service."""
98+
99+ def __init__(self, sso_login_processor_class=Account,
100+ sso_service_class=None):
101+ """Initiate the Login object."""
102+ self.sso_login_processor_class = sso_login_processor_class
103+ self.processor = self.sso_login_processor_class(
104+ sso_service_class=sso_service_class)
105+
106+ def generate_captcha(self, app_name, filename, thread_execute, result_cb,
107+ error_cb):
108+ """Call the matching method in the processor."""
109+ def f():
110+ """Inner function that will be run in a thread."""
111+ return self.processor.generate_captcha(filename)
112+ thread_execute(f, app_name, result_cb, error_cb)
113+
114+ def register_user(self, app_name, email, password, captcha_id,
115+ captcha_solution, thread_execute, result_cb, error_cb):
116+ """Call the matching method in the processor."""
117+ def f():
118+ """Inner function that will be run in a thread."""
119+ return self.processor.register_user(email, password,
120+ captcha_id, captcha_solution)
121+ thread_execute(f, app_name, result_cb, error_cb)
122+
123+ def login(self, app_name, email, password, thread_execute, result_cb,
124+ error_cb, not_validated_cb):
125+ """Call the matching method in the processor."""
126+ def f():
127+ """Inner function that will be run in a thread."""
128+ token_name = get_token_name(app_name)
129+ logger.debug('login: token_name %r, email %r, password <hidden>.',
130+ token_name, email)
131+ credentials = self.processor.login(email, password, token_name)
132+ logger.debug('login returned not None credentials? %r.',
133+ credentials is not None)
134+ return credentials
135+
136+ def success_cb(app_name, credentials):
137+ """Login finished successfull."""
138+ is_validated = self.processor.is_validated(credentials)
139+ logger.debug('user is validated? %r.', is_validated)
140+ if is_validated:
141+ # pylint: disable=E1101
142+ d = Keyring().set_credentials(app_name, credentials)
143+ d.addCallback(lambda _: result_cb(app_name, email))
144+ d.addErrback(lambda failure: \
145+ error_cb(app_name,
146+ except_to_errdict(failure.value)))
147+ else:
148+ not_validated_cb(app_name, email)
149+ thread_execute(f, app_name, success_cb, error_cb)
150+
151+ def validate_email(self, app_name, email, password, email_token,
152+ thread_execute, result_cb, error_cb):
153+ """Call the matching method in the processor."""
154+
155+ def f():
156+ """Inner function that will be run in a thread."""
157+ token_name = get_token_name(app_name)
158+ credentials = self.processor.validate_email(email, password,
159+ email_token, token_name)
160+ return credentials
161+
162+ def success_cb(app_name, credentials):
163+ """Validation finished successfully."""
164+ # pylint: disable=E1101
165+ d = Keyring().set_credentials(app_name, credentials)
166+ d.addCallback(lambda _: result_cb(app_name, email))
167+ failure_cb = lambda f: error_cb(app_name, f.value)
168+ d.addErrback(failure_cb)
169+
170+ thread_execute(f, app_name, success_cb, error_cb)
171+
172+ def request_password_reset_token(self, app_name, email, thread_execute,
173+ result_cb, error_cb):
174+ """Call the matching method in the processor."""
175+ def f():
176+ """Inner function that will be run in a thread."""
177+ return self.processor.request_password_reset_token(email)
178+ thread_execute(f, app_name, result_cb, error_cb)
179+
180+ def set_new_password(self, app_name, email, token, new_password,
181+ thread_execute, result_cb, error_cb):
182+ """Call the matching method in the processor."""
183+ def f():
184+ """Inner function that will be run in a thread."""
185+ return self.processor.set_new_password(email, token,
186+ new_password)
187+ thread_execute(f, app_name, result_cb, error_cb)
188+
189+
190+class SSOCredentialsRoot(object):
191+ """Object that gets credentials, and login/registers if needed."""
192+
193+ def __init__(self):
194+ self.ping_url = os.environ.get('USSOC_PING_URL', U1_PING_URL)
195+
196+ def find_credentials(self, app_name, callback=NO_OP, errback=NO_OP):
197+ """Get the credentials from the keyring or {} if not there."""
198+
199+ def log_result(result):
200+ """Log the result and continue."""
201+ logger.info('find_credentials: app_name "%s", result is {}? %s',
202+ app_name, result == {})
203+ return result
204+
205+ d = Credentials(app_name=app_name).find_credentials()
206+ # pylint: disable=E1101
207+ d.addCallback(log_result)
208+ d.addCallbacks(callback, errback)
209+
210+ def login_or_register_to_get_credentials(self, app_name,
211+ terms_and_conditions_url,
212+ help_text, window_id,
213+ success_cb, error_cb, denial_cb):
214+ """Get credentials if found else prompt GUI to login or register.
215+
216+ 'app_name' will be displayed in the GUI.
217+ 'terms_and_conditions_url' will be the URL pointing to T&C.
218+ 'help_text' is an explanatory text for the end-users, will be shown
219+ below the headers.
220+ 'window_id' is the id of the window which will be set as a parent of
221+ the GUI. If 0, no parent will be set.
222+
223+ """
224+ ping_url = self.ping_url if app_name == U1_APP_NAME else None
225+ obj = Credentials(app_name=app_name, ping_url=ping_url,
226+ tc_url=terms_and_conditions_url,
227+ help_text=help_text, window_id=window_id,
228+ success_cb=success_cb, error_cb=error_cb,
229+ denial_cb=denial_cb)
230+ obj.register()
231+
232+ def login_to_get_credentials(self, app_name, help_text, window_id,
233+ success_cb, error_cb, denial_cb):
234+ """Get credentials if found else prompt GUI just to login
235+
236+ 'app_name' will be displayed in the GUI.
237+ 'help_text' is an explanatory text for the end-users, will be shown
238+ before the login fields.
239+ 'window_id' is the id of the window which will be set as a parent of
240+ the GUI. If 0, no parent will be set.
241+
242+ """
243+ ping_url = self.ping_url if app_name == U1_APP_NAME else None
244+ obj = Credentials(app_name=app_name, ping_url=ping_url, tc_url=None,
245+ help_text=help_text, window_id=window_id,
246+ success_cb=success_cb, error_cb=error_cb,
247+ denial_cb=denial_cb)
248+ obj.login()
249+
250+ def clear_token(self, app_name, callback=NO_OP, errback=NO_OP):
251+ """Clear the token for an application from the keyring.
252+
253+ 'app_name' is the name of the application.
254+ """
255+ d = Credentials(app_name=app_name).clear_credentials()
256+ # pylint: disable=E1101
257+ d.addCallbacks(lambda _: callback(), errback)
258+
259+
260+class CredentialsManagementRoot(object):
261+ """Object that manages credentials.
262+
263+ Every exposed method in this class requires one mandatory argument:
264+
265+ - 'app_name': the name of the application. Will be displayed in the
266+ GUI header, plus it will be used to find/build/clear tokens.
267+
268+ And accepts another parameter named 'args', which is a dictionary that
269+ can contain the following:
270+
271+ - 'help_text': an explanatory text for the end-users, will be
272+ shown below the header. This is an optional free text field.
273+
274+ - 'ping_url': the url to open after successful token retrieval. If
275+ defined, the email will be attached to the url and will be pinged
276+ with a OAuth-signed request.
277+
278+ - 'tc_url': the link to the Terms and Conditions page. If defined,
279+ the checkbox to agree to the terms will link to it.
280+
281+ - 'window_id': the id of the window which will be set as a parent
282+ of the GUI. If not defined, no parent will be set.
283+
284+ """
285+
286+ def __init__(self, found_cb, error_cb, denied_cb, *args, **kwargs):
287+ """Create a new instance.
288+
289+ - 'found_cb' is a callback that will be executed when the credentials
290+ were found.
291+
292+ - 'error_cb' is a callback that will be executed when there was an
293+ error getting the credentials.
294+
295+ - 'denied_cb' is a callback that will be executed when the user denied
296+ the use of the crendetials.
297+
298+ """
299+ super(CredentialsManagementRoot, self).__init__(*args, **kwargs)
300+ self.found_cb = found_cb
301+ self.error_cb = error_cb
302+ self.denied_cb = denied_cb
303+
304+ valid_keys = (HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY,
305+ UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY)
306+
307+ def _parse_args(self, args):
308+ """Retrieve values from the generic param 'args'."""
309+ result = dict(i for i in args.iteritems() if i[0] in self.valid_keys)
310+ result[WINDOW_ID_KEY] = int(args.get(WINDOW_ID_KEY, 0))
311+ result[SUCCESS_CB_KEY] = self.found_cb
312+ result[ERROR_CB_KEY] = self.error_cb
313+ result[DENIAL_CB_KEY] = self.denied_cb
314+ return result
315+
316+ def find_credentials(self, app_name, args, success_cb, error_cb):
317+ """Look for the credentials for an application.
318+
319+ - 'app_name': the name of the application which credentials are
320+ going to be removed.
321+
322+ - 'args' is a dictionary, currently not used.
323+
324+ - 'success_cb' is a callback that will be execute if the operation was
325+ a success.
326+
327+ - 'error_cb' is a callback that will be executed if the operation had
328+ an error.
329+
330+ """
331+
332+ obj = Credentials(app_name)
333+ d = obj.find_credentials()
334+ # pylint: disable=E1101
335+ d.addCallback(success_cb)
336+ d.addErrback(error_cb, app_name)
337+
338+ def clear_credentials(self, app_name, args, success_cb, error_cb):
339+ """Clear the credentials for an application.
340+
341+ - 'app_name': the name of the application which credentials are
342+ going to be removed.
343+
344+ - 'args' is a dictionary, currently not used.
345+
346+ - 'success_cb' is a callback that will be execute if the operation was
347+ a success.
348+
349+ - 'error_cb' is a callback that will be executed if the operation had
350+ an error.
351+
352+ """
353+
354+ obj = Credentials(app_name)
355+ d = obj.clear_credentials()
356+ # pylint: disable=E1101
357+ d.addCallback(success_cb)
358+ d.addErrback(error_cb, app_name)
359+
360+ def store_credentials(self, app_name, args, success_cb, error_cb):
361+ """Store the token for an application.
362+
363+ - 'app_name': the name of the application which credentials are
364+ going to be stored.
365+
366+ - 'args' is the dictionary holding the credentials. Needs to provide
367+ the following mandatory keys: 'token', 'token_key', 'consumer_key',
368+ 'consumer_secret'.
369+
370+ - 'success_cb' is a callback that will be execute if the operation was
371+ a success.
372+
373+ - 'error_cb' is a callback that will be executed if the operation had
374+ an error.
375+ """
376+
377+ obj = Credentials(app_name)
378+ d = obj.store_credentials(args)
379+ # pylint: disable=E1101
380+ d.addCallback(success_cb)
381+ d.addErrback(error_cb, app_name)
382+
383+ def register(self, app_name, args):
384+ """Get credentials if found else prompt GUI to register."""
385+ obj = Credentials(app_name, **self._parse_args(args))
386+ obj.register()
387+
388+ def login(self, app_name, args):
389+ """Get credentials if found else prompt GUI to login."""
390+ obj = Credentials(app_name, **self._parse_args(args))
391+ obj.login()
392+
393+# pylint: disable=C0103
394+SSOLogin = None
395+SSOCredentials = None
396+CredentialsManagement = None
397+
398+if sys.platform == 'win32':
399+ pass
400+else:
401+ from ubuntu_sso.main import linux
402+ SSOLogin = linux.SSOLogin
403+ SSOCredentials = linux.SSOCredentials
404+ CredentialsManagement = linux.CredentialsManagement
405
406=== renamed file 'ubuntu_sso/main.py' => 'ubuntu_sso/main/linux.py'
407--- ubuntu_sso/main.py 2011-01-28 13:45:09 +0000
408+++ ubuntu_sso/main/linux.py 2011-03-17 08:43:34 +0000
409@@ -27,21 +27,17 @@
410
411 """
412
413-import os
414 import threading
415-import warnings
416
417 import dbus.service
418
419 from ubuntu_sso import (DBUS_ACCOUNT_PATH, DBUS_IFACE_USER_NAME,
420 DBUS_IFACE_CRED_NAME, DBUS_CREDENTIALS_IFACE, NO_OP)
421 from ubuntu_sso.account import Account
422-from ubuntu_sso.credentials import (Credentials, HELP_TEXT_KEY, PING_URL_KEY,
423- TC_URL_KEY, UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY,
424- SUCCESS_CB_KEY, ERROR_CB_KEY, DENIAL_CB_KEY,
425- ERROR_KEY, ERROR_DETAIL_KEY)
426-from ubuntu_sso.keyring import get_token_name, U1_APP_NAME, Keyring
427+from ubuntu_sso.credentials import ERROR_KEY, ERROR_DETAIL_KEY
428 from ubuntu_sso.logger import setup_logging
429+from ubuntu_sso.main import (CredentialsManagementRoot, SSOLoginRoot,
430+ SSOCredentialsRoot, except_to_errdict)
431
432
433 # Disable the invalid name warning, as we have a lot of DBus style names
434@@ -49,39 +45,9 @@
435
436
437 logger = setup_logging("ubuntu_sso.main")
438-U1_PING_URL = "https://one.ubuntu.com/oauth/sso-finished-so-get-tokens/"
439 TIMEOUT_INTERVAL = 10000 # 10 seconds
440
441
442-class SSOLoginProcessor(Account):
443- """Login and register users using the Ubuntu Single Sign On service.
444-
445- Alias classname to maintain backwards compatibility. DO NOT USE, use
446- ubuntu_sso.account.Account instead.
447- """
448-
449- def __init__(self, sso_service_class=None):
450- """Create a new SSO Account manager."""
451- msg = 'Use ubuntu_sso.account.Account instead.'
452- warnings.warn(msg, DeprecationWarning)
453- super(SSOLoginProcessor, self).__init__(sso_service_class)
454-
455-
456-def except_to_errdict(e):
457- """Turn an exception into a dictionary to return thru DBus."""
458- result = {
459- "errtype": e.__class__.__name__,
460- }
461- if len(e.args) == 0:
462- result["message"] = e.__class__.__doc__
463- elif isinstance(e.args[0], dict):
464- result.update(e.args[0])
465- elif isinstance(e.args[0], basestring):
466- result["message"] = e.args[0]
467-
468- return result
469-
470-
471 def blocking(f, app_name, result_cb, error_cb):
472 """Run f in a thread; return or throw an exception thru the callbacks."""
473 def _in_thread():
474@@ -107,9 +73,7 @@
475 """Initiate the Login object."""
476 dbus.service.Object.__init__(self, object_path=object_path,
477 bus_name=bus_name)
478- self.sso_login_processor_class = sso_login_processor_class
479- self.processor = self.sso_login_processor_class(
480- sso_service_class=sso_service_class)
481+ self.root = SSOLoginRoot(sso_login_processor_class, sso_service_class)
482
483 # generate_capcha signals
484 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
485@@ -128,11 +92,9 @@
486 in_signature='ss')
487 def generate_captcha(self, app_name, filename):
488 """Call the matching method in the processor."""
489- def f():
490- """Inner function that will be run in a thread."""
491- return self.processor.generate_captcha(filename)
492- blocking(f, app_name, self.CaptchaGenerated,
493- self.CaptchaGenerationError)
494+ self.root.generate_captcha(app_name, filename, blocking,
495+ self.CaptchaGenerated,
496+ self.CaptchaGenerationError)
497
498 # register_user signals
499 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
500@@ -152,11 +114,10 @@
501 def register_user(self, app_name, email, password,
502 captcha_id, captcha_solution):
503 """Call the matching method in the processor."""
504- def f():
505- """Inner function that will be run in a thread."""
506- return self.processor.register_user(email, password,
507- captcha_id, captcha_solution)
508- blocking(f, app_name, self.UserRegistered, self.UserRegistrationError)
509+ self.root.register_user(app_name, email, password, captcha_id,
510+ captcha_solution, blocking,
511+ self.UserRegistered,
512+ self.UserRegistrationError)
513
514 # login signals
515 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
516@@ -181,30 +142,8 @@
517 in_signature='sss')
518 def login(self, app_name, email, password):
519 """Call the matching method in the processor."""
520- def f():
521- """Inner function that will be run in a thread."""
522- token_name = get_token_name(app_name)
523- logger.debug('login: token_name %r, email %r, password <hidden>.',
524- token_name, email)
525- credentials = self.processor.login(email, password, token_name)
526- logger.debug('login returned not None credentials? %r.',
527- credentials is not None)
528- return credentials
529-
530- def success_cb(app_name, credentials):
531- """Login finished successfull."""
532- is_validated = self.processor.is_validated(credentials)
533- logger.debug('user is validated? %r.', is_validated)
534- if is_validated:
535- # pylint: disable=E1101
536- d = Keyring().set_credentials(app_name, credentials)
537- d.addCallback(lambda _: self.LoggedIn(app_name, email))
538- d.addErrback(lambda failure: \
539- self.LoginError(app_name,
540- except_to_errdict(failure.value)))
541- else:
542- self.UserNotValidated(app_name, email)
543- blocking(f, app_name, success_cb, self.LoginError)
544+ self.root.login(app_name, email, password, blocking, self.LoggedIn,
545+ self.LoginError, self.UserNotValidated)
546
547 # validate_email signals
548 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
549@@ -223,23 +162,9 @@
550 in_signature='ssss')
551 def validate_email(self, app_name, email, password, email_token):
552 """Call the matching method in the processor."""
553-
554- def f():
555- """Inner function that will be run in a thread."""
556- token_name = get_token_name(app_name)
557- credentials = self.processor.validate_email(email, password,
558- email_token, token_name)
559- return credentials
560-
561- def success_cb(app_name, credentials):
562- """Validation finished successfully."""
563- # pylint: disable=E1101
564- d = Keyring().set_credentials(app_name, credentials)
565- d.addCallback(lambda _: self.EmailValidated(app_name, email))
566- failure_cb = lambda f: self.EmailValidationError(app_name, f.value)
567- d.addErrback(failure_cb)
568-
569- blocking(f, app_name, success_cb, self.EmailValidationError)
570+ self.root.validate_email(app_name, email, password, email_token,
571+ blocking, self.EmailValidated,
572+ self.EmailValidationError)
573
574 # request_password_reset_token signals
575 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
576@@ -258,11 +183,9 @@
577 in_signature='ss')
578 def request_password_reset_token(self, app_name, email):
579 """Call the matching method in the processor."""
580- def f():
581- """Inner function that will be run in a thread."""
582- return self.processor.request_password_reset_token(email)
583- blocking(f, app_name, self.PasswordResetTokenSent,
584- self.PasswordResetError)
585+ self.root.request_password_reset_token(app_name, email, blocking,
586+ self.PasswordResetTokenSent,
587+ self.PasswordResetError)
588
589 # set_new_password signals
590 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
591@@ -281,11 +204,9 @@
592 in_signature='ssss')
593 def set_new_password(self, app_name, email, token, new_password):
594 """Call the matching method in the processor."""
595- def f():
596- """Inner function that will be run in a thread."""
597- return self.processor.set_new_password(email, token,
598- new_password)
599- blocking(f, app_name, self.PasswordChanged, self.PasswordChangeError)
600+ self.root.set_new_password(app_name, email, token, new_password,
601+ blocking, self.PasswordChanged,
602+ self.PasswordChangeError)
603
604
605 class SSOCredentials(dbus.service.Object):
606@@ -296,7 +217,7 @@
607
608 def __init__(self, *args, **kwargs):
609 dbus.service.Object.__init__(self, *args, **kwargs)
610- self.ping_url = os.environ.get('USSOC_PING_URL', U1_PING_URL)
611+ self.root = SSOCredentialsRoot()
612
613 def _process_error(self, app_name, error_dict):
614 """Process the 'error_dict' and emit CredentialsError."""
615@@ -327,17 +248,7 @@
616 async_callbacks=("callback", "errback"))
617 def find_credentials(self, app_name, callback=NO_OP, errback=NO_OP):
618 """Get the credentials from the keyring or {} if not there."""
619-
620- def log_result(result):
621- """Log the result and continue."""
622- logger.info('find_credentials: app_name "%s", result is {}? %s',
623- app_name, result == {})
624- return result
625-
626- d = Credentials(app_name=app_name).find_credentials()
627- # pylint: disable=E1101
628- d.addCallback(log_result)
629- d.addCallbacks(callback, errback)
630+ self.root.find_credentials(app_name, callback, errback)
631
632 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,
633 in_signature="sssx", out_signature="")
634@@ -354,14 +265,12 @@
635 the GUI. If 0, no parent will be set.
636
637 """
638- ping_url = self.ping_url if app_name == U1_APP_NAME else None
639- obj = Credentials(app_name=app_name, ping_url=ping_url,
640- tc_url=terms_and_conditions_url,
641- help_text=help_text, window_id=window_id,
642- success_cb=self.CredentialsFound,
643- error_cb=self._process_error,
644- denial_cb=self.AuthorizationDenied)
645- obj.register()
646+ self.root.login_or_register_to_get_credentials(app_name,
647+ terms_and_conditions_url,
648+ help_text, window_id,
649+ self.CredentialsFound,
650+ self._process_error,
651+ self.AuthorizationDenied)
652
653 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,
654 in_signature="ssx", out_signature="")
655@@ -375,13 +284,10 @@
656 the GUI. If 0, no parent will be set.
657
658 """
659- ping_url = self.ping_url if app_name == U1_APP_NAME else None
660- obj = Credentials(app_name=app_name, ping_url=ping_url, tc_url=None,
661- help_text=help_text, window_id=window_id,
662- success_cb=self.CredentialsFound,
663- error_cb=self._process_error,
664- denial_cb=self.AuthorizationDenied)
665- obj.login()
666+ self.root.login_to_get_credentials(app_name, help_text, window_id,
667+ self.CredentialsFound,
668+ self._process_error,
669+ self.AuthorizationDenied)
670
671 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,
672 in_signature='s', out_signature='',
673@@ -391,9 +297,7 @@
674
675 'app_name' is the name of the application.
676 """
677- d = Credentials(app_name=app_name).clear_credentials()
678- # pylint: disable=E1101
679- d.addCallbacks(lambda _: callback(), errback)
680+ self.root.clear_token(app_name, callback, errback)
681
682
683 class CredentialsManagement(dbus.service.Object):
684@@ -427,22 +331,13 @@
685 self._ref_count = 0
686 self.timeout_func = timeout_func
687 self.shutdown_func = shutdown_func
688+ self.root = CredentialsManagementRoot(self.CredentialsFound,
689+ self.CredentialsError,
690+ self.AuthorizationDenied)
691
692 # Operator not preceded by a space (fails with dbus decorators)
693 # pylint: disable=C0322
694
695- valid_keys = (HELP_TEXT_KEY, PING_URL_KEY, TC_URL_KEY,
696- UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY)
697-
698- def _parse_args(self, args):
699- """Retrieve values from the generic param 'args'."""
700- result = dict(i for i in args.iteritems() if i[0] in self.valid_keys)
701- result[WINDOW_ID_KEY] = int(args.get(WINDOW_ID_KEY, 0))
702- result[SUCCESS_CB_KEY] = self.CredentialsFound
703- result[ERROR_CB_KEY] = self.CredentialsError
704- result[DENIAL_CB_KEY] = self.AuthorizationDenied
705- return result
706-
707 def _process_failure(self, failure, app_name):
708 """Process the 'failure' and emit CredentialsError."""
709 self.CredentialsError(app_name, except_to_errdict(failure.value))
710@@ -539,11 +434,8 @@
711 else:
712 self.CredentialsNotFound(app_name)
713
714- obj = Credentials(app_name)
715- d = obj.find_credentials()
716- # pylint: disable=E1101
717- d.addCallback(success_cb)
718- d.addErrback(self._process_failure, app_name)
719+ self.root.find_credentials(app_name, args, success_cb,
720+ self._process_failure)
721
722 @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
723 in_signature='sa{ss}', out_signature='')
724@@ -557,12 +449,9 @@
725
726 """
727 self.ref_count += 1
728-
729- obj = Credentials(app_name)
730- d = obj.clear_credentials()
731- # pylint: disable=E1101
732- d.addCallback(lambda _: self.CredentialsCleared(app_name))
733- d.addErrback(self._process_failure, app_name)
734+ self.root.clear_credentials(app_name, args,
735+ lambda _: self.CredentialsCleared(app_name),
736+ self._process_failure)
737
738 @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
739 in_signature='sa{ss}', out_signature='')
740@@ -578,27 +467,20 @@
741
742 """
743 self.ref_count += 1
744-
745- obj = Credentials(app_name)
746- d = obj.store_credentials(args)
747- # pylint: disable=E1101
748- d.addCallback(lambda _: self.CredentialsStored(app_name))
749- d.addErrback(self._process_failure, app_name)
750+ self.root.store_credentials(app_name, args,
751+ lambda _: self.CredentialsStored(app_name),
752+ self._process_failure)
753
754 @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
755 in_signature='sa{ss}', out_signature='')
756 def register(self, app_name, args):
757 """Get credentials if found else prompt GUI to register."""
758 self.ref_count += 1
759-
760- obj = Credentials(app_name, **self._parse_args(args))
761- obj.register()
762+ self.root.register(app_name, args)
763
764 @dbus.service.method(dbus_interface=DBUS_CREDENTIALS_IFACE,
765 in_signature='sa{ss}', out_signature='')
766 def login(self, app_name, args):
767 """Get credentials if found else prompt GUI to login."""
768 self.ref_count += 1
769-
770- obj = Credentials(app_name, **self._parse_args(args))
771- obj.login()
772+ self.root.login(app_name, args)
773
774=== added file 'ubuntu_sso/main/windows.py'
775--- ubuntu_sso/main/windows.py 1970-01-01 00:00:00 +0000
776+++ ubuntu_sso/main/windows.py 2011-03-17 08:43:34 +0000
777@@ -0,0 +1,17 @@
778+# -*- coding: utf-8 -*-
779+# Author: Manuel de la Pena <manuel@canonical.com>
780+#
781+# Copyright 2011 Canonical Ltd.
782+#
783+# This program is free software: you can redistribute it and/or modify it
784+# under the terms of the GNU General Public License version 3, as published
785+# by the Free Software Foundation.
786+#
787+# This program is distributed in the hope that it will be useful, but
788+# WITHOUT ANY WARRANTY; without even the implied warranties of
789+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
790+# PURPOSE. See the GNU General Public License for more details.
791+#
792+# You should have received a copy of the GNU General Public License along
793+# with this program. If not, see <http://www.gnu.org/licenses/>.
794+"""Main implementation on windows."""
795
796=== renamed file 'ubuntu_sso/tests/keyring/test_linux_keyring.py' => 'ubuntu_sso/tests/keyring/test_linux.py'
797=== renamed file 'ubuntu_sso/tests/keyring/test_windows_keyring.py' => 'ubuntu_sso/tests/keyring/test_windows.py'
798=== added directory 'ubuntu_sso/tests/main'
799=== added file 'ubuntu_sso/tests/main/__init__.py'
800--- ubuntu_sso/tests/main/__init__.py 1970-01-01 00:00:00 +0000
801+++ ubuntu_sso/tests/main/__init__.py 2011-03-17 08:43:34 +0000
802@@ -0,0 +1,17 @@
803+# -*- coding: utf-8 -*-
804+# Author: Manuel de la Pena <manuel@canonical.com>
805+#
806+# Copyright 2011 Canonical Ltd.
807+#
808+# This program is free software: you can redistribute it and/or modify it
809+# under the terms of the GNU General Public License version 3, as published
810+# by the Free Software Foundation.
811+#
812+# This program is distributed in the hope that it will be useful, but
813+# WITHOUT ANY WARRANTY; without even the implied warranties of
814+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
815+# PURPOSE. See the GNU General Public License for more details.
816+#
817+# You should have received a copy of the GNU General Public License along
818+# with this program. If not, see <http://www.gnu.org/licenses/>.
819+"""Test the different main implementations."""
820
821=== added file 'ubuntu_sso/tests/main/test_common.py'
822--- ubuntu_sso/tests/main/test_common.py 1970-01-01 00:00:00 +0000
823+++ ubuntu_sso/tests/main/test_common.py 2011-03-17 08:43:34 +0000
824@@ -0,0 +1,244 @@
825+# -*- coding: utf-8 -*-
826+#
827+# test_main - tests for ubuntu_sso.main
828+#
829+# Author: Natalia Bidart <natalia.bidart@canonical.com>
830+# Author: Alejandro J. Cura <alecu@canonical.com>
831+# Author: Manuel de la Pena <manuel@canonical.com>
832+#
833+# Copyright 2009-2010 Canonical Ltd.
834+#
835+# This program is free software: you can redistribute it and/or modify it
836+# under the terms of the GNU General Public License version 3, as published
837+# by the Free Software Foundation.
838+#
839+# This program is distributed in the hope that it will be useful, but
840+# WITHOUT ANY WARRANTY; without even the implied warranties of
841+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
842+# PURPOSE. See the GNU General Public License for more details.
843+#
844+# You should have received a copy of the GNU General Public License along
845+# with this program. If not, see <http://www.gnu.org/licenses/>.
846+"""Tests share by diff platforms."""
847+
848+import os
849+
850+from unittest import TestCase
851+from mocker import MockerTestCase, MATCH
852+from ubuntu_sso.main import (
853+ CredentialsManagement,
854+ SSOCredentialsRoot,
855+ SSOCredentials,
856+ SSOLogin,
857+ U1_PING_URL)
858+
859+
860+class EnvironOverridesTestCase(TestCase):
861+ """Some URLs can be set from the environment for testing/QA purposes."""
862+
863+ def test_override_ping_url(self):
864+ """The ping url can be set from the environ via USSOC_PING_URL."""
865+ fake_url = 'this is not really a URL'
866+ old_url = os.environ.get('USSOC_PING_URL')
867+ os.environ['USSOC_PING_URL'] = fake_url
868+ try:
869+ creds = SSOCredentialsRoot()
870+ self.assertEqual(creds.ping_url, fake_url)
871+ finally:
872+ if old_url:
873+ os.environ['USSOC_PING_URL'] = old_url
874+ else:
875+ del os.environ['USSOC_PING_URL']
876+
877+ def test_no_override_ping_url(self):
878+ """If the environ is unset, the default ping url is used."""
879+ creds = SSOCredentialsRoot()
880+ self.assertEqual(creds.ping_url, U1_PING_URL)
881+
882+
883+class SSOLoginMockedTestCase(MockerTestCase):
884+ """Test that the call are relied correctly."""
885+
886+ def setUp(self):
887+ """Setup tests."""
888+ super(SSOLoginMockedTestCase, self).setUp()
889+ self.root = self.mocker.mock()
890+ mockbusname = self.mocker.mock()
891+ mockbus = self.mocker.mock()
892+ mockbusname.get_bus()
893+ self.mocker.result(mockbus)
894+ self.login = SSOLogin(mockbus)
895+ self.login.root = self.root
896+ self.mocker.reset()
897+
898+ def test_generate_captcha(self):
899+ """Test that the call is relayed."""
900+ app_name = 'app'
901+ filename = 'file'
902+ self.root.generate_captcha(app_name, filename, MATCH(callable),
903+ MATCH(callable), MATCH(callable))
904+ self.mocker.replay()
905+ self.login.generate_captcha(app_name, filename)
906+
907+ def test_register_user(self):
908+ """Test that the call is relayed."""
909+ app_name = 'app'
910+ email = 'email'
911+ password = 'pwd'
912+ captcha_id = 'id'
913+ captcha_solution = 'hello'
914+ self.root.register_user(app_name, email, password, captcha_id,
915+ captcha_solution, MATCH(callable),
916+ MATCH(callable), MATCH(callable))
917+ self.mocker.replay()
918+ self.login.register_user(app_name, email, password, captcha_id,
919+ captcha_solution)
920+
921+ def test_login(self):
922+ """Test that the call is relayed."""
923+ app_name = 'app'
924+ email = 'email'
925+ password = 'password'
926+ self.root.login(app_name, email, password, MATCH(callable),
927+ MATCH(callable), MATCH(callable),
928+ MATCH(callable))
929+ self.mocker.mock()
930+ self.mocker.replay()
931+ self.login.login(app_name, email, password)
932+
933+ def test_validate_email(self):
934+ """Test that the call is relayed."""
935+ app_name = 'app'
936+ email = 'email'
937+ password = 'passwrd'
938+ email_token = 'token'
939+ self.root.validate_email(app_name, email, password, email_token,
940+ MATCH(callable), MATCH(callable),
941+ MATCH(callable))
942+ self.mocker.replay()
943+ self.login.validate_email(app_name, email, password, email_token)
944+
945+ def test_request_password_reset_tolen(self):
946+ """Test that the call is relayed."""
947+ app_name = 'app'
948+ email = 'email'
949+ self.root.request_password_reset_token(app_name, email,
950+ MATCH(callable),
951+ MATCH(callable),
952+ MATCH(callable))
953+ self.mocker.replay()
954+ self.login.request_password_reset_token(app_name, email)
955+
956+ def test_set_new_password(self):
957+ """Test that the call is relayed."""
958+ app_name = 'app'
959+ email = 'email'
960+ token = 'token'
961+ new_password = 'new'
962+ self.root.set_new_password(app_name, email, token, new_password,
963+ MATCH(callable), MATCH(callable),
964+ MATCH(callable))
965+ self.mocker.replay()
966+ self.login.set_new_password(app_name, email, token, new_password)
967+
968+
969+class SSOCredentialsMockedTestCase(MockerTestCase):
970+ """Test that the call are relied correctly."""
971+
972+ def setUp(self):
973+ """Setup tests."""
974+ super(SSOCredentialsMockedTestCase, self).setUp()
975+ self.root = self.mocker.mock()
976+ mockbusname = self.mocker.mock()
977+ mockbus = self.mocker.mock()
978+ mockbusname.get_bus()
979+ self.mocker.result(mockbus)
980+ self.cred = SSOCredentials(mockbus)
981+ self.cred.root = self.root
982+ self.mocker.reset()
983+
984+ def test_find_credentials(self):
985+ """Test that the call is relayed."""
986+ app_name = 'app'
987+ result_cb = error_cb = lambda: None
988+ self.root.find_credentials(app_name, result_cb, error_cb)
989+ self.mocker.mock()
990+ self.mocker.replay()
991+ self.cred.find_credentials(app_name, result_cb, error_cb)
992+
993+ def test_login_or_register_to_get_credentials(self):
994+ """Test that the call is relayed."""
995+ app_name = 'app'
996+ terms = 'terms'
997+ help_text = 'help'
998+ window_id = 'id'
999+ self.root.login_or_register_to_get_credentials(app_name, terms,
1000+ help_text, window_id,
1001+ MATCH(callable),
1002+ MATCH(callable),
1003+ MATCH(callable))
1004+ self.mocker.replay()
1005+ self.cred.login_or_register_to_get_credentials(app_name, terms,
1006+ help_text, window_id)
1007+
1008+ def test_clear_token(self):
1009+ """Test that the call is relayed."""
1010+ app_name = 'app'
1011+ result_cb = error_cb = lambda: None
1012+ self.root.clear_token(app_name, result_cb, error_cb)
1013+ self.mocker.replay()
1014+ self.cred.clear_token(app_name, result_cb, error_cb)
1015+
1016+
1017+class CredentialsManagementMockedTestCase(MockerTestCase):
1018+ """Test that the call are relied correctly."""
1019+
1020+ def setUp(self):
1021+ """Setup tests."""
1022+ super(CredentialsManagementMockedTestCase, self).setUp()
1023+ self.root = self.mocker.mock()
1024+ self.cred = CredentialsManagement(None, None)
1025+ self.cred.root = self.root
1026+
1027+ def test_find_credentials(self):
1028+ """Test that the call is relayed."""
1029+ app_name = 'app'
1030+ args = 'args'
1031+ self.root.find_credentials(app_name, args, MATCH(callable),
1032+ MATCH(callable))
1033+ self.mocker.replay()
1034+ self.cred.find_credentials(app_name, args)
1035+
1036+ def test_clear_credentials(self):
1037+ """Test that the call is relayed."""
1038+ app_name = 'app'
1039+ args = 'args'
1040+ self.root.clear_credentials(app_name, args, MATCH(callable),
1041+ MATCH(callable))
1042+ self.mocker.replay()
1043+ self.cred.clear_credentials(app_name, args)
1044+
1045+ def test_store_credentials(self):
1046+ """Test that the call is relayed."""
1047+ app_name = 'app'
1048+ args = 'args'
1049+ self.root.store_credentials(app_name, args, MATCH(callable),
1050+ MATCH(callable))
1051+ self.mocker.replay()
1052+ self.cred.store_credentials(app_name, args)
1053+
1054+ def test_register(self):
1055+ """Test that the call is relayed."""
1056+ app_name = 'app'
1057+ args = 'args'
1058+ self.root.register(app_name, args)
1059+ self.mocker.replay()
1060+ self.cred.register(app_name, args)
1061+
1062+ def test_login(self):
1063+ """Test that the call is relayed."""
1064+ app_name = 'app'
1065+ args = 'args'
1066+ self.root.login(app_name, args)
1067+ self.mocker.replay()
1068+ self.cred.login(app_name, args)
1069
1070=== renamed file 'ubuntu_sso/tests/test_main.py' => 'ubuntu_sso/tests/main/test_linux.py'
1071--- ubuntu_sso/tests/test_main.py 2011-01-28 13:45:09 +0000
1072+++ ubuntu_sso/tests/main/test_linux.py 2011-03-17 08:43:34 +0000
1073@@ -31,12 +31,13 @@
1074
1075 import ubuntu_sso.keyring
1076 import ubuntu_sso.main
1077+import ubuntu_sso.main.linux
1078
1079 from ubuntu_sso import DBUS_CREDENTIALS_IFACE
1080 from ubuntu_sso.keyring import U1_APP_NAME
1081-from ubuntu_sso.main import (U1_PING_URL, TIMEOUT_INTERVAL,
1082- blocking, except_to_errdict,
1083+from ubuntu_sso.main import (U1_PING_URL, except_to_errdict,
1084 CredentialsManagement, SSOCredentials, SSOLogin)
1085+from ubuntu_sso.main.linux import TIMEOUT_INTERVAL, blocking
1086 from ubuntu_sso.main import (HELP_TEXT_KEY, PING_URL_KEY,
1087 TC_URL_KEY, UI_CLASS_KEY, UI_MODULE_KEY, WINDOW_ID_KEY,
1088 SUCCESS_CB_KEY, ERROR_CB_KEY, DENIAL_CB_KEY)
1089@@ -120,7 +121,7 @@
1090 expected_result = "expected result"
1091 self.create_mock_processor().generate_captcha(filename)
1092 self.mocker.result(expected_result)
1093- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1094+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1095 self.mocker.replay()
1096
1097 def verify(app_name, result):
1098@@ -143,7 +144,7 @@
1099 expected_result = "expected result"
1100 self.create_mock_processor().generate_captcha(filename)
1101 self.mocker.result(expected_result)
1102- self.patch(ubuntu_sso.main, "blocking", fake_err_blocking)
1103+ self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking)
1104 self.mocker.replay()
1105
1106 def verify(app_name, errdict):
1107@@ -166,7 +167,7 @@
1108 self.create_mock_processor().register_user(EMAIL, PASSWORD, CAPTCHA_ID,
1109 CAPTCHA_SOLUTION)
1110 self.mocker.result(expected_result)
1111- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1112+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1113 self.mocker.replay()
1114
1115 def verify(app_name, result):
1116@@ -190,7 +191,7 @@
1117 self.create_mock_processor().register_user(EMAIL, PASSWORD, CAPTCHA_ID,
1118 CAPTCHA_SOLUTION)
1119 self.mocker.result(expected_result)
1120- self.patch(ubuntu_sso.main, "blocking", fake_err_blocking)
1121+ self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking)
1122 self.mocker.replay()
1123
1124 def verify(app_name, errdict):
1125@@ -215,7 +216,7 @@
1126 self.mocker.result(TOKEN)
1127 processor.is_validated(TOKEN)
1128 self.mocker.result(True)
1129- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1130+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1131 self.mocker.replay()
1132
1133 def verify(app_name, result):
1134@@ -241,7 +242,7 @@
1135 self.mocker.result(TOKEN)
1136 processor.is_validated(TOKEN)
1137 self.mocker.result(False)
1138- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1139+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1140 self.mocker.replay()
1141
1142 def verify(app_name, email):
1143@@ -263,7 +264,7 @@
1144 """The login method fails as expected when get_token_name fails."""
1145 d = Deferred()
1146 self.create_mock_processor()
1147- self.patch(ubuntu_sso.main, "blocking", fake_err_blocking)
1148+ self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking)
1149
1150 def fake_gtn(*args):
1151 """A fake get_token_name that fails."""
1152@@ -296,7 +297,7 @@
1153 processor.is_validated(TOKEN)
1154 self.mocker.result(True)
1155
1156- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1157+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1158
1159 def fake_set_creds(*args):
1160 """A fake Keyring.set_credentials that fails."""
1161@@ -327,7 +328,7 @@
1162 self.create_mock_processor().validate_email(EMAIL, PASSWORD,
1163 EMAIL_TOKEN, TOKEN_NAME)
1164 self.mocker.result(TOKEN)
1165- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1166+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1167 self.mocker.replay()
1168
1169 def verify(app_name, result):
1170@@ -348,7 +349,7 @@
1171 """Test that the validate_email method fails as expected."""
1172 d = Deferred()
1173 self.create_mock_processor()
1174- self.patch(ubuntu_sso.main, "blocking", fake_err_blocking)
1175+ self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking)
1176
1177 def fake_gtn(*args):
1178 """A fake get_token_name that fails."""
1179@@ -376,7 +377,7 @@
1180 d = Deferred()
1181 processor = self.create_mock_processor()
1182 processor.request_password_reset_token(EMAIL)
1183- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1184+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1185 self.mocker.result(EMAIL)
1186 self.mocker.replay()
1187
1188@@ -399,7 +400,7 @@
1189
1190 self.create_mock_processor().request_password_reset_token(EMAIL)
1191 self.mocker.result(EMAIL)
1192- self.patch(ubuntu_sso.main, "blocking", fake_err_blocking)
1193+ self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking)
1194 self.mocker.replay()
1195
1196 def verify(app_name, errdict):
1197@@ -421,7 +422,7 @@
1198 self.create_mock_processor().set_new_password(EMAIL, EMAIL_TOKEN,
1199 PASSWORD)
1200 self.mocker.result(EMAIL)
1201- self.patch(ubuntu_sso.main, "blocking", fake_ok_blocking)
1202+ self.patch(ubuntu_sso.main.linux, "blocking", fake_ok_blocking)
1203 self.mocker.replay()
1204
1205 def verify(app_name, result):
1206@@ -445,7 +446,7 @@
1207 self.create_mock_processor().set_new_password(EMAIL, EMAIL_TOKEN,
1208 PASSWORD)
1209 self.mocker.result(expected_result)
1210- self.patch(ubuntu_sso.main, "blocking", fake_err_blocking)
1211+ self.patch(ubuntu_sso.main.linux, "blocking", fake_err_blocking)
1212 self.mocker.replay()
1213
1214 def verify(app_name, errdict):
1215@@ -687,7 +688,7 @@
1216 os.environ['USSOC_PING_URL'] = fake_url
1217 try:
1218 creds = SSOCredentials(None)
1219- self.assertEqual(creds.ping_url, fake_url)
1220+ self.assertEqual(creds.root.ping_url, fake_url)
1221 finally:
1222 if old_url:
1223 os.environ['USSOC_PING_URL'] = old_url
1224@@ -697,7 +698,7 @@
1225 def test_no_override_ping_url(self):
1226 """If the environ is unset, the default ping url is used."""
1227 creds = SSOCredentials(None)
1228- self.assertEqual(creds.ping_url, U1_PING_URL)
1229+ self.assertEqual(creds.root.ping_url, U1_PING_URL)
1230
1231
1232 class CredentialsManagementTestCase(TestCase):
1233@@ -746,7 +747,8 @@
1234
1235 def test_is_dbus_object(self):
1236 """CredentialsManagement is a Dbus object."""
1237- self.assertIsInstance(self.client, ubuntu_sso.main.dbus.service.Object)
1238+ self.assertIsInstance(self.client,
1239+ ubuntu_sso.main.linux.dbus.service.Object)
1240
1241
1242 class FakeCredentials(object):
1243
1244=== added file 'ubuntu_sso/tests/main/test_windows.py'
1245--- ubuntu_sso/tests/main/test_windows.py 1970-01-01 00:00:00 +0000
1246+++ ubuntu_sso/tests/main/test_windows.py 2011-03-17 08:43:34 +0000
1247@@ -0,0 +1,17 @@
1248+# -*- coding: utf-8 -*-
1249+# Author: Manuel de la Pena <manuel@canonical.com>
1250+#
1251+# Copyright 2011 Canonical Ltd.
1252+#
1253+# This program is free software: you can redistribute it and/or modify it
1254+# under the terms of the GNU General Public License version 3, as published
1255+# by the Free Software Foundation.
1256+#
1257+# This program is distributed in the hope that it will be useful, but
1258+# WITHOUT ANY WARRANTY; without even the implied warranties of
1259+# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
1260+# PURPOSE. See the GNU General Public License for more details.
1261+#
1262+# You should have received a copy of the GNU General Public License along
1263+# with this program. If not, see <http://www.gnu.org/licenses/>.
1264+"""Windows tests."""
1265
1266=== renamed file 'ubuntu_sso/tests/networkstate/test_linux_networkstate.py' => 'ubuntu_sso/tests/networkstate/test_linux.py'
1267=== renamed file 'ubuntu_sso/tests/networkstate/test_windows_networkstate.py' => 'ubuntu_sso/tests/networkstate/test_windows.py'

Subscribers

People subscribed via source and target branches