Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
f72974d4
Commit
f72974d4
authored
Sep 12, 2014
by
Nimisha Asthagiri
Committed by
cahrens
Oct 01, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
TNL-328 Server-side work for displaying type of cohort.
parent
138fc145
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
85 additions
and
109 deletions
+85
-109
common/djangoapps/course_groups/cohorts.py
+32
-5
common/djangoapps/course_groups/tests/helpers.py
+16
-25
common/djangoapps/course_groups/tests/test_cohorts.py
+28
-77
common/djangoapps/course_groups/tests/test_views.py
+0
-0
common/djangoapps/course_groups/views.py
+9
-2
No files found.
common/djangoapps/course_groups/cohorts.py
View file @
f72974d4
...
...
@@ -15,13 +15,40 @@ from .models import CourseUserGroup
log
=
logging
.
getLogger
(
__name__
)
# A 'default cohort' is an auto-cohort that is automatically created for a course if no auto
-cohort
s have been
# A 'default cohort' is an auto-cohort that is automatically created for a course if no auto
_cohort_group
s have been
# 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
# the "default cohort".
# Note 1: If an administrator chooses to configure a cohort with the same name, the said cohort will be used as
# 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"
# and needed across product boundaries.
DEFAULT_COHORT_NAME
=
"Default Cohort Group"
# and needed across product boundaries.
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
...
...
common/djangoapps/course_groups/tests/helpers.py
View file @
f72974d4
"""
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
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
):
...
...
@@ -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
(
course
,
discussions
,
...
...
common/djangoapps/course_groups/tests/test_cohorts.py
View file @
f72974d4
...
...
@@ -6,9 +6,10 @@ from django.http import Http404
from
django.test.utils
import
override_settings
from
student.models
import
CourseEnrollment
from
student.tests.factories
import
UserFactory
from
course_groups.models
import
CourseUserGroup
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
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
...
...
@@ -59,15 +60,11 @@ class TestCohorts(django.test.TestCase):
course
=
modulestore
()
.
get_course
(
self
.
toy_course_key
)
self
.
assertFalse
(
course
.
is_cohorted
)
user
=
User
.
objects
.
create
(
username
=
"test"
,
email
=
"a@b.com"
)
user
=
User
Factory
(
username
=
"test"
,
email
=
"a@b.com"
)
self
.
assertIsNone
(
cohorts
.
get_cohort_id
(
user
,
course
.
id
))
config_course_cohorts
(
course
,
discussions
=
[],
cohorted
=
True
)
cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"TestCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"TestCohort"
)
cohort
.
users
.
add
(
user
)
self
.
assertEqual
(
cohorts
.
get_cohort_id
(
user
,
course
.
id
),
cohort
.
id
)
...
...
@@ -84,17 +81,12 @@ class TestCohorts(django.test.TestCase):
self
.
assertEqual
(
course
.
id
,
self
.
toy_course_key
)
self
.
assertFalse
(
course
.
is_cohorted
)
user
=
User
.
objects
.
create
(
username
=
"test"
,
email
=
"a@b.com"
)
other_user
=
User
.
objects
.
create
(
username
=
"test2"
,
email
=
"a2@b.com"
)
user
=
User
Factory
(
username
=
"test"
,
email
=
"a@b.com"
)
other_user
=
User
Factory
(
username
=
"test2"
,
email
=
"a2@b.com"
)
self
.
assertIsNone
(
cohorts
.
get_cohort
(
user
,
course
.
id
),
"No cohort created yet"
)
cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"TestCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"TestCohort"
)
cohort
.
users
.
add
(
user
)
self
.
assertIsNone
(
...
...
@@ -112,7 +104,7 @@ class TestCohorts(django.test.TestCase):
)
self
.
assertEquals
(
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"
)
...
...
@@ -123,16 +115,12 @@ class TestCohorts(django.test.TestCase):
course
=
modulestore
()
.
get_course
(
self
.
toy_course_key
)
self
.
assertFalse
(
course
.
is_cohorted
)
user1
=
User
.
objects
.
create
(
username
=
"test"
,
email
=
"a@b.com"
)
user2
=
User
.
objects
.
create
(
username
=
"test2"
,
email
=
"a2@b.com"
)
user3
=
User
.
objects
.
create
(
username
=
"test3"
,
email
=
"a3@b.com"
)
user4
=
User
.
objects
.
create
(
username
=
"test4"
,
email
=
"a4@b.com"
)
user1
=
User
Factory
(
username
=
"test"
,
email
=
"a@b.com"
)
user2
=
User
Factory
(
username
=
"test2"
,
email
=
"a2@b.com"
)
user3
=
User
Factory
(
username
=
"test3"
,
email
=
"a3@b.com"
)
user4
=
User
Factory
(
username
=
"test4"
,
email
=
"a4@b.com"
)
cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"TestCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"TestCohort"
)
# user1 manually added to a cohort
cohort
.
users
.
add
(
user1
)
...
...
@@ -159,7 +147,7 @@ class TestCohorts(django.test.TestCase):
self
.
assertEquals
(
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"
)
...
...
@@ -182,7 +170,7 @@ class TestCohorts(django.test.TestCase):
)
self
.
assertEquals
(
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"
)
...
...
@@ -200,7 +188,7 @@ class TestCohorts(django.test.TestCase):
# Assign 100 users to cohorts
for
i
in
range
(
100
):
user
=
User
.
objects
.
create
(
user
=
User
Factory
(
username
=
"test_{0}"
.
format
(
i
),
email
=
"a@b{0}.com"
.
format
(
i
)
)
...
...
@@ -235,17 +223,8 @@ class TestCohorts(django.test.TestCase):
)
# add manual cohorts to course 1
CourseUserGroup
.
objects
.
create
(
name
=
"ManualCohort"
,
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
)
CohortFactory
(
course_id
=
course
.
id
,
name
=
"ManualCohort"
)
CohortFactory
(
course_id
=
course
.
id
,
name
=
"ManualCohort2"
)
cohort_set
=
{
c
.
name
for
c
in
cohorts
.
get_course_cohorts
(
course
)}
self
.
assertEqual
(
cohort_set
,
{
"AutoGroup1"
,
"AutoGroup2"
,
"ManualCohort"
,
"ManualCohort2"
})
...
...
@@ -349,11 +328,7 @@ class TestCohorts(django.test.TestCase):
lambda
:
cohorts
.
get_cohort_by_name
(
course
.
id
,
"CohortDoesNotExist"
)
)
cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"MyCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"MyCohort"
)
self
.
assertEqual
(
cohorts
.
get_cohort_by_name
(
course
.
id
,
"MyCohort"
),
cohort
)
...
...
@@ -368,11 +343,7 @@ class TestCohorts(django.test.TestCase):
course.
"""
course
=
modulestore
()
.
get_course
(
self
.
toy_course_key
)
cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"MyCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"MyCohort"
)
self
.
assertEqual
(
cohorts
.
get_cohort_by_id
(
course
.
id
,
cohort
.
id
),
cohort
)
...
...
@@ -406,20 +377,12 @@ class TestCohorts(django.test.TestCase):
Make sure cohorts.add_user_to_cohort() properly adds a user to a cohort and
handles errors.
"""
course_user
=
User
.
objects
.
create
(
username
=
"Username"
,
email
=
"a@b.com"
)
User
.
objects
.
create
(
username
=
"RandomUsername"
,
email
=
"b@b.com"
)
course_user
=
User
Factory
(
username
=
"Username"
,
email
=
"a@b.com"
)
User
Factory
(
username
=
"RandomUsername"
,
email
=
"b@b.com"
)
course
=
modulestore
()
.
get_course
(
self
.
toy_course_key
)
CourseEnrollment
.
enroll
(
course_user
,
self
.
toy_course_key
)
first_cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"FirstCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
second_cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"SecondCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
first_cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"FirstCohort"
)
second_cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"SecondCohort"
)
# Success cases
# We shouldn't get back a previous cohort, since the user wasn't in one
...
...
@@ -452,17 +415,9 @@ class TestCohorts(django.test.TestCase):
for a given course.
"""
course
=
modulestore
()
.
get_course
(
self
.
toy_course_key
)
user
=
User
.
objects
.
create
(
username
=
"Username"
,
email
=
"a@b.com"
)
empty_cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"EmptyCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
nonempty_cohort
=
CourseUserGroup
.
objects
.
create
(
name
=
"NonemptyCohort"
,
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
)
user
=
UserFactory
(
username
=
"Username"
,
email
=
"a@b.com"
)
empty_cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"EmptyCohort"
)
nonempty_cohort
=
CohortFactory
(
course_id
=
course
.
id
,
name
=
"NonemptyCohort"
)
nonempty_cohort
.
users
.
add
(
user
)
cohorts
.
delete_empty_cohort
(
course
.
id
,
"EmptyCohort"
)
...
...
@@ -470,11 +425,7 @@ class TestCohorts(django.test.TestCase):
# Make sure we cannot access the deleted cohort
self
.
assertRaises
(
CourseUserGroup
.
DoesNotExist
,
lambda
:
CourseUserGroup
.
objects
.
get
(
course_id
=
course
.
id
,
group_type
=
CourseUserGroup
.
COHORT
,
id
=
empty_cohort
.
id
)
lambda
:
cohorts
.
get_cohort_by_id
(
course
.
id
,
empty_cohort
.
id
)
)
self
.
assertRaises
(
ValueError
,
...
...
common/djangoapps/course_groups/tests/test_views.py
View file @
f72974d4
This diff is collapsed.
Click to expand it.
common/djangoapps/course_groups/views.py
View file @
f72974d4
...
...
@@ -48,8 +48,15 @@ def list_cohorts(request, course_key_string):
course
=
get_course_with_access
(
request
.
user
,
'staff'
,
course_key
)
all_cohorts
=
[{
'name'
:
c
.
name
,
'id'
:
c
.
id
,
'user_count'
:
c
.
users
.
count
()}
for
c
in
cohorts
.
get_course_cohorts
(
course
)]
all_cohorts
=
[
{
'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
,
'cohorts'
:
all_cohorts
})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment