test: VerifiedTrackCohortedCourse related tests

This commit is contained in:
Eugene Dyudyunov
2022-05-02 18:27:09 +03:00
parent 5c5d383aa0
commit 215b81534e
4 changed files with 0 additions and 412 deletions

View File

@@ -1,39 +0,0 @@
"""
Test for forms helpers.
"""
from openedx.core.djangoapps.verified_track_content.forms import VerifiedTrackCourseForm
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
class TestVerifiedTrackCourseForm(SharedModuleStoreTestCase):
"""
Test form validation.
"""
FAKE_COURSE = 'edX/Test_Course/Run'
BAD_COURSE_KEY = 'bad_course_key'
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create()
def test_form_validation_success(self):
form_data = {
'course_key': str(self.course.id), 'verified_cohort_name': 'Verified Learners', 'enabled': True
}
form = VerifiedTrackCourseForm(data=form_data)
assert form.is_valid()
def test_form_validation_failure(self):
form_data = {'course_key': self.FAKE_COURSE, 'verified_cohort_name': 'Verified Learners', 'enabled': True}
form = VerifiedTrackCourseForm(data=form_data)
assert not form.is_valid()
assert form.errors['course_key'] == ['COURSE NOT FOUND. Please check that the course ID is valid.']
form_data = {'course_key': self.BAD_COURSE_KEY, 'verified_cohort_name': 'Verified Learners', 'enabled': True}
form = VerifiedTrackCourseForm(data=form_data)
assert not form.is_valid()
assert form.errors['course_key'] == ['COURSE NOT FOUND. Please check that the course ID is valid.']

View File

