Commit f72974d4 by Nimisha Asthagiri Committed by cahrens

TNL-328 Server-side work for displaying type of cohort.

parent 138fc145
...@@ -15,13 +15,40 @@ from .models import CourseUserGroup ...@@ -15,13 +15,40 @@ from .models import CourseUserGroup
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# A 'default cohort' is an auto-cohort that is automatically created for a course if no auto-cohorts have been # A 'default cohort' is an auto-cohort that is automatically created for a course if no auto_cohort_groups have been
# specified. It is intended to be used in a cohorted-course for users who have yet to be assigned to a cohort. # specified. It is intended to be used in a cohorted-course for users who have yet to be assigned to a cohort.
# If an administrator chooses to configure a cohort with the same name, the said cohort will also be used as # Note 1: If an administrator chooses to configure a cohort with the same name, the said cohort will be used as
# the "default cohort". # the "default cohort".
# Note 2: If auto_cohort_groups are configured after the 'default cohort' has been created and populated, the
# stagnant 'default cohort' will still remain (now as a manual cohort) with its previously assigned students.
# Translation Note: We are NOT translating this string since it is the constant identifier for the "default group" # Translation Note: We are NOT translating this string since it is the constant identifier for the "default group"
# and needed across product boundaries. # and needed across product boundaries.
DEFAULT_COHORT_NAME = "Default Cohort Group" DEFAULT_COHORT_NAME = "Default Group"
class CohortAssignmentType(object):
"""
The various types of rule-based cohorts
"""
# No automatic rules are applied to this cohort; users must be manually added.
NONE = "none"
# One of (possibly) multiple cohort groups to which users are randomly assigned.
# Note: The 'default cohort' group is included in this category iff it exists and
# there are no other random groups. (Also see Note 2 above.)
RANDOM = "random"
@staticmethod
def get(cohort, course):
"""
Returns the assignment type of the given cohort for the given course
"""
if cohort.name in course.auto_cohort_groups:
return CohortAssignmentType.RANDOM
elif len(course.auto_cohort_groups) == 0 and cohort.name == DEFAULT_COHORT_NAME:
return CohortAssignmentType.RANDOM
else:
return CohortAssignmentType.NONE
# tl;dr: global state is bad. capa reseeds random every time a problem is loaded. Even # tl;dr: global state is bad. capa reseeds random every time a problem is loaded. Even
......
""" """
Helper methods for testing cohorts. Helper methods for testing cohorts.
""" """
from factory import post_generation, Sequence
from factory.django import DjangoModelFactory
from course_groups.models import CourseUserGroup
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore import ModuleStoreEnum
from course_groups.models import CourseUserGroup
from course_groups.cohorts import DEFAULT_COHORT_NAME
class CohortFactory(DjangoModelFactory):
FACTORY_FOR = CourseUserGroup
name = Sequence("cohort{}".format)
course_id = "dummy_id"
group_type = CourseUserGroup.COHORT
@post_generation
def users(self, create, extracted, **kwargs): # pylint: disable=W0613
if extracted:
self.users.add(*extracted)
def topic_name_to_id(course, name): def topic_name_to_id(course, name):
...@@ -19,29 +33,6 @@ def topic_name_to_id(course, name): ...@@ -19,29 +33,6 @@ def topic_name_to_id(course, name):
) )
def get_default_cohort(course):
"""
Returns the default cohort for a course.
Returns None if the default cohort hasn't yet been created.
"""
return get_cohort_in_course(DEFAULT_COHORT_NAME, course)
def get_cohort_in_course(cohort_name, course):
"""
Returns the cohort with the name `cohort_name` in the given `course`.
Returns None if it doesn't exist.
"""
try:
return CourseUserGroup.objects.get(
course_id=course.id,
group_type=CourseUserGroup.COHORT,
name=cohort_name
)
except CourseUserGroup.DoesNotExist:
return None
def config_course_cohorts( def config_course_cohorts(
course, course,
discussions, discussions,
......
...@@ -6,9 +6,10 @@ from django.http import Http404 ...@@ -6,9 +6,10 @@ from django.http import Http404
from django.test.utils import override_settings from django.test.utils import override_settings
from student.models import CourseEnrollment from student.models import CourseEnrollment
from student.tests.factories import UserFactory
from course_groups.models import CourseUserGroup from course_groups.models import CourseUserGroup
from course_groups import cohorts from course_groups import cohorts
from course_groups.tests.helpers import topic_name_to_id, config_course_cohorts, get_default_cohort from course_groups.tests.helpers import topic_name_to_id, config_course_cohorts, CohortFactory
from xmodule.modulestore.django import modulestore, clear_existing_modulestores from xmodule.modulestore.django import modulestore, clear_existing_modulestores
from opaque_keys.edx.locations import SlashSeparatedCourseKey from opaque_keys.edx.locations import SlashSeparatedCourseKey
...@@ -59,15 +60,11 @@ class TestCohorts(django.test.TestCase): ...@@ -59,15 +60,11 @@ class TestCohorts(django.test.TestCase):
course = modulestore().get_course(self.toy_course_key) course = modulestore().get_course(self.toy_course_key)
self.assertFalse(course.is_cohorted) self.assertFalse(course.is_cohorted)
user = User.objects.create(username="test", email="a@b.com") user = UserFactory(username="test", email="a@b.com")
self.assertIsNone(cohorts.get_cohort_id(user, course.id)) self.assertIsNone(cohorts.get_cohort_id(user, course.id))
config_course_cohorts(course, discussions=[], cohorted=True) config_course_cohorts(course, discussions=[], cohorted=True)
cohort = CourseUserGroup.objects.create( cohort = CohortFactory(course_id=course.id, name="TestCohort")
name="TestCohort",
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
cohort.users.add(user) cohort.users.add(user)
self.assertEqual(cohorts.get_cohort_id(user, course.id), cohort.id) self.assertEqual(cohorts.get_cohort_id(user, course.id), cohort.id)
...@@ -84,17 +81,12 @@ class TestCohorts(django.test.TestCase): ...@@ -84,17 +81,12 @@ class TestCohorts(django.test.TestCase):
self.assertEqual(course.id, self.toy_course_key) self.assertEqual(course.id, self.toy_course_key)
self.assertFalse(course.is_cohorted) self.assertFalse(course.is_cohorted)
user = User.objects.create(username="test", email="a@b.com") user = UserFactory(username="test", email="a@b.com")
other_user = User.objects.create(username="test2", email="a2@b.com") other_user = UserFactory(username="test2", email="a2@b.com")
self.assertIsNone(cohorts.get_cohort(user, course.id), "No cohort created yet") self.assertIsNone(cohorts.get_cohort(user, course.id), "No cohort created yet")
cohort = CourseUserGroup.objects.create( cohort = CohortFactory(course_id=course.id, name="TestCohort")
name="TestCohort",
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
cohort.users.add(user) cohort.users.add(user)
self.assertIsNone( self.assertIsNone(
...@@ -112,7 +104,7 @@ class TestCohorts(django.test.TestCase): ...@@ -112,7 +104,7 @@ class TestCohorts(django.test.TestCase):
) )
self.assertEquals( self.assertEquals(
cohorts.get_cohort(other_user, course.id).id, cohorts.get_cohort(other_user, course.id).id,
get_default_cohort(course).id, cohorts.get_cohort_by_name(course.id, cohorts.DEFAULT_COHORT_NAME).id,
"other_user should be assigned to the default cohort" "other_user should be assigned to the default cohort"
) )
...@@ -123,16 +115,12 @@ class TestCohorts(django.test.TestCase): ...@@ -123,16 +115,12 @@ class TestCohorts(django.test.TestCase):
course = modulestore().get_course(self.toy_course_key) course = modulestore().get_course(self.toy_course_key)
self.assertFalse(course.is_cohorted) self.assertFalse(course.is_cohorted)
user1 = User.objects.create(username="test", email="a@b.com") user1 = UserFactory(username="test", email="a@b.com")
user2 = User.objects.create(username="test2", email="a2@b.com") user2 = UserFactory(username="test2", email="a2@b.com")
user3 = User.objects.create(username="test3", email="a3@b.com") user3 = UserFactory(username="test3", email="a3@b.com")
user4 = User.objects.create(username="test4", email="a4@b.com") user4 = UserFactory(username="test4", email="a4@b.com")
cohort = CourseUserGroup.objects.create( cohort = CohortFactory(course_id=course.id, name="TestCohort")
name="TestCohort",
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
# user1 manually added to a cohort # user1 manually added to a cohort
cohort.users.add(user1) cohort.users.add(user1)
...@@ -159,7 +147,7 @@ class TestCohorts(django.test.TestCase): ...@@ -159,7 +147,7 @@ class TestCohorts(django.test.TestCase):
self.assertEquals( self.assertEquals(
cohorts.get_cohort(user3, course.id).id, cohorts.get_cohort(user3, course.id).id,
get_default_cohort(course).id, cohorts.get_cohort_by_name(course.id, cohorts.DEFAULT_COHORT_NAME).id,
"No groups->default cohort" "No groups->default cohort"
) )
...@@ -182,7 +170,7 @@ class TestCohorts(django.test.TestCase): ...@@ -182,7 +170,7 @@ class TestCohorts(django.test.TestCase):
) )
self.assertEquals( self.assertEquals(
cohorts.get_cohort(user3, course.id).name, cohorts.get_cohort(user3, course.id).name,
get_default_cohort(course).name, cohorts.get_cohort_by_name(course.id, cohorts.DEFAULT_COHORT_NAME).name,
"user3 should still be in the default cohort" "user3 should still be in the default cohort"
) )
...@@ -200,7 +188,7 @@ class TestCohorts(django.test.TestCase): ...@@ -200,7 +188,7 @@ class TestCohorts(django.test.TestCase):
# Assign 100 users to cohorts # Assign 100 users to cohorts
for i in range(100): for i in range(100):
user = User.objects.create( user = UserFactory(
username="test_{0}".format(i), username="test_{0}".format(i),
email="a@b{0}.com".format(i) email="a@b{0}.com".format(i)
) )
...@@ -235,17 +223,8 @@ class TestCohorts(django.test.TestCase): ...@@ -235,17 +223,8 @@ class TestCohorts(django.test.TestCase):
) )
# add manual cohorts to course 1 # add manual cohorts to course 1
CourseUserGroup.objects.create( CohortFactory(course_id=course.id, name="ManualCohort")
name="ManualCohort", CohortFactory(course_id=course.id, name="ManualCohort2")
course_id=course.location.course_key,
group_type=CourseUserGroup.COHORT
)
CourseUserGroup.objects.create(
name="ManualCohort2",
course_id=course.location.course_key,
group_type=CourseUserGroup.COHORT
)
cohort_set = {c.name for c in cohorts.get_course_cohorts(course)} cohort_set = {c.name for c in cohorts.get_course_cohorts(course)}
self.assertEqual(cohort_set, {"AutoGroup1", "AutoGroup2", "ManualCohort", "ManualCohort2"}) self.assertEqual(cohort_set, {"AutoGroup1", "AutoGroup2", "ManualCohort", "ManualCohort2"})
...@@ -349,11 +328,7 @@ class TestCohorts(django.test.TestCase): ...@@ -349,11 +328,7 @@ class TestCohorts(django.test.TestCase):
lambda: cohorts.get_cohort_by_name(course.id, "CohortDoesNotExist") lambda: cohorts.get_cohort_by_name(course.id, "CohortDoesNotExist")
) )
cohort = CourseUserGroup.objects.create( cohort = CohortFactory(course_id=course.id, name="MyCohort")
name="MyCohort",
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
self.assertEqual(cohorts.get_cohort_by_name(course.id, "MyCohort"), cohort) self.assertEqual(cohorts.get_cohort_by_name(course.id, "MyCohort"), cohort)
...@@ -368,11 +343,7 @@ class TestCohorts(django.test.TestCase): ...@@ -368,11 +343,7 @@ class TestCohorts(django.test.TestCase):
course. course.
""" """
course = modulestore().get_course(self.toy_course_key) course = modulestore().get_course(self.toy_course_key)
cohort = CourseUserGroup.objects.create( cohort = CohortFactory(course_id=course.id, name="MyCohort")
name="MyCohort",
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
self.assertEqual(cohorts.get_cohort_by_id(course.id, cohort.id), cohort) self.assertEqual(cohorts.get_cohort_by_id(course.id, cohort.id), cohort)
...@@ -406,20 +377,12 @@ class TestCohorts(django.test.TestCase): ...@@ -406,20 +377,12 @@ class TestCohorts(django.test.TestCase):
Make sure cohorts.add_user_to_cohort() properly adds a user to a cohort and Make sure cohorts.add_user_to_cohort() properly adds a user to a cohort and
handles errors. handles errors.
""" """
course_user = User.objects.create(username="Username", email="a@b.com") course_user = UserFactory(username="Username", email="a@b.com")
User.objects.create(username="RandomUsername", email="b@b.com") UserFactory(username="RandomUsername", email="b@b.com")
course = modulestore().get_course(self.toy_course_key) course = modulestore().get_course(self.toy_course_key)
CourseEnrollment.enroll(course_user, self.toy_course_key) CourseEnrollment.enroll(course_user, self.toy_course_key)
first_cohort = CourseUserGroup.objects.create( first_cohort = CohortFactory(course_id=course.id, name="FirstCohort")
name="FirstCohort", second_cohort = CohortFactory(course_id=course.id, name="SecondCohort")
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
second_cohort = CourseUserGroup.objects.create(
name="SecondCohort",
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
# Success cases # Success cases
# We shouldn't get back a previous cohort, since the user wasn't in one # We shouldn't get back a previous cohort, since the user wasn't in one
...@@ -452,17 +415,9 @@ class TestCohorts(django.test.TestCase): ...@@ -452,17 +415,9 @@ class TestCohorts(django.test.TestCase):
for a given course. for a given course.
""" """
course = modulestore().get_course(self.toy_course_key) course = modulestore().get_course(self.toy_course_key)
user = User.objects.create(username="Username", email="a@b.com") user = UserFactory(username="Username", email="a@b.com")
empty_cohort = CourseUserGroup.objects.create( empty_cohort = CohortFactory(course_id=course.id, name="EmptyCohort")
name="EmptyCohort", nonempty_cohort = CohortFactory(course_id=course.id, name="NonemptyCohort")
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
nonempty_cohort = CourseUserGroup.objects.create(
name="NonemptyCohort",
course_id=course.id,
group_type=CourseUserGroup.COHORT
)
nonempty_cohort.users.add(user) nonempty_cohort.users.add(user)
cohorts.delete_empty_cohort(course.id, "EmptyCohort") cohorts.delete_empty_cohort(course.id, "EmptyCohort")
...@@ -470,11 +425,7 @@ class TestCohorts(django.test.TestCase): ...@@ -470,11 +425,7 @@ class TestCohorts(django.test.TestCase):
# Make sure we cannot access the deleted cohort # Make sure we cannot access the deleted cohort
self.assertRaises( self.assertRaises(
CourseUserGroup.DoesNotExist, CourseUserGroup.DoesNotExist,
lambda: CourseUserGroup.objects.get( lambda: cohorts.get_cohort_by_id(course.id, empty_cohort.id)
course_id=course.id,
group_type=CourseUserGroup.COHORT,
id=empty_cohort.id
)
) )
self.assertRaises( self.assertRaises(
ValueError, ValueError,
......
...@@ -48,8 +48,15 @@ def list_cohorts(request, course_key_string): ...@@ -48,8 +48,15 @@ def list_cohorts(request, course_key_string):
course = get_course_with_access(request.user, 'staff', course_key) course = get_course_with_access(request.user, 'staff', course_key)
all_cohorts = [{'name': c.name, 'id': c.id, 'user_count': c.users.count()} all_cohorts = [
for c in cohorts.get_course_cohorts(course)] {
'name': c.name,
'id': c.id,
'user_count': c.users.count(),
'assignment_type': cohorts.CohortAssignmentType.get(c, course)
}
for c in cohorts.get_course_cohorts(course)
]
return json_http_response({'success': True, return json_http_response({'success': True,
'cohorts': all_cohorts}) 'cohorts': all_cohorts})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment