def test_delete_profile_success(self): """ Test deleting the account with a valid token. Expected result: The account is successfully deleted. """ email = '*****@*****.**' password = '******' name = 'John Doe' user_id = 1 user = User(email, name) user.set_password(password) db.session.add(user) db.session.commit() self.assertEqual(user_id, user.id) self.client.post('/user/login', follow_redirects=True, data=dict( email=email, password=password )) token_obj = DeleteAccountToken() token_obj.user_id = user.id token = token_obj.create() response = self.client.get('/user/delete/' + token, follow_redirects=True) data = response.get_data(as_text=True) self.assertIsNone(User.load_from_id(user_id)) self.assertIn('Your user profile and all data linked to it have been deleted.', data)
def test_change_email_failure_invalid_token(self): """ Test accessing the change email page with an invalid token. Expected result: The email address is not changed and a 404 error page is shown. """ email = '*****@*****.**' name = 'John Doe' user = User(email, name) db.session.add(user) db.session.commit() user_id = user.id new_email = '*****@*****.**' token_obj = ChangeEmailAddressToken() token_obj.user_id = user_id token_obj.new_email = new_email token = token_obj.create() response = self.client.get(f'/user/change-email-address/invalid-{token}', follow_redirects=True) user = User.load_from_id(user_id) self.assertEqual(404, response.status_code) self.assertEqual(email, user.get_email())
def test_change_email_success(self): """ Test accessing the change email page with a valid token. Expected result: The email address is changed. """ email = '*****@*****.**' name = 'John Doe' user = User(email, name) db.session.add(user) db.session.commit() user_id = user.id new_email = '*****@*****.**' token_obj = ChangeEmailAddressToken() token_obj.user_id = user_id token_obj.new_email = new_email token = token_obj.create() response = self.client.get(f'/user/change-email-address/{token}', follow_redirects=True) data = response.get_data(as_text=True) user = User.load_from_id(user_id) self.assertIn('Your email address has successfully been changed.', data) self.assertEqual(new_email, user.get_email())
def user_settings(user_id: int) -> ResponseType: """ Show and process a form to edit a user's settings. :param user_id: The ID of the user whose settings will be managed. :return: The response for this view. """ user = User.load_from_id(user_id) if user is None: abort(404) settings = user.settings settings_form = UserSettingsForm(obj=settings) if settings_form.validate_on_submit(): # Get the data from the form and save it. settings.language = settings_form.language.data db.session.commit() # Refresh the language in case the current user is editing themselves and they have changed their language. refresh() flash(_('Your changes have been saved.')) return redirect(url_for('.user_settings', user_id=user_id)) reset_form = UserSettingsResetForm() return render_template('administration/user_settings.html', user=user, settings_form=settings_form, reset_form=reset_form)
def test_change_email_failure_email_in_use(self): """ Test accessing the change email page with an email address that already is in use by another user. Expected result: The email address is not changed. """ existing_email = '*****@*****.**' existing_name = 'Jane Doe' existing_user = User(existing_email, existing_name) email = '*****@*****.**' name = 'John Doe' user = User(email, name) db.session.add(existing_user) db.session.add(user) db.session.commit() user_id = user.id token_obj = ChangeEmailAddressToken() token_obj.user_id = user_id token_obj.new_email = existing_email token = token_obj.create() response = self.client.get(f'/user/change-email-address/{token}', follow_redirects=True) data = response.get_data(as_text=True) user = User.load_from_id(user_id) self.assertIn('The email address already is in use.', data) self.assertEqual(email, user.get_email())
def test_user_profile_post_only_name(self): """ Test posting to the user profile page with only the name changed. Expected result: The form is shown with the new data. The user's name is changed, everything else is not. """ email = '*****@*****.**' name = 'John Doe' password = '******' user = self.create_and_login_user(email=email, name=name, password=password) new_name = 'Jane Doe' with mail.record_messages() as outgoing: data = self.post('/user/profile', data=dict(name=new_name, email=email)) self.assertEqual(0, len(outgoing)) self.assertIn('User Profile', data) self.assertIn(f'value="{new_name}"', data) self.assertIn(f'value="{email}"', data) self.assertIn('Your changes have been saved.', data) self.assertNotIn('An email has been sent to the new address', data) user = User.load_from_id(user.id) self.assertEqual(new_name, user.name) self.assertEqual(email, user.email) self.assertTrue(user.check_password(password))
def test_change_email_failure_email_in_use(self): """ Test accessing the change email page with an email address that already is in use by another user. Expected result: The email address is not changed. """ existing_email = '*****@*****.**' existing_name = 'Jane Doe' self.create_user(email=existing_email, name=existing_name, password='******') email = '*****@*****.**' name = 'John Doe' user = self.create_user(email=email, name=name, password='******') token_obj = ChangeEmailAddressToken() token_obj.user_id = user.id token_obj.new_email = existing_email token = token_obj.create() data = self.get(f'/user/change-email-address/{token}') user = User.load_from_id(user.id) self.assertIn('The email address already is in use.', data) self.assertEqual(email, user.email)
def test_change_email_failure_invalid_token(self): """ Test accessing the change email page with an invalid token. Expected result: The email address is not changed and a 404 error page is shown. """ email = '*****@*****.**' user = self.create_user(email=email, name='John Doe', password='******') new_email = '*****@*****.**' token_obj = ChangeEmailAddressToken() token_obj.user_id = user.id token_obj.new_email = new_email token = token_obj.create() data = self.get(f'/user/change-email-address/invalid-{token}', expected_status=404) user = User.load_from_id(user.id) self.assertNotIn('Your email address has successfully been changed.', data) self.assertEqual(email, user.email)
def test_delete_profile_failure(self): """ Test deleting the account with an invalid token. Expected result: The account is not deleted. """ email = '*****@*****.**' password = '******' name = 'John Doe' user_id = 1 user = User(email, name) user.set_password(password) db.session.add(user) db.session.commit() self.assertEqual(user_id, user.id) self.client.post('/user/login', follow_redirects=True, data=dict( email=email, password=password )) response = self.client.get('/user/delete/invalid-token', follow_redirects=True) data = response.get_data(as_text=True) self.assertEqual(404, response.status_code) self.assertIsNotNone(User.load_from_id(user_id)) self.assertNotIn('Your user profile and all data linked to it have been deleted.', data)
def test_user_profile_post_name_and_password_and_email(self): """ Test posting to the user profile page with the name, the password, and the email changed. Expected result: The form is shown with the new data. The user's name and password are changed, the email is not, but a mail has been sent to the new address. """ email = '*****@*****.**' name = 'John Doe' password = '******' user = User(email, name) user.set_password(password + '!') with mail.record_messages() as outgoing: user.set_password(password) self.assertEqual(1, len(outgoing)) self.assertIn('Your Password Has Been Changed', outgoing[0].subject) db.session.add(user) db.session.commit() user_id = user.id self.client.post('/user/login', follow_redirects=True, data=dict( email=email, password=password )) new_name = 'Jane Doe' new_password = '******' new_email = '*****@*****.**' with mail.record_messages() as outgoing: response = self.client.post('/user/profile', follow_redirects=True, data=dict( name=new_name, email=new_email, password=new_password, password_confirmation=new_password )) data = response.get_data(as_text=True) self.assertEqual(2, len(outgoing)) self.assertIn('Change Your Email Address', outgoing[1].subject) self.assertEqual([new_email], outgoing[1].recipients) self.assertIn('User Profile', data) self.assertIn(f'value="{new_name}"', data) self.assertIn(f'value="{email}"', data) self.assertIn('Your changes have been saved.', data) self.assertIn('An email has been sent to the new address', data) user = User.load_from_id(user_id) self.assertEqual(new_name, user.name) self.assertEqual(email, user.get_email()) self.assertTrue(user.check_password(new_password))
def user_edit(user_id: int) -> ResponseType: """ Show and process a form to edit an existing user. :param user_id: The ID of the user. :return: The response for this view. """ user = User.load_from_id(user_id) if user is None: abort(404) return render_template('administration/user_header.html', user=user)
def user_security(user_id: int) -> ResponseType: """ Show options to edit a user's security settings. :param user_id: The ID of the user whose security settings will be managed. :return: The response for this view. """ user = User.load_from_id(user_id) if user is None: abort(404) password_reset_form = UserPasswordResetForm() return render_template('administration/user_security.html', user=user, password_reset_form=password_reset_form)
def test_delete_profile_failure(self): """ Test deleting the account with an invalid token. Expected result: The account is not deleted. """ user = self.create_and_login_user() user_id = user.id data = self.get('/user/delete/invalid-token', expected_status=404) self.assertIsNotNone(User.load_from_id(user_id)) self.assertNotIn( 'Your user profile and all data linked to it have been deleted.', data)
def user_profile() -> ResponseType: """ Show and process a form to edit account details. :return: The response for this view. """ profile_form = UserProfileForm(obj=current_user, email=current_user.email) if profile_form.validate_on_submit(): # Always change the name. user = User.load_from_id(current_user.get_id()) user.name = profile_form.name.data # If the user entered a password, change that as well. if profile_form.password.data: user.set_password(profile_form.password.data) # Write the changes to the database. db.session.commit() # If the email address changed send a confirmation mail to the new address. if user.email != profile_form.email.data: token_validity = user.request_email_address_change( profile_form.email.data) validity = timedelta_to_minutes(token_validity) flash(Markup( _('An email has been sent to the new address %(email)s. Please open the link included in the \ mail within the next %(validity)d minutes to confirm your new email address. Otherwise, \ your email address will not be changed.', email='<em>{email}</em>'.format( email=profile_form.email.data), validity=validity)), category='warning') flash(_('Your changes have been saved.')) return redirect(url_for('userprofile.user_profile')) delete_form = DeleteUserProfileForm() return render_template('userprofile/profile.html', title=_('User Profile'), profile_form=profile_form, delete_form=delete_form)
def test_create_user_without_role(self) -> None: """ Test creating a new user without a role. Expected result: The user is created with the given parameters and without a role. The user is saved on the DB. """ email = '*****@*****.**' name = 'John Doe' password = '******' user = self.create_user(email, name, password) self.assertIsNotNone(user) self.assertEqual(email, user.email) self.assertEqual(name, user.name) self.assertTrue(user.check_password(password)) self.assertIsNone(user.role) self.assertEqual(user, User.load_from_id(user.id))
def test_delete_profile_success(self): """ Test deleting the account with a valid token. Expected result: The account is successfully deleted. """ user = self.create_and_login_user() user_id = user.id token_obj = DeleteAccountToken() token_obj.user_id = user_id token = token_obj.create() data = self.get('/user/delete/' + token) self.assertIsNone(User.load_from_id(user_id)) self.assertIn( 'Your user profile and all data linked to it have been deleted.', data)
def user_reset_password(user_id: int) -> ResponseType: """ Process a request to reset a user's password. :param user_id: The ID of the user whose password will be reset. :return: The response for this view. """ user = User.load_from_id(user_id) if user is None: abort(404) password_reset_form = UserPasswordResetForm() if password_reset_form.validate_on_submit(): user.request_password_reset() flash(_('The user\'s password has been reset. An email has been sent to their mail account allowing them to \ set a new password.')) return redirect(url_for('.user_security', user_id=user_id))
def test_user_profile_post_only_name(self): """ Test posting to the user profile page with only the name changed. Expected result: The form is shown with the new data. The user's name is changed, everything else is not. """ email = '*****@*****.**' name = 'John Doe' password = '******' user = User(email, name) user.set_password(password) db.session.add(user) db.session.commit() user_id = user.id self.client.post('/user/login', follow_redirects=True, data=dict( email=email, password=password )) new_name = 'Jane Doe' with mail.record_messages() as outgoing: response = self.client.post('/user/profile', follow_redirects=True, data=dict( name=new_name, email=email )) data = response.get_data(as_text=True) self.assertEqual(0, len(outgoing)) self.assertIn('User Profile', data) self.assertIn(f'value="{new_name}"', data) self.assertIn(f'value="{email}"', data) self.assertIn('Your changes have been saved.', data) self.assertNotIn('An email has been sent to the new address', data) user = User.load_from_id(user_id) self.assertEqual(new_name, user.name) self.assertEqual(email, user.get_email()) self.assertTrue(user.check_password(password))
def test_user_profile_post_name_and_password_and_email(self): """ Test posting to the user profile page with the name, the password, and the email changed. Expected result: The form is shown with the new data. The user's name and password are changed, the email is not, but a mail has been sent to the new address. """ email = '*****@*****.**' name = 'John Doe' password = '******' user = self.create_and_login_user(email=email, name=name, password=password) new_name = 'Jane Doe' new_password = '******' new_email = '*****@*****.**' with mail.record_messages() as outgoing: data = self.post('/user/profile', data=dict(name=new_name, email=new_email, password=new_password, password_confirmation=new_password)) self.assertEqual(2, len(outgoing)) self.assertIn('Change Your Email Address', outgoing[1].subject) self.assertEqual([new_email], outgoing[1].recipients) self.assertIn('User Profile', data) self.assertIn(f'value="{new_name}"', data) self.assertIn(f'value="{email}"', data) self.assertIn('Your changes have been saved.', data) self.assertIn('An email has been sent to the new address', data) user = User.load_from_id(user.id) self.assertEqual(new_name, user.name) self.assertEqual(email, user.email) self.assertTrue(user.check_password(new_password))
def test_create_and_login_user(self) -> None: """ Test creating a new user and logging them in. Expected result: The user is created and logged in. """ user = self.create_and_login_user() self.assertIsNotNone(user) self.assertEqual('*****@*****.**', user.email) self.assertEqual('Jane Doe', user.name) self.assertTrue(user.check_password('ABC123!')) self.assertIsNone(user.role) self.assertEqual(user, User.load_from_id(user.id)) # Check if the login was successful by checking if the login page is shown. response = self.client.get('/user/login', follow_redirects=True) data = response.get_data(as_text=True) self.assertNotIn('<h1>Log In</h1>', data) self.assertIn('<h1>Dashboard</h1>', data)
def user_profile() -> str: """ Show a page to edit account details. Upon submission, change the account details. :return: The HTML response. """ profile_form = UserProfileForm(obj=current_user, email=current_user.get_email()) if profile_form.validate_on_submit(): # Always change the name. user = User.load_from_id(current_user.get_id()) user.name = profile_form.name.data # If the user entered a password, change that as well. if profile_form.password.data: user.set_password(profile_form.password.data) # Write the changes to the database. db.session.commit() # If the email address changed send a confirmation mail to the new address. if user.get_email() != profile_form.email.data: token = user.send_change_email_address_email(profile_form.email.data) validity = token.get_validity(in_minutes=True) flash(Markup(_('An email has been sent to the new address %(email)s. Please open the link included in the \ mail within the next %(validity)d minutes to confirm your new email address. Otherwise, \ your email address will not be changed.', email='<em>{email}</em>'.format(email=profile_form.email.data), validity=validity)), category='warning') flash(_('Your changes have been saved.')) return redirect(url_for('userprofile.user_profile')) delete_form = DeleteUserProfileForm() return render_template('userprofile/profile.html', title=_('User Profile'), profile_form=profile_form, delete_form=delete_form)
def user_settings_reset(user_id: int) -> ResponseType: """ Reset the user's settings and redirect to the settings page. :param user_id: The ID of the user whose settings will be reset. :return: The response for this view. """ user = User.load_from_id(user_id) if user is None: abort(404) settings = user.settings reset_form = UserSettingsResetForm() if reset_form.validate_on_submit(): settings.reset() db.session.commit() # Refresh the language in case the current user is editing themselves and they have changed their language. refresh() flash(_('The settings have been set to their default values.')) return redirect(url_for('.user_settings', user_id=user_id))
def test_change_email_success(self): """ Test accessing the change email page with a valid token. Expected result: The email address is changed. """ user = self.create_user(email='*****@*****.**', name='John Doe', password='******') new_email = '*****@*****.**' token_obj = ChangeEmailAddressToken() token_obj.user_id = user.id token_obj.new_email = new_email token = token_obj.create() data = self.get(f'/user/change-email-address/{token}') user = User.load_from_id(user.id) self.assertIn('Your email address has successfully been changed.', data) self.assertEqual(new_email, user.email)