replaced unittest assertions pytest assertions (#26513)

This commit is contained in:
Aarif
2021-02-18 18:07:46 +05:00
committed by GitHub
parent d2644e2dc2
commit 774caac305
12 changed files with 363 additions and 419 deletions

View File

@@ -93,8 +93,8 @@ class TPAContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
is returned.
"""
response = self.client.get(self.url)
self.assertEqual(response.status_code, 400)
self.assertEqual(response.data, {'message': 'Request missing required parameter: redirect_to'})
assert response.status_code == 400
assert response.data == {'message': 'Request missing required parameter: redirect_to'}
@patch.dict(settings.FEATURES, {'ENABLE_THIRD_PARTY_AUTH': False})
def test_no_third_party_auth_providers(self):
@@ -103,8 +103,8 @@ class TPAContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
the provider information
"""
response = self.client.get(self.url, self.query_params)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, self.get_context())
assert response.status_code == 200
assert response.data == self.get_context()
def test_third_party_auth_providers(self):
"""
@@ -115,8 +115,8 @@ class TPAContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
'next': self.query_params['redirect_to']
}
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, self.get_context(params))
assert response.status_code == 200
assert response.data == self.get_context(params)
@ddt.data(
('google-oauth2', 'Google', False),
@@ -139,8 +139,8 @@ class TPAContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
with simulate_running_pipeline(pipeline_target, current_backend, email=email):
response = self.client.get(self.url, self.query_params)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data, self.get_context(params, current_provider, current_backend, add_user_details))
assert response.status_code == 200
assert response.data == self.get_context(params, current_provider, current_backend, add_user_details)
def test_tpa_hint(self):
"""
@@ -164,4 +164,4 @@ class TPAContextViewTest(ThirdPartyAuthTestMixin, APITestCase):
})
response = self.client.get(self.url, self.query_params)
self.assertEqual(response.data['providers'], provider_data)
assert response.data['providers'] == provider_data

View File

