Merge lp:~nataliabidart/ubuntu-sso-client/handle-user-not-validated-stable into lp:ubuntu-sso-client/stable-1-0

Proposed by Natalia Bidart
Status: Merged
Approved by: Natalia Bidart
Approved revision: 637
Merged at revision: 637
Proposed branch: lp:~nataliabidart/ubuntu-sso-client/handle-user-not-validated-stable
Merge into: lp:ubuntu-sso-client/stable-1-0
Diff against target: 449 lines (+173/-34)
4 files modified
ubuntu_sso/gui.py (+19/-6)
ubuntu_sso/main.py (+57/-24)
ubuntu_sso/tests/test_gui.py (+26/-1)
ubuntu_sso/tests/test_main.py (+71/-3)
To merge this branch: bzr merge lp:~nataliabidart/ubuntu-sso-client/handle-user-not-validated-stable
Reviewer Review Type Date Requested Status
Alejandro J. Cura (community) Approve
Roman Yepishev (community) fieldtest Approve
Review via email: mp+39786@code.launchpad.net

Commit message

* Added a new DBus signal UserNotValidated to indicate when a user is registered but not validated (LP: #667899).
* Added new workflow so email validation is requested if necessary.

Description of the change

To test, follow the same procedure as in

https://code.launchpad.net/~nataliabidart/ubuntu-sso-client/handle-user-not-validated/+merge/39779

but use instead the ApplicationCredentials interface in the /credentials object path. Run the "login_or_register_to_get_credentials" method and pass parameters like these:

'Ubuntu One', '', '', 0

The rest of the workflow is the same.

To post a comment you must log in.
Revision history for this message
Roman Yepishev (rye) wrote :

Works as advertised. This branch is awesome too.

review: Approve (fieldtest)
Revision history for this message
Alejandro J. Cura (alecu) wrote :

I approve of this branch.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ubuntu_sso/gui.py'
--- ubuntu_sso/gui.py 2010-10-01 13:14:34 +0000
+++ ubuntu_sso/gui.py 2010-11-01 21:13:47 +0000
@@ -252,6 +252,8 @@
252 self.tc_uri = tc_uri252 self.tc_uri = tc_uri
253 self.help_text = help_text253 self.help_text = help_text
254 self.close_callback = close_callback254 self.close_callback = close_callback
255 self.user_email = None
256 self.user_password = None
255257
256 ui_filename = get_data_file('ui.glade')258 ui_filename = get_data_file('ui.glade')
257 builder = gtk.Builder()259 builder = gtk.Builder()
@@ -357,6 +359,8 @@
357 self._filter_by_app_name(self.on_logged_in),359 self._filter_by_app_name(self.on_logged_in),
358 'LoginError':360 'LoginError':
359 self._filter_by_app_name(self.on_login_error),361 self._filter_by_app_name(self.on_login_error),
362 'UserNotValidated':
363 self._filter_by_app_name(self.on_user_not_validated),
360 'PasswordResetTokenSent':364 'PasswordResetTokenSent':
361 self._filter_by_app_name(self.on_password_reset_token_sent),365 self._filter_by_app_name(self.on_password_reset_token_sent),
362 'PasswordResetError':366 'PasswordResetError':
@@ -417,8 +421,8 @@
417421
418 match = self.bus.add_signal_receiver(method, signal_name=signal,422 match = self.bus.add_signal_receiver(method, signal_name=signal,
419 dbus_interface=iface)423 dbus_interface=iface)
420 logger.info('Connecting signal %r with method %r at iface %r.' \424 logger.debug('Connecting signal %r with method %r at iface %r.' \
421 'Match: %r', signal, method, iface, match)425 'Match: %r', signal, method, iface, match)
422 self._signals_receivers[(iface, signal)] = method426 self._signals_receivers[(iface, signal)] = method
423427
424 def _debug(self, *args, **kwargs):428 def _debug(self, *args, **kwargs):
@@ -725,8 +729,8 @@
725 remove = self.bus.remove_signal_receiver729 remove = self.bus.remove_signal_receiver
726 for (iface, signal) in self._signals_receivers.keys():730 for (iface, signal) in self._signals_receivers.keys():
727 method = self._signals_receivers.pop((iface, signal))731 method = self._signals_receivers.pop((iface, signal))
728 logger.info('Removing signal %r with method %r at iface %r.',732 logger.debug('Removing signal %r with method %r at iface %r.',
729 signal, method, iface)733 signal, method, iface)
730 remove(method, signal_name=signal, dbus_interface=iface)734 remove(method, signal_name=signal, dbus_interface=iface)
731735
732 # hide the main window736 # hide the main window
@@ -804,6 +808,8 @@
804 return808 return
805809
806 self._set_current_page(self.processing_vbox)810 self._set_current_page(self.processing_vbox)
811 self.user_email = email1
812 self.user_password = password1
807813
808 logger.info('Calling register_user with email %r, password <hidden>,' \814 logger.info('Calling register_user with email %r, password <hidden>,' \
809 ' captcha_id %r and captcha_solution %r.', email1,815 ' captcha_id %r and captcha_solution %r.', email1,
@@ -832,8 +838,8 @@
832 self.email_token_entry.set_warning(self.FIELD_REQUIRED)838 self.email_token_entry.set_warning(self.FIELD_REQUIRED)
833 return839 return
834840
835 email = self.email1_entry.get_text()841 email = self.user_email
836 password = self.password1_entry.get_text()842 password = self.user_password
837 f = self.backend.validate_email843 f = self.backend.validate_email
838 logger.info('Calling validate_email with email %r, password <hidden>' \844 logger.info('Calling validate_email with email %r, password <hidden>' \
839 ', app_name %r and email_token %r.', email, self.app_name,845 ', app_name %r and email_token %r.', email, self.app_name,
@@ -871,6 +877,8 @@
871 reply_handler=NO_OP, error_handler=NO_OP)877 reply_handler=NO_OP, error_handler=NO_OP)
872878
873 self._set_current_page(self.processing_vbox)879 self._set_current_page(self.processing_vbox)
880 self.user_email = email
881 self.user_password = password
874882
875 def on_login_back_button_clicked(self, *args, **kwargs):883 def on_login_back_button_clicked(self, *args, **kwargs):
876 """User wants to go to the previous page."""884 """User wants to go to the previous page."""
@@ -1061,6 +1069,11 @@
1061 msg))1069 msg))
10621070
1063 @log_call1071 @log_call
1072 def on_user_not_validated(self, app_name, email, *args, **kwargs):
1073 """User was not validated."""
1074 self.on_user_registered(app_name, email)
1075
1076 @log_call
1064 def on_password_reset_token_sent(self, app_name, email, *args, **kwargs):1077 def on_password_reset_token_sent(self, app_name, email, *args, **kwargs):
1065 """Password reset token was successfully sent."""1078 """Password reset token was successfully sent."""
1066 msg = self.SET_NEW_PASSWORD_LABEL % {'email': email}1079 msg = self.SET_NEW_PASSWORD_LABEL % {'email': email}
10671080
=== modified file 'ubuntu_sso/main.py'
--- ubuntu_sso/main.py 2010-10-18 17:34:04 +0000
+++ ubuntu_sso/main.py 2010-11-01 21:13:47 +0000
@@ -209,6 +209,27 @@
209 'token_name: %r', credentials['consumer_key'], token_name)209 'token_name: %r', credentials['consumer_key'], token_name)
210 return credentials210 return credentials
211211
212 def is_validated(self, email, password, token_name, sso_service=None):
213 """Return if user with 'email' and 'password' is validated."""
214 if sso_service is None:
215 token = self.login(email=email, password=password,
216 token_name=token_name)
217
218 oauth_token = oauth.OAuthToken(token['token'],
219 token['token_secret'])
220 authorizer = OAuthAuthorizer(token['consumer_key'],
221 token['consumer_secret'],
222 oauth_token)
223 sso_service = self.sso_service_class(authorizer, self.service_url)
224
225 me_info = sso_service.accounts.me()
226 key = 'preferred_email'
227 result = key in me_info and me_info[key] != None
228
229 logger.debug('is_validated: email: %r token_name: %r, result: %r.',
230 email, token_name, result)
231 return result
232
212 def validate_email(self, email, password, email_token, token_name):233 def validate_email(self, email, password, email_token, token_name):
213 """Validate an email token for user with 'email' and 'password'."""234 """Validate an email token for user with 'email' and 'password'."""
214 logger.debug('validate_email: email: %r password: <hidden>, '235 logger.debug('validate_email: email: %r password: <hidden>, '
@@ -311,12 +332,8 @@
311 dbus.service.Object.__init__(self, object_path="/sso",332 dbus.service.Object.__init__(self, object_path="/sso",
312 bus_name=bus_name)333 bus_name=bus_name)
313 self.sso_login_processor_class = sso_login_processor_class334 self.sso_login_processor_class = sso_login_processor_class
314 self.sso_service_class = sso_service_class335 self.processor = self.sso_login_processor_class(
315336 sso_service_class=sso_service_class)
316 def processor(self):
317 """Create a login processor with the given class and service class."""
318 return self.sso_login_processor_class(
319 sso_service_class=self.sso_service_class)
320337
321 # generate_capcha signals338 # generate_capcha signals
322 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")339 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
@@ -337,7 +354,7 @@
337 """Call the matching method in the processor."""354 """Call the matching method in the processor."""
338 def f():355 def f():
339 """Inner function that will be run in a thread."""356 """Inner function that will be run in a thread."""
340 return self.processor().generate_captcha(filename)357 return self.processor.generate_captcha(filename)
341 blocking(f, app_name, self.CaptchaGenerated,358 blocking(f, app_name, self.CaptchaGenerated,
342 self.CaptchaGenerationError)359 self.CaptchaGenerationError)
343360
@@ -361,8 +378,8 @@
361 """Call the matching method in the processor."""378 """Call the matching method in the processor."""
362 def f():379 def f():
363 """Inner function that will be run in a thread."""380 """Inner function that will be run in a thread."""
364 return self.processor().register_user(email, password,381 return self.processor.register_user(email, password,
365 captcha_id, captcha_solution)382 captcha_id, captcha_solution)
366 blocking(f, app_name, self.UserRegistered, self.UserRegistrationError)383 blocking(f, app_name, self.UserRegistered, self.UserRegistrationError)
367384
368 # login signals385 # login signals
@@ -378,6 +395,12 @@
378 logger.debug('SSOLogin: emitting LoginError with '395 logger.debug('SSOLogin: emitting LoginError with '
379 'app_name "%s" and error %r', app_name, error)396 'app_name "%s" and error %r', app_name, error)
380397
398 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
399 def UserNotValidated(self, app_name, result):
400 """Signal thrown when the user is not validated."""
401 logger.debug('SSOLogin: emitting UserNotValidated with app_name "%s" '
402 'and result %r', app_name, result)
403
381 @dbus.service.method(dbus_interface=DBUS_IFACE_USER_NAME,404 @dbus.service.method(dbus_interface=DBUS_IFACE_USER_NAME,
382 in_signature='sss')405 in_signature='sss')
383 def login(self, app_name, email, password):406 def login(self, app_name, email, password):
@@ -387,13 +410,23 @@
387 token_name = get_token_name(app_name)410 token_name = get_token_name(app_name)
388 logger.debug('login: token_name %r, email %r, password <hidden>.',411 logger.debug('login: token_name %r, email %r, password <hidden>.',
389 token_name, email)412 token_name, email)
390 credentials = self.processor().login(email, password, token_name)413 credentials = self.processor.login(email, password, token_name)
391 logger.debug('login returned not None credentials? %r.',414 logger.debug('login returned not None credentials? %r.',
392 credentials is not None)415 credentials is not None)
393 assert credentials is not None416 return credentials
394 keyring_store_credentials(app_name, credentials)417
395 return email418 def success_cb(app_name, credentials):
396 blocking(f, app_name, self.LoggedIn, self.LoginError)419 """Login finished successfull."""
420 token_name = get_token_name(app_name)
421 is_validated = self.processor.is_validated(email, password,
422 token_name)
423 logger.debug('user is validated? %r.', is_validated)
424 if is_validated:
425 keyring_store_credentials(app_name, credentials)
426 self.LoggedIn(app_name, email)
427 else:
428 self.UserNotValidated(app_name, email)
429 blocking(f, app_name, success_cb, self.LoginError)
397430
398 # validate_email signals431 # validate_email signals
399 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")432 @dbus.service.signal(DBUS_IFACE_USER_NAME, signature="ss")
@@ -415,8 +448,8 @@
415 def f():448 def f():
416 """Inner function that will be run in a thread."""449 """Inner function that will be run in a thread."""
417 token_name = get_token_name(app_name)450 token_name = get_token_name(app_name)
418 credentials = self.processor().validate_email(email, password,451 credentials = self.processor.validate_email(email, password,
419 email_token, token_name)452 email_token, token_name)
420 keyring_store_credentials(app_name, credentials)453 keyring_store_credentials(app_name, credentials)
421 return email454 return email
422 blocking(f, app_name, self.EmailValidated, self.EmailValidationError)455 blocking(f, app_name, self.EmailValidated, self.EmailValidationError)
@@ -440,7 +473,7 @@
440 """Call the matching method in the processor."""473 """Call the matching method in the processor."""
441 def f():474 def f():
442 """Inner function that will be run in a thread."""475 """Inner function that will be run in a thread."""
443 return self.processor().request_password_reset_token(email)476 return self.processor.request_password_reset_token(email)
444 blocking(f, app_name, self.PasswordResetTokenSent,477 blocking(f, app_name, self.PasswordResetTokenSent,
445 self.PasswordResetError)478 self.PasswordResetError)
446479
@@ -463,8 +496,8 @@
463 """Call the matching method in the processor."""496 """Call the matching method in the processor."""
464 def f():497 def f():
465 """Inner function that will be run in a thread."""498 """Inner function that will be run in a thread."""
466 return self.processor().set_new_password(email, token,499 return self.processor.set_new_password(email, token,
467 new_password)500 new_password)
468 blocking(f, app_name, self.PasswordChanged, self.PasswordChangeError)501 blocking(f, app_name, self.PasswordChanged, self.PasswordChangeError)
469502
470503
@@ -481,19 +514,19 @@
481 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="s")514 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="s")
482 def AuthorizationDenied(self, app_name):515 def AuthorizationDenied(self, app_name):
483 """Signal thrown when the user denies the authorization."""516 """Signal thrown when the user denies the authorization."""
484 logger.info('SSOLogin: emitting AuthorizationDenied with app_name '517 logger.info('SSOCredentials: emitting AuthorizationDenied with '
485 '"%s"', app_name)518 'app_name "%s"', app_name)
486519
487 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="sa{ss}")520 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="sa{ss}")
488 def CredentialsFound(self, app_name, credentials):521 def CredentialsFound(self, app_name, credentials):
489 """Signal thrown when the credentials are found."""522 """Signal thrown when the credentials are found."""
490 logger.info('SSOLogin: emitting CredentialsFound with app_name "%s"',523 logger.info('SSOCredentials: emitting CredentialsFound with '
491 app_name)524 'app_name "%s"', app_name)
492525
493 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="sss")526 @dbus.service.signal(DBUS_IFACE_CRED_NAME, signature="sss")
494 def CredentialsError(self, app_name, error_message, detailed_error):527 def CredentialsError(self, app_name, error_message, detailed_error):
495 """Signal thrown when there is a problem finding the credentials."""528 """Signal thrown when there is a problem finding the credentials."""
496 logger.debug('SSOCredentials: emitting CredentialsError with app_name '529 logger.error('SSOCredentials: emitting CredentialsError with app_name '
497 '"%s" and error_message %r', app_name, error_message)530 '"%s" and error_message %r', app_name, error_message)
498531
499 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,532 @dbus.service.method(dbus_interface=DBUS_IFACE_CRED_NAME,
500533
=== modified file 'ubuntu_sso/tests/test_gui.py'
--- ubuntu_sso/tests/test_gui.py 2010-09-07 13:57:35 +0000
+++ ubuntu_sso/tests/test_gui.py 2010-11-01 21:13:47 +0000
@@ -856,6 +856,12 @@
856 self.ui.join_ok_button.clicked()856 self.ui.join_ok_button.clicked()
857 self.assertTrue(self._called)857 self.assertTrue(self._called)
858858
859 def test_user_and_pass_are_cached(self):
860 """Username and password are temporarly cached for further use."""
861 self.click_join_with_valid_data()
862 self.assertEqual(self.ui.user_email, EMAIL)
863 self.assertEqual(self.ui.user_password, PASSWORD)
864
859865
860class NoTermsAndConditionsTestCase(UbuntuSSOClientTestCase):866class NoTermsAndConditionsTestCase(UbuntuSSOClientTestCase):
861 """Test suite for the user registration (with no t&c link)."""867 """Test suite for the user registration (with no t&c link)."""
@@ -1328,6 +1334,12 @@
1328 self.ui.on_login_error(app_name=APP_NAME, error=self.error)1334 self.ui.on_login_error(app_name=APP_NAME, error=self.error)
1329 self.assert_pages_visibility(login=True)1335 self.assert_pages_visibility(login=True)
13301336
1337 def test_on_user_not_validated_morphs_to_verify_page(self):
1338 """On user not validated, the verify page is shown."""
1339 self.click_connect_with_valid_data()
1340 self.ui.on_user_not_validated(app_name=APP_NAME, email=EMAIL)
1341 self.assert_pages_visibility(verify_email=True)
1342
1331 def test_on_login_error_a_warning_is_shown(self):1343 def test_on_login_error_a_warning_is_shown(self):
1332 """On user login error, a warning is shown with proper wording."""1344 """On user login error, a warning is shown with proper wording."""
1333 self.click_connect_with_valid_data()1345 self.click_connect_with_valid_data()
@@ -1377,6 +1389,12 @@
1377 self.ui.login_ok_button.clicked()1389 self.ui.login_ok_button.clicked()
1378 self.assertTrue(self._called)1390 self.assertTrue(self._called)
13791391
1392 def test_user_and_pass_are_cached(self):
1393 """Username and password are temporarly cached for further use."""
1394 self.click_connect_with_valid_data()
1395 self.assertEqual(self.ui.user_email, EMAIL)
1396 self.assertEqual(self.ui.user_password, PASSWORD)
1397
13801398
1381class LoginValidationTestCase(UbuntuSSOClientTestCase):1399class LoginValidationTestCase(UbuntuSSOClientTestCase):
1382 """Test suite for the user login validation."""1400 """Test suite for the user login validation."""
@@ -1782,7 +1800,7 @@
1782 """All the backend signals are listed to be binded."""1800 """All the backend signals are listed to be binded."""
1783 for sig in ('CaptchaGenerated', 'CaptchaGenerationError',1801 for sig in ('CaptchaGenerated', 'CaptchaGenerationError',
1784 'UserRegistered', 'UserRegistrationError',1802 'UserRegistered', 'UserRegistrationError',
1785 'LoggedIn', 'LoginError',1803 'LoggedIn', 'LoginError', 'UserNotValidated',
1786 'EmailValidated', 'EmailValidationError',1804 'EmailValidated', 'EmailValidationError',
1787 'PasswordResetTokenSent', 'PasswordResetError',1805 'PasswordResetTokenSent', 'PasswordResetError',
1788 'PasswordChanged', 'PasswordChangeError'):1806 'PasswordChanged', 'PasswordChangeError'):
@@ -1864,6 +1882,13 @@
1864 self.ui._signals['LoginError'](mismatch_app_name, 'dummy')1882 self.ui._signals['LoginError'](mismatch_app_name, 'dummy')
1865 self.assertFalse(self._called)1883 self.assertFalse(self._called)
18661884
1885 def test_on_user_not_validated_is_not_called(self):
1886 """on_user_not_validated is not called if incorrect app_name."""
1887 self.patch(self.ui, 'on_user_not_validated', self._set_called)
1888 mismatch_app_name = self.ui.app_name * 2
1889 self.ui._signals['UserNotValidated'](mismatch_app_name, 'dummy')
1890 self.assertFalse(self._called)
1891
1867 def test_on_password_reset_token_sent_is_not_called(self):1892 def test_on_password_reset_token_sent_is_not_called(self):
1868 """on_password_reset_token_sent is not called if incorrect app_name."""1893 """on_password_reset_token_sent is not called if incorrect app_name."""
1869 self.patch(self.ui, 'on_password_reset_token_sent', self._set_called)1894 self.patch(self.ui, 'on_password_reset_token_sent', self._set_called)
18701895
=== modified file 'ubuntu_sso/tests/test_main.py'
--- ubuntu_sso/tests/test_main.py 2010-10-18 17:34:04 +0000
+++ ubuntu_sso/tests/test_main.py 2010-11-01 21:13:47 +0000
@@ -152,6 +152,9 @@
152class FakedAccounts(object):152class FakedAccounts(object):
153 """Fake the accounts service."""153 """Fake the accounts service."""
154154
155 def __init__(self):
156 self.preferred_email = EMAIL
157
155 def validate_email(self, email_token):158 def validate_email(self, email_token):
156 """Fake the email validation. Return a fix result."""159 """Fake the email validation. Return a fix result."""
157 if email_token is None:160 if email_token is None:
@@ -164,6 +167,17 @@
164 else:167 else:
165 return STATUS_EMAIL_OK168 return STATUS_EMAIL_OK
166169
170 # pylint: disable=E0202, C0103
171
172 def me(self):
173 """Fake the 'me' information."""
174 return {u'username': u'Wh46bKY',
175 u'preferred_email': self.preferred_email,
176 u'displayname': u'',
177 u'unverified_emails': [u'aaaaaa@example.com'],
178 u'verified_emails': [],
179 u'openid_identifier': u'Wh46bKY'}
180
167181
168class FakedSSOServer(object):182class FakedSSOServer(object):
169 """Fake an SSO server."""183 """Fake an SSO server."""
@@ -279,6 +293,29 @@
279 result = self.processor.login(**self.login_kwargs)293 result = self.processor.login(**self.login_kwargs)
280 self.assertEqual(TOKEN, result, 'authentication was successful.')294 self.assertEqual(TOKEN, result, 'authentication was successful.')
281295
296 # is_validated
297
298 def test_is_validated(self):
299 """If preferred email is not None, user is validated."""
300 result = self.processor.is_validated(**self.login_kwargs)
301 self.assertTrue(result, 'user must be validated.')
302
303 def test_is_not_validated(self):
304 """If preferred email is None, user is not validated."""
305 service = FakedSSOServer(None, None)
306 service.accounts.preferred_email = None
307 result = self.processor.is_validated(sso_service=service,
308 **self.login_kwargs)
309 self.assertFalse(result, 'user must not be validated.')
310
311 def test_is_not_validated_empty_result(self):
312 """If preferred email is None, user is not validated."""
313 service = FakedSSOServer(None, None)
314 service.accounts.me = lambda: {}
315 result = self.processor.is_validated(sso_service=service,
316 **self.login_kwargs)
317 self.assertFalse(result, 'user must not be validated.')
318
282 # validate_email319 # validate_email
283320
284 def test_validate_email_if_status_ok(self):321 def test_validate_email_if_status_ok(self):
@@ -519,8 +556,11 @@
519 def test_login(self):556 def test_login(self):
520 """Test that the login method works ok."""557 """Test that the login method works ok."""
521 d = Deferred()558 d = Deferred()
522 self.create_mock_processor().login(EMAIL, PASSWORD, TOKEN_NAME)559 processor = self.create_mock_processor()
560 processor.login(EMAIL, PASSWORD, TOKEN_NAME)
523 self.mocker.result(TOKEN)561 self.mocker.result(TOKEN)
562 processor.is_validated(EMAIL, PASSWORD, TOKEN_NAME)
563 self.mocker.result(True)
524 self.patch(ubuntu_sso.main, "blocking", self.fake_ok_blocking)564 self.patch(ubuntu_sso.main, "blocking", self.fake_ok_blocking)
525 self.mocker.replay()565 self.mocker.replay()
526566
@@ -535,13 +575,40 @@
535 sso_login_processor_class=self.mockprocessorclass)575 sso_login_processor_class=self.mockprocessorclass)
536 self.patch(client, "LoggedIn", verify)576 self.patch(client, "LoggedIn", verify)
537 self.patch(client, "LoginError", d.errback)577 self.patch(client, "LoginError", d.errback)
578 self.patch(client, "UserNotValidated", d.errback)
579 client.login(APP_NAME, EMAIL, PASSWORD)
580 return d
581
582 def test_login_user_not_validated(self):
583 """Test that the login sends EmailNotValidated signal."""
584 d = Deferred()
585 processor = self.create_mock_processor()
586 processor.login(EMAIL, PASSWORD, TOKEN_NAME)
587 self.mocker.result(TOKEN)
588 processor.is_validated(EMAIL, PASSWORD, TOKEN_NAME)
589 self.mocker.result(False)
590 self.patch(ubuntu_sso.main, "blocking", self.fake_ok_blocking)
591 self.mocker.replay()
592
593 def verify(app_name, email):
594 """The actual test."""
595 self.assertEqual(app_name, APP_NAME)
596 self.assertEqual(email, EMAIL)
597 self.assertFalse(self.keyring_was_set, "Keyring should not be set")
598 d.callback("Ok")
599
600 client = SSOLogin(self.mockbusname,
601 sso_login_processor_class=self.mockprocessorclass)
602 self.patch(client, "LoggedIn", d.errback)
603 self.patch(client, "LoginError", d.errback)
604 self.patch(client, "UserNotValidated", verify)
538 client.login(APP_NAME, EMAIL, PASSWORD)605 client.login(APP_NAME, EMAIL, PASSWORD)
539 return d606 return d
540607
541 def test_login_error(self):608 def test_login_error(self):
542 """Test that the login method fails as expected."""609 """Test that the login method fails as expected."""
543 d = Deferred()610 d = Deferred()
544 self.mockprocessorclass = self.mocker.mock()611 self.create_mock_processor()
545 self.patch(ubuntu_sso.main, "blocking", self.fake_err_blocking)612 self.patch(ubuntu_sso.main, "blocking", self.fake_err_blocking)
546613
547 def fake_gtn(*args):614 def fake_gtn(*args):
@@ -562,6 +629,7 @@
562 sso_login_processor_class=self.mockprocessorclass)629 sso_login_processor_class=self.mockprocessorclass)
563 self.patch(client, "LoggedIn", d.errback)630 self.patch(client, "LoggedIn", d.errback)
564 self.patch(client, "LoginError", verify)631 self.patch(client, "LoginError", verify)
632 self.patch(client, "UserNotValidated", d.errback)
565 client.login(APP_NAME, EMAIL, PASSWORD)633 client.login(APP_NAME, EMAIL, PASSWORD)
566 return d634 return d
567635
@@ -591,7 +659,7 @@
591 def test_validate_email_error(self):659 def test_validate_email_error(self):
592 """Test that the validate_email method fails as expected."""660 """Test that the validate_email method fails as expected."""
593 d = Deferred()661 d = Deferred()
594 self.mockprocessorclass = self.mocker.mock()662 self.create_mock_processor()
595 self.patch(ubuntu_sso.main, "blocking", self.fake_err_blocking)663 self.patch(ubuntu_sso.main, "blocking", self.fake_err_blocking)
596664
597 def fake_gtn(*args):665 def fake_gtn(*args):

Subscribers

People subscribed via source and target branches