def test_permissions( # regular test fixtures client, request, # parameters from get_permissions_tests() path, has_tests, view_func, url_args, request_method, status_code, user_string): """ This test function runs a single request on behalf of a single user. The example at the top of this file would run this function four separate times. """ # all routes are required to have tests if not has_tests: raise Exception( "View function or method for path %s is missing a @perms_test decorator. " "Use @no_perms_test if you are sure your view doesn't need tests." % path) # Helper method to fetch and return a particular fixture, like 'casebook' or 'casebook.owner'. # Values are also stored in the `context` dictionary so they can be reused instead of recreated. # The part of `path` before the first period is treated as a pytest fixture, and the remainder is # resolved using the Django template language (so lookups like 'casebook.resources.1.some_func' # will work). def hydrate(context, path): if path not in context: fixture_name = path.split('.', 1)[0] if fixture_name not in context: try: context[fixture_name] = request.getfixturevalue( fixture_name) except FixtureLookupError: pass # path may not be a fixture name, like '"some string"' context[path] = Variable(path).resolve(context) return context[path] # Special handling for status code 'login' -- expect a 302, but also check that we redirect to # the login page. This lets us differentiate from pages that redirect on success. should_redirect_to_login = False if status_code == 'login': status_code = 302 should_redirect_to_login = True # run request context = {} url = reverse(view_func, args=[hydrate(context, arg) for arg in url_args]) user = hydrate(context, user_string) if user_string else None response = getattr(client, request_method)(url, as_user=user) # check response check_response(response, status_code=status_code, content_type=None) if should_redirect_to_login: assert response.url.startswith( '/user_sessions/new'), "View failed to redirect to login page"
def test_csrf_error_page(): """ Verify that our injected context variables are present. """ client = Client(raise_request_exception=False, enforce_csrf_checks=True) check_response(client.post(reverse('403_csrf')), status_code=403, content_includes=[ settings.APP_NAME, settings.CONTACT_EMAIL, ])
def test_forgot_password(user, client, mailoutbox): user.set_password('old_password') user.save() # request reset email check_response(client.get(reverse('password_reset')), content_includes=['Forgotten your password?']) check_response(client.post(reverse('password_reset'), {'email': user.email_address}, follow=True), content_includes=["We've emailed you instructions"]) # submit new password assert len(mailoutbox) == 1 reset_url = re.search(r'(http:.*)', mailoutbox[0].body).group(0) new_password_form_response = client.get(reset_url, follow=True) check_response(new_password_form_response, content_includes=['Please enter your new password']) post_url = new_password_form_response.redirect_chain[0][0] check_response(client.post(post_url, { 'new_password1': 'new_password', 'new_password2': 'new_password' }, follow=True), content_includes=['Your password has been updated']) # password changed user.refresh_from_db() assert user.check_password('new_password') # since they use the same flow... verify that the "new user" email wasn't sent assert len(mailoutbox) == 1
def test_error_pages(error, client_with_raise_request_exception, mailoutbox): """ Verify that our injected context variables are present. """ client = client_with_raise_request_exception(raise_request_exception=False) check_response( client.get(reverse(error)), status_code=int(error), content_includes=settings.CONTACT_EMAIL, ) if error == '500': [email] = mailoutbox assert 'Internal Server Error' in email.subject elif error == '400': [email] = mailoutbox assert 'Fishy' in email.subject else: assert len(mailoutbox) == 0
def test_change_password(user, client): user.set_password('old_password') user.save() client.force_login(user) # visit form check_response(client.get(reverse('password_change')), content_includes=['Change your password']) # try to change with wrong password check_response( client.post( reverse('password_change'), { 'old_password': '******', 'new_password1': 'new_password', 'new_password2': 'new_password' }, ), content_includes=['Your old password was entered incorrectly.']) # password not updated user.refresh_from_db() assert user.check_password('old_password') # try to change with correct password check_response(client.post( reverse('password_change'), { 'old_password': '******', 'new_password1': 'new_password', 'new_password2': 'new_password' }, follow=True, ), content_includes=['Your password has been updated.']) # password has been updated user.refresh_from_db() assert user.check_password('new_password')