replaced unittest assertions pytest assertions (#26527)
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
|
||||
import ddt
|
||||
import pytest
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.core.management.base import CommandError
|
||||
from mock import call, patch
|
||||
@@ -35,7 +37,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
CourseModeFactory(course_id=self.course.id, mode_slug=to_mode)
|
||||
|
||||
# Verify that no users are in the `from` mode yet.
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(mode=to_mode, course_id=self.course.id)), 0)
|
||||
assert len(CourseEnrollment.objects.filter(mode=to_mode, course_id=self.course.id)) == 0
|
||||
|
||||
args = '--course {course} --from_mode {from_mode} --to_mode {to_mode} --commit'.format(
|
||||
course=text_type(self.course.id),
|
||||
@@ -69,8 +71,8 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
self._enroll_users(course_2, self.users, from_mode)
|
||||
|
||||
# Verify that no users are in the `to` mode yet.
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(mode=to_mode, course_id=self.course.id)), 0)
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(mode=to_mode, course_id=course_2.id)), 0)
|
||||
assert len(CourseEnrollment.objects.filter(mode=to_mode, course_id=self.course.id)) == 0
|
||||
assert len(CourseEnrollment.objects.filter(mode=to_mode, course_id=course_2.id)) == 0
|
||||
|
||||
args = '--org {org} --from_mode {from_mode} --to_mode {to_mode} --commit'.format(
|
||||
org=self.org,
|
||||
@@ -95,7 +97,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
self._enroll_users(self.course, self.users, 'audit')
|
||||
CourseModeFactory(course_id=self.course.id, mode_slug='no-id-professional')
|
||||
|
||||
with self.assertRaises(CommandError) as err:
|
||||
with pytest.raises(CommandError) as err:
|
||||
call_command(
|
||||
'bulk_change_enrollment',
|
||||
org=self.org,
|
||||
@@ -105,7 +107,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
commit=True,
|
||||
)
|
||||
|
||||
self.assertEqual('Error: one of the arguments -c/--course -o/--org is required', text_type(err.exception))
|
||||
assert 'Error: one of the arguments -c/--course -o/--org is required' == text_type(err.value)
|
||||
|
||||
@patch('common.djangoapps.student.models.tracker')
|
||||
def test_with_org_and_invalid_to_mode(self, mock_tracker):
|
||||
@@ -121,8 +123,8 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
self._enroll_users(course_2, self.users, from_mode)
|
||||
|
||||
# Verify that no users are in the `to` mode yet.
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(mode=to_mode, course_id=self.course.id)), 0)
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(mode=to_mode, course_id=course_2.id)), 0)
|
||||
assert len(CourseEnrollment.objects.filter(mode=to_mode, course_id=self.course.id)) == 0
|
||||
assert len(CourseEnrollment.objects.filter(mode=to_mode, course_id=course_2.id)) == 0
|
||||
|
||||
args = '--org {org} --from_mode {from_mode} --to_mode {to_mode} --commit'.format(
|
||||
org=self.org,
|
||||
@@ -137,7 +139,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
|
||||
# Verify that users were not moved for the invalid course/mode combination
|
||||
for user in self.users:
|
||||
with self.assertRaises(CourseEnrollment.DoesNotExist):
|
||||
with pytest.raises(CourseEnrollment.DoesNotExist):
|
||||
CourseEnrollment.objects.get(mode=to_mode, course_id=self.course.id, user=user)
|
||||
|
||||
# Verify that all users have been moved -- if not, this will
|
||||
@@ -151,7 +153,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
self._enroll_users(self.course, self.users, 'audit')
|
||||
CourseModeFactory(course_id=self.course.id, mode_slug='no-id-professional')
|
||||
|
||||
with self.assertRaises(CommandError) as err:
|
||||
with pytest.raises(CommandError) as err:
|
||||
args = '--org {org} --from_mode {from_mode} --to_mode {to_mode} --commit'.format(
|
||||
org='fakeX',
|
||||
from_mode='audit',
|
||||
@@ -162,7 +164,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
'bulk_change_enrollment', *args.split(' ')
|
||||
)
|
||||
|
||||
self.assertEqual('No courses exist for the org "fakeX".', text_type(err.exception))
|
||||
assert 'No courses exist for the org "fakeX".' == text_type(err.value)
|
||||
|
||||
def test_without_commit(self):
|
||||
"""Verify that nothing happens when the `commit` flag is not given."""
|
||||
@@ -181,7 +183,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
)
|
||||
|
||||
# Verify that no users are in the honor mode.
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(mode='honor', course_id=self.course.id)), 0)
|
||||
assert len(CourseEnrollment.objects.filter(mode='honor', course_id=self.course.id)) == 0
|
||||
|
||||
def test_without_to_mode(self):
|
||||
"""Verify that the command fails when the `to_mode` argument does not exist."""
|
||||
@@ -193,13 +195,13 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
from_mode='audit'
|
||||
)
|
||||
|
||||
with self.assertRaises(CommandError) as err:
|
||||
with pytest.raises(CommandError) as err:
|
||||
call_command(
|
||||
'bulk_change_enrollment',
|
||||
*args.split(' ')
|
||||
)
|
||||
|
||||
self.assertEqual('Error: the following arguments are required: -t/--to_mode', text_type(err.exception))
|
||||
assert 'Error: the following arguments are required: -t/--to_mode' == text_type(err.value)
|
||||
|
||||
@ddt.data('from_mode', 'to_mode', 'course')
|
||||
def test_without_options(self, option):
|
||||
@@ -211,7 +213,7 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
}
|
||||
command_options.pop(option)
|
||||
|
||||
with self.assertRaises(CommandError):
|
||||
with pytest.raises(CommandError):
|
||||
call_command('bulk_change_enrollment', **command_options)
|
||||
|
||||
def test_bad_course_id(self):
|
||||
@@ -222,10 +224,10 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
to_mode='honor'
|
||||
)
|
||||
|
||||
with self.assertRaises(CommandError) as err:
|
||||
with pytest.raises(CommandError) as err:
|
||||
call_command('bulk_change_enrollment', *args.split(' '))
|
||||
|
||||
self.assertEqual('Course ID yolo is invalid.', text_type(err.exception))
|
||||
assert 'Course ID yolo is invalid.' == text_type(err.value)
|
||||
|
||||
def test_nonexistent_course_id(self):
|
||||
"""Verify that the command fails when the given course does not exist."""
|
||||
@@ -235,12 +237,12 @@ class BulkChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
to_mode='honor'
|
||||
)
|
||||
|
||||
with self.assertRaises(CommandError) as err:
|
||||
with pytest.raises(CommandError) as err:
|
||||
call_command(
|
||||
'bulk_change_enrollment',
|
||||
*args.split(' ')
|
||||
)
|
||||
self.assertEqual('The given course course-v1:testX+test+2016 does not exist.', text_type(err.exception))
|
||||
assert 'The given course course-v1:testX+test+2016 does not exist.' == text_type(err.value)
|
||||
|
||||
def _assert_mode_changed(self, mock_tracker, course, user, to_mode):
|
||||
"""Confirm the analytics event was emitted."""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# lint-amnesty, pylint: disable=missing-module-docstring
|
||||
|
||||
import unittest
|
||||
import pytest
|
||||
from tempfile import NamedTemporaryFile
|
||||
|
||||
import six
|
||||
@@ -122,8 +123,8 @@ class BulkChangeEnrollmentCSVTests(SharedModuleStoreTestCase):
|
||||
|
||||
for enrollment in self.enrollments:
|
||||
new_enrollment = CourseEnrollment.get_enrollment(user=enrollment.user, course_key=enrollment.course)
|
||||
self.assertEqual(new_enrollment.is_active, True)
|
||||
self.assertEqual(new_enrollment.mode, CourseMode.VERIFIED)
|
||||
assert new_enrollment.is_active is True
|
||||
assert new_enrollment.mode == CourseMode.VERIFIED
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_bulk_enrollment_from_config_model(self):
|
||||
@@ -138,12 +139,12 @@ class BulkChangeEnrollmentCSVTests(SharedModuleStoreTestCase):
|
||||
|
||||
for enrollment in self.enrollments:
|
||||
new_enrollment = CourseEnrollment.get_enrollment(user=enrollment.user, course_key=enrollment.course)
|
||||
self.assertEqual(new_enrollment.is_active, True)
|
||||
self.assertEqual(new_enrollment.mode, CourseMode.VERIFIED)
|
||||
assert new_enrollment.is_active is True
|
||||
assert new_enrollment.mode == CourseMode.VERIFIED
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_command_error_for_config_model(self):
|
||||
""" Test command error raised if file_from_database is required and the config model is not enabled"""
|
||||
|
||||
with self.assertRaises(CommandError):
|
||||
with pytest.raises(CommandError):
|
||||
call_command("bulk_change_enrollment_csv", "--file_from_database")
|
||||
|
||||
@@ -78,7 +78,7 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
|
||||
|
||||
call_command("bulk_unenroll", "--csv_path={}".format(csv.name), "--commit")
|
||||
for enrollment in CourseEnrollment.objects.all():
|
||||
self.assertEqual(enrollment.is_active, False)
|
||||
assert enrollment.is_active is False
|
||||
|
||||
def test_bulk_un_enroll_without_commit(self):
|
||||
"""
|
||||
@@ -94,7 +94,7 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
|
||||
|
||||
call_command("bulk_unenroll", "--csv_path={}".format(csv.name))
|
||||
for enrollment in CourseEnrollment.objects.all():
|
||||
self.assertEqual(enrollment.is_active, True)
|
||||
assert enrollment.is_active is True
|
||||
|
||||
def test_bulk_unenroll_from_config_model(self):
|
||||
"""Verify users are unenrolled using the command."""
|
||||
@@ -108,7 +108,7 @@ class BulkUnenrollTests(SharedModuleStoreTestCase):
|
||||
|
||||
call_command("bulk_unenroll", "--commit")
|
||||
for enrollment in CourseEnrollment.objects.all():
|
||||
self.assertEqual(enrollment.is_active, False)
|
||||
assert enrollment.is_active is False
|
||||
|
||||
def test_users_unenroll_successfully_logged(self):
|
||||
"""Verify users unenrolled are logged """
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
import pytest
|
||||
|
||||
from django.core.management import call_command
|
||||
from opaque_keys import InvalidKeyError
|
||||
@@ -44,29 +45,29 @@ class ChangeEligibilityDeadlineTests(SharedModuleStoreTestCase):
|
||||
username = self.enrolled_user.username
|
||||
|
||||
# Incorrect username
|
||||
with self.assertRaises(User.DoesNotExist):
|
||||
with pytest.raises(User.DoesNotExist):
|
||||
call_command('change_eligibility_deadline',
|
||||
*command_args.format(username='XYZ', course=course_id_str, date='2018-12-30').split(' ')
|
||||
)
|
||||
# Incorrect course id
|
||||
with self.assertRaises(InvalidKeyError):
|
||||
with pytest.raises(InvalidKeyError):
|
||||
call_command('change_eligibility_deadline',
|
||||
*command_args.format(username=username, course='XYZ', date='2018-12-30').split(' ')
|
||||
)
|
||||
# Student not enrolled
|
||||
with self.assertRaises(CourseEnrollment.DoesNotExist):
|
||||
with pytest.raises(CourseEnrollment.DoesNotExist):
|
||||
unenrolled_user = UserFactory.create()
|
||||
call_command('change_eligibility_deadline',
|
||||
*command_args.format(username=unenrolled_user.username, course=course_id_str,
|
||||
date='2018-12-30').split(' ')
|
||||
)
|
||||
# Date format Invalid
|
||||
with self.assertRaises(ValueError):
|
||||
with pytest.raises(ValueError):
|
||||
call_command('change_eligibility_deadline',
|
||||
*command_args.format(username=username, course=course_id_str, date='30-12-2018').split(' ')
|
||||
)
|
||||
# Date not provided
|
||||
with self.assertRaises(KeyError):
|
||||
with pytest.raises(KeyError):
|
||||
call_command('change_eligibility_deadline',
|
||||
*command_args.format(username=username, course=course_id_str,).split(' '))
|
||||
|
||||
@@ -105,4 +106,4 @@ class ChangeEligibilityDeadlineTests(SharedModuleStoreTestCase):
|
||||
credit_eligibility = CreditEligibility.objects.get(username=username,
|
||||
course__course_key=self.course.id)
|
||||
credit_deadline = credit_eligibility.deadline.date()
|
||||
self.assertEqual(credit_deadline, new_deadline.date())
|
||||
assert credit_deadline == new_deadline.date()
|
||||
|
||||
@@ -56,10 +56,7 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
user_ids = [u.id for u in self.users]
|
||||
|
||||
# Verify users are not in honor mode yet
|
||||
self.assertEqual(
|
||||
len(CourseEnrollment.objects.filter(mode='honor', user_id__in=user_ids)),
|
||||
0
|
||||
)
|
||||
assert len(CourseEnrollment.objects.filter(mode='honor', user_id__in=user_ids)) == 0
|
||||
|
||||
noop = " --noop" if noop else ""
|
||||
|
||||
@@ -75,10 +72,7 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
call_command('change_enrollment', *command_args.split(' '))
|
||||
|
||||
# Verify correct number of users are now in honor mode
|
||||
self.assertEqual(
|
||||
len(CourseEnrollment.objects.filter(mode='honor', user_id__in=user_ids)),
|
||||
expected_conversions
|
||||
)
|
||||
assert len(CourseEnrollment.objects.filter(mode='honor', user_id__in=user_ids)) == expected_conversions
|
||||
|
||||
mock_logger.info.assert_called_with(
|
||||
'Successfully updated %i out of %i users',
|
||||
@@ -99,10 +93,7 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
real_user_ids = [u.id for u in self.users]
|
||||
|
||||
# Verify users are not in honor mode yet
|
||||
self.assertEqual(
|
||||
len(CourseEnrollment.objects.filter(mode='honor', user_id__in=real_user_ids)),
|
||||
0
|
||||
)
|
||||
assert len(CourseEnrollment.objects.filter(mode='honor', user_id__in=real_user_ids)) == 0
|
||||
|
||||
command_args = '--course {course} --to honor --from audit --{method} {user_str}'.format(
|
||||
course=text_type(self.course.id),
|
||||
@@ -113,10 +104,7 @@ class ChangeEnrollmentTests(SharedModuleStoreTestCase):
|
||||
call_command('change_enrollment', *command_args.split(' '))
|
||||
|
||||
# Verify correct number of users are now in honor mode
|
||||
self.assertEqual(
|
||||
len(CourseEnrollment.objects.filter(mode='honor', user_id__in=real_user_ids)),
|
||||
expected_success
|
||||
)
|
||||
assert len(CourseEnrollment.objects.filter(mode='honor', user_id__in=real_user_ids)) == expected_success
|
||||
|
||||
mock_logger.info.assert_called_with(
|
||||
'user: [%s] reason: [%s] %s', fake_user, 'DoesNotExist', 'User matching query does not exist.'
|
||||
|
||||
@@ -32,7 +32,7 @@ class CreateRandomUserTests(SharedModuleStoreTestCase):
|
||||
call_command('create_random_users', text_type(users_to_create))
|
||||
|
||||
# Verify correct number of users are now in the database
|
||||
self.assertEqual(self.num_users_start + users_to_create, len(self.user_model.objects.all()))
|
||||
assert (self.num_users_start + users_to_create) == len(self.user_model.objects.all())
|
||||
|
||||
def test_create_users_with_course(self):
|
||||
"""
|
||||
@@ -42,10 +42,10 @@ class CreateRandomUserTests(SharedModuleStoreTestCase):
|
||||
call_command('create_random_users', text_type(users_to_create), text_type(self.course.id))
|
||||
|
||||
# Verify correct number of users are now in the database
|
||||
self.assertEqual(self.num_users_start + users_to_create, len(self.user_model.objects.all()))
|
||||
assert (self.num_users_start + users_to_create) == len(self.user_model.objects.all())
|
||||
|
||||
# Verify that the users are enrolled in our course
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(course__id=self.course.id)), users_to_create)
|
||||
assert len(CourseEnrollment.objects.filter(course__id=self.course.id)) == users_to_create
|
||||
|
||||
def test_create_users_with_bad_course(self):
|
||||
"""
|
||||
@@ -57,7 +57,7 @@ class CreateRandomUserTests(SharedModuleStoreTestCase):
|
||||
call_command('create_random_users', text_type(users_to_create), u'invalid_course_id')
|
||||
|
||||
# Verify correct number of users are now in the database
|
||||
self.assertEqual(self.num_users_start, len(self.user_model.objects.all()))
|
||||
assert self.num_users_start == len(self.user_model.objects.all())
|
||||
|
||||
# Verify that the users are enrolled in our course
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(course__id=self.course.id)), 0)
|
||||
assert len(CourseEnrollment.objects.filter(course__id=self.course.id)) == 0
|
||||
|
||||
@@ -53,19 +53,19 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
usernames = ['test_create_users_u1', 'test_create_users_u2']
|
||||
|
||||
# Check users don't already exist
|
||||
self.assertEqual(self.user_model.objects.filter(username__in=usernames).count(), 0)
|
||||
assert self.user_model.objects.filter(username__in=usernames).count() == 0
|
||||
|
||||
self.call_command(usernames)
|
||||
|
||||
# Verify users were created, are active, and were created with default settings
|
||||
users = self.user_model.objects.filter(username__in=usernames).all()
|
||||
self.assertEqual(len(users), len(usernames))
|
||||
assert len(users) == len(usernames)
|
||||
for user in users:
|
||||
self.assertTrue(user.is_active)
|
||||
self.assertEqual(user.email, '{}@example.com'.format(user.username))
|
||||
self.assertTrue(self.client.login(username=user.username, password='12345'))
|
||||
assert user.is_active
|
||||
assert user.email == '{}@example.com'.format(user.username)
|
||||
assert self.client.login(username=user.username, password='12345')
|
||||
|
||||
self.assertFalse(CourseEnrollment.objects.filter(user__in=users).exists())
|
||||
assert not CourseEnrollment.objects.filter(user__in=users).exists()
|
||||
|
||||
def test_create_user__username_taken(self):
|
||||
"""
|
||||
@@ -86,11 +86,11 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
|
||||
# Check that the users exist and were enrolled in the course with the default settings
|
||||
users = self.user_model.objects.filter(username__in=usernames).all()
|
||||
self.assertEqual(len(users), len(usernames))
|
||||
assert len(users) == len(usernames)
|
||||
for user in users:
|
||||
enrollment = CourseEnrollment.get_enrollment(user, self.course.id)
|
||||
self.assertEqual(enrollment.mode, 'audit')
|
||||
self.assertFalse(CourseStaffRole(self.course.id).has_user(user))
|
||||
assert enrollment.mode == 'audit'
|
||||
assert not CourseStaffRole(self.course.id).has_user(user)
|
||||
|
||||
def test_create_user_with_course__bad_course(self):
|
||||
"""
|
||||
@@ -100,9 +100,9 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
self.call_command(['username1'], course='invalid_course_id')
|
||||
|
||||
# Verify no users have been created
|
||||
self.assertEqual(self.num_users_start, len(self.user_model.objects.all()))
|
||||
assert self.num_users_start == len(self.user_model.objects.all())
|
||||
# Verify that no one is enrolled in the course
|
||||
self.assertEqual(len(CourseEnrollment.objects.filter(course__id=self.course.id)), 0)
|
||||
assert len(CourseEnrollment.objects.filter(course__id=self.course.id)) == 0
|
||||
|
||||
def test_create_user__mode(self):
|
||||
"""
|
||||
@@ -115,7 +115,7 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
# Verify enrollment
|
||||
user = self.user_model.objects.get(username='user1')
|
||||
enrollment = CourseEnrollment.get_enrollment(user, self.course.id)
|
||||
self.assertEqual(enrollment.mode, 'verified')
|
||||
assert enrollment.mode == 'verified'
|
||||
|
||||
def test_create_user__mode__invalid(self):
|
||||
"""
|
||||
@@ -134,7 +134,7 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
self.call_command([username], domain=domain)
|
||||
|
||||
user = self.user_model.objects.get(username=username)
|
||||
self.assertEqual(user.email, '{}@{}'.format(username, domain))
|
||||
assert user.email == '{}@{}'.format(username, domain)
|
||||
|
||||
def test_create_user__email_taken(self):
|
||||
"""
|
||||
@@ -142,7 +142,7 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
"""
|
||||
existing_username = 'some-username'
|
||||
self.user_model.objects.create_user(existing_username, 'taken_email@example.com', '12345')
|
||||
with self.assertRaises(ValidationError):
|
||||
with pytest.raises(ValidationError):
|
||||
self.call_command(['taken_email'], domain='example.com')
|
||||
|
||||
def test_create_user__bad_domain(self):
|
||||
@@ -150,9 +150,9 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
Try to create a user with a bad email domain
|
||||
"""
|
||||
username = 'user1'
|
||||
with self.assertRaises(ValidationError):
|
||||
with pytest.raises(ValidationError):
|
||||
self.call_command([username], domain='this-aint-no-domain')
|
||||
self.assertFalse(self.user_model.objects.filter(username=username).exists())
|
||||
assert not self.user_model.objects.filter(username=username).exists()
|
||||
|
||||
def test_create_user__password(self):
|
||||
"""
|
||||
@@ -162,7 +162,7 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
password = 'somepassword1234512341241234'
|
||||
self.call_command([username], password=password)
|
||||
|
||||
self.assertTrue(self.client.login(username=username, password=password))
|
||||
assert self.client.login(username=username, password=password)
|
||||
|
||||
def test_create_user__password__error(self):
|
||||
"""
|
||||
@@ -179,8 +179,8 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
|
||||
user = self.user_model.objects.get(username=username)
|
||||
enrollment = CourseEnrollment.get_enrollment(user, self.course.id)
|
||||
self.assertEqual(enrollment.mode, 'audit')
|
||||
self.assertTrue(CourseStaffRole(self.course.id).has_user(user))
|
||||
assert enrollment.mode == 'audit'
|
||||
assert CourseStaffRole(self.course.id).has_user(user)
|
||||
|
||||
def test_create_user__course_staff__ignore_mode(self):
|
||||
"""
|
||||
@@ -191,8 +191,8 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
|
||||
user = self.user_model.objects.get(username=username)
|
||||
enrollment = CourseEnrollment.get_enrollment(user, self.course.id)
|
||||
self.assertEqual(enrollment.mode, 'audit')
|
||||
self.assertTrue(CourseStaffRole(self.course.id).has_user(user))
|
||||
assert enrollment.mode == 'audit'
|
||||
assert CourseStaffRole(self.course.id).has_user(user)
|
||||
|
||||
def test_create_user__ignore_course_staff_and_mode_when_no_course(self):
|
||||
"""
|
||||
@@ -202,5 +202,5 @@ class CreateTestUsersTestCase(SharedModuleStoreTestCase):
|
||||
self.call_command([username], course_staff=True, mode='verified')
|
||||
|
||||
user = self.user_model.objects.get(username=username)
|
||||
self.assertFalse(CourseAccessRole.objects.filter(user=user).exists())
|
||||
self.assertFalse(CourseEnrollment.objects.filter(user=user).exists())
|
||||
assert not CourseAccessRole.objects.filter(user=user).exists()
|
||||
assert not CourseEnrollment.objects.filter(user=user).exists()
|
||||
|
||||
@@ -4,8 +4,9 @@ Unit tests for user_management management commands.
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
import ddt
|
||||
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.management import CommandError, call_command
|
||||
@@ -58,16 +59,13 @@ class TestManageGroupCommand(TestCase):
|
||||
"""
|
||||
DRY helper.
|
||||
"""
|
||||
self.assertEqual(set(group_names), {g.name for g in Group.objects.all()})
|
||||
assert set(group_names) == {g.name for g in Group.objects.all()}
|
||||
|
||||
def check_permissions(self, group_name, permission_codenames):
|
||||
"""
|
||||
DRY helper.
|
||||
"""
|
||||
self.assertEqual(
|
||||
set(permission_codenames),
|
||||
{p.codename for p in Group.objects.get(name=group_name).permissions.all()}
|
||||
)
|
||||
assert set(permission_codenames) == {p.codename for p in Group.objects.get(name=group_name).permissions.all()}
|
||||
|
||||
@ddt.data(
|
||||
*(
|
||||
@@ -89,9 +87,9 @@ class TestManageGroupCommand(TestCase):
|
||||
"""
|
||||
self.set_group_permissions(initial_group_permissions)
|
||||
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_group', *command_args)
|
||||
self.assertIn(exception_message, str(exc_context.exception).lower())
|
||||
assert exception_message in str(exc_context.value).lower()
|
||||
self.check_group_permissions(initial_group_permissions)
|
||||
|
||||
@ddt.data(*TEST_DATA)
|
||||
@@ -103,35 +101,35 @@ class TestManageGroupCommand(TestCase):
|
||||
self.set_group_permissions(initial_group_permissions)
|
||||
|
||||
# not parseable
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_group', TEST_GROUP, '--permissions', 'fail')
|
||||
self.assertIn('invalid permission option', str(exc_context.exception).lower())
|
||||
assert 'invalid permission option' in str(exc_context.value).lower()
|
||||
self.check_group_permissions(initial_group_permissions)
|
||||
|
||||
# not parseable
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_group', TEST_GROUP, '--permissions', 'f:a:i:l')
|
||||
self.assertIn('invalid permission option', str(exc_context.exception).lower())
|
||||
assert 'invalid permission option' in str(exc_context.value).lower()
|
||||
self.check_group_permissions(initial_group_permissions)
|
||||
|
||||
# invalid app label
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_group', TEST_GROUP, '--permissions', 'nonexistent-label:dummy-model:dummy-perm')
|
||||
self.assertIn('no installed app', str(exc_context.exception).lower())
|
||||
self.assertIn('nonexistent-label', str(exc_context.exception).lower())
|
||||
assert 'no installed app' in str(exc_context.value).lower()
|
||||
assert 'nonexistent-label' in str(exc_context.value).lower()
|
||||
self.check_group_permissions(initial_group_permissions)
|
||||
|
||||
# invalid model name
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:nonexistent-model:dummy-perm')
|
||||
self.assertIn('nonexistent-model', str(exc_context.exception).lower())
|
||||
assert 'nonexistent-model' in str(exc_context.value).lower()
|
||||
self.check_group_permissions(initial_group_permissions)
|
||||
|
||||
# invalid model name
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_group', TEST_GROUP, '--permissions', 'auth:Group:nonexistent-perm')
|
||||
self.assertIn('invalid permission codename', str(exc_context.exception).lower())
|
||||
self.assertIn('nonexistent-perm', str(exc_context.exception).lower())
|
||||
assert 'invalid permission codename' in str(exc_context.value).lower()
|
||||
assert 'nonexistent-perm' in str(exc_context.value).lower()
|
||||
self.check_group_permissions(initial_group_permissions)
|
||||
|
||||
def test_group(self):
|
||||
|
||||
@@ -5,7 +5,9 @@ Unit tests for user_management management commands.
|
||||
|
||||
import itertools
|
||||
|
||||
import pytest
|
||||
import ddt
|
||||
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from django.contrib.auth.models import Group, User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.core.management import CommandError, call_command
|
||||
@@ -27,52 +29,52 @@ class TestManageUserCommand(TestCase):
|
||||
"""
|
||||
Ensures that users are created if they don't exist and reused if they do.
|
||||
"""
|
||||
self.assertEqual([], list(User.objects.all()))
|
||||
assert [] == list(User.objects.all())
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL)
|
||||
user = User.objects.get(username=TEST_USERNAME)
|
||||
self.assertEqual(user.username, TEST_USERNAME)
|
||||
self.assertEqual(user.email, TEST_EMAIL)
|
||||
self.assertIsNotNone(user.profile)
|
||||
assert user.username == TEST_USERNAME
|
||||
assert user.email == TEST_EMAIL
|
||||
assert user.profile is not None
|
||||
|
||||
# check idempotency
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL)
|
||||
self.assertEqual([(TEST_USERNAME, TEST_EMAIL)], [(u.username, u.email) for u in User.objects.all()])
|
||||
assert [(TEST_USERNAME, TEST_EMAIL)] == [(u.username, u.email) for u in User.objects.all()]
|
||||
|
||||
def test_remove(self):
|
||||
"""
|
||||
Ensures that users are removed if they exist and exit cleanly otherwise.
|
||||
"""
|
||||
User.objects.create(username=TEST_USERNAME, email=TEST_EMAIL)
|
||||
self.assertEqual([(TEST_USERNAME, TEST_EMAIL)], [(u.username, u.email) for u in User.objects.all()])
|
||||
assert [(TEST_USERNAME, TEST_EMAIL)] == [(u.username, u.email) for u in User.objects.all()]
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '--remove')
|
||||
self.assertEqual([], list(User.objects.all()))
|
||||
assert [] == list(User.objects.all())
|
||||
|
||||
# check idempotency
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '--remove')
|
||||
self.assertEqual([], list(User.objects.all()))
|
||||
assert [] == list(User.objects.all())
|
||||
|
||||
def test_unusable_password(self):
|
||||
"""
|
||||
Ensure that a user's password is set to an unusable_password.
|
||||
"""
|
||||
user = User.objects.create(username=TEST_USERNAME, email=TEST_EMAIL)
|
||||
self.assertEqual([(TEST_USERNAME, TEST_EMAIL)], [(u.username, u.email) for u in User.objects.all()])
|
||||
assert [(TEST_USERNAME, TEST_EMAIL)] == [(u.username, u.email) for u in User.objects.all()]
|
||||
user.set_password(generate_password())
|
||||
user.save()
|
||||
|
||||
# Run once without passing --unusable-password and make sure the password is usable
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL)
|
||||
user = User.objects.get(username=TEST_USERNAME, email=TEST_EMAIL)
|
||||
self.assertTrue(user.has_usable_password())
|
||||
assert user.has_usable_password()
|
||||
|
||||
# Make sure the user now has an unusable_password
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '--unusable-password')
|
||||
user = User.objects.get(username=TEST_USERNAME, email=TEST_EMAIL)
|
||||
self.assertFalse(user.has_usable_password())
|
||||
assert not user.has_usable_password()
|
||||
|
||||
# check idempotency
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '--unusable-password')
|
||||
self.assertFalse(user.has_usable_password())
|
||||
assert not user.has_usable_password()
|
||||
|
||||
def test_initial_password_hash(self):
|
||||
"""
|
||||
@@ -82,14 +84,14 @@ class TestManageUserCommand(TestCase):
|
||||
initial_hash = make_password('hunter2')
|
||||
|
||||
# Make sure the command aborts if the provided hash isn't a valid Django password hash
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '--initial-password-hash', 'invalid_hash')
|
||||
self.assertIn('password hash', str(exc_context.exception).lower())
|
||||
assert 'password hash' in str(exc_context.value).lower()
|
||||
|
||||
# Make sure the hash gets set correctly for a new user
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '--initial-password-hash', initial_hash)
|
||||
user = User.objects.get(username=TEST_USERNAME)
|
||||
self.assertEqual(user.password, initial_hash)
|
||||
assert user.password == initial_hash
|
||||
|
||||
# Change the password
|
||||
new_hash = make_password('correct horse battery staple')
|
||||
@@ -99,7 +101,7 @@ class TestManageUserCommand(TestCase):
|
||||
# Verify that calling manage_user again leaves the password untouched
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '--initial-password-hash', initial_hash)
|
||||
user = User.objects.get(username=TEST_USERNAME)
|
||||
self.assertEqual(user.password, new_hash)
|
||||
assert user.password == new_hash
|
||||
|
||||
def test_wrong_email(self):
|
||||
"""
|
||||
@@ -107,16 +109,16 @@ class TestManageUserCommand(TestCase):
|
||||
existing user account but the supplied email doesn't match.
|
||||
"""
|
||||
User.objects.create(username=TEST_USERNAME, email=TEST_EMAIL)
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_user', TEST_USERNAME, 'other@example.com')
|
||||
self.assertIn('email addresses do not match', str(exc_context.exception).lower())
|
||||
self.assertEqual([(TEST_USERNAME, TEST_EMAIL)], [(u.username, u.email) for u in User.objects.all()])
|
||||
assert 'email addresses do not match' in str(exc_context.value).lower()
|
||||
assert [(TEST_USERNAME, TEST_EMAIL)] == [(u.username, u.email) for u in User.objects.all()]
|
||||
|
||||
# check that removal uses the same check
|
||||
with self.assertRaises(CommandError) as exc_context:
|
||||
with pytest.raises(CommandError) as exc_context:
|
||||
call_command('manage_user', TEST_USERNAME, 'other@example.com', '--remove')
|
||||
self.assertIn('email addresses do not match', str(exc_context.exception).lower())
|
||||
self.assertEqual([(TEST_USERNAME, TEST_EMAIL)], [(u.username, u.email) for u in User.objects.all()])
|
||||
assert 'email addresses do not match' in str(exc_context.value).lower()
|
||||
assert [(TEST_USERNAME, TEST_EMAIL)] == [(u.username, u.email) for u in User.objects.all()]
|
||||
|
||||
def test_same_email_varied_case(self):
|
||||
"""
|
||||
@@ -126,7 +128,7 @@ class TestManageUserCommand(TestCase):
|
||||
User.objects.create(username=TEST_USERNAME, email=TEST_EMAIL.upper())
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL.lower())
|
||||
user = User.objects.get(username=TEST_USERNAME)
|
||||
self.assertEqual(user.email, TEST_EMAIL.upper())
|
||||
assert user.email == TEST_EMAIL.upper()
|
||||
|
||||
@ddt.data(*itertools.product([(True, True), (True, False), (False, True), (False, False)], repeat=2))
|
||||
@ddt.unpack
|
||||
@@ -148,8 +150,8 @@ class TestManageUserCommand(TestCase):
|
||||
args = [opt for bit, opt in ((expected_staff, '--staff'), (expected_super, '--superuser')) if bit]
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, *args)
|
||||
user = User.objects.all().first()
|
||||
self.assertEqual(user.is_staff, expected_staff)
|
||||
self.assertEqual(user.is_superuser, expected_super)
|
||||
assert user.is_staff == expected_staff
|
||||
assert user.is_superuser == expected_super
|
||||
|
||||
@ddt.data(*itertools.product(('', 'a', 'ab', 'abc'), repeat=2))
|
||||
@ddt.unpack
|
||||
@@ -167,7 +169,7 @@ class TestManageUserCommand(TestCase):
|
||||
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '-g', *expected_groups)
|
||||
actual_groups = [group.name for group in user.groups.all()]
|
||||
self.assertEqual(actual_groups, list(expected_groups))
|
||||
assert actual_groups == list(expected_groups)
|
||||
|
||||
def test_nonexistent_group(self):
|
||||
"""
|
||||
@@ -181,4 +183,4 @@ class TestManageUserCommand(TestCase):
|
||||
|
||||
call_command('manage_user', TEST_USERNAME, TEST_EMAIL, '-g', 'b', 'c', 'd')
|
||||
actual_groups = [group.name for group in user.groups.all()]
|
||||
self.assertEqual(actual_groups, ['b', 'c'])
|
||||
assert actual_groups == ['b', 'c']
|
||||
|
||||
@@ -5,6 +5,8 @@ Unittests for populate_created_on_site_user_attribute management command.
|
||||
|
||||
import ddt
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.core.management import CommandError, call_command
|
||||
from django.test import TestCase
|
||||
@@ -50,7 +52,7 @@ class TestPopulateUserAttribute(SiteMixin, TestCase):
|
||||
)
|
||||
|
||||
for user in self.users:
|
||||
self.assertEqual(UserAttribute.get_user_attribute(user, CREATED_ON_SITE), self.site.domain)
|
||||
assert UserAttribute.get_user_attribute(user, CREATED_ON_SITE) == self.site.domain
|
||||
|
||||
# Populate 'created_on_site' attribute with different site domain
|
||||
call_command(
|
||||
@@ -61,7 +63,7 @@ class TestPopulateUserAttribute(SiteMixin, TestCase):
|
||||
|
||||
for user in self.users:
|
||||
# 'created_on_site' attribute already exists. Attribute's value will not change
|
||||
self.assertNotEqual(UserAttribute.get_user_attribute(user, CREATED_ON_SITE), self.site_other.domain)
|
||||
assert UserAttribute.get_user_attribute(user, CREATED_ON_SITE) != self.site_other.domain
|
||||
|
||||
def test_command_by_activation_keys(self):
|
||||
"""
|
||||
@@ -74,7 +76,7 @@ class TestPopulateUserAttribute(SiteMixin, TestCase):
|
||||
)
|
||||
|
||||
for register_user in self.registered_users:
|
||||
self.assertEqual(UserAttribute.get_user_attribute(register_user.user, CREATED_ON_SITE), self.site.domain)
|
||||
assert UserAttribute.get_user_attribute(register_user.user, CREATED_ON_SITE) == self.site.domain
|
||||
|
||||
# Populate 'created_on_site' attribute with different site domain
|
||||
call_command(
|
||||
@@ -85,16 +87,13 @@ class TestPopulateUserAttribute(SiteMixin, TestCase):
|
||||
|
||||
for register_user in self.registered_users:
|
||||
# 'created_on_site' attribute already exists. Attribute's value will not change
|
||||
self.assertNotEqual(
|
||||
UserAttribute.get_user_attribute(register_user.user, CREATED_ON_SITE),
|
||||
self.site_other.domain
|
||||
)
|
||||
assert UserAttribute.get_user_attribute(register_user.user, CREATED_ON_SITE) != self.site_other.domain
|
||||
|
||||
def test_command_with_incomplete_argument(self):
|
||||
"""
|
||||
Test management command raises CommandError without '--users' and '--activation_keys' arguments.
|
||||
"""
|
||||
with self.assertRaises(CommandError):
|
||||
with pytest.raises(CommandError):
|
||||
call_command(
|
||||
"populate_created_on_site_user_attribute",
|
||||
"--site-domain", self.site.domain
|
||||
@@ -110,7 +109,7 @@ class TestPopulateUserAttribute(SiteMixin, TestCase):
|
||||
"--users", '9{id}'.format(id=user.id), # invalid id
|
||||
"--site-domain", self.site.domain
|
||||
)
|
||||
self.assertIsNone(UserAttribute.get_user_attribute(user, CREATED_ON_SITE))
|
||||
assert UserAttribute.get_user_attribute(user, CREATED_ON_SITE) is None
|
||||
|
||||
register_user = self.registered_users[0]
|
||||
call_command(
|
||||
@@ -118,13 +117,13 @@ class TestPopulateUserAttribute(SiteMixin, TestCase):
|
||||
"--activation-keys", "invalid-{key}".format(key=register_user.activation_key), # invalid key
|
||||
"--site-domain", self.site.domain
|
||||
)
|
||||
self.assertIsNone(UserAttribute.get_user_attribute(register_user.user, CREATED_ON_SITE))
|
||||
assert UserAttribute.get_user_attribute(register_user.user, CREATED_ON_SITE) is None
|
||||
|
||||
def test_command_without_site_domain(self):
|
||||
"""
|
||||
Test management command raises CommandError without '--site-domain' argument.
|
||||
"""
|
||||
with self.assertRaises(CommandError):
|
||||
with pytest.raises(CommandError):
|
||||
call_command(
|
||||
"populate_created_on_site_user_attribute",
|
||||
"--user", self.user_ids,
|
||||
@@ -146,6 +145,6 @@ class TestPopulateUserAttribute(SiteMixin, TestCase):
|
||||
|
||||
for user in self.users:
|
||||
if populate == 'y':
|
||||
self.assertEqual(UserAttribute.get_user_attribute(user, CREATED_ON_SITE), fake_site_domain)
|
||||
assert UserAttribute.get_user_attribute(user, CREATED_ON_SITE) == fake_site_domain
|
||||
else:
|
||||
self.assertIsNone(UserAttribute.get_user_attribute(user, CREATED_ON_SITE))
|
||||
assert UserAttribute.get_user_attribute(user, CREATED_ON_SITE) is None
|
||||
|
||||
@@ -3,6 +3,7 @@ Test cases for recover account management command
|
||||
"""
|
||||
import re
|
||||
from tempfile import NamedTemporaryFile
|
||||
import pytest
|
||||
import six
|
||||
|
||||
from django.core import mail
|
||||
@@ -49,7 +50,7 @@ class RecoverAccountTests(TestCase):
|
||||
csv = self._write_test_csv(csv, lines=['amy,amy@edx.com,amy@newemail.com\n'])
|
||||
call_command("recover_account", "--csv_file_path={}".format(csv.name))
|
||||
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
assert len(mail.outbox) == 1
|
||||
|
||||
reset_link = re.findall("(http.+pwreset)", mail.outbox[0].body)[0]
|
||||
request_params = {'new_password1': 'password1', 'new_password2': 'password1'}
|
||||
@@ -57,19 +58,19 @@ class RecoverAccountTests(TestCase):
|
||||
resp = self.client.post(reset_link, data=request_params)
|
||||
|
||||
# Verify the response status code is: 302 with password reset because 302 means success
|
||||
self.assertEqual(resp.status_code, 302)
|
||||
assert resp.status_code == 302
|
||||
|
||||
self.assertTrue(self.client.login(username=self.user.username, password='password1'))
|
||||
assert self.client.login(username=self.user.username, password='password1')
|
||||
|
||||
# try to login with previous password
|
||||
self.assertFalse(self.client.login(username=self.user.username, password='password'))
|
||||
assert not self.client.login(username=self.user.username, password='password')
|
||||
|
||||
def test_file_not_found_error(self):
|
||||
"""
|
||||
Test command error raised when csv path is invalid
|
||||
:return:
|
||||
"""
|
||||
with self.assertRaises(CommandError):
|
||||
with pytest.raises(CommandError):
|
||||
call_command("recover_account", "--csv_file_path={}".format('test'))
|
||||
|
||||
def test_exception_raised(self):
|
||||
@@ -117,4 +118,4 @@ class RecoverAccountTests(TestCase):
|
||||
call_command("recover_account")
|
||||
|
||||
email = get_user_model().objects.get(pk=self.user.pk).email
|
||||
self.assertEqual(email, 'amy@newemail.com')
|
||||
assert email == 'amy@newemail.com'
|
||||
|
||||
@@ -51,8 +51,8 @@ class TestTransferStudents(ModuleStoreTestCase):
|
||||
"""
|
||||
Signal Receiver stub for testing that the unenroll signal was fired.
|
||||
"""
|
||||
self.assertFalse(self.signal_fired)
|
||||
self.assertTrue(skip_refund)
|
||||
assert not self.signal_fired
|
||||
assert skip_refund
|
||||
self.signal_fired = True
|
||||
|
||||
def test_transfer_students(self):
|
||||
@@ -89,7 +89,7 @@ class TestTransferStudents(ModuleStoreTestCase):
|
||||
'--from', original_key,
|
||||
'--to', new_key_one, new_key_two,
|
||||
)
|
||||
self.assertTrue(self.signal_fired)
|
||||
assert self.signal_fired
|
||||
|
||||
# Confirm the analytics event was emitted.
|
||||
self.mock_tracker.emit.assert_has_calls(
|
||||
@@ -127,9 +127,9 @@ class TestTransferStudents(ModuleStoreTestCase):
|
||||
self.mock_tracker.reset_mock()
|
||||
|
||||
# Confirm the enrollment mode is verified on the new courses, and enrollment is enabled as appropriate.
|
||||
self.assertEqual((mode, False), CourseEnrollment.enrollment_mode_for_user(student, course.id))
|
||||
self.assertEqual((mode, True), CourseEnrollment.enrollment_mode_for_user(student, new_course_one.id))
|
||||
self.assertEqual((mode, True), CourseEnrollment.enrollment_mode_for_user(student, new_course_two.id))
|
||||
assert (mode, False) == CourseEnrollment.enrollment_mode_for_user(student, course.id)
|
||||
assert (mode, True) == CourseEnrollment.enrollment_mode_for_user(student, new_course_one.id)
|
||||
assert (mode, True) == CourseEnrollment.enrollment_mode_for_user(student, new_course_two.id)
|
||||
|
||||
def _create_course(self, course_location):
|
||||
"""
|
||||
|
||||
@@ -69,12 +69,12 @@ class TestActivateAccount(TestCase):
|
||||
def assert_no_tracking(self, mock_segment_identify):
|
||||
""" Assert that activate sets the flag but does not call segment. """
|
||||
# Ensure that the user starts inactive
|
||||
self.assertFalse(self.user.is_active)
|
||||
assert not self.user.is_active
|
||||
|
||||
# Until you explicitly activate it
|
||||
self.registration.activate()
|
||||
self.assertTrue(self.user.is_active)
|
||||
self.assertFalse(mock_segment_identify.called)
|
||||
assert self.user.is_active
|
||||
assert not mock_segment_identify.called
|
||||
|
||||
@patch('common.djangoapps.student.models.USER_ACCOUNT_ACTIVATED')
|
||||
def test_activation_signal(self, mock_signal):
|
||||
@@ -122,7 +122,7 @@ class TestActivateAccount(TestCase):
|
||||
|
||||
def _assert_user_active_state(self, expected_active_state):
|
||||
user = User.objects.get(username=self.user.username)
|
||||
self.assertEqual(user.is_active, expected_active_state)
|
||||
assert user.is_active == expected_active_state
|
||||
|
||||
def test_account_activation_notification_on_logistration(self):
|
||||
"""
|
||||
@@ -168,12 +168,12 @@ class TestActivateAccount(TestCase):
|
||||
|
||||
# Access activation link, the user is redirected to login page with success query param
|
||||
response = self.client.get(reverse('activate', args=[self.registration.activation_key]))
|
||||
self.assertEqual(response.url, login_page_url + 'success')
|
||||
assert response.url == (login_page_url + 'success')
|
||||
|
||||
# Access activation link again, the user is redirected to login page with info query param
|
||||
response = self.client.get(reverse('activate', args=[self.registration.activation_key]))
|
||||
self.assertEqual(response.url, login_page_url + 'info')
|
||||
assert response.url == (login_page_url + 'info')
|
||||
|
||||
# Open account activation page with an invalid activation link, the query param should contain error
|
||||
response = self.client.get(reverse('activate', args=[uuid4().hex]))
|
||||
self.assertEqual(response.url, login_page_url + 'error')
|
||||
assert response.url == (login_page_url + 'error')
|
||||
|
||||
@@ -7,6 +7,7 @@ Tests student admin.py
|
||||
import datetime
|
||||
|
||||
import ddt
|
||||
import pytest
|
||||
import six
|
||||
from django.conf import settings # lint-amnesty, pylint: disable=unused-import
|
||||
from django.contrib.admin.sites import AdminSite
|
||||
@@ -186,7 +187,7 @@ class AdminUserPageTest(TestCase):
|
||||
Ensures that the username is not readonly, when admin creates new user.
|
||||
"""
|
||||
request = Mock()
|
||||
self.assertNotIn('username', self.admin.get_readonly_fields(request))
|
||||
assert 'username' not in self.admin.get_readonly_fields(request)
|
||||
|
||||
def test_username_is_readonly_for_user(self):
|
||||
"""
|
||||
@@ -201,7 +202,7 @@ class AdminUserPageTest(TestCase):
|
||||
"""
|
||||
request = Mock()
|
||||
user = Mock()
|
||||
self.assertIn('username', self.admin.get_readonly_fields(request, user))
|
||||
assert 'username' in self.admin.get_readonly_fields(request, user)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -237,7 +238,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
All CourseEnrollmentAdmin views are disabled by default.
|
||||
"""
|
||||
response = getattr(self.client, method)(url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
assert response.status_code == 403
|
||||
|
||||
@ddt.data(*ADMIN_URLS)
|
||||
@ddt.unpack
|
||||
@@ -247,7 +248,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
"""
|
||||
with override_waffle_switch(COURSE_ENROLLMENT_ADMIN_SWITCH, active=True):
|
||||
response = getattr(self.client, method)(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_username_exact_match(self):
|
||||
"""
|
||||
@@ -261,14 +262,14 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
search_url = '{}?q={}'.format(reverse('admin:student_courseenrollment_changelist'), self.user.username)
|
||||
with override_waffle_switch(COURSE_ENROLLMENT_ADMIN_SWITCH, active=True):
|
||||
response = self.client.get(search_url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
# context['results'] is an array of arrays of HTML <td> elements to be rendered
|
||||
self.assertEqual(len(response.context['results']), 2)
|
||||
assert len(response.context['results']) == 2
|
||||
for idx, username in enumerate([self.user.username, user2.username]):
|
||||
# Locate the <td> column containing the username
|
||||
user_field = next(col for col in response.context['results'][idx] if "field-user" in col)
|
||||
self.assertIn(username, user_field)
|
||||
assert username in user_field
|
||||
|
||||
def test_save_toggle_active(self):
|
||||
"""
|
||||
@@ -277,7 +278,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
This test implicitly verifies that the POST parameters are handled correctly.
|
||||
"""
|
||||
# is_active will change from True to False
|
||||
self.assertTrue(self.course_enrollment.is_active)
|
||||
assert self.course_enrollment.is_active
|
||||
data = {
|
||||
'user': six.text_type(self.course_enrollment.user.id),
|
||||
'course': six.text_type(self.course_enrollment.course.id),
|
||||
@@ -290,10 +291,10 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
reverse('admin:student_courseenrollment_change', args=(self.course_enrollment.id, )),
|
||||
data=data,
|
||||
)
|
||||
self.assertEqual(response.status_code, 302)
|
||||
assert response.status_code == 302
|
||||
|
||||
self.course_enrollment.refresh_from_db()
|
||||
self.assertFalse(self.course_enrollment.is_active)
|
||||
assert not self.course_enrollment.is_active
|
||||
|
||||
def test_save_invalid_course_id(self):
|
||||
"""
|
||||
@@ -307,7 +308,7 @@ class CourseEnrollmentAdminTest(SharedModuleStoreTestCase):
|
||||
}
|
||||
|
||||
with override_waffle_switch(COURSE_ENROLLMENT_ADMIN_SWITCH, active=True):
|
||||
with self.assertRaises(ValidationError):
|
||||
with pytest.raises(ValidationError):
|
||||
self.client.post(
|
||||
reverse('admin:student_courseenrollment_change', args=(self.course_enrollment.id, )),
|
||||
data=data,
|
||||
@@ -344,16 +345,14 @@ class LoginFailuresAdminTest(TestCase):
|
||||
Test if `__str__` method behaves correctly for unicode username.
|
||||
It shouldn't raise `TypeError`.
|
||||
"""
|
||||
self.assertEqual(
|
||||
str(LoginFailures.objects.get(user=self.user)), '§: 10 - {}'.format(self.user_lockout_until.isoformat())
|
||||
)
|
||||
self.assertEqual(str(LoginFailures.objects.get(user=self.user2)), 'Zażółć gęślą jaźń: 2 - -')
|
||||
assert str(LoginFailures.objects.get(user=self.user)) == f'§: 10 - {self.user_lockout_until.isoformat()}'
|
||||
assert str(LoginFailures.objects.get(user=self.user2)) == 'Zażółć gęślą jaźń: 2 - -'
|
||||
|
||||
@override_settings(FEATURES={'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True})
|
||||
def test_feature_enabled(self):
|
||||
url = reverse('admin:student_loginfailures_changelist')
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
@ddt.data(
|
||||
reverse('admin:student_loginfailures_changelist'),
|
||||
@@ -364,9 +363,9 @@ class LoginFailuresAdminTest(TestCase):
|
||||
def test_feature_disabled(self, url):
|
||||
"""Test if feature is disabled there's no access to the admin module."""
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
assert response.status_code == 403
|
||||
response = self.client.post(url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
assert response.status_code == 403
|
||||
|
||||
@override_settings(FEATURES={'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True})
|
||||
def test_unlock_student_accounts(self):
|
||||
@@ -381,7 +380,7 @@ class LoginFailuresAdminTest(TestCase):
|
||||
follow=True
|
||||
)
|
||||
count = LoginFailures.objects.count()
|
||||
self.assertEqual(count, 0)
|
||||
assert count == 0
|
||||
|
||||
@override_settings(FEATURES={'ENABLE_MAX_FAILED_LOGIN_ATTEMPTS': True})
|
||||
def test_unlock_account(self):
|
||||
@@ -393,7 +392,7 @@ class LoginFailuresAdminTest(TestCase):
|
||||
data={'_unlock': 1}
|
||||
)
|
||||
count = LoginFailures.objects.count()
|
||||
self.assertEqual(count, start_count - 1)
|
||||
assert count == (start_count - 1)
|
||||
|
||||
|
||||
class CourseEnrollmentAdminFormTest(SharedModuleStoreTestCase):
|
||||
@@ -413,7 +412,7 @@ class CourseEnrollmentAdminFormTest(SharedModuleStoreTestCase):
|
||||
"""
|
||||
Test CourseEnrollmentAdminForm creation.
|
||||
"""
|
||||
self.assertEqual(CourseEnrollment.objects.count(), 0)
|
||||
assert CourseEnrollment.objects.count() == 0
|
||||
|
||||
form = CourseEnrollmentForm({
|
||||
'user': self.user.id,
|
||||
@@ -421,10 +420,10 @@ class CourseEnrollmentAdminFormTest(SharedModuleStoreTestCase):
|
||||
'is_active': True,
|
||||
'mode': 'audit',
|
||||
})
|
||||
self.assertTrue(form.is_valid())
|
||||
assert form.is_valid()
|
||||
enrollment = form.save()
|
||||
self.assertEqual(CourseEnrollment.objects.count(), 1)
|
||||
self.assertEqual(CourseEnrollment.objects.first(), enrollment)
|
||||
assert CourseEnrollment.objects.count() == 1
|
||||
assert CourseEnrollment.objects.first() == enrollment
|
||||
|
||||
def test_admin_model_form_update(self):
|
||||
"""
|
||||
@@ -439,11 +438,11 @@ class CourseEnrollmentAdminFormTest(SharedModuleStoreTestCase):
|
||||
'mode': 'audit'},
|
||||
instance=enrollment
|
||||
)
|
||||
self.assertTrue(form.is_valid())
|
||||
assert form.is_valid()
|
||||
course_enrollment = form.save()
|
||||
self.assertEqual(count, CourseEnrollment.objects.count())
|
||||
self.assertFalse(course_enrollment.is_active)
|
||||
self.assertEqual(enrollment.id, course_enrollment.id)
|
||||
assert count == CourseEnrollment.objects.count()
|
||||
assert not course_enrollment.is_active
|
||||
assert enrollment.id == course_enrollment.id
|
||||
|
||||
|
||||
class AllowedAuthUserFormTest(SiteMixin, TestCase):
|
||||
@@ -473,10 +472,10 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
|
||||
instance = None
|
||||
form = AllowedAuthUserForm({'site': site.id, 'email': email})
|
||||
if is_valid_form:
|
||||
self.assertTrue(form.is_valid())
|
||||
assert form.is_valid()
|
||||
instance = form.save()
|
||||
else:
|
||||
self.assertFalse(form.is_valid())
|
||||
assert not form.is_valid()
|
||||
error = form.errors['email'][0]
|
||||
return error, instance
|
||||
|
||||
@@ -485,11 +484,8 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
|
||||
Test form with wrong site's configuration.
|
||||
"""
|
||||
error, _ = self._assert_form(self.site, self.valid_email)
|
||||
self.assertEqual(
|
||||
error,
|
||||
"Please add a key/value 'THIRD_PARTY_AUTH_ONLY_DOMAIN/{site_email_domain}' in SiteConfiguration "
|
||||
"model's site_values field."
|
||||
)
|
||||
assert error == "Please add a key/value 'THIRD_PARTY_AUTH_ONLY_DOMAIN/{site_email_domain}'" \
|
||||
" in SiteConfiguration model's site_values field."
|
||||
|
||||
def test_form_with_invalid_domain_name(self):
|
||||
"""
|
||||
@@ -497,10 +493,7 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
|
||||
"""
|
||||
self._update_site_configuration()
|
||||
error, _ = self._assert_form(self.site, self.email_with_wrong_domain)
|
||||
self.assertEqual(
|
||||
error,
|
||||
"Email doesn't have {email_domain_name} domain name.".format(email_domain_name=self.email_domain_name)
|
||||
)
|
||||
assert error == f"Email doesn't have {self.email_domain_name} domain name."
|
||||
|
||||
def test_form_with_invalid_user(self):
|
||||
"""
|
||||
@@ -508,7 +501,7 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
|
||||
"""
|
||||
self._update_site_configuration()
|
||||
error, _ = self._assert_form(self.site, self.other_valid_email)
|
||||
self.assertEqual(error, "User with this email doesn't exist in system.")
|
||||
assert error == "User with this email doesn't exist in system."
|
||||
|
||||
def test_form_creation(self):
|
||||
"""
|
||||
@@ -517,8 +510,8 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
|
||||
self._update_site_configuration()
|
||||
_, allowed_auth_user = self._assert_form(self.site, self.valid_email, is_valid_form=True)
|
||||
db_allowed_auth_user = AllowedAuthUser.objects.all().first()
|
||||
self.assertEqual(db_allowed_auth_user.site.id, allowed_auth_user.site.id)
|
||||
self.assertEqual(db_allowed_auth_user.email, allowed_auth_user.email)
|
||||
assert db_allowed_auth_user.site.id == allowed_auth_user.site.id
|
||||
assert db_allowed_auth_user.email == allowed_auth_user.email
|
||||
|
||||
def test_form_update(self):
|
||||
"""
|
||||
@@ -527,13 +520,13 @@ class AllowedAuthUserFormTest(SiteMixin, TestCase):
|
||||
self._update_site_configuration()
|
||||
UserFactory(email=self.other_valid_email)
|
||||
_, allowed_auth_user = self._assert_form(self.site, self.valid_email, is_valid_form=True)
|
||||
self.assertEqual(AllowedAuthUser.objects.all().count(), 1)
|
||||
assert AllowedAuthUser.objects.all().count() == 1
|
||||
|
||||
# update the object with new instance.
|
||||
form = AllowedAuthUserForm({'site': self.site.id, 'email': self.other_valid_email}, instance=allowed_auth_user)
|
||||
self.assertTrue(form.is_valid())
|
||||
assert form.is_valid()
|
||||
form.save()
|
||||
|
||||
db_allowed_auth_user = AllowedAuthUser.objects.all().first()
|
||||
self.assertEqual(AllowedAuthUser.objects.all().count(), 1)
|
||||
self.assertEqual(db_allowed_auth_user.email, self.other_valid_email)
|
||||
assert AllowedAuthUser.objects.all().count() == 1
|
||||
assert db_allowed_auth_user.email == self.other_valid_email
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
Tests authz.py
|
||||
"""
|
||||
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from ccx_keys.locator import CCXLocator
|
||||
from django.contrib.auth.models import AnonymousUser, User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.core.exceptions import PermissionDenied
|
||||
@@ -32,30 +33,30 @@ class CreatorGroupTest(TestCase):
|
||||
Tests that CourseCreatorRole().has_user always returns True if ENABLE_CREATOR_GROUP
|
||||
and DISABLE_COURSE_CREATION are both not turned on.
|
||||
"""
|
||||
self.assertTrue(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
def test_creator_group_enabled_but_empty(self):
|
||||
""" Tests creator group feature on, but group empty. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {"ENABLE_CREATOR_GROUP": True}):
|
||||
self.assertFalse(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert not user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
# Make user staff. This will cause CourseCreatorRole().has_user to return True.
|
||||
self.user.is_staff = True
|
||||
self.assertTrue(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
def test_creator_group_enabled_nonempty(self):
|
||||
""" Tests creator group feature on, user added. """
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {"ENABLE_CREATOR_GROUP": True}):
|
||||
add_users(self.admin, CourseCreatorRole(), self.user)
|
||||
self.assertTrue(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
# check that a user who has not been added to the group still returns false
|
||||
user_not_added = User.objects.create_user('testuser2', 'test+courses2@edx.org', 'foo2')
|
||||
self.assertFalse(user_has_role(user_not_added, CourseCreatorRole()))
|
||||
assert not user_has_role(user_not_added, CourseCreatorRole())
|
||||
|
||||
# remove first user from the group and verify that CourseCreatorRole().has_user now returns false
|
||||
remove_users(self.admin, CourseCreatorRole(), self.user)
|
||||
self.assertFalse(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert not user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
def test_course_creation_disabled(self):
|
||||
""" Tests that the COURSE_CREATION_DISABLED flag overrides course creator group settings. """
|
||||
@@ -65,15 +66,15 @@ class CreatorGroupTest(TestCase):
|
||||
add_users(self.admin, CourseCreatorRole(), self.user)
|
||||
|
||||
# DISABLE_COURSE_CREATION overrides (user is not marked as staff).
|
||||
self.assertFalse(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert not user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
# Mark as staff. Now CourseCreatorRole().has_user returns true.
|
||||
self.user.is_staff = True
|
||||
self.assertTrue(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
# Remove user from creator group. CourseCreatorRole().has_user still returns true because is_staff=True
|
||||
remove_users(self.admin, CourseCreatorRole(), self.user)
|
||||
self.assertTrue(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
def test_add_user_not_authenticated(self):
|
||||
"""
|
||||
@@ -86,7 +87,7 @@ class CreatorGroupTest(TestCase):
|
||||
anonymous_user = AnonymousUser()
|
||||
role = CourseCreatorRole()
|
||||
add_users(self.admin, role, anonymous_user)
|
||||
self.assertFalse(user_has_role(anonymous_user, role))
|
||||
assert not user_has_role(anonymous_user, role)
|
||||
|
||||
def test_add_user_not_active(self):
|
||||
"""
|
||||
@@ -98,23 +99,23 @@ class CreatorGroupTest(TestCase):
|
||||
):
|
||||
self.user.is_active = False
|
||||
add_users(self.admin, CourseCreatorRole(), self.user)
|
||||
self.assertFalse(user_has_role(self.user, CourseCreatorRole()))
|
||||
assert not user_has_role(self.user, CourseCreatorRole())
|
||||
|
||||
def test_add_user_to_group_requires_staff_access(self):
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
self.admin.is_staff = False
|
||||
add_users(self.admin, CourseCreatorRole(), self.user)
|
||||
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
add_users(self.user, CourseCreatorRole(), self.user)
|
||||
|
||||
def test_add_user_to_group_requires_active(self):
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
self.admin.is_active = False
|
||||
add_users(self.admin, CourseCreatorRole(), self.user)
|
||||
|
||||
def test_add_user_to_group_requires_authenticated(self):
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
with mock.patch(
|
||||
'django.contrib.auth.models.User.is_authenticated',
|
||||
new_callable=mock.PropertyMock
|
||||
@@ -123,17 +124,17 @@ class CreatorGroupTest(TestCase):
|
||||
add_users(self.admin, CourseCreatorRole(), self.user)
|
||||
|
||||
def test_remove_user_from_group_requires_staff_access(self):
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
self.admin.is_staff = False
|
||||
remove_users(self.admin, CourseCreatorRole(), self.user)
|
||||
|
||||
def test_remove_user_from_group_requires_active(self):
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
self.admin.is_active = False
|
||||
remove_users(self.admin, CourseCreatorRole(), self.user)
|
||||
|
||||
def test_remove_user_from_group_requires_authenticated(self):
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
with mock.patch(
|
||||
'django.contrib.auth.models.User.is_authenticated',
|
||||
new_callable=mock.PropertyMock
|
||||
@@ -160,25 +161,25 @@ class CCXCourseGroupTest(TestCase):
|
||||
"""
|
||||
Test that global admins have no write access
|
||||
"""
|
||||
self.assertFalse(has_studio_write_access(self.global_admin, self.ccx_course_key))
|
||||
assert not has_studio_write_access(self.global_admin, self.ccx_course_key)
|
||||
|
||||
def test_no_staff_write_access(self):
|
||||
"""
|
||||
Test that course staff have no write access
|
||||
"""
|
||||
self.assertFalse(has_studio_write_access(self.staff, self.ccx_course_key))
|
||||
assert not has_studio_write_access(self.staff, self.ccx_course_key)
|
||||
|
||||
def test_no_global_admin_read_access(self):
|
||||
"""
|
||||
Test that global admins have no read access
|
||||
"""
|
||||
self.assertFalse(has_studio_read_access(self.global_admin, self.ccx_course_key))
|
||||
assert not has_studio_read_access(self.global_admin, self.ccx_course_key)
|
||||
|
||||
def test_no_staff_read_access(self):
|
||||
"""
|
||||
Test that course staff have no read access
|
||||
"""
|
||||
self.assertFalse(has_studio_read_access(self.staff, self.ccx_course_key))
|
||||
assert not has_studio_read_access(self.staff, self.ccx_course_key)
|
||||
|
||||
|
||||
class CourseGroupTest(TestCase):
|
||||
@@ -199,15 +200,15 @@ class CourseGroupTest(TestCase):
|
||||
Tests adding user to course group (happy path).
|
||||
"""
|
||||
# Create groups for a new course (and assign instructor role to the creator).
|
||||
self.assertFalse(user_has_role(self.creator, CourseInstructorRole(self.course_key)))
|
||||
assert not user_has_role(self.creator, CourseInstructorRole(self.course_key))
|
||||
add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
|
||||
self.assertTrue(user_has_role(self.creator, CourseInstructorRole(self.course_key)))
|
||||
assert user_has_role(self.creator, CourseInstructorRole(self.course_key))
|
||||
|
||||
# Add another user to the staff role.
|
||||
self.assertFalse(user_has_role(self.staff, CourseStaffRole(self.course_key)))
|
||||
assert not user_has_role(self.staff, CourseStaffRole(self.course_key))
|
||||
add_users(self.creator, CourseStaffRole(self.course_key), self.staff)
|
||||
self.assertTrue(user_has_role(self.staff, CourseStaffRole(self.course_key)))
|
||||
assert user_has_role(self.staff, CourseStaffRole(self.course_key))
|
||||
|
||||
def test_add_user_to_course_group_permission_denied(self):
|
||||
"""
|
||||
@@ -215,7 +216,7 @@ class CourseGroupTest(TestCase):
|
||||
"""
|
||||
add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
add_users(self.staff, CourseStaffRole(self.course_key), self.staff)
|
||||
|
||||
def test_remove_user_from_course_group(self):
|
||||
@@ -226,13 +227,13 @@ class CourseGroupTest(TestCase):
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator)
|
||||
|
||||
add_users(self.creator, CourseStaffRole(self.course_key), self.staff)
|
||||
self.assertTrue(user_has_role(self.staff, CourseStaffRole(self.course_key)))
|
||||
assert user_has_role(self.staff, CourseStaffRole(self.course_key))
|
||||
|
||||
remove_users(self.creator, CourseStaffRole(self.course_key), self.staff)
|
||||
self.assertFalse(user_has_role(self.staff, CourseStaffRole(self.course_key)))
|
||||
assert not user_has_role(self.staff, CourseStaffRole(self.course_key))
|
||||
|
||||
remove_users(self.creator, CourseInstructorRole(self.course_key), self.creator)
|
||||
self.assertFalse(user_has_role(self.creator, CourseInstructorRole(self.course_key)))
|
||||
assert not user_has_role(self.creator, CourseInstructorRole(self.course_key))
|
||||
|
||||
def test_remove_user_from_course_group_permission_denied(self):
|
||||
"""
|
||||
@@ -241,5 +242,5 @@ class CourseGroupTest(TestCase):
|
||||
add_users(self.global_admin, CourseInstructorRole(self.course_key), self.creator)
|
||||
another_staff = User.objects.create_user('another', 'teststaff+anothercourses@edx.org', 'foo')
|
||||
add_users(self.global_admin, CourseStaffRole(self.course_key), self.creator, self.staff, another_staff)
|
||||
with self.assertRaises(PermissionDenied):
|
||||
with pytest.raises(PermissionDenied):
|
||||
remove_users(self.staff, CourseStaffRole(self.course_key), another_staff)
|
||||
|
||||
@@ -69,7 +69,7 @@ class TestStudentDashboardEmailView(SharedModuleStoreTestCase):
|
||||
def test_email_unauthorized(self):
|
||||
BulkEmailFlag.objects.create(enabled=True, require_course_email_auth=True)
|
||||
# Assert that instructor email is not enabled for this course
|
||||
self.assertFalse(is_bulk_email_feature_enabled(self.course.id))
|
||||
assert not is_bulk_email_feature_enabled(self.course.id)
|
||||
# Assert that the URL for the email view is not in the response
|
||||
# if this course isn't authorized
|
||||
response = self.client.get(self.url)
|
||||
@@ -81,7 +81,7 @@ class TestStudentDashboardEmailView(SharedModuleStoreTestCase):
|
||||
cauth = CourseAuthorization(course_id=self.course.id, email_enabled=True)
|
||||
cauth.save()
|
||||
# Assert that instructor email is enabled for this course
|
||||
self.assertTrue(is_bulk_email_feature_enabled(self.course.id))
|
||||
assert is_bulk_email_feature_enabled(self.course.id)
|
||||
# Assert that the URL for the email view is not in the response
|
||||
# if this course isn't authorized
|
||||
response = self.client.get(self.url)
|
||||
|
||||
@@ -48,7 +48,7 @@ class CertificateDisplayTestBase(SharedModuleStoreTestCase):
|
||||
super(CertificateDisplayTestBase, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
|
||||
result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
|
||||
self.assertTrue(result, msg="Could not log in")
|
||||
assert result, 'Could not log in'
|
||||
|
||||
def _check_linkedin_visibility(self, is_visible):
|
||||
"""
|
||||
|
||||
@@ -80,8 +80,8 @@ class TestSite(TestCase):
|
||||
saved in the UserSignupSource Table.
|
||||
"""
|
||||
response = self.client.post(self.url, self.params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertGreater(len(UserSignupSource.objects.filter(site='openedx.localhost')), 0)
|
||||
assert response.status_code == 200
|
||||
assert len(UserSignupSource.objects.filter(site='openedx.localhost')) > 0
|
||||
|
||||
def test_user_signup_from_non_configured_site(self):
|
||||
"""
|
||||
@@ -89,8 +89,8 @@ class TestSite(TestCase):
|
||||
in UserSignupSource Table.
|
||||
"""
|
||||
response = self.client.post(self.url, self.params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(len(UserSignupSource.objects.filter(site='openedx.localhost')), 0)
|
||||
assert response.status_code == 200
|
||||
assert len(UserSignupSource.objects.filter(site='openedx.localhost')) == 0
|
||||
|
||||
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
|
||||
def test_user_signup_missing_enhanced_profile(self):
|
||||
@@ -99,7 +99,7 @@ class TestSite(TestCase):
|
||||
profile information.
|
||||
"""
|
||||
response = self.client.post(self.url, self.params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
@mock.patch("openedx.core.djangoapps.site_configuration.helpers.get_value", fake_get_value)
|
||||
def test_user_signup_including_enhanced_profile(self):
|
||||
@@ -108,10 +108,10 @@ class TestSite(TestCase):
|
||||
profile information.
|
||||
"""
|
||||
response = self.client.post(self.url, self.extended_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
user = User.objects.get(username=self.username)
|
||||
meta = json.loads(user.profile.meta)
|
||||
self.assertEqual(meta['address1'], 'foo')
|
||||
self.assertEqual(meta['state'], 'foo')
|
||||
self.assertEqual(meta['company'], 'foo')
|
||||
self.assertEqual(meta['title'], 'foo')
|
||||
assert meta['address1'] == 'foo'
|
||||
assert meta['state'] == 'foo'
|
||||
assert meta['company'] == 'foo'
|
||||
assert meta['title'] == 'foo'
|
||||
|
||||
@@ -77,13 +77,13 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
|
||||
# get dashboard
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(len(courses_list), 1)
|
||||
self.assertEqual(courses_list[0].course_id, course_location)
|
||||
assert len(courses_list) == 1
|
||||
assert courses_list[0].course_id == course_location
|
||||
|
||||
CourseEnrollment.unenroll(self.student, course_location)
|
||||
# get dashboard
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(len(courses_list), 0)
|
||||
assert len(courses_list) == 0
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_get_limited_number_of_courses_using_config(self):
|
||||
@@ -95,12 +95,12 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
|
||||
# get dashboard
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(len(courses_list), 2)
|
||||
assert len(courses_list) == 2
|
||||
|
||||
with self.settings(DASHBOARD_COURSE_LIMIT=1):
|
||||
course_limit = settings.DASHBOARD_COURSE_LIMIT
|
||||
courses_list = list(get_course_enrollments(self.student, None, [], course_limit))
|
||||
self.assertEqual(len(courses_list), 1)
|
||||
assert len(courses_list) == 1
|
||||
|
||||
def test_errored_course_regular_access(self):
|
||||
"""
|
||||
@@ -112,13 +112,13 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
self._create_course_with_access_groups(course_key, default_store=ModuleStoreEnum.Type.mongo)
|
||||
|
||||
with mock.patch('xmodule.modulestore.mongo.base.MongoKeyValueStore', mock.Mock(side_effect=Exception)):
|
||||
self.assertIsInstance(modulestore().get_course(course_key), ErrorBlock)
|
||||
assert isinstance(modulestore().get_course(course_key), ErrorBlock)
|
||||
|
||||
# Invalidate (e.g., delete) the corresponding CourseOverview, forcing get_course to be called.
|
||||
CourseOverview.objects.filter(id=course_key).delete()
|
||||
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(courses_list, [])
|
||||
assert courses_list == []
|
||||
|
||||
def test_course_listing_errored_deleted_courses(self):
|
||||
"""
|
||||
@@ -135,8 +135,8 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
mongo_store.delete_course(course_location, ModuleStoreEnum.UserID.test)
|
||||
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(len(courses_list), 1, courses_list)
|
||||
self.assertEqual(courses_list[0].course_id, good_location)
|
||||
assert len(courses_list) == 1, courses_list
|
||||
assert courses_list[0].course_id == good_location
|
||||
|
||||
@mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True})
|
||||
def test_course_listing_has_pre_requisite_courses(self):
|
||||
@@ -172,4 +172,4 @@ class TestCourseListing(ModuleStoreTestCase, MilestonesTestCaseMixin):
|
||||
self.student,
|
||||
courses_having_prerequisites
|
||||
)
|
||||
self.assertEqual(len(courses_requirements_not_met[course_location]['courses']), len(pre_requisite_courses))
|
||||
assert len(courses_requirements_not_met[course_location]['courses']) == len(pre_requisite_courses)
|
||||
|
||||
@@ -48,7 +48,7 @@ class CreditCourseDashboardTest(ModuleStoreTestCase):
|
||||
# Create a user and log in
|
||||
self.user = UserFactory.create(username=self.USERNAME, password=self.PASSWORD)
|
||||
result = self.client.login(username=self.USERNAME, password=self.PASSWORD)
|
||||
self.assertTrue(result, msg="Could not log in")
|
||||
assert result, 'Could not log in'
|
||||
|
||||
# Create a course and configure it as a credit course
|
||||
self.course = CourseFactory()
|
||||
|
||||
@@ -7,6 +7,7 @@ from string import capwords
|
||||
|
||||
import ddt
|
||||
import six
|
||||
import pytest
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User # lint-amnesty, pylint: disable=imported-auth-user
|
||||
from django.core import mail
|
||||
@@ -154,21 +155,16 @@ class ActivationEmailTests(EmailTemplateTagMixin, CacheIsolationTestCase):
|
||||
'terms_of_service': True
|
||||
}
|
||||
resp = self.client.post(url, params)
|
||||
self.assertEqual(
|
||||
resp.status_code, 200,
|
||||
msg=u"Could not create account (status {status}). The response was {response}".format(
|
||||
status=resp.status_code,
|
||||
response=resp.content
|
||||
)
|
||||
)
|
||||
assert resp.status_code == 200, "Could not create account (status {status}). The response was {response}"\
|
||||
.format(status=resp.status_code, response=resp.content)
|
||||
|
||||
def _assert_activation_email(self, subject, body_fragments, test_body_type):
|
||||
"""
|
||||
Verify that the activation email was sent.
|
||||
"""
|
||||
self.assertEqual(len(mail.outbox), 1)
|
||||
assert len(mail.outbox) == 1
|
||||
msg = mail.outbox[0]
|
||||
self.assertEqual(msg.subject, subject)
|
||||
assert msg.subject == subject
|
||||
|
||||
body_text = {
|
||||
'plain_text': msg.body,
|
||||
@@ -178,7 +174,7 @@ class ActivationEmailTests(EmailTemplateTagMixin, CacheIsolationTestCase):
|
||||
body_to_be_tested = body_text[test_body_type]
|
||||
|
||||
for fragment in body_fragments:
|
||||
self.assertIn(fragment, body_to_be_tested)
|
||||
assert fragment in body_to_be_tested
|
||||
|
||||
def test_do_not_send_email_and_do_activate(self):
|
||||
"""
|
||||
@@ -203,8 +199,8 @@ class ActivationEmailTests(EmailTemplateTagMixin, CacheIsolationTestCase):
|
||||
with patch('common.djangoapps.third_party_auth.is_enabled', return_value=True):
|
||||
reg.skip_email_verification = True
|
||||
inactive_user_view(request)
|
||||
self.assertEqual(user.is_active, True)
|
||||
self.assertEqual(email.called, False, msg='method should not have been called')
|
||||
assert user.is_active
|
||||
assert email.called is False, 'method should not have been called'
|
||||
|
||||
@patch('common.djangoapps.student.views.management.compose_activation_email')
|
||||
def test_send_email_to_inactive_user(self, email):
|
||||
@@ -219,7 +215,7 @@ class ActivationEmailTests(EmailTemplateTagMixin, CacheIsolationTestCase):
|
||||
with patch('common.djangoapps.edxmako.request_context.get_current_request', return_value=request):
|
||||
with patch('common.djangoapps.third_party_auth.pipeline.running', return_value=False):
|
||||
inactive_user_view(request)
|
||||
self.assertEqual(email.called, True, msg='method should have been called')
|
||||
assert email.called is True, 'method should have been called'
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -231,6 +227,7 @@ class ProctoringRequirementsEmailTests(EmailTemplateTagMixin, ModuleStoreTestCas
|
||||
"""
|
||||
Test sending of the proctoring requirements email.
|
||||
"""
|
||||
|
||||
# pylint: disable=no-member
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
@@ -252,10 +249,7 @@ class ProctoringRequirementsEmailTests(EmailTemplateTagMixin, ModuleStoreTestCas
|
||||
text = message.body
|
||||
html = message.alternatives[0][0]
|
||||
|
||||
self.assertEqual(
|
||||
message.subject,
|
||||
"Proctoring requirements for {}".format(self.course.display_name)
|
||||
)
|
||||
assert message.subject == "Proctoring requirements for {}".format(self.course.display_name)
|
||||
|
||||
for fragment in self._get_fragments():
|
||||
assert fragment in text
|
||||
@@ -325,11 +319,12 @@ class EmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, CacheIsolat
|
||||
"""
|
||||
Assert that `response_data` indicates a failed request that returns `expected_error`
|
||||
"""
|
||||
self.assertFalse(response_data['success'])
|
||||
self.assertEqual(expected_error, response_data['error'])
|
||||
self.assertFalse(self.user.email_user.called)
|
||||
assert response_data['success'] is False
|
||||
assert expected_error == response_data['error']
|
||||
assert self.user.email_user.called is False
|
||||
|
||||
@patch('common.djangoapps.student.views.management.render_to_string', Mock(side_effect=mock_render_to_string, autospec=True)) # lint-amnesty, pylint: disable=line-too-long
|
||||
@patch('common.djangoapps.student.views.management.render_to_string',
|
||||
Mock(side_effect=mock_render_to_string, autospec=True)) # lint-amnesty, pylint: disable=line-too-long
|
||||
def test_duplicate_activation_key(self):
|
||||
"""
|
||||
Assert that if two users change Email address simultaneously, no error is thrown
|
||||
@@ -352,13 +347,13 @@ class EmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, CacheIsolat
|
||||
(improperly formatted) email address.
|
||||
"""
|
||||
for email in ('bad_email', 'bad_email@', '@bad_email'):
|
||||
self.assertEqual(self.do_email_validation(email), 'Valid e-mail address required.')
|
||||
assert self.do_email_validation(email) == 'Valid e-mail address required.'
|
||||
|
||||
def test_change_email_to_existing_value(self):
|
||||
"""
|
||||
Test the error message if user attempts to change email to the existing value.
|
||||
"""
|
||||
self.assertEqual(self.do_email_validation(self.user.email), 'Old email is the same as the new email.')
|
||||
assert self.do_email_validation(self.user.email) == 'Old email is the same as the new email.'
|
||||
|
||||
@patch('django.core.mail.EmailMultiAlternatives.send')
|
||||
def test_email_failure(self, send_mail):
|
||||
@@ -418,12 +413,15 @@ class EmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, CacheIsolat
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@patch('common.djangoapps.student.views.management.render_to_response', Mock(side_effect=mock_render_to_response, autospec=True)) # lint-amnesty, pylint: disable=line-too-long
|
||||
@patch('common.djangoapps.student.views.management.render_to_string', Mock(side_effect=mock_render_to_string, autospec=True)) # lint-amnesty, pylint: disable=line-too-long
|
||||
@patch('common.djangoapps.student.views.management.render_to_response',
|
||||
Mock(side_effect=mock_render_to_response, autospec=True)) # lint-amnesty, pylint: disable=line-too-long
|
||||
@patch('common.djangoapps.student.views.management.render_to_string',
|
||||
Mock(side_effect=mock_render_to_string, autospec=True)) # lint-amnesty, pylint: disable=line-too-long
|
||||
class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheIsolationMixin, TransactionTestCase):
|
||||
"""
|
||||
Test that confirmation of email change requests function even in the face of exceptions thrown while sending email
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(EmailChangeConfirmationTests, self).setUp() # lint-amnesty, pylint: disable=super-with-arguments
|
||||
self.clear_caches()
|
||||
@@ -467,16 +465,16 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
"""
|
||||
Assert that no changes to user, profile, or pending email have been made to the db
|
||||
"""
|
||||
self.assertEqual(self.user.email, User.objects.get(username=self.user.username).email)
|
||||
self.assertEqual(self.profile.meta, UserProfile.objects.get(user=self.user).meta)
|
||||
self.assertEqual(1, PendingEmailChange.objects.count())
|
||||
assert self.user.email == User.objects.get(username=self.user.username).email
|
||||
assert self.profile.meta == UserProfile.objects.get(user=self.user).meta
|
||||
assert PendingEmailChange.objects.count() == 1
|
||||
|
||||
def assertFailedBeforeEmailing(self):
|
||||
"""
|
||||
Assert that the function failed before emailing a user
|
||||
"""
|
||||
self.assertRolledBack()
|
||||
self.assertEqual(len(mail.outbox), 0)
|
||||
assert len(mail.outbox) == 0
|
||||
|
||||
def check_confirm_email_change(self, expected_template, expected_context):
|
||||
"""
|
||||
@@ -488,11 +486,9 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
generate the content
|
||||
"""
|
||||
response = confirm_email_change(self.request, self.key)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
mock_render_to_response(expected_template, expected_context).content.decode('utf-8'),
|
||||
response.content.decode('utf-8')
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert mock_render_to_response(expected_template, expected_context).content.decode('utf-8') \
|
||||
== response.content.decode('utf-8')
|
||||
|
||||
def assertChangeEmailSent(self, test_body_type):
|
||||
"""
|
||||
@@ -505,7 +501,7 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
})
|
||||
|
||||
# Must have two items in outbox: one for old email, another for new email
|
||||
self.assertEqual(len(mail.outbox), 2)
|
||||
assert len(mail.outbox) == 2
|
||||
|
||||
use_https = self.request.is_secure()
|
||||
if settings.FEATURES['ENABLE_MKTG_SITE']:
|
||||
@@ -519,7 +515,7 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
|
||||
# Verifying contents
|
||||
for msg in mail.outbox:
|
||||
self.assertEqual(msg.subject, self.email_subject)
|
||||
assert msg.subject == self.email_subject
|
||||
|
||||
body_text = {
|
||||
'plain_text': msg.body,
|
||||
@@ -529,9 +525,9 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
|
||||
body_to_be_tested = body_text[test_body_type]
|
||||
for fragment in self.email_fragments:
|
||||
self.assertIn(fragment, body_to_be_tested)
|
||||
assert fragment in body_to_be_tested
|
||||
|
||||
self.assertIn(contact_link, body_to_be_tested)
|
||||
assert contact_link in body_to_be_tested
|
||||
|
||||
def test_not_pending(self):
|
||||
self.key = 'not_a_key'
|
||||
@@ -550,7 +546,7 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
self.check_confirm_email_change('email_change_failed.html', {
|
||||
'email': self.user.email,
|
||||
})
|
||||
self.assertEqual(ace_mail.send.call_count, 1)
|
||||
assert ace_mail.send.call_count == 1
|
||||
self.assertRolledBack()
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', "Test only valid in LMS")
|
||||
@@ -560,7 +556,7 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
self.check_confirm_email_change('email_change_failed.html', {
|
||||
'email': self.pending_change_request.new_email
|
||||
})
|
||||
self.assertEqual(ace_mail.send.call_count, 2)
|
||||
assert ace_mail.send.call_count == 2
|
||||
self.assertRolledBack()
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', "Test only valid in LMS")
|
||||
@@ -577,19 +573,16 @@ class EmailChangeConfirmationTests(EmailTestMixin, EmailTemplateTagMixin, CacheI
|
||||
self.assertChangeEmailSent(test_body_type)
|
||||
|
||||
meta = json.loads(UserProfile.objects.get(user=self.user).meta)
|
||||
self.assertIn('old_emails', meta)
|
||||
self.assertEqual(self.user.email, meta['old_emails'][0][0])
|
||||
self.assertEqual(
|
||||
self.pending_change_request.new_email,
|
||||
User.objects.get(username=self.user.username).email
|
||||
)
|
||||
self.assertEqual(0, PendingEmailChange.objects.count())
|
||||
assert 'old_emails' in meta
|
||||
assert self.user.email == meta['old_emails'][0][0]
|
||||
assert self.pending_change_request.new_email == User.objects.get(username=self.user.username).email
|
||||
assert PendingEmailChange.objects.count() == 0
|
||||
|
||||
@patch('common.djangoapps.student.views.PendingEmailChange.objects.get', Mock(side_effect=TestException))
|
||||
def test_always_rollback(self):
|
||||
connection = transaction.get_connection()
|
||||
with patch.object(connection, 'rollback', wraps=connection.rollback) as mock_rollback:
|
||||
with self.assertRaises(TestException):
|
||||
with pytest.raises(TestException):
|
||||
confirm_email_change(self.request, self.key)
|
||||
|
||||
mock_rollback.assert_called_with()
|
||||
@@ -602,7 +595,7 @@ class SecondaryEmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, Ca
|
||||
"""
|
||||
|
||||
def setUp(self, tracker='common.djangoapps.student.views.management.tracker'):
|
||||
super(SecondaryEmailChangeRequestTests, self).setUp(tracker) # lint-amnesty, pylint: disable=super-with-arguments
|
||||
super().setUp(tracker)
|
||||
self.user = UserFactory.create()
|
||||
self.new_secondary_email = 'new.secondary.email@edx.org'
|
||||
self.req_factory = RequestFactory()
|
||||
@@ -638,9 +631,9 @@ class SecondaryEmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, Ca
|
||||
"""
|
||||
Assert that `response_data` indicates a failed request that returns `expected_error`
|
||||
"""
|
||||
self.assertFalse(response_data['success'])
|
||||
self.assertEqual(expected_error, response_data['error'])
|
||||
self.assertFalse(self.user.email_user.called)
|
||||
assert not response_data['success']
|
||||
assert expected_error == response_data['error']
|
||||
assert not self.user.email_user.called
|
||||
|
||||
def test_invalid_emails(self):
|
||||
"""
|
||||
@@ -648,7 +641,7 @@ class SecondaryEmailChangeRequestTests(EventTestMixin, EmailTemplateTagMixin, Ca
|
||||
(improperly formatted) email address.
|
||||
"""
|
||||
for email in ('bad_email', 'bad_email@', '@bad_email'):
|
||||
self.assertEqual(self.do_email_validation(email), 'Valid e-mail address required.')
|
||||
assert self.do_email_validation(email) == 'Valid e-mail address required.'
|
||||
|
||||
@patch('django.core.mail.EmailMultiAlternatives.send')
|
||||
def test_email_failure(self, send_mail):
|
||||
|
||||
@@ -4,6 +4,7 @@ Tests for student enrollment.
|
||||
|
||||
|
||||
import unittest
|
||||
import pytest
|
||||
|
||||
import ddt
|
||||
import six
|
||||
@@ -128,19 +129,19 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
|
||||
# Enroll in the course and verify the URL we get sent to
|
||||
resp = self._change_enrollment('enroll')
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
self.assertEqual(resp.content.decode('utf-8'), full_url)
|
||||
assert resp.status_code == 200
|
||||
assert resp.content.decode('utf-8') == full_url
|
||||
|
||||
# If we're not expecting to be enrolled, verify that this is the case
|
||||
if enrollment_mode is None:
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course.id))
|
||||
assert not CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
|
||||
# Otherwise, verify that we're enrolled with the expected course mode
|
||||
else:
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
|
||||
assert CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
course_mode, is_active = CourseEnrollment.enrollment_mode_for_user(self.user, self.course.id)
|
||||
self.assertTrue(is_active)
|
||||
self.assertEqual(course_mode, enrollment_mode)
|
||||
assert is_active
|
||||
assert course_mode == enrollment_mode
|
||||
|
||||
def test_unenroll(self):
|
||||
# Enroll the student in the course
|
||||
@@ -148,10 +149,10 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
|
||||
# Attempt to unenroll the student
|
||||
resp = self._change_enrollment('unenroll')
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
# Expect that we're no longer enrolled
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(self.user, self.course.id))
|
||||
assert not CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
|
||||
@patch.dict(settings.FEATURES, {'ENABLE_MKTG_EMAIL_OPT_IN': True})
|
||||
@patch('openedx.core.djangoapps.user_api.preferences.api.update_email_opt_in')
|
||||
@@ -187,7 +188,7 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
opt_in = email_opt_in == 'true'
|
||||
mock_update_email_opt_in.assert_called_once_with(self.user, self.course.org, opt_in)
|
||||
else:
|
||||
self.assertFalse(mock_update_email_opt_in.called)
|
||||
assert not mock_update_email_opt_in.called
|
||||
|
||||
@ddt.data(
|
||||
('honor', False),
|
||||
@@ -211,11 +212,11 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
) as mock_send_email:
|
||||
# First enroll in a non-proctored course. This should not trigger the email.
|
||||
CourseEnrollment.enroll(self.user, self.course.id, mode)
|
||||
self.assertFalse(mock_send_email.called)
|
||||
assert not mock_send_email.called
|
||||
# Then, enroll in a proctored course, and assert that the email is sent only when
|
||||
# enrolling in a verified mode.
|
||||
CourseEnrollment.enroll(self.user, self.proctored_course.id, mode) # pylint: disable=no-member
|
||||
self.assertEqual(email_sent, mock_send_email.called)
|
||||
assert email_sent == mock_send_email.called
|
||||
|
||||
def test_enroll_in_proctored_course_no_exam(self):
|
||||
"""
|
||||
@@ -229,7 +230,7 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
CourseEnrollment.enroll(
|
||||
self.user, self.proctored_course_no_exam.id, 'verified' # pylint: disable=no-member
|
||||
)
|
||||
self.assertFalse(mock_send_email.called)
|
||||
assert not mock_send_email.called
|
||||
|
||||
@ddt.data('verified', 'masters', 'professional', 'executive-education')
|
||||
def test_upgrade_proctoring_enrollment(self, mode):
|
||||
@@ -245,7 +246,7 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
self.user, self.proctored_course.id, 'audit' # pylint: disable=no-member
|
||||
)
|
||||
enrollment.update_enrollment(mode=mode)
|
||||
self.assertTrue(mock_send_email.called)
|
||||
assert mock_send_email.called
|
||||
|
||||
@patch.dict(
|
||||
'django.conf.settings.PROCTORING_BACKENDS', {'test_provider_honor_mode': {'allow_honor_mode': True}}
|
||||
@@ -266,7 +267,7 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
)
|
||||
self._create_proctored_exam(course_honor_mode)
|
||||
CourseEnrollment.enroll(self.user, course_honor_mode.id, 'honor') # pylint: disable=no-member
|
||||
self.assertTrue(mock_send_email.called)
|
||||
assert mock_send_email.called
|
||||
|
||||
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||
def test_embargo_restrict(self):
|
||||
@@ -274,22 +275,22 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
# we should be blocked.
|
||||
with restrict_course(self.course.id) as redirect_url:
|
||||
response = self._change_enrollment('enroll')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content.decode('utf-8'), redirect_url)
|
||||
assert response.status_code == 200
|
||||
assert response.content.decode('utf-8') == redirect_url
|
||||
|
||||
# Verify that we weren't enrolled
|
||||
is_enrolled = CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
self.assertFalse(is_enrolled)
|
||||
assert not is_enrolled
|
||||
|
||||
@patch.dict(settings.FEATURES, {'EMBARGO': True})
|
||||
def test_embargo_allow(self):
|
||||
response = self._change_enrollment('enroll')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.content.decode('utf-8'), '')
|
||||
assert response.status_code == 200
|
||||
assert response.content.decode('utf-8') == ''
|
||||
|
||||
# Verify that we were enrolled
|
||||
is_enrolled = CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
self.assertTrue(is_enrolled)
|
||||
assert is_enrolled
|
||||
|
||||
def test_user_not_authenticated(self):
|
||||
# Log out, so we're no longer authenticated
|
||||
@@ -297,35 +298,35 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
|
||||
# Try to enroll, expecting a forbidden response
|
||||
resp = self._change_enrollment('enroll')
|
||||
self.assertEqual(resp.status_code, 403)
|
||||
assert resp.status_code == 403
|
||||
|
||||
def test_missing_course_id_param(self):
|
||||
resp = self.client.post(
|
||||
reverse('change_enrollment'),
|
||||
{'enrollment_action': 'enroll'}
|
||||
)
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_unenroll_not_enrolled_in_course(self):
|
||||
# Try unenroll without first enrolling in the course
|
||||
resp = self._change_enrollment('unenroll')
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_invalid_enrollment_action(self):
|
||||
resp = self._change_enrollment('not_an_action')
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_with_invalid_course_id(self):
|
||||
CourseEnrollment.enroll(self.user, self.course.id, mode="honor")
|
||||
resp = self._change_enrollment('unenroll', course_id="edx/")
|
||||
self.assertEqual(resp.status_code, 400)
|
||||
assert resp.status_code == 400
|
||||
|
||||
def test_enrollment_limit(self):
|
||||
"""
|
||||
Assert that in a course with max student limit set to 1, we can enroll staff and instructor along with
|
||||
student. To make sure course full check excludes staff and instructors.
|
||||
"""
|
||||
self.assertEqual(self.course_limited.max_student_enrollments_allowed, 1)
|
||||
assert self.course_limited.max_student_enrollments_allowed == 1
|
||||
user1 = UserFactory.create(username="tester1", email="tester1@e.com", password="test")
|
||||
user2 = UserFactory.create(username="tester2", email="tester2@e.com", password="test")
|
||||
|
||||
@@ -342,25 +343,17 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
CourseEnrollment.enroll(staff, self.course_limited.id, check_access=True)
|
||||
CourseEnrollment.enroll(instructor, self.course_limited.id, check_access=True)
|
||||
|
||||
self.assertTrue(
|
||||
CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=staff).exists()
|
||||
)
|
||||
assert CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=staff).exists()
|
||||
|
||||
self.assertTrue(
|
||||
CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=instructor).exists()
|
||||
)
|
||||
assert CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=instructor).exists()
|
||||
|
||||
CourseEnrollment.enroll(user1, self.course_limited.id, check_access=True)
|
||||
self.assertTrue(
|
||||
CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=user1).exists()
|
||||
)
|
||||
assert CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=user1).exists()
|
||||
|
||||
with self.assertRaises(CourseFullError):
|
||||
with pytest.raises(CourseFullError):
|
||||
CourseEnrollment.enroll(user2, self.course_limited.id, check_access=True)
|
||||
|
||||
self.assertFalse(
|
||||
CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=user2).exists()
|
||||
)
|
||||
assert not CourseEnrollment.objects.filter(course_id=self.course_limited.id, user=user2).exists()
|
||||
|
||||
def _change_enrollment(self, action, course_id=None, email_opt_in=None):
|
||||
"""Change the student's enrollment status in a course.
|
||||
@@ -405,51 +398,47 @@ class EnrollmentTest(UrlResetMixin, SharedModuleStoreTestCase):
|
||||
auto_enroll=False,
|
||||
)
|
||||
# Still unlinked
|
||||
self.assertIsNone(cea.user)
|
||||
assert cea.user is None
|
||||
|
||||
user1 = UserFactory.create(username="tester1", email="tester1@e.com", password="test")
|
||||
user2 = UserFactory.create(username="tester2", email="tester2@e.com", password="test")
|
||||
|
||||
self.assertFalse(
|
||||
CourseEnrollment.objects.filter(course_id=self.course.id, user=user1).exists()
|
||||
)
|
||||
assert not CourseEnrollment.objects.filter(course_id=self.course.id, user=user1).exists()
|
||||
|
||||
user1.email = 'allowed@edx.org'
|
||||
user1.save()
|
||||
|
||||
CourseEnrollment.enroll(user1, self.course.id, check_access=True)
|
||||
|
||||
self.assertTrue(
|
||||
CourseEnrollment.objects.filter(course_id=self.course.id, user=user1).exists()
|
||||
)
|
||||
assert CourseEnrollment.objects.filter(course_id=self.course.id, user=user1).exists()
|
||||
|
||||
# The CEA is now linked
|
||||
cea.refresh_from_db()
|
||||
self.assertEqual(cea.user, user1)
|
||||
assert cea.user == user1
|
||||
|
||||
# user2 wants to enroll too, (ab)using the same allowed e-mail, but cannot
|
||||
user1.email = 'my_other_email@edx.org'
|
||||
user1.save()
|
||||
user2.email = 'allowed@edx.org'
|
||||
user2.save()
|
||||
with self.assertRaises(EnrollmentClosedError):
|
||||
with pytest.raises(EnrollmentClosedError):
|
||||
CourseEnrollment.enroll(user2, self.course.id, check_access=True)
|
||||
|
||||
# CEA still linked to user1. Also after unenrolling
|
||||
cea.refresh_from_db()
|
||||
self.assertEqual(cea.user, user1)
|
||||
assert cea.user == user1
|
||||
|
||||
CourseEnrollment.unenroll(user1, self.course.id)
|
||||
|
||||
cea.refresh_from_db()
|
||||
self.assertEqual(cea.user, user1)
|
||||
assert cea.user == user1
|
||||
|
||||
# Enroll user1 again. Because it's the original owner of the CEA, the enrollment is allowed
|
||||
CourseEnrollment.enroll(user1, self.course.id, check_access=True)
|
||||
|
||||
# Still same
|
||||
cea.refresh_from_db()
|
||||
self.assertEqual(cea.user, user1)
|
||||
assert cea.user == user1
|
||||
|
||||
def test_score_recalculation_on_enrollment_update(self):
|
||||
"""
|
||||
|
||||
@@ -5,6 +5,8 @@ Test that various events are fired for models in the student app.
|
||||
|
||||
|
||||
import mock
|
||||
import pytest
|
||||
|
||||
from django.db.utils import IntegrityError
|
||||
from django.test import TestCase
|
||||
from django_countries.fields import Country
|
||||
@@ -36,7 +38,7 @@ class TestUserProfileEvents(UserSettingsEventTestMixin, TestCase):
|
||||
|
||||
# Verify that we remove the temporary `_changed_fields` property from
|
||||
# the model after we're done emitting events.
|
||||
with self.assertRaises(AttributeError):
|
||||
with pytest.raises(AttributeError):
|
||||
self.profile._changed_fields # pylint: disable=pointless-statement, protected-access
|
||||
|
||||
def test_change_many_fields(self):
|
||||
@@ -83,7 +85,7 @@ class TestUserProfileEvents(UserSettingsEventTestMixin, TestCase):
|
||||
should never emit an event if save fails.
|
||||
"""
|
||||
self.profile.gender = "unknown"
|
||||
with self.assertRaises(IntegrityError):
|
||||
with pytest.raises(IntegrityError):
|
||||
self.profile.save()
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
@@ -144,7 +146,7 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
|
||||
should never emit an event if save fails.
|
||||
"""
|
||||
self.user.password = u'new password'
|
||||
with self.assertRaises(IntegrityError):
|
||||
with pytest.raises(IntegrityError):
|
||||
self.user.save()
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
@@ -164,11 +166,11 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
|
||||
pending_enrollment = CourseEnrollmentAllowedFactory(auto_enroll=True) # lint-amnesty, pylint: disable=unused-variable
|
||||
|
||||
# the e-mail will change to test@edx.org (from something else)
|
||||
self.assertNotEqual(self.user.email, 'test@edx.org')
|
||||
assert self.user.email != 'test@edx.org'
|
||||
|
||||
# there's a CEA for the new e-mail
|
||||
self.assertEqual(CourseEnrollmentAllowed.objects.count(), 1)
|
||||
self.assertEqual(CourseEnrollmentAllowed.objects.filter(email='test@edx.org').count(), 1)
|
||||
assert CourseEnrollmentAllowed.objects.count() == 1
|
||||
assert CourseEnrollmentAllowed.objects.filter(email='test@edx.org').count() == 1
|
||||
|
||||
# Changing the e-mail to the enrollment-allowed e-mail should enroll
|
||||
self.user.email = 'test@edx.org'
|
||||
@@ -176,5 +178,5 @@ class TestUserEvents(UserSettingsEventTestMixin, TestCase):
|
||||
self.assert_user_enrollment_occurred('edX/toy/2012_Fall')
|
||||
|
||||
# CEAs shouldn't have been affected
|
||||
self.assertEqual(CourseEnrollmentAllowed.objects.count(), 1)
|
||||
self.assertEqual(CourseEnrollmentAllowed.objects.filter(email='test@edx.org').count(), 1)
|
||||
assert CourseEnrollmentAllowed.objects.count() == 1
|
||||
assert CourseEnrollmentAllowed.objects.filter(email='test@edx.org').count() == 1
|
||||
|
||||
@@ -77,7 +77,7 @@ class TestLoginHelper(TestCase):
|
||||
req = self.request.get(settings.LOGIN_URL + "?next={url}".format(url=next_url), HTTP_HOST=host)
|
||||
req.META["HTTP_ACCEPT"] = http_accept
|
||||
next_page = get_next_url_for_login_page(req)
|
||||
self.assertEqual(next_page, next_url)
|
||||
assert next_page == next_url
|
||||
|
||||
tpa_hint_test_cases = [
|
||||
# Test requests outside the TPA pipeline - tpa_hint should be added.
|
||||
@@ -127,7 +127,7 @@ class TestLoginHelper(TestCase):
|
||||
req.META["HTTP_ACCEPT"] = "text/html"
|
||||
self._add_session(req)
|
||||
next_page = get_next_url_for_login_page(req)
|
||||
self.assertEqual(next_page, expected_url)
|
||||
assert next_page == expected_url
|
||||
|
||||
with override_settings(FEATURES=dict(settings.FEATURES, THIRD_PARTY_AUTH_HINT=tpa_hint)):
|
||||
validate_login()
|
||||
@@ -153,4 +153,4 @@ class TestLoginHelper(TestCase):
|
||||
with with_site_configuration_context(configuration=configuration_values):
|
||||
next_page = get_next_url_for_login_page(req)
|
||||
|
||||
self.assertEqual(next_page, expected_url)
|
||||
assert next_page == expected_url
|
||||
|
||||
@@ -57,12 +57,10 @@ class LinkedInAddToProfileUrlTests(TestCase):
|
||||
# There was a problem with dict ordering in the add_to_profile_url function that will go away then.
|
||||
# self.assertEqual(actual_url, expected_url)
|
||||
|
||||
self.assertIn('https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME', actual_url)
|
||||
self.assertIn('&name={platform}+{cert_name}'.format(
|
||||
platform=quote(settings.PLATFORM_NAME.encode('utf-8')), cert_name=expected_cert_name
|
||||
), actual_url)
|
||||
self.assertIn('&certUrl={cert_url}'.format(cert_url=quote(self.CERT_URL, safe='')), actual_url)
|
||||
self.assertIn('&organizationId={org_id}'.format(org_id=config.company_identifier), actual_url)
|
||||
assert 'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME' in actual_url
|
||||
assert f'&name={quote(settings.PLATFORM_NAME.encode("utf-8"))}+{expected_cert_name}' in actual_url
|
||||
assert '&certUrl={cert_url}'.format(cert_url=quote(self.CERT_URL, safe='')) in actual_url
|
||||
assert '&organizationId={org_id}'.format(org_id=config.company_identifier) in actual_url
|
||||
|
||||
@ddt.data(
|
||||
('honor', 'Honor+Code+Credential+for+Test+Course+%E2%98%83'),
|
||||
@@ -94,9 +92,7 @@ class LinkedInAddToProfileUrlTests(TestCase):
|
||||
# There was a problem with dict ordering in the add_to_profile_url function that will go away then.
|
||||
# self.assertEqual(actual_url, expected_url)
|
||||
|
||||
self.assertIn('https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME', actual_url)
|
||||
self.assertIn('&name={platform}+{cert_name}'.format(
|
||||
platform=quote(settings.PLATFORM_NAME.encode('utf-8')), cert_name=expected_cert_name
|
||||
), actual_url)
|
||||
self.assertIn('&certUrl={cert_url}'.format(cert_url=quote(self.CERT_URL, safe='')), actual_url)
|
||||
self.assertIn('&organizationId={org_id}'.format(org_id=config.company_identifier), actual_url)
|
||||
assert 'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME' in actual_url
|
||||
assert f'&name={quote(settings.PLATFORM_NAME.encode("utf-8"))}+{expected_cert_name}' in actual_url
|
||||
assert '&certUrl={cert_url}'.format(cert_url=quote(self.CERT_URL, safe='')) in actual_url
|
||||
assert '&organizationId={org_id}'.format(org_id=config.company_identifier) in actual_url
|
||||
|
||||
@@ -32,13 +32,10 @@ class TestLongUsernameEmail(TestCase): # lint-amnesty, pylint: disable=missing-
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
|
||||
# Status code should be 400.
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['username'][0]['user_message'],
|
||||
USERNAME_BAD_LENGTH_MSG,
|
||||
)
|
||||
assert obj['username'][0]['user_message'] == USERNAME_BAD_LENGTH_MSG
|
||||
|
||||
def test_spoffed_name(self):
|
||||
"""
|
||||
@@ -46,7 +43,7 @@ class TestLongUsernameEmail(TestCase): # lint-amnesty, pylint: disable=missing-
|
||||
"""
|
||||
self.url_params['name'] = '<p style="font-size:300px; color:green;"></br>Name<input type="text"></br>Content spoof' # lint-amnesty, pylint: disable=line-too-long
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_long_email(self):
|
||||
"""
|
||||
@@ -57,13 +54,10 @@ class TestLongUsernameEmail(TestCase): # lint-amnesty, pylint: disable=missing-
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
|
||||
# Assert that we get error when email has more than 254 characters.
|
||||
self.assertGreater(len(self.url_params['email']), 254)
|
||||
assert len(self.url_params['email']) > 254
|
||||
|
||||
# Status code should be 400.
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['email'][0]['user_message'],
|
||||
"Email cannot be more than 254 characters long",
|
||||
)
|
||||
assert obj['email'][0]['user_message'] == 'Email cannot be more than 254 characters long'
|
||||
|
||||
@@ -49,19 +49,19 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
username = 'test-user'
|
||||
user = UserFactory(username=username)
|
||||
expected = 'enrollment_status_hash_' + username
|
||||
self.assertEqual(CourseEnrollment.enrollment_status_hash_cache_key(user), expected)
|
||||
assert CourseEnrollment.enrollment_status_hash_cache_key(user) == expected
|
||||
|
||||
def assert_enrollment_status_hash_cached(self, user, expected_value):
|
||||
self.assertEqual(cache.get(CourseEnrollment.enrollment_status_hash_cache_key(user)), expected_value)
|
||||
assert cache.get(CourseEnrollment.enrollment_status_hash_cache_key(user)) == expected_value
|
||||
|
||||
def test_generate_enrollment_status_hash(self):
|
||||
""" Verify the method returns a hash of a user's current enrollments. """
|
||||
# Return None for anonymous users
|
||||
self.assertIsNone(CourseEnrollment.generate_enrollment_status_hash(AnonymousUser()))
|
||||
assert CourseEnrollment.generate_enrollment_status_hash(AnonymousUser()) is None
|
||||
|
||||
# No enrollments
|
||||
expected = hashlib.md5(self.user.username.encode('utf-8')).hexdigest() # lint-amnesty, pylint: disable=no-member
|
||||
self.assertEqual(CourseEnrollment.generate_enrollment_status_hash(self.user), expected)
|
||||
assert CourseEnrollment.generate_enrollment_status_hash(self.user) == expected
|
||||
self.assert_enrollment_status_hash_cached(self.user, expected)
|
||||
|
||||
# No active enrollments
|
||||
@@ -69,7 +69,7 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
course_id = self.course.id # pylint: disable=no-member
|
||||
enrollment = CourseEnrollmentFactory.create(user=self.user, course_id=course_id, mode=enrollment_mode,
|
||||
is_active=False)
|
||||
self.assertEqual(CourseEnrollment.generate_enrollment_status_hash(self.user), expected)
|
||||
assert CourseEnrollment.generate_enrollment_status_hash(self.user) == expected
|
||||
self.assert_enrollment_status_hash_cached(self.user, expected)
|
||||
|
||||
# One active enrollment
|
||||
@@ -79,7 +79,7 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
username=self.user.username, course_id=str(course_id).lower(), mode=enrollment_mode.lower()
|
||||
)
|
||||
expected = hashlib.md5(expected.encode('utf-8')).hexdigest()
|
||||
self.assertEqual(CourseEnrollment.generate_enrollment_status_hash(self.user), expected)
|
||||
assert CourseEnrollment.generate_enrollment_status_hash(self.user) == expected
|
||||
self.assert_enrollment_status_hash_cached(self.user, expected)
|
||||
|
||||
# Multiple enrollments
|
||||
@@ -90,13 +90,13 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
'{course_id}={mode}'.format(course_id=str(enrollment.course_id).lower(), mode=enrollment.mode.lower()) for
|
||||
enrollment in enrollments]
|
||||
expected = hashlib.md5('&'.join(hash_elements).encode('utf-8')).hexdigest()
|
||||
self.assertEqual(CourseEnrollment.generate_enrollment_status_hash(self.user), expected)
|
||||
assert CourseEnrollment.generate_enrollment_status_hash(self.user) == expected
|
||||
self.assert_enrollment_status_hash_cached(self.user, expected)
|
||||
|
||||
def test_save_deletes_cached_enrollment_status_hash(self):
|
||||
""" Verify the method deletes the cached enrollment status hash for the user. """
|
||||
# There should be no cached value for a new user with no enrollments.
|
||||
self.assertIsNone(cache.get(CourseEnrollment.enrollment_status_hash_cache_key(self.user)))
|
||||
assert cache.get(CourseEnrollment.enrollment_status_hash_cache_key(self.user)) is None
|
||||
|
||||
# Generating a status hash should cache the generated value.
|
||||
status_hash = CourseEnrollment.generate_enrollment_status_hash(self.user)
|
||||
@@ -104,7 +104,7 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
|
||||
# Modifying enrollments should delete the cached value.
|
||||
CourseEnrollmentFactory.create(user=self.user)
|
||||
self.assertIsNone(cache.get(CourseEnrollment.enrollment_status_hash_cache_key(self.user)))
|
||||
assert cache.get(CourseEnrollment.enrollment_status_hash_cache_key(self.user)) is None
|
||||
|
||||
def test_users_enrolled_in_active_only(self):
|
||||
"""CourseEnrollment.users_enrolled_in should return only Users with active enrollments when
|
||||
@@ -113,7 +113,7 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
CourseEnrollmentFactory.create(user=self.user_2, course_id=self.course.id, is_active=False) # lint-amnesty, pylint: disable=no-member
|
||||
|
||||
active_enrolled_users = list(CourseEnrollment.objects.users_enrolled_in(self.course.id)) # lint-amnesty, pylint: disable=no-member
|
||||
self.assertEqual([self.user], active_enrolled_users)
|
||||
assert [self.user] == active_enrolled_users
|
||||
|
||||
def test_users_enrolled_in_all(self):
|
||||
"""CourseEnrollment.users_enrolled_in should return active and inactive users when
|
||||
@@ -139,8 +139,8 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
expiration_datetime=datetime.datetime.now(pytz.UTC) + datetime.timedelta(days=1)
|
||||
)
|
||||
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
||||
self.assertEqual(Schedule.objects.all().count(), 0)
|
||||
self.assertEqual(enrollment.upgrade_deadline, course_mode.expiration_datetime)
|
||||
assert Schedule.objects.all().count() == 0
|
||||
assert enrollment.upgrade_deadline == course_mode.expiration_datetime
|
||||
|
||||
@skip_unless_lms
|
||||
# NOTE: We mute the post_save signal to prevent Schedules from being created for new enrollments
|
||||
@@ -164,14 +164,14 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
# The schedule's upgrade deadline should be used if a schedule exists
|
||||
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
||||
schedule = ScheduleFactory(enrollment=enrollment)
|
||||
self.assertEqual(enrollment.upgrade_deadline, schedule.upgrade_deadline)
|
||||
assert enrollment.upgrade_deadline == schedule.upgrade_deadline
|
||||
|
||||
@skip_unless_lms
|
||||
@ddt.data(*(set(CourseMode.ALL_MODES) - set(CourseMode.AUDIT_MODES)))
|
||||
def test_upgrade_deadline_for_non_upgradeable_enrollment(self, mode):
|
||||
""" The property should return None if an upgrade cannot be upgraded. """
|
||||
enrollment = CourseEnrollmentFactory(course_id=self.course.id, mode=mode) # lint-amnesty, pylint: disable=no-member
|
||||
self.assertIsNone(enrollment.upgrade_deadline)
|
||||
assert enrollment.upgrade_deadline is None
|
||||
|
||||
@skip_unless_lms
|
||||
def test_upgrade_deadline_instructor_paced(self):
|
||||
@@ -186,8 +186,8 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
||||
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
||||
ScheduleFactory(enrollment=enrollment)
|
||||
self.assertIsNotNone(enrollment.schedule)
|
||||
self.assertEqual(enrollment.upgrade_deadline, course_upgrade_deadline)
|
||||
assert enrollment.schedule is not None
|
||||
assert enrollment.upgrade_deadline == course_upgrade_deadline
|
||||
|
||||
@skip_unless_lms
|
||||
def test_upgrade_deadline_with_schedule_and_professional_mode(self):
|
||||
@@ -204,8 +204,8 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
enrollment = CourseEnrollmentFactory(course_id=course.id, mode=CourseMode.AUDIT)
|
||||
DynamicUpgradeDeadlineConfiguration.objects.create(enabled=True)
|
||||
ScheduleFactory(enrollment=enrollment)
|
||||
self.assertIsNotNone(enrollment.schedule)
|
||||
self.assertIsNone(enrollment.upgrade_deadline)
|
||||
assert enrollment.schedule is not None
|
||||
assert enrollment.upgrade_deadline is None
|
||||
|
||||
@skip_unless_lms
|
||||
# NOTE: We mute the post_save signal to prevent Schedules from being created for new enrollments
|
||||
@@ -236,12 +236,12 @@ class CourseEnrollmentTests(SharedModuleStoreTestCase): # lint-amnesty, pylint:
|
||||
# Re-fetch the CourseOverview record.
|
||||
# As a side effect, this will recreate the record, and update the version.
|
||||
course_overview_new = CourseOverview.get_from_id(course.id)
|
||||
self.assertEqual(course_overview_new.version, CourseOverview.VERSION)
|
||||
assert course_overview_new.version == CourseOverview.VERSION
|
||||
|
||||
# Ensure that the enrollment record was unchanged during this re-creation
|
||||
enrollment_refetched = CourseEnrollment.objects.filter(id=enrollment.id)
|
||||
self.assertTrue(enrollment_refetched.exists())
|
||||
self.assertEqual(enrollment_refetched.all()[0], enrollment)
|
||||
assert enrollment_refetched.exists()
|
||||
assert enrollment_refetched.all()[0] == enrollment
|
||||
|
||||
|
||||
class PendingNameChangeTests(SharedModuleStoreTestCase):
|
||||
@@ -260,17 +260,17 @@ class PendingNameChangeTests(SharedModuleStoreTestCase):
|
||||
new_name='New Name PII',
|
||||
rationale='for testing!'
|
||||
)
|
||||
self.assertEqual(1, len(PendingNameChange.objects.all()))
|
||||
assert 1 == len(PendingNameChange.objects.all())
|
||||
|
||||
def test_delete_by_user_removes_pending_name_change(self):
|
||||
record_was_deleted = PendingNameChange.delete_by_user_value(self.user, field='user')
|
||||
self.assertTrue(record_was_deleted)
|
||||
self.assertEqual(0, len(PendingNameChange.objects.all()))
|
||||
assert record_was_deleted
|
||||
assert 0 == len(PendingNameChange.objects.all())
|
||||
|
||||
def test_delete_by_user_no_effect_for_user_with_no_name_change(self):
|
||||
record_was_deleted = PendingNameChange.delete_by_user_value(self.user2, field='user')
|
||||
self.assertFalse(record_was_deleted)
|
||||
self.assertEqual(1, len(PendingNameChange.objects.all()))
|
||||
assert not record_was_deleted
|
||||
assert 1 == len(PendingNameChange.objects.all())
|
||||
|
||||
|
||||
class PendingEmailChangeTests(SharedModuleStoreTestCase):
|
||||
@@ -292,13 +292,13 @@ class PendingEmailChangeTests(SharedModuleStoreTestCase):
|
||||
|
||||
def test_delete_by_user_removes_pending_email_change(self):
|
||||
record_was_deleted = PendingEmailChange.delete_by_user_value(self.user, field='user')
|
||||
self.assertTrue(record_was_deleted)
|
||||
self.assertEqual(0, len(PendingEmailChange.objects.all()))
|
||||
assert record_was_deleted
|
||||
assert 0 == len(PendingEmailChange.objects.all())
|
||||
|
||||
def test_delete_by_user_no_effect_for_user_with_no_email_change(self):
|
||||
record_was_deleted = PendingEmailChange.delete_by_user_value(self.user2, field='user')
|
||||
self.assertFalse(record_was_deleted)
|
||||
self.assertEqual(1, len(PendingEmailChange.objects.all()))
|
||||
assert not record_was_deleted
|
||||
assert 1 == len(PendingEmailChange.objects.all())
|
||||
|
||||
|
||||
class TestCourseEnrollmentAllowed(TestCase): # lint-amnesty, pylint: disable=missing-class-docstring
|
||||
@@ -319,22 +319,22 @@ class TestCourseEnrollmentAllowed(TestCase): # lint-amnesty, pylint: disable=mi
|
||||
value=self.email,
|
||||
field='email'
|
||||
)
|
||||
self.assertTrue(is_successful)
|
||||
assert is_successful
|
||||
user_search_results = CourseEnrollmentAllowed.objects.filter(
|
||||
email=self.email
|
||||
)
|
||||
self.assertFalse(user_search_results)
|
||||
assert not user_search_results
|
||||
|
||||
def test_retiring_nonexistent_user_doesnt_modify_records(self):
|
||||
is_successful = CourseEnrollmentAllowed.delete_by_user_value(
|
||||
value='nonexistentlearner@example.com',
|
||||
field='email'
|
||||
)
|
||||
self.assertFalse(is_successful)
|
||||
assert not is_successful
|
||||
user_search_results = CourseEnrollmentAllowed.objects.filter(
|
||||
email=self.email
|
||||
)
|
||||
self.assertTrue(user_search_results.exists())
|
||||
assert user_search_results.exists()
|
||||
|
||||
|
||||
class TestManualEnrollmentAudit(SharedModuleStoreTestCase):
|
||||
@@ -373,16 +373,12 @@ class TestManualEnrollmentAudit(SharedModuleStoreTestCase):
|
||||
self.instructor, self.user.email, ALLOWEDTOENROLL_TO_ENROLLED,
|
||||
'manually enrolling unenrolled user again', other_enrollment
|
||||
)
|
||||
self.assertTrue(ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exists())
|
||||
assert ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exists()
|
||||
# retire the ManualEnrollmentAudit objects associated with the above enrollments
|
||||
ManualEnrollmentAudit.retire_manual_enrollments(user=self.user, retired_email="xxx")
|
||||
self.assertTrue(ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exists())
|
||||
self.assertFalse(ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exclude(
|
||||
enrolled_email="xxx"
|
||||
))
|
||||
self.assertFalse(ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exclude(
|
||||
reason=""
|
||||
))
|
||||
assert ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exists()
|
||||
assert not ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exclude(enrolled_email='xxx')
|
||||
assert not ManualEnrollmentAudit.objects.filter(enrollment=enrollment).exclude(reason='')
|
||||
|
||||
|
||||
class TestAccountRecovery(TestCase):
|
||||
@@ -439,9 +435,9 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
|
||||
actual_student = User.objects.get(email=student.email)
|
||||
actual_cea = CourseEnrollmentAllowed.objects.get(email=student.email)
|
||||
|
||||
self.assertEqual(actual_course_enrollment.mode, mode)
|
||||
self.assertEqual(actual_student.is_active, True)
|
||||
self.assertEqual(actual_cea.user, student)
|
||||
assert actual_course_enrollment.mode == mode
|
||||
assert actual_student.is_active is True
|
||||
assert actual_cea.user == student
|
||||
|
||||
def test_not_enrolled_student_is_enrolled(self):
|
||||
"""
|
||||
@@ -464,9 +460,9 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
|
||||
actual_student = User.objects.get(email=student.email)
|
||||
actual_cea = CourseEnrollmentAllowed.objects.get(email=student.email)
|
||||
|
||||
self.assertEqual(actual_course_enrollment.mode, u"audit")
|
||||
self.assertEqual(actual_student.is_active, True)
|
||||
self.assertEqual(actual_cea.user, student)
|
||||
assert actual_course_enrollment.mode == u'audit'
|
||||
assert actual_student.is_active is True
|
||||
assert actual_cea.user == student
|
||||
|
||||
def test_verified_student_not_downgraded_when_changing_email(self):
|
||||
"""
|
||||
@@ -488,8 +484,8 @@ class TestUserPostSaveCallback(SharedModuleStoreTestCase):
|
||||
actual_course_enrollment = CourseEnrollment.objects.get(user=student, course_id=self.course.id)
|
||||
actual_student = User.objects.get(email=student.email)
|
||||
|
||||
self.assertEqual(actual_course_enrollment.mode, u"verified")
|
||||
self.assertEqual(actual_student.is_active, True)
|
||||
assert actual_course_enrollment.mode == u'verified'
|
||||
assert actual_student.is_active is True
|
||||
|
||||
def _set_up_invited_student(self, course, active=False, enrolled=True, course_mode=''):
|
||||
"""
|
||||
|
||||
@@ -30,28 +30,28 @@ class ProfileParentalControlsTest(TestCase):
|
||||
|
||||
def test_no_year_of_birth(self):
|
||||
"""Verify the behavior for users with no specified year of birth."""
|
||||
self.assertTrue(self.profile.requires_parental_consent())
|
||||
self.assertTrue(self.profile.requires_parental_consent(default_requires_consent=True))
|
||||
self.assertFalse(self.profile.requires_parental_consent(default_requires_consent=False))
|
||||
assert self.profile.requires_parental_consent()
|
||||
assert self.profile.requires_parental_consent(default_requires_consent=True)
|
||||
assert not self.profile.requires_parental_consent(default_requires_consent=False)
|
||||
|
||||
@override_settings(PARENTAL_CONSENT_AGE_LIMIT=None)
|
||||
def test_no_parental_controls(self):
|
||||
"""Verify the behavior for all users when parental controls are not enabled."""
|
||||
self.assertFalse(self.profile.requires_parental_consent())
|
||||
self.assertFalse(self.profile.requires_parental_consent(default_requires_consent=True))
|
||||
self.assertFalse(self.profile.requires_parental_consent(default_requires_consent=False))
|
||||
assert not self.profile.requires_parental_consent()
|
||||
assert not self.profile.requires_parental_consent(default_requires_consent=True)
|
||||
assert not self.profile.requires_parental_consent(default_requires_consent=False)
|
||||
|
||||
# Verify that even a child does not require parental consent
|
||||
current_year = now().year
|
||||
self.set_year_of_birth(current_year - 10)
|
||||
self.assertFalse(self.profile.requires_parental_consent())
|
||||
assert not self.profile.requires_parental_consent()
|
||||
|
||||
def test_adult_user(self):
|
||||
"""Verify the behavior for an adult."""
|
||||
current_year = now().year
|
||||
self.set_year_of_birth(current_year - 20)
|
||||
self.assertFalse(self.profile.requires_parental_consent())
|
||||
self.assertTrue(self.profile.requires_parental_consent(age_limit=21))
|
||||
assert not self.profile.requires_parental_consent()
|
||||
assert self.profile.requires_parental_consent(age_limit=21)
|
||||
|
||||
def test_child_user(self):
|
||||
"""Verify the behavior for a child."""
|
||||
@@ -59,14 +59,14 @@ class ProfileParentalControlsTest(TestCase):
|
||||
|
||||
# Verify for a child born 13 years agp
|
||||
self.set_year_of_birth(current_year - 13)
|
||||
self.assertTrue(self.profile.requires_parental_consent())
|
||||
self.assertTrue(self.profile.requires_parental_consent(date=datetime.date(current_year, 12, 31)))
|
||||
self.assertFalse(self.profile.requires_parental_consent(date=datetime.date(current_year + 1, 1, 1)))
|
||||
assert self.profile.requires_parental_consent()
|
||||
assert self.profile.requires_parental_consent(date=datetime.date(current_year, 12, 31))
|
||||
assert not self.profile.requires_parental_consent(date=datetime.date((current_year + 1), 1, 1))
|
||||
|
||||
# Verify for a child born 14 years ago
|
||||
self.set_year_of_birth(current_year - 14)
|
||||
self.assertFalse(self.profile.requires_parental_consent())
|
||||
self.assertFalse(self.profile.requires_parental_consent(date=datetime.date(current_year, 1, 1)))
|
||||
assert not self.profile.requires_parental_consent()
|
||||
assert not self.profile.requires_parental_consent(date=datetime.date(current_year, 1, 1))
|
||||
|
||||
def test_profile_image(self):
|
||||
"""Verify that a profile's image obeys parental controls."""
|
||||
@@ -74,16 +74,16 @@ class ProfileParentalControlsTest(TestCase):
|
||||
# Verify that an image cannot be set for a user with no year of birth set
|
||||
self.profile.profile_image_uploaded_at = now()
|
||||
self.profile.save()
|
||||
self.assertFalse(self.profile.has_profile_image)
|
||||
assert not self.profile.has_profile_image
|
||||
|
||||
# Verify that an image can be set for an adult user
|
||||
current_year = now().year
|
||||
self.set_year_of_birth(current_year - 20)
|
||||
self.profile.profile_image_uploaded_at = now()
|
||||
self.profile.save()
|
||||
self.assertTrue(self.profile.has_profile_image)
|
||||
assert self.profile.has_profile_image
|
||||
|
||||
# verify that a user's profile image is removed when they switch to requiring parental controls
|
||||
self.set_year_of_birth(current_year - 10)
|
||||
self.profile.save()
|
||||
self.assertFalse(self.profile.has_profile_image)
|
||||
assert not self.profile.has_profile_image
|
||||
|
||||
@@ -39,12 +39,10 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_password_length_too_short(self):
|
||||
self.url_params['password'] = 'aaa'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password is too short. It must contain at least 6 characters.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] ==\
|
||||
'This password is too short. It must contain at least 6 characters.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.MinimumLengthValidator', {'min_length': 6}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -52,9 +50,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_password_length_long_enough(self):
|
||||
self.url_params['password'] = 'ThisIsALongerPassword'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.MaximumLengthValidator', {'max_length': 12}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -62,12 +60,10 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_password_length_too_long(self):
|
||||
self.url_params['password'] = 'ThisPasswordIsWayTooLong'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password is too long. It must contain no more than 12 characters.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] ==\
|
||||
'This password is too long. It must contain no more than 12 characters.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.UppercaseValidator', {'min_upper': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -75,12 +71,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_password_not_enough_uppercase(self):
|
||||
self.url_params['password'] = 'thisshouldfail'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password must contain at least 3 uppercase letters.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] == 'This password must contain at least 3 uppercase letters.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.UppercaseValidator', {'min_upper': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -88,9 +81,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_password_enough_uppercase(self):
|
||||
self.url_params['password'] = 'ThisShouldPass'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.LowercaseValidator', {'min_lower': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -98,12 +91,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_password_not_enough_lowercase(self):
|
||||
self.url_params['password'] = 'THISSHOULDFAIL'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password must contain at least 3 lowercase letters.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] == 'This password must contain at least 3 lowercase letters.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.LowercaseValidator', {'min_lower': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -111,9 +101,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_password_enough_lowercase(self):
|
||||
self.url_params['password'] = 'ThisShouldPass'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.PunctuationValidator', {'min_punctuation': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -121,12 +111,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_not_enough_punctuations(self):
|
||||
self.url_params['password'] = 'thisshouldfail'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password must contain at least 3 punctuation marks.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] == 'This password must contain at least 3 punctuation marks.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.PunctuationValidator', {'min_punctuation': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -134,9 +121,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_enough_punctuations(self):
|
||||
self.url_params['password'] = 'Th!sSh.uldPa$*'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.NumericValidator', {'min_numeric': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -145,12 +132,9 @@ class TestPasswordPolicy(TestCase):
|
||||
# The unicode ២ is the number 2 in Khmer and the ٧ is the Arabic-Indic number 7
|
||||
self.url_params['password'] = u'thisShouldFail២٧'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password must contain at least 3 numbers.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] == 'This password must contain at least 3 numbers.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.NumericValidator', {'min_numeric': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -159,9 +143,9 @@ class TestPasswordPolicy(TestCase):
|
||||
# The unicode ២ is the number 2 in Khmer
|
||||
self.url_params['password'] = u'thisShouldPass២33'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.AlphabeticValidator', {'min_alphabetic': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -169,12 +153,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_not_enough_alphabetic_characters(self):
|
||||
self.url_params['password'] = '123456ab'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password must contain at least 3 letters.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] == 'This password must contain at least 3 letters.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.AlphabeticValidator', {'min_alphabetic': 3}) # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -182,9 +163,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_enough_alphabetic_characters(self):
|
||||
self.url_params['password'] = u'𝒯𝓗Ï𝓼𝒫å𝓼𝓼𝔼𝓼'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.MinimumLengthValidator', {'min_length': 3}), # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -195,7 +176,7 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_multiple_errors_fail(self):
|
||||
self.url_params['password'] = 'thisshouldfail'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
error_strings = [
|
||||
"This password must contain at least 3 uppercase letters.",
|
||||
@@ -203,7 +184,7 @@ class TestPasswordPolicy(TestCase):
|
||||
"This password must contain at least 3 punctuation marks.",
|
||||
]
|
||||
for i in range(3):
|
||||
self.assertEqual(obj['password'][i]['user_message'], error_strings[i])
|
||||
assert obj['password'][i]['user_message'] == error_strings[i]
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.MinimumLengthValidator', {'min_length': 3}), # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -215,9 +196,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_multiple_errors_pass(self):
|
||||
self.url_params['password'] = u'tH1s Sh0u!d P3#$!'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('django.contrib.auth.password_validation.CommonPasswordValidator')
|
||||
@@ -225,12 +206,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_common_password_fail(self):
|
||||
self.url_params['password'] = 'password'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"This password is too common.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] == 'This password is too common.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('django.contrib.auth.password_validation.CommonPasswordValidator')
|
||||
@@ -238,9 +216,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_common_password_pass(self):
|
||||
self.url_params['password'] = 'this_is_ok'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('common.djangoapps.util.password_policy_validators.MinimumLengthValidator', {'min_length': 6}), # lint-amnesty, pylint: disable=line-too-long
|
||||
@@ -249,9 +227,9 @@ class TestPasswordPolicy(TestCase):
|
||||
def test_with_unicode(self):
|
||||
self.url_params['password'] = u'四節比分和七年前'
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
|
||||
class TestUsernamePasswordNonmatch(TestCase):
|
||||
@@ -277,12 +255,9 @@ class TestUsernamePasswordNonmatch(TestCase):
|
||||
self.url_params['username'] = "foobar"
|
||||
self.url_params['password'] = "foobar"
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertEqual(
|
||||
obj['password'][0]['user_message'],
|
||||
"The password is too similar to the username.",
|
||||
)
|
||||
assert obj['password'][0]['user_message'] == 'The password is too similar to the username.'
|
||||
|
||||
@override_settings(AUTH_PASSWORD_VALIDATORS=[
|
||||
create_validator_config('django.contrib.auth.password_validation.UserAttributeSimilarityValidator')
|
||||
@@ -291,6 +266,6 @@ class TestUsernamePasswordNonmatch(TestCase):
|
||||
self.url_params['username'] = "foobar"
|
||||
self.url_params['password'] = "nonmatch"
|
||||
response = self.client.post(self.url, self.url_params)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
obj = json.loads(response.content.decode('utf-8'))
|
||||
self.assertTrue(obj['success'])
|
||||
assert obj['success']
|
||||
|
||||
@@ -20,11 +20,11 @@ class ReceiversTest(SharedModuleStoreTestCase):
|
||||
@override_waffle_flag(COURSEWARE_MICROFRONTEND_PROGRESS_MILESTONES_FIRST_SECTION_CELEBRATION, active=True)
|
||||
def test_celebration_created(self):
|
||||
""" Test that we make celebration objects when enrollments are created """
|
||||
self.assertEqual(CourseEnrollmentCelebration.objects.count(), 0)
|
||||
assert CourseEnrollmentCelebration.objects.count() == 0
|
||||
|
||||
# Test initial creation upon an enrollment being made
|
||||
enrollment = CourseEnrollmentFactory()
|
||||
self.assertEqual(CourseEnrollmentCelebration.objects.count(), 1)
|
||||
assert CourseEnrollmentCelebration.objects.count() == 1
|
||||
celebration = CourseEnrollmentCelebration.objects.get(enrollment=enrollment, celebrate_first_section=True)
|
||||
|
||||
# Test nothing changes if we update that enrollment
|
||||
@@ -32,10 +32,10 @@ class ReceiversTest(SharedModuleStoreTestCase):
|
||||
celebration.save()
|
||||
enrollment.mode = 'test-mode'
|
||||
enrollment.save()
|
||||
self.assertEqual(CourseEnrollmentCelebration.objects.count(), 1)
|
||||
assert CourseEnrollmentCelebration.objects.count() == 1
|
||||
CourseEnrollmentCelebration.objects.get(enrollment=enrollment, celebrate_first_section=False)
|
||||
|
||||
def test_celebration_gated_by_waffle(self):
|
||||
""" Test we don't make a celebration if the MFE redirect waffle flag is off """
|
||||
CourseEnrollmentFactory()
|
||||
self.assertEqual(CourseEnrollmentCelebration.objects.count(), 0)
|
||||
assert CourseEnrollmentCelebration.objects.count() == 0
|
||||
|
||||
@@ -75,10 +75,10 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
|
||||
|
||||
# get courses through iterating all courses
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(len(courses_list), 2)
|
||||
assert len(courses_list) == 2
|
||||
|
||||
recent_course_list = _get_recently_enrolled_courses(courses_list)
|
||||
self.assertEqual(len(recent_course_list), 1)
|
||||
assert len(recent_course_list) == 1
|
||||
|
||||
def test_zero_second_delta(self):
|
||||
"""
|
||||
@@ -86,10 +86,10 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
|
||||
"""
|
||||
self._configure_message_timeout(0)
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(len(courses_list), 2)
|
||||
assert len(courses_list) == 2
|
||||
|
||||
recent_course_list = _get_recently_enrolled_courses(courses_list)
|
||||
self.assertEqual(len(recent_course_list), 0)
|
||||
assert len(recent_course_list) == 0
|
||||
|
||||
def test_enrollments_sorted_most_recent(self):
|
||||
"""
|
||||
@@ -114,15 +114,15 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
|
||||
courses.append(course)
|
||||
|
||||
courses_list = list(get_course_enrollments(self.student, None, []))
|
||||
self.assertEqual(len(courses_list), 6)
|
||||
assert len(courses_list) == 6
|
||||
|
||||
recent_course_list = _get_recently_enrolled_courses(courses_list)
|
||||
self.assertEqual(len(recent_course_list), 5)
|
||||
assert len(recent_course_list) == 5
|
||||
|
||||
self.assertEqual(recent_course_list[1].course.id, courses[0].id)
|
||||
self.assertEqual(recent_course_list[2].course.id, courses[1].id)
|
||||
self.assertEqual(recent_course_list[3].course.id, courses[2].id)
|
||||
self.assertEqual(recent_course_list[4].course.id, courses[3].id)
|
||||
assert recent_course_list[1].course.id == courses[0].id
|
||||
assert recent_course_list[2].course.id == courses[1].id
|
||||
assert recent_course_list[3].course.id == courses[2].id
|
||||
assert recent_course_list[4].course.id == courses[3].id
|
||||
|
||||
self.client.login(username=self.student.username, password=self.PASSWORD)
|
||||
response = self.client.get(reverse("dashboard"))
|
||||
@@ -166,10 +166,10 @@ class TestRecentEnrollments(ModuleStoreTestCase, XssTestMixin):
|
||||
|
||||
courses_enrollments = list(get_course_enrollments(self.student, None, []))
|
||||
courses_enrollments.sort(key=lambda x: x.created, reverse=True)
|
||||
self.assertEqual(len(courses_enrollments), 3)
|
||||
assert len(courses_enrollments) == 3
|
||||
|
||||
recent_course_enrollments = _get_recently_enrolled_courses(courses_enrollments)
|
||||
self.assertEqual(len(recent_course_enrollments), 2)
|
||||
assert len(recent_course_enrollments) == 2
|
||||
|
||||
self.assertContains(
|
||||
response,
|
||||
|
||||
@@ -69,7 +69,7 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
def test_refundable(self, cutoff_date):
|
||||
""" Assert base case is refundable"""
|
||||
cutoff_date.return_value = datetime.now(pytz.UTC) + timedelta(days=1)
|
||||
self.assertTrue(self.enrollment.refundable())
|
||||
assert self.enrollment.refundable()
|
||||
|
||||
@patch('common.djangoapps.student.models.CourseEnrollment.refund_cutoff_date')
|
||||
def test_refundable_expired_verification(self, cutoff_date):
|
||||
@@ -77,7 +77,7 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
cutoff_date.return_value = datetime.now(pytz.UTC) + timedelta(days=1)
|
||||
self.verified_mode.expiration_datetime = datetime.now(pytz.UTC) - timedelta(days=1)
|
||||
self.verified_mode.save()
|
||||
self.assertTrue(self.enrollment.refundable())
|
||||
assert self.enrollment.refundable()
|
||||
|
||||
@patch('common.djangoapps.student.models.CourseEnrollment.refund_cutoff_date')
|
||||
def test_refundable_when_certificate_exists(self, cutoff_date):
|
||||
@@ -85,7 +85,7 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
|
||||
cutoff_date.return_value = datetime.now(pytz.UTC) + timedelta(days=1)
|
||||
|
||||
self.assertTrue(self.enrollment.refundable())
|
||||
assert self.enrollment.refundable()
|
||||
|
||||
GeneratedCertificateFactory.create(
|
||||
user=self.user,
|
||||
@@ -94,33 +94,28 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
mode='verified'
|
||||
)
|
||||
|
||||
self.assertFalse(self.enrollment.refundable())
|
||||
self.assertFalse(
|
||||
self.enrollment.refundable(
|
||||
user_already_has_certs_for=GeneratedCertificate.course_ids_with_certs_for_user(self.user)
|
||||
)
|
||||
)
|
||||
assert not self.enrollment.refundable()
|
||||
assert not self.enrollment.\
|
||||
refundable(user_already_has_certs_for=GeneratedCertificate.course_ids_with_certs_for_user(self.user))
|
||||
|
||||
# Assert that can_refund overrides this and allows refund
|
||||
self.enrollment.can_refund = True
|
||||
self.assertTrue(self.enrollment.refundable())
|
||||
self.assertTrue(
|
||||
self.enrollment.refundable(
|
||||
user_already_has_certs_for=GeneratedCertificate.course_ids_with_certs_for_user(self.user)
|
||||
)
|
||||
assert self.enrollment.refundable()
|
||||
assert self.enrollment.refundable(
|
||||
user_already_has_certs_for=GeneratedCertificate.course_ids_with_certs_for_user(self.user)
|
||||
)
|
||||
|
||||
@patch('common.djangoapps.student.models.CourseEnrollment.refund_cutoff_date')
|
||||
def test_refundable_with_cutoff_date(self, cutoff_date):
|
||||
""" Assert enrollment is refundable before cutoff and not refundable after."""
|
||||
cutoff_date.return_value = datetime.now(pytz.UTC) + timedelta(days=1)
|
||||
self.assertTrue(self.enrollment.refundable())
|
||||
assert self.enrollment.refundable()
|
||||
|
||||
cutoff_date.return_value = datetime.now(pytz.UTC) - timedelta(minutes=5)
|
||||
self.assertFalse(self.enrollment.refundable())
|
||||
assert not self.enrollment.refundable()
|
||||
|
||||
cutoff_date.return_value = datetime.now(pytz.UTC) + timedelta(minutes=5)
|
||||
self.assertTrue(self.enrollment.refundable())
|
||||
assert self.enrollment.refundable()
|
||||
|
||||
@ddt.data(
|
||||
(timedelta(days=1), timedelta(days=2), timedelta(days=2), 14),
|
||||
@@ -161,10 +156,7 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
with patch('common.djangoapps.student.models.EnrollmentRefundConfiguration.current') as config:
|
||||
instance = config.return_value
|
||||
instance.refund_window = refund_period
|
||||
self.assertEqual(
|
||||
self.enrollment.refund_cutoff_date(),
|
||||
expected_date + refund_period
|
||||
)
|
||||
assert self.enrollment.refund_cutoff_date() == (expected_date + refund_period)
|
||||
|
||||
expected_date_placed_attr = {
|
||||
"namespace": "order",
|
||||
@@ -172,14 +164,11 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
"value": date_placed,
|
||||
}
|
||||
|
||||
self.assertIn(
|
||||
expected_date_placed_attr,
|
||||
CourseEnrollmentAttribute.get_enrollment_attributes(self.enrollment)
|
||||
)
|
||||
assert expected_date_placed_attr in CourseEnrollmentAttribute.get_enrollment_attributes(self.enrollment)
|
||||
|
||||
def test_refund_cutoff_date_no_attributes(self):
|
||||
""" Assert that the None is returned when no order number attribute is found."""
|
||||
self.assertIsNone(self.enrollment.refund_cutoff_date())
|
||||
assert self.enrollment.refund_cutoff_date() is None
|
||||
|
||||
@patch('openedx.core.djangoapps.commerce.utils.ecommerce_api_client')
|
||||
def test_refund_cutoff_date_with_date_placed_attr(self, mock_ecommerce_api_client):
|
||||
@@ -200,10 +189,7 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
)
|
||||
|
||||
refund_config = EnrollmentRefundConfiguration.current()
|
||||
self.assertEqual(
|
||||
self.enrollment.refund_cutoff_date(),
|
||||
order_date + refund_config.refund_window
|
||||
)
|
||||
assert self.enrollment.refund_cutoff_date() == (order_date + refund_config.refund_window)
|
||||
mock_ecommerce_api_client.assert_not_called()
|
||||
|
||||
@httpretty.activate
|
||||
@@ -232,4 +218,4 @@ class RefundableTest(SharedModuleStoreTestCase):
|
||||
|
||||
self.client.login(username=self.user.username, password=self.USER_PASSWORD)
|
||||
resp = self.client.post(reverse('dashboard', args=[]))
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
assert resp.status_code == 200
|
||||
|
||||
@@ -38,10 +38,10 @@ class RolesTestCase(TestCase):
|
||||
self.course_instructor = InstructorFactory(course_key=self.course_key)
|
||||
|
||||
def test_global_staff(self):
|
||||
self.assertFalse(GlobalStaff().has_user(self.student))
|
||||
self.assertFalse(GlobalStaff().has_user(self.course_staff))
|
||||
self.assertFalse(GlobalStaff().has_user(self.course_instructor))
|
||||
self.assertTrue(GlobalStaff().has_user(self.global_staff))
|
||||
assert not GlobalStaff().has_user(self.student)
|
||||
assert not GlobalStaff().has_user(self.course_staff)
|
||||
assert not GlobalStaff().has_user(self.course_instructor)
|
||||
assert GlobalStaff().has_user(self.global_staff)
|
||||
|
||||
def test_group_name_case_sensitive(self):
|
||||
uppercase_course_id = "ORG/COURSE/NAME"
|
||||
@@ -56,54 +56,42 @@ class RolesTestCase(TestCase):
|
||||
uppercase_user = UserFactory()
|
||||
CourseRole(role, uppercase_course_key).add_users(uppercase_user)
|
||||
|
||||
self.assertTrue(CourseRole(role, lowercase_course_key).has_user(lowercase_user))
|
||||
self.assertFalse(CourseRole(role, uppercase_course_key).has_user(lowercase_user))
|
||||
self.assertFalse(CourseRole(role, lowercase_course_key).has_user(uppercase_user))
|
||||
self.assertTrue(CourseRole(role, uppercase_course_key).has_user(uppercase_user))
|
||||
assert CourseRole(role, lowercase_course_key).has_user(lowercase_user)
|
||||
assert not CourseRole(role, uppercase_course_key).has_user(lowercase_user)
|
||||
assert not CourseRole(role, lowercase_course_key).has_user(uppercase_user)
|
||||
assert CourseRole(role, uppercase_course_key).has_user(uppercase_user)
|
||||
|
||||
def test_course_role(self):
|
||||
"""
|
||||
Test that giving a user a course role enables access appropriately
|
||||
"""
|
||||
self.assertFalse(
|
||||
CourseStaffRole(self.course_key).has_user(self.student),
|
||||
"Student has premature access to {}".format(self.course_key)
|
||||
)
|
||||
assert not CourseStaffRole(self.course_key).has_user(self.student), \
|
||||
f'Student has premature access to {self.course_key}'
|
||||
CourseStaffRole(self.course_key).add_users(self.student)
|
||||
self.assertTrue(
|
||||
CourseStaffRole(self.course_key).has_user(self.student),
|
||||
"Student doesn't have access to {}".format(six.text_type(self.course_key))
|
||||
)
|
||||
assert CourseStaffRole(self.course_key).has_user(self.student), \
|
||||
f"Student doesn't have access to {six.text_type(self.course_key)}"
|
||||
|
||||
# remove access and confirm
|
||||
CourseStaffRole(self.course_key).remove_users(self.student)
|
||||
self.assertFalse(
|
||||
CourseStaffRole(self.course_key).has_user(self.student),
|
||||
"Student still has access to {}".format(self.course_key)
|
||||
)
|
||||
assert not CourseStaffRole(self.course_key).has_user(self.student), \
|
||||
f'Student still has access to {self.course_key}'
|
||||
|
||||
def test_org_role(self):
|
||||
"""
|
||||
Test that giving a user an org role enables access appropriately
|
||||
"""
|
||||
self.assertFalse(
|
||||
OrgStaffRole(self.course_key.org).has_user(self.student),
|
||||
"Student has premature access to {}".format(self.course_key.org)
|
||||
)
|
||||
assert not OrgStaffRole(self.course_key.org).has_user(self.student), \
|
||||
f'Student has premature access to {self.course_key.org}'
|
||||
OrgStaffRole(self.course_key.org).add_users(self.student)
|
||||
self.assertTrue(
|
||||
OrgStaffRole(self.course_key.org).has_user(self.student),
|
||||
"Student doesn't have access to {}".format(six.text_type(self.course_key.org))
|
||||
)
|
||||
assert OrgStaffRole(self.course_key.org).has_user(self.student), \
|
||||
f"Student doesn't have access to {six.text_type(self.course_key.org)}"
|
||||
|
||||
# remove access and confirm
|
||||
OrgStaffRole(self.course_key.org).remove_users(self.student)
|
||||
if hasattr(self.student, '_roles'):
|
||||
del self.student._roles
|
||||
self.assertFalse(
|
||||
OrgStaffRole(self.course_key.org).has_user(self.student),
|
||||
"Student still has access to {}".format(self.course_key.org)
|
||||
)
|
||||
assert not OrgStaffRole(self.course_key.org).has_user(self.student), \
|
||||
f'Student still has access to {self.course_key.org}'
|
||||
|
||||
def test_org_and_course_roles(self):
|
||||
"""
|
||||
@@ -111,37 +99,25 @@ class RolesTestCase(TestCase):
|
||||
"""
|
||||
OrgInstructorRole(self.course_key.org).add_users(self.student)
|
||||
CourseInstructorRole(self.course_key).add_users(self.student)
|
||||
self.assertTrue(
|
||||
OrgInstructorRole(self.course_key.org).has_user(self.student),
|
||||
"Student doesn't have access to {}".format(six.text_type(self.course_key.org))
|
||||
)
|
||||
self.assertTrue(
|
||||
CourseInstructorRole(self.course_key).has_user(self.student),
|
||||
"Student doesn't have access to {}".format(six.text_type(self.course_key))
|
||||
)
|
||||
assert OrgInstructorRole(self.course_key.org).has_user(self.student), \
|
||||
f"Student doesn't have access to {six.text_type(self.course_key.org)}"
|
||||
assert CourseInstructorRole(self.course_key).has_user(self.student), \
|
||||
f"Student doesn't have access to {six.text_type(self.course_key)}"
|
||||
|
||||
# remove access and confirm
|
||||
OrgInstructorRole(self.course_key.org).remove_users(self.student)
|
||||
self.assertFalse(
|
||||
OrgInstructorRole(self.course_key.org).has_user(self.student),
|
||||
"Student still has access to {}".format(self.course_key.org)
|
||||
)
|
||||
self.assertTrue(
|
||||
CourseInstructorRole(self.course_key).has_user(self.student),
|
||||
"Student doesn't have access to {}".format(six.text_type(self.course_key))
|
||||
)
|
||||
assert not OrgInstructorRole(self.course_key.org).has_user(self.student), \
|
||||
f'Student still has access to {self.course_key.org}'
|
||||
assert CourseInstructorRole(self.course_key).has_user(self.student), \
|
||||
f"Student doesn't have access to {six.text_type(self.course_key)}"
|
||||
|
||||
# ok now keep org role and get rid of course one
|
||||
OrgInstructorRole(self.course_key.org).add_users(self.student)
|
||||
CourseInstructorRole(self.course_key).remove_users(self.student)
|
||||
self.assertTrue(
|
||||
OrgInstructorRole(self.course_key.org).has_user(self.student),
|
||||
"Student lost has access to {}".format(self.course_key.org)
|
||||
)
|
||||
self.assertFalse(
|
||||
CourseInstructorRole(self.course_key).has_user(self.student),
|
||||
"Student doesn't have access to {}".format(six.text_type(self.course_key))
|
||||
)
|
||||
assert OrgInstructorRole(self.course_key.org).has_user(self.student), \
|
||||
f'Student lost has access to {self.course_key.org}'
|
||||
assert not CourseInstructorRole(self.course_key).has_user(self.student), \
|
||||
f"Student doesn't have access to {six.text_type(self.course_key)}"
|
||||
|
||||
def test_get_user_for_role(self):
|
||||
"""
|
||||
@@ -149,7 +125,7 @@ class RolesTestCase(TestCase):
|
||||
"""
|
||||
role = CourseStaffRole(self.course_key)
|
||||
role.add_users(self.student)
|
||||
self.assertGreater(len(role.users_with_role()), 0)
|
||||
assert len(role.users_with_role()) > 0
|
||||
|
||||
def test_add_users_doesnt_add_duplicate_entry(self):
|
||||
"""
|
||||
@@ -158,11 +134,11 @@ class RolesTestCase(TestCase):
|
||||
"""
|
||||
role = CourseStaffRole(self.course_key)
|
||||
role.add_users(self.student)
|
||||
self.assertTrue(role.has_user(self.student))
|
||||
assert role.has_user(self.student)
|
||||
# Call add_users a second time, then remove just once.
|
||||
role.add_users(self.student)
|
||||
role.remove_users(self.student)
|
||||
self.assertFalse(role.has_user(self.student))
|
||||
assert not role.has_user(self.student)
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -188,16 +164,16 @@ class RoleCacheTestCase(TestCase): # lint-amnesty, pylint: disable=missing-clas
|
||||
def test_only_in_role(self, role, target):
|
||||
role.add_users(self.user)
|
||||
cache = RoleCache(self.user)
|
||||
self.assertTrue(cache.has_role(*target))
|
||||
assert cache.has_role(*target)
|
||||
|
||||
for other_role, other_target in self.ROLES:
|
||||
if other_role == role:
|
||||
continue
|
||||
|
||||
self.assertFalse(cache.has_role(*other_target))
|
||||
assert not cache.has_role(*other_target)
|
||||
|
||||
@ddt.data(*ROLES)
|
||||
@ddt.unpack
|
||||
def test_empty_cache(self, role, target): # lint-amnesty, pylint: disable=unused-argument
|
||||
cache = RoleCache(self.user)
|
||||
self.assertFalse(cache.has_role(*target))
|
||||
assert not cache.has_role(*target)
|
||||
|
||||
@@ -34,14 +34,14 @@ class SendActivationEmailTestCase(TestCase):
|
||||
Tests that attributes of the message are being filled correctly in compose_activation_email
|
||||
"""
|
||||
# Check that variables used by the base template are present in generated context
|
||||
self.assertIn('platform_name', self.msg.context)
|
||||
self.assertIn('contact_mailing_address', self.msg.context)
|
||||
assert 'platform_name' in self.msg.context
|
||||
assert 'contact_mailing_address' in self.msg.context
|
||||
# Verify the presence of the activation-email specific attributes
|
||||
self.assertEqual(self.msg.recipient.username, self.student.username)
|
||||
self.assertEqual(self.msg.recipient.email_address, self.student.email)
|
||||
self.assertEqual(self.msg.context['routed_user'], self.student.username)
|
||||
self.assertEqual(self.msg.context['routed_user_email'], self.student.email)
|
||||
self.assertEqual(self.msg.context['routed_profile_name'], '')
|
||||
assert self.msg.recipient.username == self.student.username
|
||||
assert self.msg.recipient.email_address == self.student.email
|
||||
assert self.msg.context['routed_user'] == self.student.username
|
||||
assert self.msg.context['routed_user_email'] == self.student.email
|
||||
assert self.msg.context['routed_profile_name'] == ''
|
||||
|
||||
@mock.patch('time.sleep', mock.Mock(return_value=None))
|
||||
@mock.patch('common.djangoapps.student.tasks.log')
|
||||
@@ -63,7 +63,7 @@ class SendActivationEmailTestCase(TestCase):
|
||||
attempt=attempt,
|
||||
max_attempts=email_max_attempts
|
||||
))
|
||||
self.assertEqual(mock_log.info.call_count, 6)
|
||||
assert mock_log.info.call_count == 6
|
||||
|
||||
# Asserts that the error was logged on crossing max retry attempts.
|
||||
mock_log.error.assert_called_with(
|
||||
@@ -72,7 +72,7 @@ class SendActivationEmailTestCase(TestCase):
|
||||
self.student.email,
|
||||
exc_info=True
|
||||
)
|
||||
self.assertEqual(mock_log.error.call_count, 1)
|
||||
assert mock_log.error.call_count == 1
|
||||
|
||||
@mock.patch('common.djangoapps.student.tasks.log')
|
||||
@mock.patch('common.djangoapps.student.tasks.ace.send', mock.Mock(side_effect=ChannelError))
|
||||
@@ -92,6 +92,6 @@ class SendActivationEmailTestCase(TestCase):
|
||||
)
|
||||
|
||||
# Assert that nothing else was logged
|
||||
self.assertEqual(mock_log.info.call_count, 0)
|
||||
self.assertEqual(mock_log.error.call_count, 0)
|
||||
self.assertEqual(mock_log.exception.call_count, 1)
|
||||
assert mock_log.info.call_count == 0
|
||||
assert mock_log.error.call_count == 0
|
||||
assert mock_log.exception.call_count == 1
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
import datetime
|
||||
|
||||
import pytest
|
||||
import ddt
|
||||
from django.core.cache import cache
|
||||
from django.core.exceptions import ValidationError
|
||||
@@ -56,11 +56,11 @@ class UserProfilePropertiesTest(CacheIsolationTestCase):
|
||||
# year younger than that in that same year. We calculate age based off of
|
||||
# the youngest you could be that year.
|
||||
age = years_ago - 1
|
||||
self.assertEqual(self.profile.age, age)
|
||||
assert self.profile.age == age
|
||||
|
||||
def test_age_no_birth_year(self):
|
||||
"""Verify nothing is returned."""
|
||||
self.assertIsNone(self.profile.age)
|
||||
assert self.profile.age is None
|
||||
|
||||
@ddt.data(*UserProfile.LEVEL_OF_EDUCATION_CHOICES)
|
||||
@ddt.unpack
|
||||
@@ -68,11 +68,11 @@ class UserProfilePropertiesTest(CacheIsolationTestCase):
|
||||
"""Verify the level of education is displayed correctly."""
|
||||
self._set_level_of_education(level_enum)
|
||||
|
||||
self.assertEqual(self.profile.level_of_education_display, display_level)
|
||||
assert self.profile.level_of_education_display == display_level
|
||||
|
||||
def test_display_level_of_education_none_set(self):
|
||||
"""Verify nothing is returned."""
|
||||
self.assertIsNone(self.profile.level_of_education_display)
|
||||
assert self.profile.level_of_education_display is None
|
||||
|
||||
@ddt.data(*UserProfile.GENDER_CHOICES)
|
||||
@ddt.unpack
|
||||
@@ -80,13 +80,13 @@ class UserProfilePropertiesTest(CacheIsolationTestCase):
|
||||
"""Verify the gender displayed correctly."""
|
||||
self._set_gender(gender_enum)
|
||||
|
||||
self.assertEqual(self.profile.gender_display, display_gender)
|
||||
assert self.profile.gender_display == display_gender
|
||||
|
||||
def test_display_gender_none_set(self):
|
||||
"""Verify nothing is returned."""
|
||||
self._set_gender(None)
|
||||
|
||||
self.assertIsNone(self.profile.gender_display)
|
||||
assert self.profile.gender_display is None
|
||||
|
||||
def test_invalidate_cache_user_profile_country_updated(self):
|
||||
|
||||
@@ -95,32 +95,32 @@ class UserProfilePropertiesTest(CacheIsolationTestCase):
|
||||
self.profile.save()
|
||||
|
||||
cache_key = UserProfile.country_cache_key_name(self.user.id)
|
||||
self.assertIsNone(cache.get(cache_key))
|
||||
assert cache.get(cache_key) is None
|
||||
|
||||
cache.set(cache_key, self.profile.country)
|
||||
self.assertEqual(cache.get(cache_key), country)
|
||||
assert cache.get(cache_key) == country
|
||||
|
||||
country = 'bd'
|
||||
self.profile.country = country
|
||||
self.profile.save()
|
||||
|
||||
self.assertNotEqual(cache.get(cache_key), country)
|
||||
self.assertIsNone(cache.get(cache_key))
|
||||
assert cache.get(cache_key) != country
|
||||
assert cache.get(cache_key) is None
|
||||
|
||||
def test_phone_number_can_only_contain_digits(self):
|
||||
# validating the profile will fail, because there are letters
|
||||
# in the phone number
|
||||
self.profile.phone_number = 'abc'
|
||||
self.assertRaises(ValidationError, self.profile.full_clean)
|
||||
pytest.raises(ValidationError, self.profile.full_clean)
|
||||
# fail if mixed digits/letters
|
||||
self.profile.phone_number = '1234gb'
|
||||
self.assertRaises(ValidationError, self.profile.full_clean)
|
||||
pytest.raises(ValidationError, self.profile.full_clean)
|
||||
# fail if whitespace
|
||||
self.profile.phone_number = ' 123'
|
||||
self.assertRaises(ValidationError, self.profile.full_clean)
|
||||
pytest.raises(ValidationError, self.profile.full_clean)
|
||||
# fail with special characters
|
||||
self.profile.phone_number = '123!@#$%^&*'
|
||||
self.assertRaises(ValidationError, self.profile.full_clean)
|
||||
pytest.raises(ValidationError, self.profile.full_clean)
|
||||
# valid phone number
|
||||
self.profile.phone_number = '123456789'
|
||||
try:
|
||||
|
||||
@@ -65,25 +65,20 @@ class UserStandingTest(TestCase):
|
||||
response = self.admin_client.get(reverse('manage_user_standing'), {
|
||||
'user': self.admin,
|
||||
})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_disable_account(self):
|
||||
self.assertEqual(
|
||||
UserStanding.objects.filter(user=self.good_user).count(), 0
|
||||
)
|
||||
assert UserStanding.objects.filter(user=self.good_user).count() == 0
|
||||
response = self.admin_client.post(reverse('disable_account_ajax'), { # lint-amnesty, pylint: disable=unused-variable
|
||||
'username': self.good_user.username,
|
||||
'account_action': 'disable',
|
||||
})
|
||||
self.assertEqual(
|
||||
UserStanding.objects.get(user=self.good_user).account_status,
|
||||
UserStanding.ACCOUNT_DISABLED
|
||||
)
|
||||
assert UserStanding.objects.get(user=self.good_user).account_status == UserStanding.ACCOUNT_DISABLED
|
||||
|
||||
def test_disabled_account_403s(self):
|
||||
response = self.bad_user_client.get(self.some_url)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
assert response.status_code == 403
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_reenable_account(self):
|
||||
@@ -91,17 +86,14 @@ class UserStandingTest(TestCase):
|
||||
'username': self.bad_user.username,
|
||||
'account_action': 'reenable'
|
||||
})
|
||||
self.assertEqual(
|
||||
UserStanding.objects.get(user=self.bad_user).account_status,
|
||||
UserStanding.ACCOUNT_ENABLED
|
||||
)
|
||||
assert UserStanding.objects.get(user=self.bad_user).account_status == UserStanding.ACCOUNT_ENABLED
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_non_staff_cant_access_disable_view(self):
|
||||
response = self.non_staff_client.get(reverse('manage_user_standing'), {
|
||||
'user': self.non_staff,
|
||||
})
|
||||
self.assertEqual(response.status_code, 404)
|
||||
assert response.status_code == 404
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_non_staff_cant_disable_account(self):
|
||||
@@ -110,7 +102,5 @@ class UserStandingTest(TestCase):
|
||||
'user': self.non_staff,
|
||||
'account_action': 'disable'
|
||||
})
|
||||
self.assertEqual(response.status_code, 404)
|
||||
self.assertEqual(
|
||||
UserStanding.objects.filter(user=self.good_user).count(), 0
|
||||
)
|
||||
assert response.status_code == 404
|
||||
assert UserStanding.objects.filter(user=self.good_user).count() == 0
|
||||
|
||||
@@ -53,7 +53,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
|
||||
self.user = UserFactory(password="edx")
|
||||
self.course = CourseFactory.create()
|
||||
success = self.client.login(username=self.user.username, password="edx")
|
||||
self.assertTrue(success, msg="Did not log in successfully")
|
||||
assert success, 'Did not log in successfully'
|
||||
self.dashboard_url = reverse('dashboard')
|
||||
|
||||
def test_enrolled_as_non_verified(self):
|
||||
@@ -407,7 +407,7 @@ class TestCourseVerificationStatus(UrlResetMixin, ModuleStoreTestCase):
|
||||
fail_msg = "Could not find any of these messages: {expected}".format(
|
||||
expected=self.NOTIFICATION_MESSAGES[status]
|
||||
)
|
||||
self.assertTrue(found_msg, msg=fail_msg)
|
||||
assert found_msg, fail_msg
|
||||
else:
|
||||
# Combine all possible messages into a single list
|
||||
all_messages = []
|
||||
|
||||
@@ -96,7 +96,7 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
|
||||
with patch('common.djangoapps.student.views.dashboard.cert_info', side_effect=self.mock_cert):
|
||||
response = self.client.get(reverse('dashboard'))
|
||||
|
||||
self.assertEqual(pq(response.content)(self.UNENROLL_ELEMENT_ID).length, unenroll_action_count)
|
||||
assert pq(response.content)(self.UNENROLL_ELEMENT_ID).length == unenroll_action_count
|
||||
|
||||
@ddt.data(
|
||||
('notpassing', 200),
|
||||
@@ -119,10 +119,10 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
|
||||
{'enrollment_action': 'unenroll', 'course_id': self.course.id}
|
||||
)
|
||||
|
||||
self.assertEqual(response.status_code, status_code)
|
||||
assert response.status_code == status_code
|
||||
if status_code == 200:
|
||||
course_enrollment.assert_called_with(self.user, self.course.id)
|
||||
self.assertTrue(mock_refund_handler.called)
|
||||
assert mock_refund_handler.called
|
||||
else:
|
||||
course_enrollment.assert_not_called()
|
||||
|
||||
@@ -134,21 +134,21 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
|
||||
):
|
||||
response = self.client.get(reverse('dashboard'))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_course_run_refund_status_successful(self):
|
||||
""" Assert that view:course_run_refund_status returns correct Json for successful refund call."""
|
||||
with patch('common.djangoapps.student.models.CourseEnrollment.refundable', return_value=True):
|
||||
response = self.client.get(reverse('course_run_refund_status', kwargs={'course_id': self.course.id}))
|
||||
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8')), {'course_refundable_status': True})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert json.loads(response.content.decode('utf-8')) == {'course_refundable_status': True}
|
||||
assert response.status_code == 200
|
||||
|
||||
with patch('common.djangoapps.student.models.CourseEnrollment.refundable', return_value=False):
|
||||
response = self.client.get(reverse('course_run_refund_status', kwargs={'course_id': self.course.id}))
|
||||
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8')), {'course_refundable_status': False})
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert json.loads(response.content.decode('utf-8')) == {'course_refundable_status': False}
|
||||
assert response.status_code == 200
|
||||
|
||||
def test_course_run_refund_status_invalid_course_key(self):
|
||||
""" Assert that view:course_run_refund_status returns correct Json for Invalid Course Key ."""
|
||||
@@ -157,8 +157,8 @@ class TestStudentDashboardUnenrollments(SharedModuleStoreTestCase):
|
||||
InvalidKeyError during look up.')
|
||||
response = self.client.get(reverse('course_run_refund_status', kwargs={'course_id': self.course.id}))
|
||||
|
||||
self.assertEqual(json.loads(response.content.decode('utf-8')), {'course_refundable_status': ''})
|
||||
self.assertEqual(response.status_code, 406)
|
||||
assert json.loads(response.content.decode('utf-8')) == {'course_refundable_status': ''}
|
||||
assert response.status_code == 406
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -275,8 +275,8 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
|
||||
# Assert course sharing icons
|
||||
response = self.client.get(reverse('dashboard'))
|
||||
self.assertEqual('Share on Twitter' in response.content.decode('utf-8'), set_marketing or set_social_sharing)
|
||||
self.assertEqual('Share on Facebook' in response.content.decode('utf-8'), set_marketing or set_social_sharing)
|
||||
assert ('Share on Twitter' in response.content.decode('utf-8')) == (set_marketing or set_social_sharing)
|
||||
assert ('Share on Facebook' in response.content.decode('utf-8')) == (set_marketing or set_social_sharing)
|
||||
|
||||
@patch.dict("django.conf.settings.FEATURES", {'ENABLE_PREREQUISITE_COURSES': True})
|
||||
def test_pre_requisites_appear_on_dashboard(self):
|
||||
@@ -545,7 +545,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
mock_get_course_runs.return_value = course_runs
|
||||
|
||||
response = self.client.get(self.path)
|
||||
self.assertEqual(pq(response.content)(self.EMAIL_SETTINGS_ELEMENT_ID).length, 1)
|
||||
assert pq(response.content)(self.EMAIL_SETTINGS_ELEMENT_ID).length == 1
|
||||
|
||||
@patch.object(CourseOverview, 'get_from_id')
|
||||
@patch('common.djangoapps.student.views.dashboard.is_bulk_email_feature_enabled')
|
||||
@@ -557,7 +557,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
mock_course_overview.return_value = CourseOverviewFactory(start=self.TOMORROW)
|
||||
CourseEntitlementFactory(user=self.user)
|
||||
response = self.client.get(self.path)
|
||||
self.assertEqual(pq(response.content)(self.EMAIL_SETTINGS_ELEMENT_ID).length, 0)
|
||||
assert pq(response.content)(self.EMAIL_SETTINGS_ELEMENT_ID).length == 0
|
||||
|
||||
@patch.multiple('django.conf.settings', **MOCK_SETTINGS_HIDE_COURSES)
|
||||
def test_hide_dashboard_courses_until_activated(self):
|
||||
@@ -566,7 +566,7 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
inactive users don't see the Courses list, but active users still do.
|
||||
"""
|
||||
# Ensure active users see the course list
|
||||
self.assertTrue(self.user.is_active)
|
||||
assert self.user.is_active
|
||||
response = self.client.get(reverse('dashboard'))
|
||||
self.assertContains(response, 'You are not enrolled in any courses yet.')
|
||||
|
||||
@@ -704,14 +704,8 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
resume_button_html = self._remove_whitespace_from_html_string(resume_button_html)
|
||||
dashboard_html = self._remove_whitespace_from_response(response)
|
||||
|
||||
self.assertIn(
|
||||
view_button_html,
|
||||
dashboard_html
|
||||
)
|
||||
self.assertNotIn(
|
||||
resume_button_html,
|
||||
dashboard_html
|
||||
)
|
||||
assert view_button_html in dashboard_html
|
||||
assert resume_button_html not in dashboard_html
|
||||
|
||||
def test_resume_course_appears_on_dashboard(self):
|
||||
"""
|
||||
@@ -758,14 +752,8 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
resume_button_html = self._remove_whitespace_from_html_string(resume_button_html)
|
||||
dashboard_html = self._remove_whitespace_from_response(response)
|
||||
|
||||
self.assertIn(
|
||||
resume_button_html,
|
||||
dashboard_html
|
||||
)
|
||||
self.assertNotIn(
|
||||
view_button_html,
|
||||
dashboard_html
|
||||
)
|
||||
assert resume_button_html in dashboard_html
|
||||
assert view_button_html not in dashboard_html
|
||||
|
||||
@override_waffle_flag(COURSE_UPDATE_WAFFLE_FLAG, True)
|
||||
def test_content_gating_course_card_changes(self):
|
||||
@@ -795,15 +783,9 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
access_expired_substring = 'Accessexpired'
|
||||
course_link_class = 'course-target-link'
|
||||
|
||||
self.assertNotIn(
|
||||
course_link_class,
|
||||
dashboard_html
|
||||
)
|
||||
assert course_link_class not in dashboard_html
|
||||
|
||||
self.assertIn(
|
||||
access_expired_substring,
|
||||
dashboard_html
|
||||
)
|
||||
assert access_expired_substring in dashboard_html
|
||||
|
||||
def test_dashboard_with_resume_buttons_and_view_buttons(self):
|
||||
'''
|
||||
@@ -907,14 +889,8 @@ class StudentDashboardTests(SharedModuleStoreTestCase, MilestonesTestCaseMixin,
|
||||
expected_button = html_for_view_buttons[i]
|
||||
unexpected_button = html_for_resume_buttons[i] + html_for_entitlement[i]
|
||||
|
||||
self.assertIn(
|
||||
expected_button,
|
||||
dashboard_html
|
||||
)
|
||||
self.assertNotIn(
|
||||
unexpected_button,
|
||||
dashboard_html
|
||||
)
|
||||
assert expected_button in dashboard_html
|
||||
assert unexpected_button not in dashboard_html
|
||||
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
|
||||
@@ -64,11 +64,11 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
user = Mock(username=username)
|
||||
user_id = unique_id_for_user(user)
|
||||
link1 = "http://www.mysurvey.com"
|
||||
self.assertEqual(process_survey_link(link1, user), link1)
|
||||
assert process_survey_link(link1, user) == link1
|
||||
|
||||
link2 = "http://www.mysurvey.com?unique={UNIQUE_ID}"
|
||||
link2_expected = "http://www.mysurvey.com?unique={UNIQUE_ID}".format(UNIQUE_ID=user_id)
|
||||
self.assertEqual(process_survey_link(link2, user), link2_expected)
|
||||
assert process_survey_link(link2, user) == link2_expected
|
||||
|
||||
@patch.dict('django.conf.settings.FEATURES', {'CERTIFICATES_HTML_VIEW': False})
|
||||
def test_cert_info(self):
|
||||
@@ -87,56 +87,24 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
download_url='http://s3.edx/cert'
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, None),
|
||||
{
|
||||
'status': 'processing',
|
||||
'show_survey_button': False,
|
||||
'can_unenroll': True,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, None) ==\
|
||||
{'status': 'processing', 'show_survey_button': False, 'can_unenroll': True}
|
||||
|
||||
cert_status = {'status': 'unavailable', 'mode': 'honor', 'uuid': None}
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, cert_status),
|
||||
{
|
||||
'status': 'processing',
|
||||
'show_survey_button': False,
|
||||
'mode': 'honor',
|
||||
'linked_in_url': None,
|
||||
'can_unenroll': True,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, cert_status) == {'status': 'processing', 'show_survey_button': False,
|
||||
'mode': 'honor', 'linked_in_url': None, 'can_unenroll': True}
|
||||
|
||||
cert_status = {'status': 'generating', 'grade': '0.67', 'mode': 'honor', 'uuid': None}
|
||||
with patch('lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read') as patch_persisted_grade:
|
||||
patch_persisted_grade.return_value = Mock(percent=1.0)
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, cert_status),
|
||||
{
|
||||
'status': 'generating',
|
||||
'show_survey_button': True,
|
||||
'survey_url': survey_url,
|
||||
'grade': '1.0',
|
||||
'mode': 'honor',
|
||||
'linked_in_url': None,
|
||||
'can_unenroll': False,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, cert_status) == {'status': 'generating', 'show_survey_button': True,
|
||||
'survey_url': survey_url, 'grade': '1.0', 'mode': 'honor',
|
||||
'linked_in_url': None, 'can_unenroll': False}
|
||||
|
||||
cert_status = {'status': 'generating', 'grade': '0.67', 'mode': 'honor', 'uuid': None}
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, cert_status),
|
||||
{
|
||||
'status': 'generating',
|
||||
'show_survey_button': True,
|
||||
'survey_url': survey_url,
|
||||
'grade': '0.67',
|
||||
'mode': 'honor',
|
||||
'linked_in_url': None,
|
||||
'can_unenroll': False,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, cert_status) == {'status': 'generating', 'show_survey_button': True,
|
||||
'survey_url': survey_url, 'grade': '0.67', 'mode': 'honor',
|
||||
'linked_in_url': None, 'can_unenroll': False}
|
||||
|
||||
cert_status = {
|
||||
'status': 'downloadable',
|
||||
@@ -145,19 +113,10 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
'mode': 'honor',
|
||||
'uuid': 'fakeuuidbutitsfine',
|
||||
}
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, cert_status),
|
||||
{
|
||||
'status': 'downloadable',
|
||||
'download_url': cert.download_url,
|
||||
'show_survey_button': True,
|
||||
'survey_url': survey_url,
|
||||
'grade': '0.67',
|
||||
'mode': 'honor',
|
||||
'linked_in_url': None,
|
||||
'can_unenroll': False,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, cert_status) == {'status': 'downloadable', 'download_url': cert.download_url,
|
||||
'show_survey_button': True, 'survey_url': survey_url,
|
||||
'grade': '0.67', 'mode': 'honor', 'linked_in_url': None,
|
||||
'can_unenroll': False}
|
||||
|
||||
cert_status = {
|
||||
'status': 'notpassing', 'grade': '0.67',
|
||||
@@ -165,18 +124,9 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
'mode': 'honor',
|
||||
'uuid': 'fakeuuidbutitsfine',
|
||||
}
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, cert_status),
|
||||
{
|
||||
'status': 'notpassing',
|
||||
'show_survey_button': True,
|
||||
'survey_url': survey_url,
|
||||
'grade': '0.67',
|
||||
'mode': 'honor',
|
||||
'linked_in_url': None,
|
||||
'can_unenroll': True,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, cert_status) == {'status': 'notpassing', 'show_survey_button': True,
|
||||
'survey_url': survey_url, 'grade': '0.67', 'mode': 'honor',
|
||||
'linked_in_url': None, 'can_unenroll': True}
|
||||
|
||||
# Test a course that doesn't have a survey specified
|
||||
course2 = Mock(end_of_course_survey_url=None, id=CourseLocator(org="a", course="b", run="c"))
|
||||
@@ -184,29 +134,15 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
'status': 'notpassing', 'grade': '0.67',
|
||||
'download_url': cert.download_url, 'mode': 'honor', 'uuid': 'fakeuuidbutitsfine'
|
||||
}
|
||||
self.assertEqual(
|
||||
_cert_info(user, course2, cert_status),
|
||||
{
|
||||
'status': 'notpassing',
|
||||
'show_survey_button': False,
|
||||
'grade': '0.67',
|
||||
'mode': 'honor',
|
||||
'linked_in_url': None,
|
||||
'can_unenroll': True,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course2, cert_status) == {'status': 'notpassing', 'show_survey_button': False,
|
||||
'grade': '0.67', 'mode': 'honor', 'linked_in_url': None,
|
||||
'can_unenroll': True}
|
||||
|
||||
# test when the display is unavailable or notpassing, we get the correct results out
|
||||
course2.certificates_display_behavior = 'early_no_info'
|
||||
cert_status = {'status': 'unavailable', 'mode': 'honor', 'uuid': None}
|
||||
self.assertEqual(
|
||||
_cert_info(user, course2, cert_status),
|
||||
{
|
||||
'status': 'processing',
|
||||
'show_survey_button': False,
|
||||
'can_unenroll': True,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course2, cert_status) == {'status': 'processing', 'show_survey_button': False,
|
||||
'can_unenroll': True}
|
||||
|
||||
cert_status = {
|
||||
'status': 'notpassing', 'grade': '0.67',
|
||||
@@ -214,14 +150,8 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
'mode': 'honor',
|
||||
'uuid': 'fakeuuidbutitsfine'
|
||||
}
|
||||
self.assertEqual(
|
||||
_cert_info(user, course2, cert_status),
|
||||
{
|
||||
'status': 'processing',
|
||||
'show_survey_button': False,
|
||||
'can_unenroll': True,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course2, cert_status) == {'status': 'processing', 'show_survey_button': False,
|
||||
'can_unenroll': True}
|
||||
|
||||
@ddt.data(
|
||||
(0.70, 0.60),
|
||||
@@ -254,18 +184,10 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
|
||||
with patch('lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read') as patch_persisted_grade:
|
||||
patch_persisted_grade.return_value = Mock(percent=persisted_grade)
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, cert_status),
|
||||
{
|
||||
'status': 'generating',
|
||||
'show_survey_button': True,
|
||||
'survey_url': survey_url,
|
||||
'grade': str(expected_grade),
|
||||
'mode': 'honor',
|
||||
'linked_in_url': None,
|
||||
'can_unenroll': False,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, cert_status) == {'status': 'generating', 'show_survey_button': True,
|
||||
'survey_url': survey_url, 'grade': str(expected_grade),
|
||||
'mode': 'honor', 'linked_in_url': None,
|
||||
'can_unenroll': False}
|
||||
|
||||
def test_cert_grade_no_grades(self):
|
||||
"""
|
||||
@@ -283,14 +205,8 @@ class CourseEndingTest(ModuleStoreTestCase):
|
||||
|
||||
with patch('lms.djangoapps.grades.course_grade_factory.CourseGradeFactory.read') as patch_persisted_grade:
|
||||
patch_persisted_grade.return_value = None
|
||||
self.assertEqual(
|
||||
_cert_info(user, course, cert_status),
|
||||
{
|
||||
'status': 'processing',
|
||||
'show_survey_button': False,
|
||||
'can_unenroll': True,
|
||||
}
|
||||
)
|
||||
assert _cert_info(user, course, cert_status) == {'status': 'processing', 'show_survey_button': False,
|
||||
'can_unenroll': True}
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@@ -359,7 +275,7 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
|
||||
|
||||
if mode == 'audit':
|
||||
# Audit mode does not have a banner. Assert no banner element.
|
||||
self.assertEqual(pq(response.content)(".sts-enrollment").length, 0)
|
||||
assert pq(response.content)('.sts-enrollment').length == 0
|
||||
else:
|
||||
self.assertNotContains(response, "class=\"course {0}\"".format(mode))
|
||||
self.assertNotContains(response, value)
|
||||
@@ -384,14 +300,14 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
|
||||
)
|
||||
enrollment = CourseEnrollment.enroll(self.user, self.course.id)
|
||||
course_mode_info = complete_course_mode_info(self.course.id, enrollment)
|
||||
self.assertTrue(course_mode_info['show_upsell'])
|
||||
self.assertEqual(course_mode_info['days_for_upsell'], 1)
|
||||
assert course_mode_info['show_upsell']
|
||||
assert course_mode_info['days_for_upsell'] == 1
|
||||
|
||||
verified_mode.expiration_datetime = datetime.now(pytz.UTC) + timedelta(days=-1)
|
||||
verified_mode.save()
|
||||
course_mode_info = complete_course_mode_info(self.course.id, enrollment)
|
||||
self.assertFalse(course_mode_info['show_upsell'])
|
||||
self.assertIsNone(course_mode_info['days_for_upsell'])
|
||||
assert not course_mode_info['show_upsell']
|
||||
assert course_mode_info['days_for_upsell'] is None
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_linked_in_add_to_profile_btn_not_appearing_without_config(self):
|
||||
@@ -423,7 +339,7 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
|
||||
)
|
||||
response = self.client.get(reverse('dashboard'))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
self.assertNotContains(response, 'Add Certificate to LinkedIn')
|
||||
|
||||
response_url = 'https://www.linkedin.com/profile/add?startTask=CERTIFICATION_NAME'
|
||||
@@ -460,7 +376,7 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
|
||||
)
|
||||
response = self.client.get(reverse('dashboard'))
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
self.assertContains(response, 'Add Certificate to LinkedIn')
|
||||
|
||||
# We can switch to this and the commented out assertContains once edx-platform reaches Python 3.8
|
||||
@@ -519,9 +435,9 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
|
||||
# CourseOverview object that has been created.
|
||||
with check_mongo_calls(0):
|
||||
response_1 = self.client.get(reverse('dashboard'))
|
||||
self.assertEqual(response_1.status_code, 200)
|
||||
assert response_1.status_code == 200
|
||||
response_2 = self.client.get(reverse('dashboard'))
|
||||
self.assertEqual(response_2.status_code, 200)
|
||||
assert response_2.status_code == 200
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_dashboard_header_nav_has_find_courses(self):
|
||||
@@ -538,8 +454,8 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
|
||||
def test_course_mode_info_with_honor_enrollment(self):
|
||||
"""It will be true only if enrollment mode is honor and course has verified mode."""
|
||||
course_mode_info = self._enrollment_with_complete_course('honor')
|
||||
self.assertTrue(course_mode_info['show_upsell'])
|
||||
self.assertEqual(course_mode_info['days_for_upsell'], 1)
|
||||
assert course_mode_info['show_upsell']
|
||||
assert course_mode_info['days_for_upsell'] == 1
|
||||
|
||||
@ddt.data('verified', 'credit')
|
||||
def test_course_mode_info_with_different_enrollments(self, enrollment_mode):
|
||||
@@ -547,8 +463,8 @@ class DashboardTest(ModuleStoreTestCase, TestVerificationBase):
|
||||
will be always false.
|
||||
"""
|
||||
course_mode_info = self._enrollment_with_complete_course(enrollment_mode)
|
||||
self.assertFalse(course_mode_info['show_upsell'])
|
||||
self.assertIsNone(course_mode_info['days_for_upsell'])
|
||||
assert not course_mode_info['show_upsell']
|
||||
assert course_mode_info['days_for_upsell'] is None
|
||||
|
||||
def _enrollment_with_complete_course(self, enrollment_mode):
|
||||
""""Dry method for course enrollment."""
|
||||
@@ -646,7 +562,7 @@ class UserSettingsEventTestMixin(EventTestMixin):
|
||||
"""
|
||||
Helper method to assert that the user is enrolled in the given course.
|
||||
"""
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(self.user, CourseKey.from_string(course_key)))
|
||||
assert CourseEnrollment.is_enrolled(self.user, CourseKey.from_string(course_key))
|
||||
|
||||
|
||||
class EnrollmentEventTestMixin(EventTestMixin):
|
||||
@@ -701,29 +617,29 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, CacheIsolationTestCase):
|
||||
course_id_partial = CourseKey.from_string("edX/Test101/")
|
||||
|
||||
# Test basic enrollment
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
self.assertFalse(CourseEnrollment.is_enrolled_by_partial(user, course_id_partial))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
assert not CourseEnrollment.is_enrolled_by_partial(user, course_id_partial)
|
||||
CourseEnrollment.enroll(user, course_id)
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
self.assertTrue(CourseEnrollment.is_enrolled_by_partial(user, course_id_partial))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
assert CourseEnrollment.is_enrolled_by_partial(user, course_id_partial)
|
||||
self.assert_enrollment_event_was_emitted(user, course_id)
|
||||
|
||||
# Enrolling them again should be harmless
|
||||
CourseEnrollment.enroll(user, course_id)
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
self.assertTrue(CourseEnrollment.is_enrolled_by_partial(user, course_id_partial))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
assert CourseEnrollment.is_enrolled_by_partial(user, course_id_partial)
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
# Now unenroll the user
|
||||
CourseEnrollment.unenroll(user, course_id)
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
self.assertFalse(CourseEnrollment.is_enrolled_by_partial(user, course_id_partial))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
assert not CourseEnrollment.is_enrolled_by_partial(user, course_id_partial)
|
||||
self.assert_unenrollment_event_was_emitted(user, course_id)
|
||||
|
||||
# Unenrolling them again should also be harmless
|
||||
CourseEnrollment.unenroll(user, course_id)
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
self.assertFalse(CourseEnrollment.is_enrolled_by_partial(user, course_id_partial))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
assert not CourseEnrollment.is_enrolled_by_partial(user, course_id_partial)
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
# The enrollment record should still exist, just be inactive
|
||||
@@ -731,22 +647,22 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, CacheIsolationTestCase):
|
||||
user=user,
|
||||
course_id=course_id
|
||||
)
|
||||
self.assertFalse(enrollment_record.is_active)
|
||||
assert not enrollment_record.is_active
|
||||
|
||||
# Make sure mode is updated properly if user unenrolls & re-enrolls
|
||||
enrollment = CourseEnrollment.enroll(user, course_id, "verified")
|
||||
self.assertEqual(enrollment.mode, "verified")
|
||||
assert enrollment.mode == 'verified'
|
||||
CourseEnrollment.unenroll(user, course_id)
|
||||
enrollment = CourseEnrollment.enroll(user, course_id, "audit")
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
self.assertEqual(enrollment.mode, "audit")
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
assert enrollment.mode == 'audit'
|
||||
|
||||
def test_enrollment_non_existent_user(self):
|
||||
# Testing enrollment of newly unsaved user (i.e. no database entry)
|
||||
user = User(username="rusty", email="rusty@fake.edx.org")
|
||||
course_id = CourseLocator("edX", "Test101", "2013")
|
||||
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
|
||||
# Unenroll does nothing
|
||||
CourseEnrollment.unenroll(user, course_id)
|
||||
@@ -755,7 +671,7 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, CacheIsolationTestCase):
|
||||
# Implicit save() happens on new User object when enrolling, so this
|
||||
# should still work
|
||||
CourseEnrollment.enroll(user, course_id)
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_enrollment_event_was_emitted(user, course_id)
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
@@ -764,13 +680,11 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, CacheIsolationTestCase):
|
||||
course_id = CourseLocator("edX", "Test101", "2013")
|
||||
|
||||
CourseEnrollment.enroll_by_email("jack@fake.edx.org", course_id)
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_enrollment_event_was_emitted(user, course_id)
|
||||
|
||||
# This won't throw an exception, even though the user is not found
|
||||
self.assertIsNone(
|
||||
CourseEnrollment.enroll_by_email("not_jack@fake.edx.org", course_id)
|
||||
)
|
||||
assert CourseEnrollment.enroll_by_email('not_jack@fake.edx.org', course_id) is None
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
self.assertRaises(
|
||||
@@ -784,12 +698,12 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, CacheIsolationTestCase):
|
||||
|
||||
# Now unenroll them by email
|
||||
CourseEnrollment.unenroll_by_email("jack@fake.edx.org", course_id)
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_unenrollment_event_was_emitted(user, course_id)
|
||||
|
||||
# Harmless second unenroll
|
||||
CourseEnrollment.unenroll_by_email("jack@fake.edx.org", course_id)
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
# Unenroll on non-existent user shouldn't throw an error
|
||||
@@ -806,55 +720,55 @@ class EnrollInCourseTest(EnrollmentEventTestMixin, CacheIsolationTestCase):
|
||||
self.assert_enrollment_event_was_emitted(user, course_id1)
|
||||
CourseEnrollment.enroll(user, course_id2)
|
||||
self.assert_enrollment_event_was_emitted(user, course_id2)
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id1))
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id2))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id1)
|
||||
assert CourseEnrollment.is_enrolled(user, course_id2)
|
||||
|
||||
CourseEnrollment.unenroll(user, course_id1)
|
||||
self.assert_unenrollment_event_was_emitted(user, course_id1)
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id1))
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id2))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id1)
|
||||
assert CourseEnrollment.is_enrolled(user, course_id2)
|
||||
|
||||
CourseEnrollment.unenroll(user, course_id2)
|
||||
self.assert_unenrollment_event_was_emitted(user, course_id2)
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id1))
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id2))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id1)
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id2)
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
def test_activation(self):
|
||||
user = User.objects.create(username="jack", email="jack@fake.edx.org")
|
||||
course_id = CourseLocator("edX", "Test101", "2013")
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
|
||||
# Creating an enrollment doesn't actually enroll a student
|
||||
# (calling CourseEnrollment.enroll() would have)
|
||||
enrollment = CourseEnrollment.get_or_create_enrollment(user, course_id)
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
# Until you explicitly activate it
|
||||
enrollment.activate()
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_enrollment_event_was_emitted(user, course_id)
|
||||
|
||||
# Activating something that's already active does nothing
|
||||
enrollment.activate()
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
# Now deactive
|
||||
enrollment.deactivate()
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_unenrollment_event_was_emitted(user, course_id)
|
||||
|
||||
# Deactivating something that's already inactive does nothing
|
||||
enrollment.deactivate()
|
||||
self.assertFalse(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert not CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_no_events_were_emitted()
|
||||
|
||||
# A deactivated enrollment should be activated if enroll() is called
|
||||
# for that user/course_id combination
|
||||
CourseEnrollment.enroll(user, course_id)
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(user, course_id))
|
||||
assert CourseEnrollment.is_enrolled(user, course_id)
|
||||
self.assert_enrollment_event_was_emitted(user, course_id)
|
||||
|
||||
def test_change_enrollment_modes(self):
|
||||
@@ -899,12 +813,12 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
|
||||
def test_enroll_as_default(self):
|
||||
"""Tests that a student can successfully enroll through this view"""
|
||||
response = self._enroll_through_view(self.course)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
|
||||
self.user, self.course.id
|
||||
)
|
||||
self.assertTrue(is_active)
|
||||
self.assertEqual(enrollment_mode, CourseMode.DEFAULT_MODE_SLUG)
|
||||
assert is_active
|
||||
assert enrollment_mode == CourseMode.DEFAULT_MODE_SLUG
|
||||
|
||||
def test_cannot_enroll_if_already_enrolled(self):
|
||||
"""
|
||||
@@ -912,10 +826,10 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
|
||||
they are already enrolled in the course
|
||||
"""
|
||||
CourseEnrollment.enroll(self.user, self.course.id)
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
|
||||
assert CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
# now try to enroll that student
|
||||
response = self._enroll_through_view(self.course)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_change_to_default_if_verified(self):
|
||||
"""
|
||||
@@ -923,15 +837,15 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
|
||||
accidentally change their enrollment mode
|
||||
"""
|
||||
CourseEnrollment.enroll(self.user, self.course.id, mode=u'verified')
|
||||
self.assertTrue(CourseEnrollment.is_enrolled(self.user, self.course.id))
|
||||
assert CourseEnrollment.is_enrolled(self.user, self.course.id)
|
||||
# now try to enroll the student in the default mode:
|
||||
response = self._enroll_through_view(self.course)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
assert response.status_code == 400
|
||||
enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
|
||||
self.user, self.course.id
|
||||
)
|
||||
self.assertTrue(is_active)
|
||||
self.assertEqual(enrollment_mode, u'verified')
|
||||
assert is_active
|
||||
assert enrollment_mode == u'verified'
|
||||
|
||||
def test_change_to_default_if_verified_not_active(self):
|
||||
"""
|
||||
@@ -945,16 +859,16 @@ class ChangeEnrollmentViewTest(ModuleStoreTestCase):
|
||||
enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
|
||||
self.user, self.course.id
|
||||
)
|
||||
self.assertFalse(is_active)
|
||||
self.assertEqual(enrollment_mode, u'verified')
|
||||
assert not is_active
|
||||
assert enrollment_mode == u'verified'
|
||||
# now enroll them through the view:
|
||||
response = self._enroll_through_view(self.course)
|
||||
self.assertEqual(response.status_code, 200)
|
||||
assert response.status_code == 200
|
||||
enrollment_mode, is_active = CourseEnrollment.enrollment_mode_for_user(
|
||||
self.user, self.course.id
|
||||
)
|
||||
self.assertTrue(is_active)
|
||||
self.assertEqual(enrollment_mode, CourseMode.DEFAULT_MODE_SLUG)
|
||||
assert is_active
|
||||
assert enrollment_mode == CourseMode.DEFAULT_MODE_SLUG
|
||||
|
||||
|
||||
class AnonymousLookupTable(ModuleStoreTestCase):
|
||||
@@ -983,31 +897,31 @@ class AnonymousLookupTable(ModuleStoreTestCase):
|
||||
anonymous_id_1 = anonymous_id_for_user(self.user, None)
|
||||
delattr(self.user, "_anonymous_id") # pylint: disable=literal-used-as-attribute
|
||||
anonymous_id_2 = anonymous_id_for_user(self.user, None)
|
||||
self.assertEqual(anonymous_id_1, anonymous_id_2)
|
||||
assert anonymous_id_1 == anonymous_id_2
|
||||
|
||||
def test_diff_anonymous_id_for_diff_users(self):
|
||||
anonymous_id_1 = anonymous_id_for_user(self.user, None)
|
||||
anonymous_id_2 = anonymous_id_for_user(self.user2, None)
|
||||
self.assertNotEqual(anonymous_id_1, anonymous_id_2)
|
||||
assert anonymous_id_1 != anonymous_id_2
|
||||
|
||||
def test_for_unregistered_user(self): # same path as for logged out user
|
||||
self.assertEqual(None, anonymous_id_for_user(AnonymousUser(), self.course.id))
|
||||
self.assertIsNone(user_by_anonymous_id(None))
|
||||
assert anonymous_id_for_user(AnonymousUser(), self.course.id) is None
|
||||
assert user_by_anonymous_id(None) is None
|
||||
|
||||
def test_roundtrip_for_logged_user(self):
|
||||
CourseEnrollment.enroll(self.user, self.course.id)
|
||||
anonymous_id = anonymous_id_for_user(self.user, self.course.id)
|
||||
real_user = user_by_anonymous_id(anonymous_id)
|
||||
self.assertEqual(self.user, real_user)
|
||||
self.assertEqual(anonymous_id, anonymous_id_for_user(self.user, self.course.id))
|
||||
assert self.user == real_user
|
||||
assert anonymous_id == anonymous_id_for_user(self.user, self.course.id)
|
||||
|
||||
def test_roundtrip_with_unicode_course_id(self):
|
||||
course2 = CourseFactory.create(display_name=u"Omega Course Ω")
|
||||
CourseEnrollment.enroll(self.user, course2.id)
|
||||
anonymous_id = anonymous_id_for_user(self.user, course2.id)
|
||||
real_user = user_by_anonymous_id(anonymous_id)
|
||||
self.assertEqual(self.user, real_user)
|
||||
self.assertEqual(anonymous_id, anonymous_id_for_user(self.user, course2.id))
|
||||
assert self.user == real_user
|
||||
assert anonymous_id == anonymous_id_for_user(self.user, course2.id)
|
||||
|
||||
def test_anonymous_id_secret_key_changes_do_not_change_existing_anonymous_ids(self):
|
||||
"""Test that a same anonymous id is returned when the SECRET_KEY changes."""
|
||||
@@ -1017,9 +931,9 @@ class AnonymousLookupTable(ModuleStoreTestCase):
|
||||
# Recreate user object to clear cached anonymous id.
|
||||
self.user = User.objects.get(pk=self.user.id)
|
||||
new_anonymous_id = anonymous_id_for_user(self.user, self.course.id)
|
||||
self.assertEqual(anonymous_id, new_anonymous_id)
|
||||
self.assertEqual(self.user, user_by_anonymous_id(anonymous_id))
|
||||
self.assertEqual(self.user, user_by_anonymous_id(new_anonymous_id))
|
||||
assert anonymous_id == new_anonymous_id
|
||||
assert self.user == user_by_anonymous_id(anonymous_id)
|
||||
assert self.user == user_by_anonymous_id(new_anonymous_id)
|
||||
|
||||
def test_anonymous_id_secret_key_changes_result_in_diff_values_for_same_new_user(self):
|
||||
"""Test that a different anonymous id is returned when the SECRET_KEY changes."""
|
||||
@@ -1030,8 +944,8 @@ class AnonymousLookupTable(ModuleStoreTestCase):
|
||||
self.user = User.objects.get(pk=self.user.id)
|
||||
AnonymousUserId.objects.filter(user=self.user).filter(course_id=self.course.id).delete()
|
||||
new_anonymous_id = anonymous_id_for_user(self.user, self.course.id)
|
||||
self.assertNotEqual(anonymous_id, new_anonymous_id)
|
||||
self.assertEqual(self.user, user_by_anonymous_id(new_anonymous_id))
|
||||
assert anonymous_id != new_anonymous_id
|
||||
assert self.user == user_by_anonymous_id(new_anonymous_id)
|
||||
|
||||
|
||||
@skip_unless_lms
|
||||
@@ -1122,14 +1036,14 @@ class UserAttributeTests(TestCase):
|
||||
self.value = 'test-value'
|
||||
|
||||
def test_get_set_attribute(self):
|
||||
self.assertIsNone(UserAttribute.get_user_attribute(self.user, self.name))
|
||||
assert UserAttribute.get_user_attribute(self.user, self.name) is None
|
||||
UserAttribute.set_user_attribute(self.user, self.name, self.value)
|
||||
self.assertEqual(UserAttribute.get_user_attribute(self.user, self.name), self.value)
|
||||
assert UserAttribute.get_user_attribute(self.user, self.name) == self.value
|
||||
new_value = 'new_value'
|
||||
UserAttribute.set_user_attribute(self.user, self.name, new_value)
|
||||
self.assertEqual(UserAttribute.get_user_attribute(self.user, self.name), new_value)
|
||||
assert UserAttribute.get_user_attribute(self.user, self.name) == new_value
|
||||
|
||||
def test_unicode(self):
|
||||
UserAttribute.set_user_attribute(self.user, self.name, self.value)
|
||||
for field in (self.name, self.value, self.user.username):
|
||||
self.assertIn(field, str(UserAttribute.objects.get(user=self.user)))
|
||||
assert field in str(UserAttribute.objects.get(user=self.user))
|
||||
|
||||
Reference in New Issue
Block a user