@@ -1,292 +0,0 @@
"""
Tests for Verified Track Cohorting models
"""
# pylint: disable=attribute-defined-outside-init
from unittest import mock
import ddt
from django.test import TestCase
from opaque_keys.edx.keys import CourseKey
from openedx.core.djangoapps.course_groups.cohorts import (
DEFAULT_COHORT_NAME,
CourseCohort,
add_cohort,
get_cohort,
set_course_cohorted
)
from openedx.core.djangolib.testing.utils import skip_unless_lms
from common.djangoapps.student.models import CourseMode
from common.djangoapps.student.tests.factories import CourseEnrollmentFactory, UserFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
from ..models import DEFAULT_VERIFIED_COHORT_NAME, VerifiedTrackCohortedCourse
from ..tasks import sync_cohort_with_mode
class TestVerifiedTrackCohortedCourse(TestCase):
"""
Tests that the configuration works as expected.
"""
SAMPLE_COURSE = 'edX/Test_Course/Run'
def test_course_enabled(self):
course_key = CourseKey.from_string(self.SAMPLE_COURSE)
# Test when no configuration exists
assert not VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(course_key)
# Enable for a course
config = VerifiedTrackCohortedCourse.objects.create(course_key=course_key, enabled=True)
config.save()
assert VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(course_key)
# Disable for the course
config.enabled = False
config.save()
assert not VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(course_key)
def test_unicode(self):
course_key = CourseKey.from_string(self.SAMPLE_COURSE)
# Enable for a course
config = VerifiedTrackCohortedCourse.objects.create(course_key=course_key, enabled=True)
config.save()
assert str(config) == f'Course: {self.SAMPLE_COURSE}, enabled: True'
def test_verified_cohort_name(self):
cohort_name = 'verified cohort'
course_key = CourseKey.from_string(self.SAMPLE_COURSE)
config = VerifiedTrackCohortedCourse.objects.create(
course_key=course_key, enabled=True, verified_cohort_name=cohort_name
)
config.save()
assert VerifiedTrackCohortedCourse.verified_cohort_name_for_course(course_key) == cohort_name
def test_unset_verified_cohort_name(self):
fake_course_id = 'fake/course/key'
course_key = CourseKey.from_string(fake_course_id)
assert VerifiedTrackCohortedCourse.verified_cohort_name_for_course(course_key) is None
@skip_unless_lms
@ddt.ddt
class TestMoveToVerified(SharedModuleStoreTestCase):
""" Tests for the post-save listener. """
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create()
def setUp(self):
super().setUp()
self.user = UserFactory()
# Spy on number of calls to celery task.
celery_task_patcher = mock.patch.object(
sync_cohort_with_mode, 'apply_async',
mock.Mock(wraps=sync_cohort_with_mode.apply_async)
)
self.mocked_celery_task = celery_task_patcher.start()
self.addCleanup(celery_task_patcher.stop)
def _enable_cohorting(self):
""" Turn on cohorting in the course. """
set_course_cohorted(self.course.id, True)
def _create_verified_cohort(self, name=DEFAULT_VERIFIED_COHORT_NAME):
""" Create a verified cohort. """
add_cohort(self.course.id, name, CourseCohort.MANUAL)
def _create_named_random_cohort(self, name):
""" Create a random cohort with the supplied name. """
return add_cohort(self.course.id, name, CourseCohort.RANDOM)
def _enable_verified_track_cohorting(self, cohort_name=None):
""" Enable verified track cohorting for the default course. """
if cohort_name:
config = VerifiedTrackCohortedCourse.objects.create(
course_key=self.course.id, enabled=True, verified_cohort_name=cohort_name
)
else:
config = VerifiedTrackCohortedCourse.objects.create(course_key=self.course.id, enabled=True)
config.save()
def _enroll_in_course(self):
""" Enroll self.user in self.course. """
self.enrollment = CourseEnrollmentFactory(course_id=self.course.id, user=self.user)
def _upgrade_enrollment(self, mode=CourseMode.VERIFIED):
""" Upgrade the default enrollment to verified. """
self.enrollment.update_enrollment(mode=mode)
def _verify_no_automatic_cohorting(self):
""" Check that upgrading self.user to verified does not move them into a cohort. """
self._enroll_in_course()
assert get_cohort(self.user, self.course.id, assign=False) is None
self._upgrade_enrollment()
assert get_cohort(self.user, self.course.id, assign=False) is None
assert 0 == self.mocked_celery_task.call_count
def _unenroll(self):
""" Unenroll self.user from self.course. """
self.enrollment.unenroll(self.user, self.course.id)
def _reenroll(self):
""" Re-enroll the learner into mode AUDIT. """
self.enrollment.activate()
self.enrollment.change_mode(CourseMode.AUDIT)
@mock.patch('openedx.core.djangoapps.verified_track_content.models.log.error')
def test_automatic_cohorting_disabled(self, error_logger):
"""
If the VerifiedTrackCohortedCourse feature is disabled for a course, enrollment mode changes do not move
learners into a cohort.
"""
# Enable cohorting and create a verified cohort.
self._enable_cohorting()
self._create_verified_cohort()
# But do not enable the verified track cohorting feature.
assert not VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)
self._verify_no_automatic_cohorting()
# No logging occurs if feature is disabled for course.
assert not error_logger.called
@mock.patch('openedx.core.djangoapps.verified_track_content.models.log.error')
def test_cohorting_enabled_course_not_cohorted(self, error_logger):
"""
If the VerifiedTrackCohortedCourse feature is enabled for a course, but the course is not cohorted,
an error is logged and enrollment mode changes do not move learners into a cohort.
"""
# Enable verified track cohorting feature, but course has not been marked as cohorting.
self._enable_verified_track_cohorting()
assert VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)
self._verify_no_automatic_cohorting()
assert error_logger.called
assert 'course is not cohorted' in error_logger.call_args[0][0]
@mock.patch('openedx.core.djangoapps.verified_track_content.models.log.error')
def test_cohorting_enabled_missing_verified_cohort(self, error_logger):
"""
If the VerifiedTrackCohortedCourse feature is enabled for a course and the course is cohorted,
but the course does not have a verified cohort, an error is logged and enrollment mode changes do not
move learners into a cohort.
"""
# Enable cohorting, but do not create the verified cohort.
self._enable_cohorting()
# Enable verified track cohorting feature
self._enable_verified_track_cohorting()
assert VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)
self._verify_no_automatic_cohorting()
assert error_logger.called
error_message = "cohort named '%s' does not exist"
assert error_message in error_logger.call_args[0][0]
@ddt.data(CourseMode.VERIFIED, CourseMode.CREDIT_MODE)
def test_automatic_cohorting_enabled(self, upgrade_mode):
"""
If the VerifiedTrackCohortedCourse feature is enabled for a course (with course cohorting enabled
with an existing verified cohort), enrollment in the verified track automatically moves learners
into the verified cohort.
"""
# Enable cohorting and create a verified cohort.
self._enable_cohorting()
self._create_verified_cohort()
# Enable verified track cohorting feature
self._enable_verified_track_cohorting()
assert VerifiedTrackCohortedCourse.is_verified_track_cohort_enabled(self.course.id)
self._enroll_in_course()
assert 2 == self.mocked_celery_task.call_count
assert DEFAULT_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
self._upgrade_enrollment(upgrade_mode)
assert 4 == self.mocked_celery_task.call_count
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
def test_cohorting_enabled_multiple_random_cohorts(self):
"""
If the VerifiedTrackCohortedCourse feature is enabled for a course, and the course is cohorted
with > 1 random cohorts, the learner is randomly assigned to one of the random
cohorts when in the audit track.
"""
# Enable cohorting, and create the verified cohort.
self._enable_cohorting()
self._create_verified_cohort()
# Create two random cohorts.
self._create_named_random_cohort("Random 1")
self._create_named_random_cohort("Random 2")
# Enable verified track cohorting feature
self._enable_verified_track_cohorting()
self._enroll_in_course()
assert get_cohort(self.user, self.course.id, assign=False).name in ['Random 1', 'Random 2']
self._upgrade_enrollment()
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
self._unenroll()
self._reenroll()
assert get_cohort(self.user, self.course.id, assign=False).name in ['Random 1', 'Random 2']
def test_unenrolled(self):
"""
Test that un-enrolling and re-enrolling works correctly. This is important because usually
learners maintain their previously assigned cohort on re-enrollment.
"""
# Enable verified track cohorting feature and enroll in the verified track
self._enable_cohorting()
self._create_verified_cohort()
self._enable_verified_track_cohorting()
self._enroll_in_course()
self._upgrade_enrollment()
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
# Un-enroll from the course and then re-enroll
self._unenroll()
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
self._reenroll()
assert DEFAULT_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
self._upgrade_enrollment()
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
def test_custom_verified_cohort_name(self):
"""
Test that enrolling in verified works correctly when the "verified cohort" has a custom name.
"""
custom_cohort_name = 'special verified cohort'
self._enable_cohorting()
self._create_verified_cohort(name=custom_cohort_name)
self._enable_verified_track_cohorting(cohort_name=custom_cohort_name)
self._enroll_in_course()
self._upgrade_enrollment()
assert custom_cohort_name == get_cohort(self.user, self.course.id, assign=False).name
def test_custom_default_cohort_name(self):
"""
Test that enrolling and un-enrolling works correctly when the single cohort
of type random has a different name from "Default Group".
"""
random_cohort_name = "custom random cohort"
self._enable_cohorting()
self._create_verified_cohort()
default_cohort = self._create_named_random_cohort(random_cohort_name)
self._enable_verified_track_cohorting()
self._enroll_in_course()
assert random_cohort_name == get_cohort(self.user, self.course.id, assign=False).name
self._upgrade_enrollment()
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
# Un-enroll from the course. The learner stays in the verified cohort, but is no longer active.
self._unenroll()
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name
# Change the name of the "default" cohort.
modified_cohort_name = "renamed random cohort"
default_cohort.name = modified_cohort_name
default_cohort.save()
# Re-enroll in the course, which will downgrade the learner to audit.
self._reenroll()
assert modified_cohort_name == get_cohort(self.user, self.course.id, assign=False).name
self._upgrade_enrollment()
assert DEFAULT_VERIFIED_COHORT_NAME == get_cohort(self.user, self.course.id, assign=False).name

