testing.py 8.46 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
""" Mixins for setting up particular course structures (such as split tests or cohorted content) """

from datetime import datetime
from pytz import UTC

from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup
from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory
from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
from xmodule.partitions.partitions import UserPartition, Group
from student.tests.factories import CourseEnrollmentFactory, UserFactory


class ContentGroupTestCase(ModuleStoreTestCase):
    """
    Sets up discussion modules visible to content groups 'Alpha' and
    'Beta', as well as a module visible to all students.  Creates a
    staff user, users with access to Alpha/Beta (by way of cohorts),
    and a non-cohorted user with no special access.
    """
    def setUp(self):
        super(ContentGroupTestCase, self).setUp()

        self.course = CourseFactory.create(
            org='org', number='number', run='run',
            # This test needs to use a course that has already started --
            # discussion topics only show up if the course has already started,
            # and the default start date for courses is Jan 1, 2030.
            start=datetime(2012, 2, 3, tzinfo=UTC),
            user_partitions=[
                UserPartition(
                    0,
                    'Content Group Configuration',
                    '',
                    [Group(1, 'Alpha'), Group(2, 'Beta')],
                    scheme_id='cohort'
                )
            ],
            grading_policy={
                "GRADER": [{
                    "type": "Homework",
                    "min_count": 1,
                    "drop_count": 0,
                    "short_label": "HW",
                    "weight": 1.0
                }]
            },
            cohort_config={'cohorted': True},
            discussion_topics={}
        )

        self.staff_user = UserFactory.create(is_staff=True)
        self.alpha_user = UserFactory.create()
        self.beta_user = UserFactory.create()
        self.non_cohorted_user = UserFactory.create()
        for user in [self.staff_user, self.alpha_user, self.beta_user, self.non_cohorted_user]:
            CourseEnrollmentFactory.create(user=user, course_id=self.course.id)

        alpha_cohort = CohortFactory(
            course_id=self.course.id,
            name='Cohort Alpha',
            users=[self.alpha_user]
        )
        beta_cohort = CohortFactory(
            course_id=self.course.id,
            name='Cohort Beta',
            users=[self.beta_user]
        )
        CourseUserGroupPartitionGroup.objects.create(
            course_user_group=alpha_cohort,
            partition_id=self.course.user_partitions[0].id,
            group_id=self.course.user_partitions[0].groups[0].id
        )
        CourseUserGroupPartitionGroup.objects.create(
            course_user_group=beta_cohort,
            partition_id=self.course.user_partitions[0].id,
            group_id=self.course.user_partitions[0].groups[1].id
        )
        self.alpha_module = ItemFactory.create(
            parent_location=self.course.location,
            category='discussion',
            discussion_id='alpha_group_discussion',
            discussion_target='Visible to Alpha',
            group_access={self.course.user_partitions[0].id: [self.course.user_partitions[0].groups[0].id]}
        )
        self.beta_module = ItemFactory.create(
            parent_location=self.course.location,
            category='discussion',
            discussion_id='beta_group_discussion',
            discussion_target='Visible to Beta',
            group_access={self.course.user_partitions[0].id: [self.course.user_partitions[0].groups[1].id]}
        )
        self.global_module = ItemFactory.create(
            parent_location=self.course.location,
            category='discussion',
            discussion_id='global_group_discussion',
            discussion_target='Visible to Everyone'
        )
        self.course = self.store.get_item(self.course.location)


class TestConditionalContent(ModuleStoreTestCase):
    """
    Construct a course with graded problems that exist within a split test.
    """
    TEST_SECTION_NAME = 'Problem'

    def setUp(self):
        """
        Set up a course with graded problems within a split test.

        Course hierarchy is as follows (modeled after how split tests
        are created in studio):
        -> course
            -> chapter
                -> sequential (graded)
                    -> vertical
                        -> split_test
                            -> vertical (Group A)
                                -> problem
                            -> vertical (Group B)
                                -> problem
        """
        super(TestConditionalContent, self).setUp()

        # Create user partitions
        self.user_partition_group_a = 0
        self.user_partition_group_b = 1
        self.partition = UserPartition(
            0,
            'first_partition',
            'First Partition',
            [
                Group(self.user_partition_group_a, 'Group A'),
                Group(self.user_partition_group_b, 'Group B')
            ]
        )

        # Create course with group configurations and grading policy
        self.course = CourseFactory.create(
            user_partitions=[self.partition],
            grading_policy={
                "GRADER": [{
                    "type": "Homework",
                    "min_count": 1,
                    "drop_count": 0,
                    "short_label": "HW",
                    "weight": 1.0
                }]
            }
        )
        chapter = ItemFactory.create(parent_location=self.course.location,
                                     display_name='Chapter')

        # add a sequence to the course to which the problems can be added
        self.problem_section = ItemFactory.create(parent_location=chapter.location,
                                                  category='sequential',
                                                  metadata={'graded': True, 'format': 'Homework'},
                                                  display_name=self.TEST_SECTION_NAME)

        # Create users and partition them
        self.student_a = UserFactory.create(username='student_a', email='student_a@example.com')
        CourseEnrollmentFactory.create(user=self.student_a, course_id=self.course.id)
        self.student_b = UserFactory.create(username='student_b', email='student_b@example.com')
        CourseEnrollmentFactory.create(user=self.student_b, course_id=self.course.id)

        UserCourseTagFactory(
            user=self.student_a,
            course_id=self.course.id,
171
            key='xblock.partition_service.partition_{0}'.format(self.partition.id),
172 173 174 175 176
            value=str(self.user_partition_group_a)
        )
        UserCourseTagFactory(
            user=self.student_b,
            course_id=self.course.id,
177
            key='xblock.partition_service.partition_{0}'.format(self.partition.id),
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194
            value=str(self.user_partition_group_b)
        )

        # Create a vertical to contain our split test
        problem_vertical = ItemFactory.create(
            parent_location=self.problem_section.location,
            category='vertical',
            display_name='Problem Unit'
        )

        # Create the split test and child vertical containers
        vertical_a_url = self.course.id.make_usage_key('vertical', 'split_test_vertical_a')
        vertical_b_url = self.course.id.make_usage_key('vertical', 'split_test_vertical_b')
        self.split_test = ItemFactory.create(
            parent_location=problem_vertical.location,
            category='split_test',
            display_name='Split Test',
195
            user_partition_id=self.partition.id,
196 197 198 199 200 201 202 203 204 205 206 207 208 209
            group_id_to_child={str(index): url for index, url in enumerate([vertical_a_url, vertical_b_url])}
        )
        self.vertical_a = ItemFactory.create(
            parent_location=self.split_test.location,
            category='vertical',
            display_name='Group A problem container',
            location=vertical_a_url
        )
        self.vertical_b = ItemFactory.create(
            parent_location=self.split_test.location,
            category='vertical',
            display_name='Group B problem container',
            location=vertical_b_url
        )