@@ -85,14 +85,11 @@ class CookieTests(TestCase):
"""
self._copy_cookies_to_request(response, self.request)
JwtAuthCookieMiddleware().process_view(self.request, None, None, None)
self.assertEqual(
cookies_api.jwt_cookies.jwt_cookie_name() in self.request.COOKIES,
can_recreate,
)
assert (cookies_api.jwt_cookies.jwt_cookie_name() in self.request.COOKIES) == can_recreate
if can_recreate:
jwt_string = self.request.COOKIES[cookies_api.jwt_cookies.jwt_cookie_name()]
jwt = jwt_decode_handler(jwt_string)
self.assertEqual(jwt['scopes'], ['user_id', 'email', 'profile'])
assert jwt['scopes'] == ['user_id', 'email', 'profile']
def _assert_cookies_present(self, response, expected_cookies):
""" Verify all expected_cookies are present in the response. """
@@ -100,10 +97,7 @@ class CookieTests(TestCase):
def _assert_consistent_expires(self, response, num_of_unique_expires=1):
""" Verify cookies in the response have the same expiration, as expected. """
self.assertEqual(
num_of_unique_expires,
len(set([response.cookies[c]['expires'] for c in response.cookies])), # lint-amnesty, pylint: disable=consider-using-set-comprehension
)
assert num_of_unique_expires == len({response.cookies[c]['expires'] for c in response.cookies})
@skip_unless_lms
def test_get_user_info_cookie_data(self):
@@ -148,11 +142,11 @@ class CookieTests(TestCase):
setup_login_oauth_client()
response = cookies_api.set_logged_in_cookies(self.request, HttpResponse(), self.user)
self._copy_cookies_to_request(response, self.request)
self.assertTrue(cookies_api.are_logged_in_cookies_set(self.request))
assert cookies_api.are_logged_in_cookies_set(self.request)
cookies_api.delete_logged_in_cookies(response)
self._copy_cookies_to_request(response, self.request)
self.assertFalse(cookies_api.are_logged_in_cookies_set(self.request))
assert not cookies_api.are_logged_in_cookies_set(self.request)
@patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
def test_refresh_jwt_cookies(self):
@@ -160,8 +154,8 @@ class CookieTests(TestCase):
self._set_use_jwt_cookie_header(self.request)
response = cookies_api.get_response_with_refreshed_jwt_cookies(self.request, self.user)
data = json.loads(response.content.decode('utf8').replace("'", '"'))
self.assertGreater(data['expires_epoch_seconds'], 0)
self.assertNotEqual(data['expires'], 'not-found')
assert data['expires_epoch_seconds'] > 0
assert data['expires'] != 'not-found'
self._assert_cookies_present(response, cookies_api.JWT_COOKIE_NAMES)
self._assert_consistent_expires(response, num_of_unique_expires=1)
self._assert_recreate_jwt_from_cookies(response, can_recreate=True)

View File

@@ -16,4 +16,4 @@ class AuthFailedErrorTests(TestCase):
exception = AuthFailedError(script_tag)
expected_value = Text(script_tag)
self.assertEqual(exception.value, expected_value)
assert exception.value == expected_value

View File

@@ -2,7 +2,7 @@
from collections import namedtuple
import pytest
import ddt
from django.test import TestCase
from django.test.client import RequestFactory
@@ -54,7 +54,7 @@ class TestRedirectUtils(TestCase):
req = self.request.get('/login', HTTP_HOST=host)
req.is_secure = lambda: req_is_secure
actual_is_safe = self._is_safe_redirect(req, url)
self.assertEqual(actual_is_safe, expected_is_safe)
assert actual_is_safe == expected_is_safe
@ddt.data(
('https://test.com/test', 'https://test.com/test', 'edx.org', True),
@@ -70,7 +70,7 @@ class TestRedirectUtils(TestCase):
}
req = self.request.get('/logout?{}'.format(urlencode(params)), HTTP_HOST=host)
actual_is_safe = self._is_safe_redirect(req, redirect_url)
self.assertEqual(actual_is_safe, expected_is_safe)
assert actual_is_safe == expected_is_safe
class GeneratePasswordTest(TestCase):
@@ -78,22 +78,22 @@ class GeneratePasswordTest(TestCase):
def test_default_args(self):
password = generate_password()
self.assertEqual(12, len(password))
self.assertTrue(any(c.isdigit for c in password))
self.assertTrue(any(c.isalpha for c in password))
assert 12 == len(password)
assert any((c.isdigit for c in password))
assert any((c.isalpha for c in password))
def test_length(self):
length = 25
self.assertEqual(length, len(generate_password(length=length)))
assert length == len(generate_password(length=length))
def test_chars(self):
char = '!'
password = generate_password(length=12, chars=(char,))
self.assertTrue(any(c.isdigit for c in password))
self.assertTrue(any(c.isalpha for c in password))
self.assertEqual(char * 10, password[2:])
assert any((c.isdigit for c in password))
assert any((c.isalpha for c in password))
assert (char * 10) == password[2:]
def test_min_length(self):
with self.assertRaises(ValueError):
with pytest.raises(ValueError):
generate_password(length=7)

View File

@@ -134,23 +134,23 @@ class AuthAndScopesTestMixin(object):
)
def _assert_in_log(self, text, mock_log_method):
self.assertTrue(mock_log_method.called)
self.assertIn(text, mock_log_method.call_args_list[0][0][0])
assert mock_log_method.called
assert text in mock_log_method.call_args_list[0][0][0]
def test_anonymous_user(self):
resp = self.client.get(self.get_url(self.student.username))
self.assertEqual(resp.status_code, status.HTTP_401_UNAUTHORIZED)
assert resp.status_code == status.HTTP_401_UNAUTHORIZED
@ddt.data(*JWT_AUTH_TYPES)
def test_self_user(self, auth_type):
resp = self.get_response(auth_type)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
assert resp.status_code == status.HTTP_200_OK
self.assert_success_response_for_student(resp)
@ddt.data(*list(AuthType))
def test_staff_user(self, auth_type):
resp = self.get_response(auth_type, requesting_user=self.global_staff)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
assert resp.status_code == status.HTTP_200_OK
self.assert_success_response_for_student(resp)
@ddt.data(*list(AuthType))
@@ -158,7 +158,7 @@ class AuthAndScopesTestMixin(object):
self.student.is_active = False
self.student.save()
resp = self.get_response(auth_type)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
assert resp.status_code == status.HTTP_200_OK
@patch('edx_rest_framework_extensions.permissions.log')
@ddt.data(*list(AuthType))
@@ -172,10 +172,7 @@ class AuthAndScopesTestMixin(object):
# Restricted JWT tokens without the user:me filter have access to other users
expected_jwt_access_granted = auth_type == AuthType.jwt_restricted
self.assertEqual(
resp.status_code,
status.HTTP_200_OK if expected_jwt_access_granted else status.HTTP_403_FORBIDDEN,
)
assert resp.status_code == (status.HTTP_200_OK if expected_jwt_access_granted else status.HTTP_403_FORBIDDEN)
if not expected_jwt_access_granted:
self._assert_in_log("IsUserInUrl", mock_log.info)
@@ -187,7 +184,7 @@ class AuthAndScopesTestMixin(object):
resp = self.get_response(AuthType.jwt, token=jwt_token)
is_enforced = auth_type == AuthType.jwt_restricted
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN if is_enforced else status.HTTP_200_OK)
assert resp.status_code == (status.HTTP_403_FORBIDDEN if is_enforced else status.HTTP_200_OK)
if is_enforced:
self._assert_in_log("JwtHasScope", mock_log.warning)
@@ -200,7 +197,7 @@ class AuthAndScopesTestMixin(object):
resp = self.get_response(AuthType.jwt, token=jwt_token)
is_enforced = auth_type == AuthType.jwt_restricted
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN if is_enforced else status.HTTP_200_OK)
assert resp.status_code == (status.HTTP_403_FORBIDDEN if is_enforced else status.HTTP_200_OK)
if is_enforced:
self._assert_in_log("JwtHasContentOrgFilterForRequestedCourse", mock_log.warning)
@@ -210,7 +207,7 @@ class AuthAndScopesTestMixin(object):
jwt_token = self._create_jwt_token(self.student, auth_type, include_me_filter=True)
resp = self.get_response(AuthType.jwt, token=jwt_token)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
assert resp.status_code == status.HTTP_200_OK
@patch('edx_rest_framework_extensions.permissions.log')
@ddt.data(*JWT_AUTH_TYPES)
@@ -219,7 +216,7 @@ class AuthAndScopesTestMixin(object):
jwt_token = self._create_jwt_token(self.other_student, auth_type, include_me_filter=True)
resp = self.get_response(AuthType.jwt, token=jwt_token)
self.assertEqual(resp.status_code, status.HTTP_403_FORBIDDEN)
assert resp.status_code == status.HTTP_403_FORBIDDEN
if auth_type == AuthType.jwt_restricted:
self._assert_in_log("JwtHasUserFilterForRequestedUser", mock_log.warning)
@@ -228,15 +225,15 @@ class AuthAndScopesTestMixin(object):
def test_valid_oauth_token(self):
resp = self.get_response(AuthType.oauth)
self.assertEqual(resp.status_code, status.HTTP_200_OK)
assert resp.status_code == status.HTTP_200_OK
def test_invalid_oauth_token(self):
resp = self.get_response(AuthType.oauth, token="fooooooooooToken")
self.assertEqual(resp.status_code, status.HTTP_401_UNAUTHORIZED)
assert resp.status_code == status.HTTP_401_UNAUTHORIZED
def test_expired_oauth_token(self):
token = self._create_oauth_token(self.student)
token.expires = utcnow() - timedelta(weeks=1)
token.save()
resp = self.get_response(AuthType.oauth, token=token)
self.assertEqual(resp.status_code, status.HTTP_401_UNAUTHORIZED)
assert resp.status_code == status.HTTP_401_UNAUTHORIZED

View File

@@ -60,16 +60,16 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
Test that user gets created when visiting the page.
"""
self._auto_auth()
self.assertEqual(User.objects.count(), 1)
assert User.objects.count() == 1
user = User.objects.all()[0]
self.assertTrue(user.is_active)
self.assertFalse(user.profile.requires_parental_consent())
assert user.is_active
assert not user.profile.requires_parental_consent()
@patch.dict("django.conf.settings.FEATURES", {'RESTRICT_AUTOMATIC_AUTH': False})
def test_create_same_user(self):
self._auto_auth({'username': 'test'})
self._auto_auth({'username': 'test'})
self.assertEqual(User.objects.count(), 1)
assert User.objects.count() == 1
def test_create_multiple_users(self):
"""
@@ -78,7 +78,7 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
self._auto_auth()
self.client.logout()
self._auto_auth()
self.assertEqual(User.objects.all().count(), 2)
assert User.objects.all().count() == 2
def test_create_defined_user(self):
"""
@@ -92,16 +92,16 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
# Check that the user has the correct info
user = User.objects.get(username='robot')
self.assertEqual(user.username, 'robot')
self.assertTrue(user.check_password('test'))
self.assertEqual(user.email, 'robot@edx.org')
assert user.username == 'robot'
assert user.check_password('test')
assert user.email == 'robot@edx.org'
# Check that the user has a profile
user_profile = UserProfile.objects.get(user=user)
self.assertEqual(user_profile.name, "Robot Name")
assert user_profile.name == 'Robot Name'
# By default, the user should not be global staff
self.assertFalse(user.is_staff)
assert not user.is_staff
@patch.dict("django.conf.settings.FEATURES", {'RESTRICT_AUTOMATIC_AUTH': False})
def test_create_staff_user(self):
@@ -109,12 +109,12 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
# Create a staff user
self._auto_auth({'username': 'test', 'staff': 'true'})
user = User.objects.get(username='test')
self.assertTrue(user.is_staff)
assert user.is_staff
# Revoke staff privileges
self._auto_auth({'username': 'test', 'staff': 'false'})
user = User.objects.get(username='test')
self.assertFalse(user.is_staff)
assert not user.is_staff
@ddt.data(*COURSE_IDS_DDT)
@ddt.unpack
@@ -124,9 +124,9 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
self._auto_auth({'username': 'test', 'course_id': course_id})
# Check that a course enrollment was created for the user
self.assertEqual(CourseEnrollment.objects.count(), 1)
assert CourseEnrollment.objects.count() == 1
enrollment = CourseEnrollment.objects.get(course_id=course_key)
self.assertEqual(enrollment.user.username, "test")
assert enrollment.user.username == 'test'
@ddt.data(*COURSE_IDS_DDT)
@ddt.unpack
@@ -140,32 +140,30 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
self._auto_auth({'username': 'test', 'course_id': course_id})
# Check that only one course enrollment was created for the user
self.assertEqual(CourseEnrollment.objects.count(), 1)
assert CourseEnrollment.objects.count() == 1
enrollment = CourseEnrollment.objects.get(course_id=course_key)
self.assertEqual(enrollment.user.username, "test")
assert enrollment.user.username == 'test'
@ddt.data(*COURSE_IDS_DDT)
@ddt.unpack
def test_set_roles(self, course_id, course_key):
seed_permissions_roles(course_key)
course_roles = dict((r.name, r) for r in Role.objects.filter(course_id=course_key))
self.assertEqual(len(course_roles), 5) # sanity check
assert len(course_roles) == 5
# sanity check
# Student role is assigned by default on course enrollment.
self._auto_auth({'username': 'a_student', 'course_id': course_id})
user = User.objects.get(username='a_student')
user_roles = user.roles.all()
self.assertEqual(len(user_roles), 1)
self.assertEqual(user_roles[0], course_roles[FORUM_ROLE_STUDENT])
assert len(user_roles) == 1
assert user_roles[0] == course_roles[FORUM_ROLE_STUDENT]
self.client.logout()
self._auto_auth({'username': 'a_moderator', 'course_id': course_id, 'roles': 'Moderator'})
user = User.objects.get(username='a_moderator')
user_roles = user.roles.all()
self.assertEqual(
set(user_roles),
set([course_roles[FORUM_ROLE_STUDENT],
course_roles[FORUM_ROLE_MODERATOR]]))
assert set(user_roles) == set([course_roles[FORUM_ROLE_STUDENT], course_roles[FORUM_ROLE_MODERATOR]])
# check multiple roles work.
self.client.logout()
@@ -175,18 +173,15 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
})
user = User.objects.get(username='an_admin')
user_roles = user.roles.all()
self.assertEqual(
set(user_roles),
set([course_roles[FORUM_ROLE_STUDENT],
course_roles[FORUM_ROLE_MODERATOR],
course_roles[FORUM_ROLE_ADMINISTRATOR]]))
assert set(user_roles) == {course_roles[FORUM_ROLE_STUDENT], course_roles[FORUM_ROLE_MODERATOR],
course_roles[FORUM_ROLE_ADMINISTRATOR]}
def test_json_response(self):
""" The view should return JSON. """
response = self._auto_auth()
response_data = json.loads(response.content.decode('utf-8'))
for key in ['created_status', 'username', 'email', 'password', 'user_id', 'anonymous_id']:
self.assertIn(key, response_data)
assert key in response_data
user = User.objects.get(username=response_data['username'])
self.assertDictContainsSubset(
{
@@ -208,9 +203,9 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
}, status_code=302)
# Check that a course enrollment was created for the user
self.assertEqual(CourseEnrollment.objects.count(), 1)
assert CourseEnrollment.objects.count() == 1
enrollment = CourseEnrollment.objects.get(course_id=course_key)
self.assertEqual(enrollment.user.username, "test")
assert enrollment.user.username == 'test'
# Check that the redirect was to the course info/outline page
if settings.ROOT_URLCONF == 'lms.urls':
@@ -218,7 +213,7 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
else:
url_pattern = '/course/{}'.format(six.text_type(course_key))
self.assertTrue(response.url.endswith(url_pattern))
assert response.url.endswith(url_pattern)
def test_redirect_to_main(self):
# Create user and redirect to 'home' (cms) or 'dashboard' (lms)
@@ -234,7 +229,7 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
else:
url_pattern = '/home'
self.assertTrue(response.url.endswith(url_pattern))
assert response.url.endswith(url_pattern)
def test_redirect_to_specified(self):
# Create user and redirect to specified url
@@ -245,7 +240,7 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
'staff': 'true',
}, status_code=302)
self.assertTrue(response.url.endswith(url_pattern))
assert response.url.endswith(url_pattern)
def _auto_auth(self, params=None, status_code=200, **kwargs):
"""
@@ -263,12 +258,12 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
params = params or {}
response = self.client.get(self.url, params, **kwargs)
self.assertEqual(response.status_code, status_code)
assert response.status_code == status_code
# Check that session and CSRF are set in the response
for cookie in ['csrftoken', 'sessionid']:
self.assertIn(cookie, response.cookies)
self.assertTrue(response.cookies[cookie].value)
assert cookie in response.cookies
assert response.cookies[cookie].value
return response
@@ -278,7 +273,7 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
Test case to check user creation is forbidden when ALLOW_PUBLIC_ACCOUNT_CREATION feature flag is turned off
"""
response = self.client.get(self.url)
self.assertEqual(response.status_code, 403)
assert response.status_code == 403
def test_course_access_roles(self):
""" Passing role names via the course_access_roles query string parameter should create CourseAccessRole
@@ -296,11 +291,8 @@ class AutoAuthEnabledTestCase(AutoAuthTestCase, ModuleStoreTestCase):
user_info = json.loads(response.content.decode('utf-8'))
for role in expected_roles:
self.assertTrue(
CourseAccessRole.objects.filter(
user__id=user_info['user_id'], course_id=course_key, org=course_key.org, role=role
).exists()
)
assert CourseAccessRole.objects\
.filter(user__id=user_info['user_id'], course_id=course_key, org=course_key.org, role=role).exists()
class AutoAuthDisabledTestCase(AutoAuthTestCase):
@@ -323,7 +315,7 @@ class AutoAuthDisabledTestCase(AutoAuthTestCase):
Make sure automatic authentication is disabled.
"""
response = self.client.get(self.url)
self.assertEqual(response.status_code, 404)
assert response.status_code == 404
class AutoAuthRestrictedTestCase(AutoAuthTestCase):
@@ -356,6 +348,6 @@ class AutoAuthRestrictedTestCase(AutoAuthTestCase):
Make sure that existing users cannot be modified.
"""
response = self.client.get(self.url, {'username': 'test'})
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
response = self.client.get(self.url, {'username': 'test'})
self.assertEqual(response.status_code, 403)
assert response.status_code == 403

View File

@@ -99,11 +99,9 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
self.user_email,
self.password,
)
self.assertEqual(response.status_code, 403)
self.assertEqual(
response.content,
b"Third party authentication is required to login. Username and password were received instead."
)
assert response.status_code == 403
assert response.content == b'Third party authentication is required to login.' \
b' Username and password were received instead.'
@ddt.data(
# Default redirect is dashboard.
@@ -391,7 +389,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
self.user.save()
response, mock_audit_log = self._login_response(nonexistent_email, 'incorrect_password')
self.assertFalse(mock_inactive_user_email_and_error.called)
assert not mock_inactive_user_email_and_error.called
self._assert_response(response, success=False, value=self.LOGIN_FAILED_WARNING)
self._assert_audit_log(mock_audit_log, 'warning', [u'Login failed', u'Unknown user email', email_hash])
@@ -422,7 +420,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
logout_url = reverse('logout')
with patch('common.djangoapps.student.models.AUDIT_LOG') as mock_audit_log:
response = self.client.post(logout_url)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self._assert_audit_log(mock_audit_log, 'info', [u'Logout', u'test'])
def test_login_user_info_cookie(self):
@@ -433,20 +431,20 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
cookie = self.client.cookies[settings.EDXMKTG_USER_INFO_COOKIE_NAME]
user_info = json.loads(cookie.value)
self.assertEqual(user_info["version"], settings.EDXMKTG_USER_INFO_COOKIE_VERSION)
self.assertEqual(user_info["username"], self.user.username)
assert user_info['version'] == settings.EDXMKTG_USER_INFO_COOKIE_VERSION
assert user_info['username'] == self.user.username
# Check that the URLs are absolute
for url in user_info["header_urls"].values():
self.assertIn("http://testserver/", url)
assert 'http://testserver/' in url
def test_logout_deletes_mktg_cookies(self):
response, _ = self._login_response(self.user_email, self.password)
self._assert_response(response, success=True)
# Check that the marketing site cookies have been set
self.assertIn(settings.EDXMKTG_LOGGED_IN_COOKIE_NAME, self.client.cookies)
self.assertIn(settings.EDXMKTG_USER_INFO_COOKIE_NAME, self.client.cookies)
assert settings.EDXMKTG_LOGGED_IN_COOKIE_NAME in self.client.cookies
assert settings.EDXMKTG_USER_INFO_COOKIE_NAME in self.client.cookies
# Log out
logout_url = reverse('logout')
@@ -456,7 +454,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
# (cookies are deleted by setting an expiration date in 1970)
for cookie_name in [settings.EDXMKTG_LOGGED_IN_COOKIE_NAME, settings.EDXMKTG_USER_INFO_COOKIE_NAME]:
cookie = self.client.cookies[cookie_name]
self.assertIn("01 Jan 1970", cookie.get('expires').replace('-', ' '))
assert '01 Jan 1970' in cookie.get('expires').replace('-', ' ')
@override_settings(
EDXMKTG_LOGGED_IN_COOKIE_NAME=u"unicode-logged-in",
@@ -482,7 +480,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
logout_url = reverse('logout')
with patch('common.djangoapps.student.models.AUDIT_LOG') as mock_audit_log:
response = self.client.post(logout_url)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self._assert_audit_log(mock_audit_log, 'info', [u'Logout'])
self._assert_not_in_audit_log(mock_audit_log, 'info', [u'test'])
@@ -537,8 +535,8 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
@patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
def test_login_refresh(self):
def _assert_jwt_cookie_present(response):
self.assertEqual(response.status_code, 200)
self.assertIn(jwt_cookies.jwt_cookie_header_payload_name(), self.client.cookies)
assert response.status_code == 200
assert jwt_cookies.jwt_cookie_header_payload_name() in self.client.cookies
setup_login_oauth_client()
response, _ = self._login_response(self.user_email, self.password)
@@ -550,8 +548,8 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
@patch.dict("django.conf.settings.FEATURES", {"DISABLE_SET_JWT_COOKIES_FOR_TESTS": False})
def test_login_refresh_anonymous_user(self):
response = self.client.post(reverse('login_refresh'))
self.assertEqual(response.status_code, 401)
self.assertNotIn(jwt_cookies.jwt_cookie_header_payload_name(), self.client.cookies)
assert response.status_code == 401
assert jwt_cookies.jwt_cookie_header_payload_name() not in self.client.cookies
@patch.dict("django.conf.settings.FEATURES", {'PREVENT_CONCURRENT_LOGINS': True})
def test_single_session(self):
@@ -565,7 +563,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
# Reload the user from the database
self.user = User.objects.get(pk=self.user.pk)
self.assertEqual(self.user.profile.get_meta()['session_id'], client1.session.session_key)
assert self.user.profile.get_meta()['session_id'] == client1.session.session_key
# second login should log out the first
response = client2.post(self.url, creds)
@@ -580,7 +578,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
url = reverse('upload_transcripts')
response = client1.get(url)
# client1 will be logged out
self.assertEqual(response.status_code, 302)
assert response.status_code == 302
@patch.dict("django.conf.settings.FEATURES", {'PREVENT_CONCURRENT_LOGINS': True})
def test_single_session_with_no_user_profile(self):
@@ -594,7 +592,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
user.save()
# Assert that no profile is created.
self.assertFalse(hasattr(user, 'profile'))
assert not hasattr(user, 'profile')
creds = {'email': 'tester@edx.org', 'password': self.password}
client1 = Client()
@@ -607,7 +605,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
user = User.objects.get(pk=user.pk)
# Assert that profile is created.
self.assertTrue(hasattr(user, 'profile'))
assert hasattr(user, 'profile')
# second login should log out the first
response = client2.post(self.url, creds)
@@ -622,7 +620,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
url = reverse('upload_transcripts')
response = client1.get(url)
# client1 will be logged out
self.assertEqual(response.status_code, 302)
assert response.status_code == 302
@patch.dict("django.conf.settings.FEATURES", {'PREVENT_CONCURRENT_LOGINS': True})
def test_single_session_with_url_not_having_login_required_decorator(self):
@@ -639,7 +637,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
# Reload the user from the database
self.user = User.objects.get(pk=self.user.pk)
self.assertEqual(self.user.profile.get_meta()['session_id'], client1.session.session_key)
assert self.user.profile.get_meta()['session_id'] == client1.session.session_key
# second login should log out the first
response = client2.post(self.url, creds)
@@ -648,7 +646,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
url = reverse('logout')
response = client1.get(url)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
@override_settings(PASSWORD_POLICY_COMPLIANCE_ROLLOUT_CONFIG={'ENFORCE_COMPLIANCE_ON_LOGIN': True})
def test_check_password_policy_compliance(self):
@@ -660,7 +658,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
mock_check_password_policy_compliance.return_value = HttpResponse()
response, _ = self._login_response(self.user_email, self.password)
response_content = json.loads(response.content.decode('utf-8'))
self.assertTrue(response_content.get('success'))
assert response_content.get('success')
@override_settings(PASSWORD_POLICY_COMPLIANCE_ROLLOUT_CONFIG={'ENFORCE_COMPLIANCE_ON_LOGIN': True})
def test_check_password_policy_compliance_exception(self):
@@ -675,9 +673,9 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
self.password
)
response_content = json.loads(response.content.decode('utf-8'))
self.assertFalse(response_content.get('success'))
self.assertEqual(len(mail.outbox), 1)
self.assertIn('Password reset', mail.outbox[0].subject)
assert not response_content.get('success')
assert len(mail.outbox) == 1
assert 'Password reset' in mail.outbox[0].subject
@override_settings(PASSWORD_POLICY_COMPLIANCE_ROLLOUT_CONFIG={'ENFORCE_COMPLIANCE_ON_LOGIN': True})
def test_check_password_policy_compliance_warning(self):
@@ -689,8 +687,8 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
mock_enforce_compliance_on_login.side_effect = NonCompliantPasswordWarning('Test warning')
response, _ = self._login_response(self.user_email, self.password)
response_content = json.loads(response.content.decode('utf-8'))
self.assertIn('Test warning', self.client.session['_messages'])
self.assertTrue(response_content.get('success'))
assert 'Test warning' in self.client.session['_messages']
assert response_content.get('success')
@ddt.data(
('test_password', 'test_password', True),
@@ -738,7 +736,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
value for 'value' in the JSON dict.
"""
expected_status_code = status_code or (400 if success is False else 200)
self.assertEqual(response.status_code, expected_status_code)
assert response.status_code == expected_status_code
try:
response_dict = json.loads(response.content.decode('utf-8'))
@@ -747,15 +745,15 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
% str(response.content))
if success is not None:
self.assertEqual(response_dict['success'], success)
assert response_dict['success'] == success
if error_code is not None:
self.assertEqual(response_dict['error_code'], error_code)
assert response_dict['error_code'] == error_code
if value is not None:
msg = (u"'%s' did not contain '%s'" %
(six.text_type(response_dict['value']), six.text_type(value)))
self.assertIn(value, response_dict['value'], msg)
assert value in response_dict['value'], msg
def _assert_redirect_url(self, response, expected_redirect_url):
"""
@@ -778,11 +776,11 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
"""
method_calls = mock_audit_log.method_calls
name, args, _kwargs = method_calls[-1]
self.assertEqual(name, level)
self.assertEqual(len(args), 1)
assert name == level
assert len(args) == 1
format_string = args[0]
for log_string in log_strings:
self.assertIn(log_string, format_string)
assert log_string in format_string
def _assert_not_in_audit_log(self, mock_audit_log, level, log_strings):
"""
@@ -790,11 +788,11 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
"""
method_calls = mock_audit_log.method_calls
name, args, _kwargs = method_calls[-1]
self.assertEqual(name, level)
self.assertEqual(len(args), 1)
assert name == level
assert len(args) == 1
format_string = args[0]
for log_string in log_strings:
self.assertNotIn(log_string, format_string)
assert log_string not in format_string
@ddt.data(
{
@@ -925,7 +923,7 @@ class LoginTest(SiteMixin, CacheIsolationTestCase):
response,
success=success
)
self.assertFalse(mock_check_user_auth_flow.called)
assert not mock_check_user_auth_flow.called
def test_check_user_auth_flow_bad_email(self):
"""Regression Exception was thrown on missing @ char in TPA."""
@@ -989,45 +987,30 @@ class LoginSessionViewTest(ApiTestCase):
# Verify that the form description matches what we expect
form_desc = json.loads(response.content.decode('utf-8'))
self.assertEqual(form_desc["method"], "post")
self.assertEqual(form_desc["submit_url"], reverse("user_api_login_session"))
self.assertEqual(form_desc["fields"], [
{
"name": "email",
"defaultValue": "",
"type": "email",
"required": True,
"label": "Email",
"placeholder": "",
"instructions": "The email address you used to register with {platform_name}".format(
platform_name=settings.PLATFORM_NAME
),
"restrictions": {
"min_length": EMAIL_MIN_LENGTH,
"max_length": EMAIL_MAX_LENGTH
},
"errorMessages": {},
"supplementalText": "",
"supplementalLink": "",
"loginIssueSupportLink": "https://support.example.com/login-issue-help.html",
},
{
"name": "password",
"defaultValue": "",
"type": "password",
"required": True,
"label": "Password",
"placeholder": "",
"instructions": "",
"restrictions": {
"max_length": DEFAULT_MAX_PASSWORD_LENGTH,
},
"errorMessages": {},
"supplementalText": "",
"supplementalLink": "",
"loginIssueSupportLink": "https://support.example.com/login-issue-help.html",
},
])
assert form_desc['method'] == 'post'
assert form_desc['submit_url'] == reverse('user_api_login_session')
assert form_desc['fields'] == [{'name': 'email', 'defaultValue': '', 'type': 'email', 'required': True,
'label': 'Email', 'placeholder': '',
'instructions': 'The email address you used to register with {platform_name}'
.format(platform_name=settings.PLATFORM_NAME),
'restrictions': {'min_length': EMAIL_MIN_LENGTH,
'max_length': EMAIL_MAX_LENGTH},
'errorMessages': {},
'supplementalText': '',
'supplementalLink': '',
'loginIssueSupportLink': 'https://support.example.com/login-issue-help.html'},
{'name': 'password',
'defaultValue': '',
'type': 'password',
'required': True,
'label': 'Password',
'placeholder': '',
'instructions': '',
'restrictions': {'max_length': DEFAULT_MAX_PASSWORD_LENGTH},
'errorMessages': {},
'supplementalText': '',
'supplementalLink': '',
'loginIssueSupportLink': 'https://support.example.com/login-issue-help.html'}]
@ddt.data(True, False)
@patch('openedx.core.djangoapps.user_authn.views.login.segment')
@@ -1085,7 +1068,7 @@ class LoginSessionViewTest(ApiTestCase):
# Verify that the session expiration was set correctly
cookie = self.client.cookies[settings.SESSION_COOKIE_NAME]
expected_expiry = datetime.datetime.utcnow() + datetime.timedelta(weeks=4)
self.assertIn(expected_expiry.strftime('%d %b %Y'), cookie.get('expires').replace('-', ' '))
assert expected_expiry.strftime('%d %b %Y') in cookie.get('expires').replace('-', ' ')
def test_invalid_credentials(self):
# Create a test user

View File

@@ -133,17 +133,17 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
login_url = reverse('signin_user')
for _ in range(5):
response = self.client.get(login_url)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
# then the rate limiter should kick in and give a HttpForbidden response
response = self.client.get(login_url)
self.assertEqual(response.status_code, 429)
assert response.status_code == 429
# now reset the time to 6 mins from now in future in order to unblock
reset_time = datetime.now(UTC) + timedelta(seconds=361)
with freeze_time(reset_time):
response = self.client.get(login_url)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
@ddt.data("signin_user", "register_user")
def test_login_and_registration_form_already_authenticated(self, url_name):
@@ -158,10 +158,10 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
'honor_code': 'true',
}
result = self.client.post(url, data=request_data)
self.assertEqual(result.status_code, 200)
assert result.status_code == 200
result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
self.assertTrue(result)
assert result
# Verify that we're redirected to the dashboard
response = self.client.get(reverse(url_name))
@@ -408,7 +408,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
tpa_hint = self.hidden_disabled_provider.provider_id
params = [("next", "/courses/something/?tpa_hint={0}".format(tpa_hint))]
response = self.client.get(reverse('signin_user'), params, HTTP_ACCEPT="text/html")
self.assertNotIn(response.content.decode('utf-8'), tpa_hint)
assert response.content.decode('utf-8') not in tpa_hint
@ddt.data(
('signin_user', 'login'),
@@ -452,7 +452,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
tpa_hint = self.hidden_disabled_provider.provider_id
params = [("next", "/courses/something/?tpa_hint={0}".format(tpa_hint))]
response = self.client.get(reverse(url_name), params, HTTP_ACCEPT="text/html")
self.assertNotIn(response.content.decode('utf-8'), tpa_hint)
assert response.content.decode('utf-8') not in tpa_hint
@override_settings(FEATURES=dict(settings.FEATURES, THIRD_PARTY_AUTH_HINT='oa2-google-oauth2'))
@ddt.data(
@@ -541,11 +541,11 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
cookies[settings.ENTERPRISE_CUSTOMER_COOKIE_NAME] = 'test-enterprise-customer'
response = self.client.get(reverse('signin_user'), HTTP_ACCEPT="text/html", cookies=cookies)
self.assertIn(settings.ENTERPRISE_CUSTOMER_COOKIE_NAME, response.cookies)
assert settings.ENTERPRISE_CUSTOMER_COOKIE_NAME in response.cookies
enterprise_cookie = response.cookies[settings.ENTERPRISE_CUSTOMER_COOKIE_NAME]
self.assertEqual(enterprise_cookie['domain'], settings.BASE_COOKIE_DOMAIN)
self.assertEqual(enterprise_cookie.value, '')
assert enterprise_cookie['domain'] == settings.BASE_COOKIE_DOMAIN
assert enterprise_cookie.value == ''
def test_login_registration_xframe_protected(self):
resp = self.client.get(
@@ -554,7 +554,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
HTTP_REFERER="http://localhost/iframe"
)
self.assertEqual(resp['X-Frame-Options'], 'DENY')
assert resp['X-Frame-Options'] == 'DENY'
self.configure_lti_provider(name='Test', lti_hostname='localhost', lti_consumer_key='test_key', enabled=True)
@@ -563,7 +563,7 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
HTTP_REFERER="http://localhost/iframe"
)
self.assertEqual(resp['X-Frame-Options'], 'ALLOW')
assert resp['X-Frame-Options'] == 'ALLOW'
def _assert_third_party_auth_data(self, response, current_backend, current_provider, providers, expected_ec,
add_user_details=False):
@@ -643,22 +643,22 @@ class LoginAndRegistrationTest(ThirdPartyAuthTestMixin, UrlResetMixin, ModuleSto
def test_english_by_default(self):
response = self.client.get(reverse('signin_user'), [], HTTP_ACCEPT="text/html")
self.assertEqual(response['Content-Language'], 'en')
assert response['Content-Language'] == 'en'
def test_unsupported_language(self):
response = self.client.get(reverse('signin_user'), [], HTTP_ACCEPT="text/html", HTTP_ACCEPT_LANGUAGE="ts-zx")
self.assertEqual(response['Content-Language'], 'en')
assert response['Content-Language'] == 'en'
def test_browser_language(self):
response = self.client.get(reverse('signin_user'), [], HTTP_ACCEPT="text/html", HTTP_ACCEPT_LANGUAGE="es")
self.assertEqual(response['Content-Language'], 'es-419')
assert response['Content-Language'] == 'es-419'
def test_browser_language_dialent(self):
response = self.client.get(reverse('signin_user'), [], HTTP_ACCEPT="text/html", HTTP_ACCEPT_LANGUAGE="es-es")
self.assertEqual(response['Content-Language'], 'es-es')
assert response['Content-Language'] == 'es-es'
@skip_unless_lms

View File

@@ -39,7 +39,7 @@ class LogoutTests(TestCase):
# Logging out should remove the session variables, and send a list of logout URLs to the template.
# The template will handle loading those URLs and redirecting the user. That functionality is not tested here.
response = self.client.get(reverse('logout'), **logout_headers)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
return response
@@ -53,7 +53,7 @@ class LogoutTests(TestCase):
}
# Authenticate with OAuth to set the appropriate session values
response = self.client.post(reverse('oauth2_provider:authorize'), data, follow=True)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
@ddt.data(
('%2Fcourses', 'testserver'),

View File

@@ -7,6 +7,7 @@ import logging
import re
from datetime import datetime, timedelta
import pytest
import ddt
from django.conf import settings
from django.contrib.auth import get_user_model
@@ -47,7 +48,7 @@ class TestRequestPasswordChange(CreateAccountMixin, TestCase):
def test_request_password_change(self):
# Create and activate an account
self.create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
self.assertEqual(len(mail.outbox), 1)
assert len(mail.outbox) == 1
request = RequestFactory().post('/password')
request.user = Mock()
@@ -58,27 +59,27 @@ class TestRequestPasswordChange(CreateAccountMixin, TestCase):
request_password_change(self.EMAIL, self.IS_SECURE)
# Verify that a new email message has been sent
self.assertEqual(len(mail.outbox), 2)
assert len(mail.outbox) == 2
# Verify that the body of the message contains something that looks
# like an activation link
email_body = mail.outbox[0].body
result = re.search(r'(?P<url>https?://[^\s]+)', email_body)
self.assertIsNot(result, None)
assert result is not None
@skip_unless_lms
def test_request_password_change_invalid_user(self):
with self.assertRaises(UserNotFound):
with pytest.raises(UserNotFound):
request_password_change(self.EMAIL, self.IS_SECURE)
# Verify that no email messages have been sent
self.assertEqual(len(mail.outbox), 0)
assert len(mail.outbox) == 0
@skip_unless_lms
def test_request_password_change_inactive_user(self):
# Create an account, but do not activate it
self.create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
self.assertEqual(len(mail.outbox), 1)
assert len(mail.outbox) == 1
request = RequestFactory().post('/password')
request.user = Mock()
@@ -88,7 +89,7 @@ class TestRequestPasswordChange(CreateAccountMixin, TestCase):
request_password_change(self.EMAIL, self.IS_SECURE)
# Verify that the password change email was still sent
self.assertEqual(len(mail.outbox), 2)
assert len(mail.outbox) == 2
@skip_unless_lms
@@ -112,7 +113,7 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
self.create_account(self.USERNAME, self.OLD_PASSWORD, self.OLD_EMAIL)
result = self.client.login(username=self.USERNAME, password=self.OLD_PASSWORD)
self.assertTrue(result)
assert result
mail.outbox = []
cache.clear()
@@ -120,20 +121,20 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
# Request a password change while logged in, simulating
# use of the password reset link from the account page
response = self._change_password()
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
# Check that an email was sent
self.assertEqual(len(mail.outbox), 1)
assert len(mail.outbox) == 1
# Retrieve the activation link from the email body
email_body = mail.outbox[0].body
result = re.search(r'(?P<url>https?://[^\s]+)', email_body)
self.assertIsNot(result, None)
assert result is not None
activation_link = result.group('url')
# Visit the activation link
response = self.client.get(activation_link)
self.assertEqual(response.status_code, 302)
assert response.status_code == 302
# Visit the redirect link
_ = self.client.get(response.url)
@@ -145,7 +146,7 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
{'new_password1': self.NEW_PASSWORD, 'new_password2': self.NEW_PASSWORD},
follow=True
)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertContains(response, "Your password has been reset.")
# Log the user out to clear session data
@@ -161,14 +162,14 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
# Try reusing the activation link to change the password again
# Visit the activation link again.
response = self.client.get(activation_link)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self.assertContains(response, "This password reset link is invalid. It may have been used already.")
self.client.logout()
# Verify that the old password cannot be used to log in
result = self.client.login(username=self.USERNAME, password=self.OLD_PASSWORD)
self.assertFalse(result)
assert not result
# Verify that the new password continues to be valid
response = self.client.post(login_api_url, {'email': self.OLD_EMAIL, 'password': self.NEW_PASSWORD})
@@ -192,10 +193,10 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
bad_email = 'doesnotexist@example.com'
response = self._change_password(email=bad_email)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
# Check that an email was sent
self.assertEqual(len(mail.outbox), 1)
assert len(mail.outbox) == 1
# Verify that the body contains the failed password reset message
sent_message = mail.outbox[0]
@@ -220,27 +221,27 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
# use of the password reset link from the login page
if send_email:
response = self._change_password(email=self.OLD_EMAIL)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
else:
# Don't send an email in the POST data, simulating
# its (potentially accidental) omission in the POST
# data sent from the login page
response = self._change_password()
self.assertEqual(response.status_code, 400)
assert response.status_code == 400
def test_access_token_invalidation_logged_out(self):
self.client.logout()
user = User.objects.get(email=self.OLD_EMAIL)
self._create_dot_tokens(user)
response = self._change_password(email=self.OLD_EMAIL)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self._assert_access_token_destroyed(user)
def test_access_token_invalidation_logged_in(self):
user = User.objects.get(email=self.OLD_EMAIL)
self._create_dot_tokens(user)
response = self._change_password()
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self._assert_access_token_destroyed(user)
def test_password_change_inactive_user(self):
@@ -256,8 +257,8 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
# Expect that the activation email is still sent,
# since the user may have lost the original activation email.
self.assertEqual(response.status_code, 200)
self.assertEqual(len(mail.outbox), 1)
assert response.status_code == 200
assert len(mail.outbox) == 1
def test_password_change_no_user(self):
# Log out the user created during test setup
@@ -266,7 +267,7 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
with LogCapture(LOGGER_NAME, level=logging.INFO) as logger:
# Send the view an email address not tied to any user
response = self._change_password(email=self.NEW_EMAIL)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
expected_logs = (
(LOGGER_NAME, 'INFO', 'Password reset initiated for email {}.'.format(self.NEW_EMAIL)),
@@ -284,14 +285,14 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
self.client.logout()
for status in [200, 403]:
response = self._change_password(email=self.NEW_EMAIL)
self.assertEqual(response.status_code, status)
assert response.status_code == status
# now reset the time to 1 min from now in future and change the email and
# verify that it will allow another request from same IP
reset_time = datetime.now(UTC) + timedelta(seconds=61)
with freeze_time(reset_time):
response = self._change_password(email=self.OLD_EMAIL)
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
@ddt.data(
('post', 'password_change_request', []),
@@ -303,7 +304,7 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
for method in wrong_methods:
response = getattr(self.client, method)(url)
self.assertEqual(response.status_code, 405)
assert response.status_code == 405
def _change_password(self, email=None):
"""Request to change the user's password. """
@@ -325,5 +326,5 @@ class TestPasswordChange(CreateAccountMixin, CacheIsolationTestCase):
def _assert_access_token_destroyed(self, user):
"""Assert all access tokens are destroyed."""
self.assertFalse(dot_access_token.objects.filter(user=user).exists())
self.assertFalse(dot_refresh_token.objects.filter(user=user).exists())
assert not dot_access_token.objects.filter(user=user).exists()
assert not dot_refresh_token.objects.filter(user=user).exists()

View File

@@ -109,11 +109,9 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 403)
self.assertEqual(
response.content,
b"Third party authentication is required to register. Username and password were received instead."
)
assert response.status_code == 403
assert response.content == (b"Third party authentication is required to register. "
b"Username and password were received instead.")
def test_register_retired_email_validation_error(self):
# Register the first user
@@ -137,7 +135,8 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -179,7 +178,9 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -214,7 +215,9 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -250,7 +253,8 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -285,7 +289,8 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -320,7 +325,8 @@ class RegistrationViewValidationErrorTest(ThirdPartyAuthTestMixin, UserAPITestCa
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -595,12 +601,8 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
('us', 'US', 'Bob-1231231&23123+1231(2312312312@3123123123', 'Bob-1231231_23123_1231_2312312'),
)
@ddt.unpack
def test_register_form_third_party_auth_running_google(
self,
input_country_code,
expected_country_code,
input_username,
expected_username):
def test_register_form_third_party_auth_running_google(self, input_country_code, expected_country_code,
input_username, expected_username):
no_extra_fields_setting = {}
country_options = (
[
@@ -613,7 +615,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
{
"value": country_code,
"name": six.text_type(country_name),
"default": True if country_code == expected_country_code else False # lint-amnesty, pylint: disable=simplifiable-if-expression
"default": country_code == expected_country_code
}
for country_code, country_name in SORTED_COUNTRIES
]
@@ -1167,7 +1169,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
# Verify that all fields render in the correct order
form_desc = json.loads(response.content.decode('utf-8'))
field_names = [field["name"] for field in form_desc["fields"]]
self.assertEqual(field_names, [
assert field_names == [
"email",
"name",
"username",
@@ -1183,7 +1185,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"mailing_address",
"goals",
"honor_code",
])
]
@override_settings(
REGISTRATION_EXTRA_FIELDS={
@@ -1230,7 +1232,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
# Verify that all fields render in the correct order
form_desc = json.loads(response.content.decode('utf-8'))
field_names = [field["name"] for field in form_desc["fields"]]
self.assertEqual(field_names, [
assert field_names == [
"name",
"username",
"email",
@@ -1244,7 +1246,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"mailing_address",
"goals",
"honor_code",
])
]
@override_settings(
REGISTRATION_EXTRA_FIELDS={
@@ -1284,7 +1286,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
# Verify that all fields render in the correct order
form_desc = json.loads(response.content.decode('utf-8'))
field_names = [field["name"] for field in form_desc["fields"]]
self.assertEqual(field_names, [
assert field_names == [
"email",
"name",
"username",
@@ -1301,7 +1303,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"mailing_address",
"goals",
"honor_code",
])
]
def test_register(self):
# Create a new registration
@@ -1313,18 +1315,18 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"honor_code": "true",
})
self.assertHttpOK(response)
self.assertIn(settings.EDXMKTG_LOGGED_IN_COOKIE_NAME, self.client.cookies)
self.assertIn(settings.EDXMKTG_USER_INFO_COOKIE_NAME, self.client.cookies)
assert settings.EDXMKTG_LOGGED_IN_COOKIE_NAME in self.client.cookies
assert settings.EDXMKTG_USER_INFO_COOKIE_NAME in self.client.cookies
user = User.objects.get(username=self.USERNAME)
request = RequestFactory().get('/url')
request.user = user
account_settings = get_account_settings(request)[0]
self.assertEqual(self.USERNAME, account_settings["username"])
self.assertEqual(self.EMAIL, account_settings["email"])
self.assertFalse(account_settings["is_active"])
self.assertEqual(self.NAME, account_settings["name"])
assert self.USERNAME == account_settings["username"]
assert self.EMAIL == account_settings["email"]
assert not account_settings["is_active"]
assert self.NAME == account_settings["name"]
# Verify that we've been logged in
# by trying to access a page that requires authentication
@@ -1361,11 +1363,11 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
request.user = user
account_settings = get_account_settings(request)[0]
self.assertEqual(account_settings["level_of_education"], self.EDUCATION)
self.assertEqual(account_settings["mailing_address"], self.ADDRESS)
self.assertEqual(account_settings["year_of_birth"], int(self.YEAR_OF_BIRTH))
self.assertEqual(account_settings["goals"], self.GOALS)
self.assertEqual(account_settings["country"], self.COUNTRY)
assert account_settings["level_of_education"] == self.EDUCATION
assert account_settings["mailing_address"] == self.ADDRESS
assert account_settings["year_of_birth"] == int(self.YEAR_OF_BIRTH)
assert account_settings["goals"] == self.GOALS
assert account_settings["country"] == self.COUNTRY
@override_settings(REGISTRATION_EXTENSION_FORM='openedx.core.djangoapps.user_api.tests.test_helpers.TestCaseForm')
@mock.patch('openedx.core.djangoapps.user_api.tests.test_helpers.TestCaseForm.DUMMY_STORAGE', new_callable=dict)
@@ -1376,7 +1378,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
dummy_model_instance = mock.Mock()
dummy_model.return_value = dummy_model_instance
# Create a new registration
self.assertEqual(storage_dict, {})
assert storage_dict == {}
response = self.client.post(self.url, {
"email": self.EMAIL,
"name": self.NAME,
@@ -1387,21 +1389,21 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"favorite_editor": "cat",
})
self.assertHttpOK(response)
self.assertIn(settings.EDXMKTG_LOGGED_IN_COOKIE_NAME, self.client.cookies)
self.assertIn(settings.EDXMKTG_USER_INFO_COOKIE_NAME, self.client.cookies)
assert settings.EDXMKTG_LOGGED_IN_COOKIE_NAME in self.client.cookies
assert settings.EDXMKTG_USER_INFO_COOKIE_NAME in self.client.cookies
user = User.objects.get(username=self.USERNAME)
request = RequestFactory().get('/url')
request.user = user
account_settings = get_account_settings(request)[0]
self.assertEqual(self.USERNAME, account_settings["username"])
self.assertEqual(self.EMAIL, account_settings["email"])
self.assertFalse(account_settings["is_active"])
self.assertEqual(self.NAME, account_settings["name"])
assert self.USERNAME == account_settings["username"]
assert self.EMAIL == account_settings["email"]
assert not account_settings["is_active"]
assert self.NAME == account_settings["name"]
self.assertEqual(storage_dict, {'favorite_movie': "Inception", "favorite_editor": "cat"})
self.assertEqual(dummy_model_instance.user, user)
assert storage_dict == {'favorite_movie': "Inception", "favorite_editor": "cat"}
assert dummy_model_instance.user == user
# Verify that we've been logged in
# by trying to access a page that requires authentication
@@ -1420,17 +1422,12 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
self.assertHttpOK(response)
# Verify that the activation email was sent
self.assertEqual(len(mail.outbox), 1)
assert len(mail.outbox) == 1
sent_email = mail.outbox[0]
self.assertEqual(sent_email.to, [self.EMAIL])
self.assertEqual(
sent_email.subject,
u"Action Required: Activate your {platform} account".format(platform=settings.PLATFORM_NAME)
)
self.assertIn(
u"high-quality {platform} courses".format(platform=settings.PLATFORM_NAME),
sent_email.body
)
assert sent_email.to == [self.EMAIL]
assert sent_email.subject ==\
"Action Required: Activate your {platform} account".format(platform=settings.PLATFORM_NAME)
assert "high-quality {platform} courses".format(platform=settings.PLATFORM_NAME) in sent_email.body
@ddt.data(
{"email": ""},
@@ -1492,7 +1489,8 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -1527,7 +1525,8 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -1562,7 +1561,8 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"password": self.PASSWORD,
"honor_code": "true",
})
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -1605,7 +1605,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
"honor_code": "true",
}
)
self.assertEqual(response.status_code, 400)
assert response.status_code == 400
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -1662,7 +1662,7 @@ class RegistrationViewTestV1(ThirdPartyAuthTestMixin, UserAPITestCase):
with mock.patch('openedx.core.djangoapps.site_configuration.helpers.get_value') as mock_get_value:
mock_get_value.side_effect = _side_effect_for_get_value
response = self.client.post(self.url, {"email": self.EMAIL, "username": self.USERNAME})
self.assertEqual(response.status_code, 403)
assert response.status_code == 403
def _assert_fields_match(self, actual_field, expected_field):
"""
@@ -1754,6 +1754,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
Test for registration api V2
"""
# pylint: disable=test-inherits-tests
def setUp(self): # pylint: disable=arguments-differ
@@ -1799,7 +1800,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
form_desc = json.loads(response.content.decode('utf-8'))
field_names = [field["name"] for field in form_desc["fields"]]
self.assertEqual(field_names, [
assert field_names == [
"email",
"name",
"username",
@@ -1816,7 +1817,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
"mailing_address",
"goals",
"honor_code",
])
]
@override_settings(
REGISTRATION_EXTRA_FIELDS={
@@ -1863,7 +1864,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
# Verify that all fields render in the correct order
form_desc = json.loads(response.content.decode('utf-8'))
field_names = [field["name"] for field in form_desc["fields"]]
self.assertEqual(field_names, [
assert field_names == [
"name",
"username",
"email",
@@ -1878,7 +1879,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
"mailing_address",
"goals",
"honor_code",
])
]
@override_settings(
REGISTRATION_EXTRA_FIELDS={
@@ -1902,7 +1903,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
# Verify that all fields render in the correct order
form_desc = json.loads(response.content.decode('utf-8'))
field_names = [field["name"] for field in form_desc["fields"]]
self.assertEqual(field_names, [
assert field_names == [
"email",
"name",
"username",
@@ -1919,7 +1920,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
"mailing_address",
"goals",
"honor_code",
])
]
def test_registration_form_confirm_email(self):
self._assert_reg_field(
@@ -1979,10 +1980,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
{
'next_url': None,
'course_id': 'coursekey',
'expected_redirect': (
'{root_url}/account/finish_auth?course_id=coursekey&next=%2Fdashboard'.
format(root_url=settings.LMS_ROOT_URL)
),
'expected_redirect': f'{settings.LMS_ROOT_URL}/account/finish_auth?course_id=coursekey&next=%2Fdashboard',
},
# If valid course_id AND next_url are provided, redirect to finish_auth with
# provided next URL.
@@ -1998,10 +1996,7 @@ class RegistrationViewTestV2(RegistrationViewTestV1):
{
'next_url': 'http://scam.scam',
'course_id': 'coursekey',
'expected_redirect': (
'{root_url}/account/finish_auth?course_id=coursekey&next=%2Fdashboard'.
format(root_url=settings.LMS_ROOT_URL)
),
'expected_redirect': f'{settings.LMS_ROOT_URL}/account/finish_auth?course_id=coursekey&next=%2Fdashboard',
},
)
@ddt.unpack
@@ -2064,15 +2059,15 @@ class ThirdPartyRegistrationTestMixin(ThirdPartyOAuthTestMixin, CacheIsolationTe
def _assert_existing_user_error(self, response):
"""Assert that the given response was an error with the given status_code and error code."""
self.assertEqual(response.status_code, 409)
assert response.status_code == 409
errors = json.loads(response.content.decode('utf-8'))
for conflict_attribute in ["username", "email"]:
self.assertIn(conflict_attribute, errors)
self.assertIn("belongs to an existing account", errors[conflict_attribute][0]["user_message"])
assert conflict_attribute in errors
assert "belongs to an existing account" in errors[conflict_attribute][0]["user_message"]
def _assert_access_token_error(self, response, expected_error_message):
"""Assert that the given response was an error for the access_token field with the given error message."""
self.assertEqual(response.status_code, 400)
assert response.status_code == 400
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -2083,7 +2078,7 @@ class ThirdPartyRegistrationTestMixin(ThirdPartyOAuthTestMixin, CacheIsolationTe
def _assert_third_party_session_expired_error(self, response, expected_error_message):
"""Assert that given response is an error due to third party session expiry"""
self.assertEqual(response.status_code, 400)
assert response.status_code == 400
response_json = json.loads(response.content.decode('utf-8'))
self.assertDictEqual(
response_json,
@@ -2097,20 +2092,20 @@ class ThirdPartyRegistrationTestMixin(ThirdPartyOAuthTestMixin, CacheIsolationTe
users = User.objects.filter(username=(username if username else "test_username"))
self.assertEqual(users.exists(), user_exists)
if user_exists:
self.assertEqual(users[0].is_active, user_is_active)
assert users[0].is_active == user_is_active
self.assertEqual(
UserSocialAuth.objects.filter(user=users[0], provider=self.BACKEND).exists(),
social_link_exists
)
else:
self.assertEqual(UserSocialAuth.objects.count(), 0)
assert UserSocialAuth.objects.count() == 0
def test_success(self):
self._verify_user_existence(user_exists=False, social_link_exists=False)
self._setup_provider_response(success=True)
response = self.client.post(self.url, self.data())
self.assertEqual(response.status_code, 200)
assert response.status_code == 200
self._verify_user_existence(user_exists=True, social_link_exists=True, user_is_active=False)
@@ -2232,16 +2227,10 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
return response.data.get('validation_decisions', {})
def assertValidationDecision(self, data, decision):
self.assertEqual(
self.get_validation_decision(data),
decision
)
assert self.get_validation_decision(data) == decision
def assertNotValidationDecision(self, data, decision):
self.assertNotEqual(
self.get_validation_decision(data),
decision
)
assert self.get_validation_decision(data) != decision
def test_no_decision_for_empty_request(self):
self.assertValidationDecision(
@@ -2257,10 +2246,10 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
@ddt.data(
['name', [name for name in testutils.VALID_NAMES]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['email', [email for email in testutils.VALID_EMAILS]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['password', [password for password in testutils.VALID_PASSWORDS]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['username', [username for username in testutils.VALID_USERNAMES]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['country', [country for country in testutils.VALID_COUNTRIES]] # lint-amnesty, pylint: disable=unnecessary-comprehension
['email', [email for email in testutils.VALID_EMAILS]], # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
['password', [password for password in testutils.VALID_PASSWORDS]], # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
['username', [username for username in testutils.VALID_USERNAMES]], # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
['country', [country for country in testutils.VALID_COUNTRIES]] # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
)
@ddt.unpack
def test_positive_validation_decision(self, form_field_name, user_data):
@@ -2274,11 +2263,11 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
@ddt.data(
# Skip None type for invalidity checks.
['name', [name for name in testutils.INVALID_NAMES[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['email', [email for email in testutils.INVALID_EMAILS[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['password', [password for password in testutils.INVALID_PASSWORDS[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['username', [username for username in testutils.INVALID_USERNAMES[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension
['country', [country for country in testutils.INVALID_COUNTRIES[1:]]] # lint-amnesty, pylint: disable=unnecessary-comprehension
['name', [name for name in testutils.INVALID_NAMES[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
['email', [email for email in testutils.INVALID_EMAILS[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
['password', [password for password in testutils.INVALID_PASSWORDS[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
['username', [username for username in testutils.INVALID_USERNAMES[1:]]], # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
['country', [country for country in testutils.INVALID_COUNTRIES[1:]]] # lint-amnesty, pylint: disable=unnecessary-comprehension, line-too-long
)
@ddt.unpack
def test_negative_validation_decision(self, form_field_name, user_data):
@@ -2430,4 +2419,4 @@ class RegistrationValidationViewTests(test_utils.ApiTestCase):
response = self.request_without_auth('post', self.path)
self.assertNotEqual(response.status_code, 403)
response = self.request_without_auth('post', self.path)
self.assertEqual(response.status_code, 403)
assert response.status_code == 403

View File

@@ -7,7 +7,6 @@ import re
import unicodedata
import unittest
from datetime import datetime, timedelta
import ddt
from django.conf import settings
from django.contrib.auth.hashers import UNUSABLE_PASSWORD_PREFIX, make_password
@@ -47,7 +46,6 @@ from common.djangoapps.student.models import AccountRecovery
from common.djangoapps.util.password_policy_validators import create_validator_config
from common.djangoapps.util.testing import EventTestMixin
ENABLE_AUTHN_MICROFRONTEND = settings.FEATURES.copy()
ENABLE_AUTHN_MICROFRONTEND['ENABLE_AUTHN_MICROFRONTEND'] = True
@@ -71,7 +69,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
ENABLED_CACHES = ['default']
def setUp(self): # pylint: disable=arguments-differ
super(ResetPasswordTests, self).setUp('openedx.core.djangoapps.user_authn.views.password_reset.tracker') # lint-amnesty, pylint: disable=super-with-arguments
super().setUp('openedx.core.djangoapps.user_authn.views.password_reset.tracker')
self.user = UserFactory.create()
self.user.is_active = False
self.user.save()
@@ -118,12 +116,9 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
bad_pwd_req.user = AnonymousUser()
bad_pwd_resp = password_reset(bad_pwd_req)
# If they've got an unusable password, we return a successful response code
self.assertEqual(bad_pwd_resp.status_code, 200)
assert bad_pwd_resp.status_code == 200
obj = json.loads(bad_pwd_resp.content.decode('utf-8'))
self.assertEqual(obj, {
'success': True,
'value': "('registration/password_reset_done.html', [])",
})
assert obj == {'success': True, 'value': "('registration/password_reset_done.html', [])"}
self.assert_no_events_were_emitted()
@patch(
@@ -141,12 +136,9 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
# Note: even if the email is bad, we return a successful response code
# This prevents someone potentially trying to "brute-force" find out which
# emails are and aren't registered with edX
self.assertEqual(bad_email_resp.status_code, 200)
assert bad_email_resp.status_code == 200
obj = json.loads(bad_email_resp.content.decode('utf-8'))
self.assertEqual(obj, {
'success': True,
'value': "('registration/password_reset_done.html', [])",
})
assert obj == {'success': True, 'value': "('registration/password_reset_done.html', [])"}
self.assert_no_events_were_emitted()
@patch(
@@ -182,11 +174,11 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
password_reset_req.user = user
password_reset_req.site = Mock(domain='example.com')
good_resp = password_reset(password_reset_req)
self.assertEqual(good_resp.status_code, 200)
assert good_resp.status_code == 200
# then the rate limiter should kick in and give a HttpForbidden response
bad_resp = password_reset(password_reset_req)
self.assertEqual(bad_resp.status_code, 403)
assert bad_resp.status_code == 403
cache.clear()
@@ -198,11 +190,11 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
sent_message = mail.outbox[0]
body = sent_message.body
self.assertIn(expected['subject'], sent_message.subject)
self.assertIn(expected['body'], body)
self.assertEqual(sent_message.from_email, from_email)
self.assertEqual(len(sent_message.to), 1)
self.assertIn(self.user.email, sent_message.to)
assert expected['subject'] in sent_message.subject
assert expected['body'] in body
assert sent_message.from_email == from_email
assert len(sent_message.to) == 1
assert self.user.email in sent_message.to
def test_ratelimitted_from_same_ip_with_different_email(self):
"""
@@ -212,14 +204,14 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
good_req = self.request_factory.post('/password_reset/', {'email': 'thisdoesnotexist@foo.com'})
good_req.user = AnonymousUser()
good_resp = password_reset(good_req)
self.assertEqual(good_resp.status_code, 200)
assert good_resp.status_code == 200
# change the email ID and verify that the rate limiter should kick in and
# give a Forbidden response if the request is from same IP.
bad_req = self.request_factory.post('/password_reset/', {'email': 'thisdoesnotexist2@foo.com'})
bad_req.user = AnonymousUser()
bad_resp = password_reset(bad_req)
self.assertEqual(bad_resp.status_code, 403)
assert bad_resp.status_code == 403
cache.clear()
@@ -255,11 +247,11 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
)
if new_ip:
self.assertEqual(reset_request.META.get('REMOTE_ADDR'), new_ip)
assert reset_request.META.get('REMOTE_ADDR') == new_ip
reset_request.user = AnonymousUser()
response = password_reset(reset_request)
self.assertEqual(response.status_code, status)
assert response.status_code == status
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', "Test only valid in LMS")
@ddt.data(('plain_text', "You're receiving this e-mail because you requested a password reset"),
@@ -274,12 +266,12 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
dot_access_token = dot_factories.AccessTokenFactory(user=self.user, application=dot_application)
dot_factories.RefreshTokenFactory(user=self.user, application=dot_application, access_token=dot_access_token)
good_resp = password_reset(good_req)
self.assertEqual(good_resp.status_code, 200)
self.assertFalse(dot_models.AccessToken.objects.filter(user=self.user).exists())
self.assertFalse(dot_models.RefreshToken.objects.filter(user=self.user).exists())
assert good_resp.status_code == 200
assert not dot_models.AccessToken.objects.filter(user=self.user).exists()
assert not dot_models.RefreshToken.objects.filter(user=self.user).exists()
obj = json.loads(good_resp.content.decode('utf-8'))
self.assertTrue(obj['success'])
self.assertIn('e-mailed you instructions for setting your password', obj['value'])
assert obj['success']
assert 'e-mailed you instructions for setting your password' in obj['value']
from_email = configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
sent_message = mail.outbox[0]
@@ -291,11 +283,11 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
body = bodies[body_type]
self.assertIn("Password reset", sent_message.subject)
self.assertIn(expected_output, body)
self.assertEqual(sent_message.from_email, from_email)
self.assertEqual(len(sent_message.to), 1)
self.assertIn(self.user.email, sent_message.to)
assert 'Password reset' in sent_message.subject
assert expected_output in body
assert sent_message.from_email == from_email
assert len(sent_message.to) == 1
assert self.user.email in sent_message.to
self.assert_event_emitted(
SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'password', old=None, new=None,
@@ -303,9 +295,9 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
# Test that the user is not active
self.user = User.objects.get(pk=self.user.pk)
self.assertFalse(self.user.is_active)
assert not self.user.is_active
self.assertIn('password_reset_confirm/', body)
assert 'password_reset_confirm/' in body
re.search(r'password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/', body).groupdict()
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', "Test only valid in LMS")
@@ -326,7 +318,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
msg = sent_message.body
expected_msg = "Please go to the following page and choose a new password:\n\n" + protocol
self.assertIn(expected_msg, msg)
assert expected_msg in msg
self.assert_event_emitted(
SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'password', old=None, new=None
@@ -356,11 +348,11 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
reset_msg = u"you requested a password reset for your user account at {}"
reset_msg = reset_msg.format(site_name)
self.assertIn(reset_msg, msg)
self.assertIn(settings.AUTHN_MICROFRONTEND_URL, msg)
assert reset_msg in msg
assert settings.AUTHN_MICROFRONTEND_URL in msg
sign_off = u"The {} Team".format(platform_name)
self.assertIn(sign_off, msg)
assert sign_off in msg
self.assert_event_emitted(
SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'password', old=None, new=None
@@ -396,12 +388,12 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
fake_get_value('PLATFORM_NAME')
)
self.assertIn(reset_msg, body)
assert reset_msg in body
self.assert_event_emitted(
SETTING_CHANGE_INITIATED, user_id=self.user.id, setting=u'password', old=None, new=None
)
self.assertEqual(sent_message.from_email, "no-reply@fakeuniversity.com")
assert sent_message.from_email == 'no-reply@fakeuniversity.com'
@ddt.data(
('invalidUid', 'invalid_token'),
@@ -428,7 +420,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
bad_request.user = AnonymousUser()
PasswordResetConfirmWrapper.as_view()(bad_request, uidb36=uidb36, token=token)
self.user = User.objects.get(pk=self.user.pk)
self.assertFalse(self.user.is_active)
assert not self.user.is_active
def test_reset_password_good_token(self):
"""
@@ -453,7 +445,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
PasswordResetConfirmWrapper.as_view()(good_reset_req, uidb36=self.uidb36, token='set-password')
self.user = User.objects.get(pk=self.user.pk)
self.assertTrue(self.user.is_active)
assert self.user.is_active
def test_reset_password_good_token_with_anonymous_user(self):
"""
@@ -478,13 +470,13 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
PasswordResetConfirmWrapper.as_view()(good_reset_req, uidb36=self.uidb36, token='set-password')
self.user = User.objects.get(pk=self.user.pk)
self.assertTrue(self.user.is_active)
assert self.user.is_active
def test_password_reset_fail(self):
"""
Tests that if we provide mismatched passwords, user is not marked as active.
"""
self.assertFalse(self.user.is_active)
assert not self.user.is_active
request_params = {'new_password1': 'password1', 'new_password2': 'password2'}
confirm_request = self.request_factory.post(self.password_reset_confirm_url, data=request_params)
@@ -496,14 +488,14 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
# Verify the response status code is: 200 with password reset fail and also verify that
# the user is not marked as active.
self.assertEqual(resp.status_code, 200)
self.assertFalse(User.objects.get(pk=self.user.pk).is_active)
assert resp.status_code == 200
assert not User.objects.get(pk=self.user.pk).is_active
def test_password_reset_retired_user_fail(self):
"""
Tests that if a retired user attempts to reset their password, it fails.
"""
self.assertFalse(self.user.is_active)
assert not self.user.is_active
# Retire the user.
UserRetirementRequest.create_retirement_request(self.user)
@@ -514,8 +506,8 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
# Verify the response status code is: 200 with password reset fail and also verify that
# the user is not marked as active.
self.assertEqual(resp.status_code, 200)
self.assertFalse(User.objects.get(pk=self.user.pk).is_active)
assert resp.status_code == 200
assert not User.objects.get(pk=self.user.pk).is_active
def test_password_reset_normalize_password(self):
# pylint: disable=anomalous-unicode-escape-in-string
@@ -536,7 +528,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
user = User.objects.get(pk=self.user.pk)
salt_val = user.password.split('$')[1]
expected_user_password = make_password(unicodedata.normalize('NFKC', u'p\u212bssword'), salt_val)
self.assertEqual(expected_user_password, user.password)
assert expected_user_password == user.password
self.assert_email_sent_successfully({
'subject': 'Password reset completed',
@@ -574,7 +566,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
# Make a password reset request with minimum/maximum passwords characters.
response = PasswordResetConfirmWrapper.as_view()(confirm_request, uidb36=self.uidb36, token=self.token)
self.assertEqual(response.context_data['err_msg'], password_dict['error_message'])
assert response.context_data['err_msg'] == password_dict['error_message']
@patch.object(PasswordResetConfirmView, 'dispatch')
@patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
@@ -586,9 +578,9 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
good_reset_req.user = self.user
PasswordResetConfirmWrapper.as_view()(good_reset_req, uidb36=self.uidb36, token=self.token)
confirm_kwargs = reset_confirm.call_args[1]
self.assertEqual(confirm_kwargs['extra_context']['platform_name'], 'Fake University')
assert confirm_kwargs['extra_context']['platform_name'] == 'Fake University'
self.user = User.objects.get(pk=self.user.pk)
self.assertTrue(self.user.is_active)
assert self.user.is_active
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', "Test only valid in LMS")
@ddt.data('Crazy Awesome Site', 'edX')
@@ -607,7 +599,7 @@ class ResetPasswordTests(EventTestMixin, CacheIsolationTestCase):
sent_message = mail.outbox[0]
subj = sent_message.subject
self.assertIn(platform_name, subj)
assert platform_name in subj
def test_reset_password_with_other_user_link(self):
"""
@@ -655,29 +647,21 @@ class PasswordResetViewTest(UserAPITestCase):
# Verify that the form description matches what we expect
form_desc = json.loads(response.content.decode('utf-8'))
self.assertEqual(form_desc["method"], "post")
self.assertEqual(form_desc["submit_url"], reverse("password_change_request"))
self.assertEqual(form_desc["fields"], [
{
"name": "email",
"defaultValue": "",
"type": "email",
"required": True,
"label": "Email",
"placeholder": "username@domain.com",
"instructions": u"The email address you used to register with {platform_name}".format(
platform_name=settings.PLATFORM_NAME
),
"restrictions": {
"min_length": EMAIL_MIN_LENGTH,
"max_length": EMAIL_MAX_LENGTH
},
"errorMessages": {},
"supplementalText": "",
"supplementalLink": "",
"loginIssueSupportLink": "https://support.example.com/login-issue-help.html",
}
])
assert form_desc['method'] == 'post'
assert form_desc['submit_url'] == reverse('password_change_request')
assert form_desc['fields'] == \
[{'name': 'email',
'defaultValue': '',
'type': 'email',
'required': True,
'label': 'Email',
'placeholder': 'username@domain.com',
'instructions': f'The email address you used to register with {settings.PLATFORM_NAME}',
'restrictions': {'min_length': EMAIL_MIN_LENGTH,
'max_length': EMAIL_MAX_LENGTH},
'errorMessages': {}, 'supplementalText': '',
'supplementalLink': '',
'loginIssueSupportLink': 'https://support.example.com/login-issue-help.html'}]
@skip_unless_lms
@@ -701,10 +685,10 @@ class PasswordResetTokenValidateViewTest(UserAPITestCase):
"""
response = self.client.post(self.url, data={'token': self.token})
json_response = json.loads(response.content.decode('utf-8'))
self.assertTrue(json_response.get('is_valid'))
assert json_response.get('is_valid')
self.user = User.objects.get(pk=self.user.pk)
self.assertTrue(self.user.is_active)
assert self.user.is_active
def test_reset_password_invalid_token(self):
"""
@@ -712,7 +696,7 @@ class PasswordResetTokenValidateViewTest(UserAPITestCase):
"""
response = self.client.post(self.url, data={'token': 'invalid-token'})
json_response = json.loads(response.content.decode('utf-8'))
self.assertFalse(json_response.get('is_valid'))
assert not json_response.get('is_valid')
def test_reset_password_token_with_other_user(self):
"""
@@ -723,10 +707,10 @@ class PasswordResetTokenValidateViewTest(UserAPITestCase):
response = self.client.post(self.url, {'token': self.token})
json_response = json.loads(response.content.decode('utf-8'))
self.assertFalse(json_response.get('is_valid'))
assert not json_response.get('is_valid')
self.user = User.objects.get(pk=self.user.pk)
self.assertFalse(self.user.is_active)
assert not self.user.is_active
@ddt.ddt
@@ -740,7 +724,7 @@ class ResetPasswordAPITests(EventTestMixin, CacheIsolationTestCase):
ENABLED_CACHES = ['default']
def setUp(self): # lint-amnesty, pylint: disable=arguments-differ
super(ResetPasswordAPITests, self).setUp('openedx.core.djangoapps.user_authn.views.password_reset.tracker') # lint-amnesty, pylint: disable=super-with-arguments
super().setUp('openedx.core.djangoapps.user_authn.views.password_reset.tracker')
self.user = UserFactory.create()
self.user.save()
self.token = default_token_generator.make_token(self.user)
@@ -778,7 +762,7 @@ class ResetPasswordAPITests(EventTestMixin, CacheIsolationTestCase):
reset_view = LogistrationPasswordResetView.as_view()
json_response = reset_view(post_request, uidb36=uidb36, token=token).render()
json_response = json.loads(json_response.content.decode('utf-8'))
self.assertEqual(json_response.get('reset_status'), status)
assert json_response.get('reset_status') == status
def test_none_token_in_password_reset_request(self):
"""
@@ -790,7 +774,11 @@ class ResetPasswordAPITests(EventTestMixin, CacheIsolationTestCase):
post_request = self.create_reset_request(self.uidb36, self.token, False)
post_request.user = AnonymousUser()
reset_view = LogistrationPasswordResetView.as_view()
self.assertRaises(Exception, reset_view(post_request, uidb36=uidb36, token=token))
response = reset_view(post_request, uidb36=uidb36, token=token)
assert response.status_code == 200
response.render()
response_dict = json.loads(response.content.decode('utf-8'))
assert response_dict.get('reset_status') is False
def test_password_mismatch_in_reset_request(self):
"""
@@ -801,7 +789,7 @@ class ResetPasswordAPITests(EventTestMixin, CacheIsolationTestCase):
reset_view = LogistrationPasswordResetView.as_view()
json_response = reset_view(post_request, uidb36=self.uidb36, token=self.token).render()
json_response = json.loads(json_response.content.decode('utf-8'))
self.assertFalse(json_response.get('reset_status'))
assert not json_response.get('reset_status')
def test_account_recovery_using_forgot_password(self):
"""
@@ -814,7 +802,7 @@ class ResetPasswordAPITests(EventTestMixin, CacheIsolationTestCase):
reset_view(post_request, uidb36=self.uidb36, token=self.token)
updated_user = User.objects.get(id=self.user.id)
self.assertEqual(updated_user.email, self.secondary_email)
assert updated_user.email == self.secondary_email
self.assert_event_emitted(
SETTING_CHANGE_INITIATED,
@@ -841,8 +829,8 @@ class ResetPasswordAPITests(EventTestMixin, CacheIsolationTestCase):
sent_message = mail.outbox[0]
body = sent_message.body
self.assertIn('Password reset completed', sent_message.subject)
self.assertIn('This is to confirm that you have successfully changed your password', body)
self.assertEqual(sent_message.from_email, from_email)
self.assertEqual(len(sent_message.to), 1)
self.assertIn(updated_user.email, sent_message.to[0])
assert 'Password reset completed' in sent_message.subject
assert 'This is to confirm that you have successfully changed your password' in body
assert sent_message.from_email == from_email
assert len(sent_message.to) == 1
assert updated_user.email in sent_message.to[0]