View File

@@ -14,7 +14,6 @@ from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase #
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.partitions.partitions import MINIMUM_STATIC_PARTITION_ID, UserPartition, ReadOnlyUserPartitionError # lint-amnesty, pylint: disable=wrong-import-order
from ..models import VerifiedTrackCohortedCourse
from ..partition_scheme import ENROLLMENT_GROUP_IDS, EnrollmentTrackPartitionScheme, EnrollmentTrackUserPartition
@@ -34,11 +33,6 @@ class EnrollmentTrackUserPartitionTest(SharedModuleStoreTestCase):
assert 1 == len(groups)
assert 'Audit' == groups[0].name
def test_using_verified_track_cohort(self):
VerifiedTrackCohortedCourse.objects.create(course_key=self.course.id, enabled=True).save()
partition = create_enrollment_track_partition(self.course)
assert 0 == len(partition.groups)
def test_multiple_groups(self):
create_mode(self.course, CourseMode.AUDIT, "Audit Enrollment Track", min_price=0)
# Note that the verified mode is expired-- this is intentional.
@@ -163,11 +157,6 @@ class EnrollmentTrackPartitionSchemeTest(SharedModuleStoreTestCase):
)
assert 'Verified Enrollment Track' == self._get_user_group().name
def test_using_verified_track_cohort(self):
VerifiedTrackCohortedCourse.objects.create(course_key=self.course.id, enabled=True).save()
CourseEnrollment.enroll(self.student, self.course.id)
assert self._get_user_group() is None
def _get_user_group(self):
"""
Gets the group the user is assigned to.

View File

@@ -1,70 +0,0 @@
"""
Tests for verified track content views.
"""
import json
import pytest
from django.http import Http404
from django.test.client import RequestFactory
from openedx.core.djangolib.testing.utils import skip_unless_lms
from common.djangoapps.student.tests.factories import UserFactory, AdminFactory
from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase # lint-amnesty, pylint: disable=wrong-import-order
from xmodule.modulestore.tests.factories import CourseFactory # lint-amnesty, pylint: disable=wrong-import-order
from ..models import VerifiedTrackCohortedCourse
from ..views import cohorting_settings
@skip_unless_lms
class CohortingSettingsTestCase(SharedModuleStoreTestCase):
"""
Tests the `cohort_discussion_topics` view.
"""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.course = CourseFactory.create()
def test_non_staff(self):
"""
Verify that we cannot access cohorting_settings if we're a non-staff user.
"""
request = RequestFactory().get("dummy_url")
request.user = UserFactory()
with pytest.raises(Http404):
cohorting_settings(request, str(self.course.id))
def test_cohorting_settings_enabled(self):
"""
Verify that cohorting_settings is working for HTTP GET when verified track cohorting is enabled.
"""
config = VerifiedTrackCohortedCourse.objects.create(
course_key=str(self.course.id), enabled=True, verified_cohort_name="Verified Learners"
)
config.save()
expected_response = {
"enabled": True,
"verified_cohort_name": "Verified Learners"
}
self._verify_cohort_settings_response(expected_response)
def test_cohorting_settings_disabled(self):
"""
Verify that cohorting_settings is working for HTTP GET when verified track cohorting is disabled.
"""
expected_response = {
"enabled": False
}
self._verify_cohort_settings_response(expected_response)
def _verify_cohort_settings_response(self, expected_response):
""" Verify that the response was successful and matches the expected JSON payload. """
request = RequestFactory().get("dummy_url")
request.user = AdminFactory()
response = cohorting_settings(request, str(self.course.id))
assert 200 == response.status_code
assert expected_response == json.loads(response.content.decode('utf-8'))