def test_delete(self): """ Deleting a user""" user = self.create_user() id = user.id with user_events.disconnect_receivers(): user_service.delete(user) self.assertIsNone(user_service.get(id))
def test_login_validates_password_before_requiring_confirmation(self): """ Validate password first before requiring account confirmation""" with user_events.disconnect_receivers(): user = self.create_user(False) with self.app.test_request_context(): result = user_service.login(user.email, 'BAD!') self.assertFalse(result)
def test_default_token_loader_fails_if_email_not_confirmed(self): """ Default token user loader fails if email unconfirmed""" with user_events.disconnect_receivers(): user = self.create_user(confirm_email=False) token = user_service.default_token_implementation(user.id) with self.assertRaises(x.EmailNotConfirmed): user_service.default_token_user_loader(token)
def test_default_token_user_loader_can_load_user(self): """ Load user by token using default loader""" with user_events.disconnect_receivers(): user = self.create_user() token = user_service.default_token_implementation(user.id) loaded = user_service.default_token_user_loader(token) self.assertEquals(loaded, user)
def test_force_login_fails_if_email_unconfirmed_for_new_users(self): """ Abort force login if email is not confirmed for new users""" with user_events.disconnect_receivers(): user = self.create_user(False) with self.app.test_request_context(): with self.assertRaises(x.EmailNotConfirmed): user_service.force_login(user)
def test_login_increments_on_failure(self): """ Increment failed logins counter on failure """ user = self.create_user() self.assertEqual(0, user.failed_logins) with user_events.disconnect_receivers(): with self.app.test_request_context(): user_service.login(user.email, 'BAD!') self.assertEqual(1, user.failed_logins)
def test_fall_back_to_default_token_loader_if_no_custom(self): """ Fall back to default token user loader if no custom""" user_service.jwt_loader_implementation = None with user_events.disconnect_receivers(): user = self.create_user() token = user_service.get_token(user.id) loaded = user_service.get_user_by_token(token) self.assertEquals(loaded, user)
def test_login_fails_with_bad_credentials(self): """ Fail to login with bad credentials """ with user_events.disconnect_receivers(): with self.app.test_request_context(): email = 'no-such-email' password = '******' res = user_service.login(email, password) self.assertFalse(res)
def test_login_successful_with_valid_credentials(self): """ Can login with valid credentials """ user = self.create_user() with user_events.disconnect_receivers(): with self.app.test_request_context(): res = user_service.login(user.email, '123456') self.assertTrue(res) self.assertTrue(current_user.is_authenticated)
def test_default_token_user_loader_fails_if_expired(self): """ Default token user loader fails if expired """ with user_events.disconnect_receivers(): user = self.create_user() user_service.jwt_lifetime = -1 token = user_service.default_token_implementation(user.id) with self.assertRaises(x.JwtExpired): user_service.default_token_user_loader(token)
def test_save_emits_event(self): """ Saving a user emits event """ user = User(email='*****@*****.**', password='******') with user_events.disconnect_receivers(): spy = mock.Mock() events.user_save_event.connect(spy, weak=False) user_service.save(user) spy.assert_called_with(user)
def test_default_token_user_loader_fails_if_tampered_with(self): """ Default token user loader fails if tampered with """ with user_events.disconnect_receivers(): user = self.create_user() token = user_service.default_token_implementation(user.id) token = 'xxx' + token with self.assertRaises(x.JwtDecodeError): user_service.default_token_user_loader(token)
def test_default_token_loader_fails_if_tokens_mismatch(self): """ Fail to load user if token doesn't match the one on file""" with user_events.disconnect_receivers(): user = self.create_user() token = user_service.default_token_implementation(user.id) user_service.revoke_user_token(user.id) with self.assertRaises(x.JwtTokenMismatch): user_service.default_token_user_loader(token)
def test_register(self): """ Can register new user """ with user_events.disconnect_receivers(): user_data = dict(email='*****@*****.**', password='******') user = user_service.register(user_data=user_data, send_welcome=False) self.assertIsInstance(user, User) self.assertEqual(1, user.id)
def test_force_login(self): """ Can force login a user """ user = self.create_user() with user_events.disconnect_receivers(): with self.app.test_request_context(): res = user_service.force_login(user) self.assertTrue(res) self.assertTrue(current_user.is_authenticated)
def test_register_returns_validation_errors(self): """ Registering returns validation error on bad data """ with user_events.disconnect_receivers(): user_data = dict(email='not.email', password='******') result = user_service.register(user_data=user_data, send_welcome=False) self.assertIsInstance(result, Result) self.assertFalse(result)
def test_default_token_user_loader_fails_if_account_locked(self): """ Default token user loader fails if account locked """ with user_events.disconnect_receivers(): user = self.create_user() user.lock_account(minutes=1) user_service.save(user) token = user_service.default_token_implementation(user.id) with self.assertRaises(x.AccountLocked): user_service.default_token_user_loader(token)
def test_default_token_user_loader_fails_if_no_user(self): """ Default token user loader fails if user not found """ with user_events.disconnect_receivers(): user_service.jwt_lifetime = 86400 user = self.create_user(confirm_email=True) token = user_service.default_token_implementation(user.id) user_service.delete(user) with self.assertRaises(x.JwtNoUser): user_service.default_token_user_loader(token)
def test_default_tokens_fail_if_tampered_with(self): """ Default tokens fail if tampered with""" with user_events.disconnect_receivers(): user = self.create_user(confirm_email=True) token = user_service.default_token_implementation(user.id) with self.assertRaises(jwt.exceptions.DecodeError): jwt.decode(token + 'x', user_service.jwt_secret, algorithms=[user_service.jwt_algo])
def test_force_login_drops_counter_on_success(self): """ Drop failed login counter on force login """ with user_events.disconnect_receivers(): user = self.create_user() user.failed_logins = 5 user_service.save(user) with self.app.test_request_context(): user_service.force_login(user) self.assertEqual(0, user.failed_logins)
def test_force_login_emits_event(self): """ Force login emits event """ user = self.create_user() with user_events.disconnect_receivers(): with self.app.test_request_context(): spy = mock.Mock() events.login_event.connect(spy, weak=False) user_service.login(user.email, '123456') spy.assert_called_with(user)
def test_force_login_fails_if_locked(self): """ Abort force login if locked """ with user_events.disconnect_receivers(): user = self.create_user() user.lock_account() user_service.save(user) with self.app.test_request_context(): with self.assertRaises(x.AccountLocked): user_service.force_login(user)
def test_login_emit_event_on_nonexistent_user(self): """ Login emits event on nonexistent user login """ event = events.login_failed_nonexistent_event with user_events.disconnect_receivers(): spy = mock.Mock() event.connect(spy, weak=False) # weak please with self.app.test_request_context(): user_service.login('NONEXISTENT', 'BAD!') spy.assert_called_with(None)
def test_delete_emits_event(self): """ Deleting a user emits event """ user = self.create_user() with user_events.disconnect_receivers(): event = events.user_delete_event spy = mock.Mock() event.connect(spy, weak=False) user_service.delete(user) spy.assert_called_with(user)
def test_register_emits_event(self): """ Registration emits event """ event = events.register_event user_data = dict(email='*****@*****.**', password='******') with user_events.disconnect_receivers(): spy = mock.Mock() event.connect(spy, weak=False) user = user_service.register(user_data=user_data, send_welcome=False) spy.assert_called_with(user)
def test_login_emits_event_on_success(self): """ Login emits event on success """ user = self.create_user() event = events.login_event with user_events.disconnect_receivers(): spy = mock.Mock() event.connect(spy, weak=False) with self.app.test_request_context(): user_service.login(user.email, '123456') spy.assert_called_with(user)
def test_login_emits_event_on_bad_credentials(self): """ Login emits event on bad credentials""" user = self.create_user() event = events.login_failed_event with user_events.disconnect_receivers(): spy = mock.Mock() event.connect(spy, weak=False) # weak please with self.app.test_request_context(): user_service.login(user.email, 'BAD!') spy.assert_called_with(user)
def test_login_locks_on_reaching_limit(self): """ Lock account on reaching failed logins limit """ with user_events.disconnect_receivers(): user = self.create_user() user.failed_logins = 10 user_service.save(user) with self.app.test_request_context(): user_service.login(user.email, 'BAD!') self.assertEqual(0, user.failed_logins) self.assertTrue(user.is_locked())
def create_user(self, confirm_email=True): """ A shortcut to quickly create and return a user """ with user_events.disconnect_receivers(): user = user_service.create(email='*****@*****.**', password='******') if confirm_email: user.confirm_email() user_service.save(user) return user
def test_fall_back_to_default_token_implementation_if_no_custom(self): """ Fall back to default token implementation if no custom """ with user_events.disconnect_receivers(): user = self.create_user() token = user_service.get_token(user.id) decoded = user_service.decode_token(token) self.assertEquals(user.id, decoded['user_id']) for claim in ['exp', 'nbf', 'iat', 'user_id']: self.assertTrue(claim in decoded.keys()) self.assertEquals(4, len(decoded.keys()))