Example #1
0
    def test_from_json_broken(self):
        test_id = 5
        name = "Grendel"
        # Bad version
        jsonified = {
            "id": test_id,
            "name": name,
            "version": -1,
        }
        with self.assertRaisesRegexp(TypeError, "has unexpected version"):
            Group.from_json(jsonified)

        # Missing key "id"
        jsonified = {
            "name": name,
            "version": Group.VERSION
        }
        with self.assertRaisesRegexp(TypeError, "missing value key 'id'"):
            Group.from_json(jsonified)

        # Has extra key - should not be a problem
        jsonified = {
            "id": test_id,
            "name": name,
            "version": Group.VERSION,
            "programmer": "Cale"
        }
        group = Group.from_json(jsonified)
        self.assertNotIn("programmer", group.to_json())
Example #2
0
 def test_to_json(self):
     test_id = 10
     name = "Grendel"
     group = Group(test_id, name)
     jsonified = group.to_json()
     act_jsonified = {"id": test_id, "name": name, "version": group.VERSION}
     self.assertEqual(jsonified, act_jsonified)
Example #3
0
 def test_from_json(self):
     test_id = 5
     name = "Grendel"
     jsonified = {"id": test_id, "name": name, "version": Group.VERSION}
     group = Group.from_json(jsonified)
     self.assertEqual(group.id, test_id)
     self.assertEqual(group.name, name)
    def test_can_handle_multiple_partitions(self):
        # Create the user partitions
        self.course.user_partitions = [
            UserPartition(
                id=0,
                name='Cohort user partition',
                scheme=UserPartition.get_scheme('cohort'),
                description='Cohorted user partition',
                groups=[
                    Group(id=0, name="Group A"),
                    Group(id=1, name="Group B"),
                ],
            ),
            UserPartition(
                id=1,
                name='Random user partition',
                scheme=UserPartition.get_scheme('random'),
                description='Random user partition',
                groups=[
                    Group(id=0, name="Group A"),
                    Group(id=1, name="Group B"),
                ],
            ),
        ]
        self.store.update_item(self.course, ModuleStoreEnum.UserID.test)

        # Assign group access rules for multiple partitions, one of which is a cohorted partition
        __, problem = self._create_problem_with_content_group(0, 1)
        problem.group_access = {
            0: [0],
            1: [1],
        }
        self.store.update_item(problem, ModuleStoreEnum.UserID.test)

        # This used to cause an exception since the code assumed that
        # only one partition would be available.
        actual = GroupConfiguration.get_content_groups_usage_info(
            self.store, self.course)
        self.assertEqual(actual.keys(), [0])

        actual = GroupConfiguration.get_content_groups_items_usage_info(
            self.store, self.course)
        self.assertEqual(actual.keys(), [0])
    def setUp(self):
        super(SplitTestPosition, self).setUp()

        self.partition = UserPartition(
            0, 'first_partition', 'First Partition',
            [Group(0, 'alpha'), Group(1, 'beta')])

        self.course = CourseFactory.create(user_partitions=[self.partition])

        self.chapter = ItemFactory.create(
            parent_location=self.course.location,
            category="chapter",
            display_name="test chapter",
        )

        self.student = UserFactory.create()
        CourseEnrollmentFactory.create(user=self.student,
                                       course_id=self.course.id)
        self.client.login(username=self.student.username, password='******')
    def test_can_cancel_editing_of_group_configuration(self):
        """
        Scenario: Ensure that editing of the group configuration can be canceled correctly.
        Given I have a course with group configuration
        When I go to the edit mode of the group configuration
        And I set new name and description, add 2 additional groups
        And I click button 'Cancel'
        Then I see that new changes were discarded
        """
        self.course_fixture._update_xblock(
            self.course_fixture._course_location, {
                "metadata": {
                    u"user_partitions": [
                        create_user_partition_json(
                            0, 'Name of the Group Configuration',
                            'Description of the group configuration.',
                            [Group("0", 'Group 0'),
                             Group("1", 'Group 1')]),
                        create_user_partition_json(
                            1, 'Name of second Group Configuration',
                            'Second group configuration.', [
                                Group("0", 'Alpha'),
                                Group("1", 'Beta'),
                                Group("2", 'Gamma')
                            ]),
                    ],
                },
            })
        self.page.visit()
        config = self.page.experiment_group_configurations[0]
        config.name = "New Group Configuration Name"
        config.description = "New Description of the group configuration."
        # Add 2 new groups
        config.add_group()  # Group C
        config.add_group()  # Group D
        # Cancel the configuration
        config.cancel()

        self._assert_fields(
            config,
            name="Name of the Group Configuration",
            description="Description of the group configuration.",
            groups=["Group 0", "Group 1"])
Example #7
0
    def test_change_group_name(self):
        # Changing the name of the group shouldn't affect anything
        # get a group assigned to the user - should be group 0 or 1
        old_group = self.partitions_service.get_user_group_for_partition(self.partition_id)
        self.assertIn(old_group, [0, 1])

        # Change the group names
        groups = [Group(0, 'Group 0'), Group(1, 'Group 1')]
        user_partition = UserPartition(self.partition_id, 'Test Partition', 'for testing purposes', groups)
        self.partitions_service = StaticPartitionService(
            [user_partition],
            user_tags_service=self.user_tags_service,
            course_id=Mock(),
            track_function=Mock()
        )

        # Now, get a new group using the same call
        new_group = self.partitions_service.get_user_group_for_partition(self.partition_id)
        self.assertEqual(old_group, new_group)
    def test_active_and_inactive_children(self):
        """
        Tests the active and inactive children returned for different split test configurations.
        """
        split_test_module = self.split_test_module
        children = split_test_module.get_children()

        # Verify that a split test has no active children if it has no specified user partition.
        split_test_module.user_partition_id = -1
        [active_children, inactive_children] = split_test_module.active_and_inactive_children()
        self.assertEqual(active_children, [])
        self.assertEqual(inactive_children, children)

        # Verify that all the children are returned as active for a correctly configured split_test
        split_test_module.user_partition_id = 0
        split_test_module.user_partitions = [
            UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha'), Group("1", 'beta')])
        ]
        [active_children, inactive_children] = split_test_module.active_and_inactive_children()
        self.assertEqual(active_children, children)
        self.assertEqual(inactive_children, [])

        # Verify that a split_test does not return inactive children in the active children
        self.split_test_module.user_partitions = [
            UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha')])
        ]
        [active_children, inactive_children] = split_test_module.active_and_inactive_children()
        self.assertEqual(active_children, [children[0]])
        self.assertEqual(inactive_children, [children[1]])

        # Verify that a split_test ignores misconfigured children
        self.split_test_module.user_partitions = [
            UserPartition(0, 'first_partition', 'First Partition', [Group("0", 'alpha'), Group("2", 'gamma')])
        ]
        [active_children, inactive_children] = split_test_module.active_and_inactive_children()
        self.assertEqual(active_children, [children[0]])
        self.assertEqual(inactive_children, [children[1]])

        # Verify that a split_test referring to a non-existent user partition has no active children
        self.split_test_module.user_partition_id = 2
        [active_children, inactive_children] = split_test_module.active_and_inactive_children()
        self.assertEqual(active_children, [])
        self.assertEqual(inactive_children, children)
    def test_change_group_name(self):
        # Changing the name of the group shouldn't affect anything
        # get a group assigned to the user - should be group 0 or 1
        old_group = RandomUserPartitionScheme.get_group_for_user(
            self.MOCK_COURSE_ID, self.user, self.user_partition)
        self.assertIn(old_group.id, [0, 1])

        # Change the group names
        groups = [Group(0, 'Group 0'), Group(1, 'Group 1')]
        user_partition = UserPartition(self.TEST_ID,
                                       'Test Partition',
                                       'for testing purposes',
                                       groups,
                                       scheme=RandomUserPartitionScheme)

        # Now, get a new group using the same call
        new_group = RandomUserPartitionScheme.get_group_for_user(
            self.MOCK_COURSE_ID, self.user, user_partition)
        self.assertEqual(old_group.id, new_group.id)
    def setUpClass(cls):
        super(SplitTestBase, cls).setUpClass()
        cls.partition = UserPartition(
            0, 'first_partition', 'First Partition',
            [Group(0, 'alpha'), Group(1, 'beta')])

        cls.course = CourseFactory.create(number=cls.COURSE_NUMBER,
                                          user_partitions=[cls.partition])

        cls.chapter = ItemFactory.create(
            parent_location=cls.course.location,
            category="chapter",
            display_name="test chapter",
        )
        cls.sequential = ItemFactory.create(
            parent_location=cls.chapter.location,
            category="sequential",
            display_name="Split Test Tests",
        )
    def setUp(self):
        """
        Set up a cohorted course with a user_partition of scheme "cohort".
        """
        super(CohortContentGroupAssociationTest, self).setUp()

        # create course with single cohort and two content groups (user_partition of type "cohort")
        self.cohort_name = "OnlyCohort"
        self.course_fixture = CourseFixture(**self.course_info).install()
        self.setup_cohort_config(self.course_fixture)
        self.cohort_id = self.add_manual_cohort(self.course_fixture,
                                                self.cohort_name)

        self.course_fixture._update_xblock(
            self.course_fixture._course_location, {
                "metadata": {
                    u"user_partitions": [
                        create_user_partition_json(
                            0,
                            'Apples, Bananas',
                            'Content Group Partition',
                            [Group("0", 'Apples'),
                             Group("1", 'Bananas')],
                            scheme="cohort")
                    ],
                },
            })

        # login as an instructor
        self.instructor_name = "instructor_user"
        self.instructor_id = AutoAuthPage(self.browser,
                                          username=self.instructor_name,
                                          email="*****@*****.**",
                                          course_id=self.course_id,
                                          staff=True).visit().get_user_id()

        # go to the membership page on the instructor dashboard
        self.instructor_dashboard_page = InstructorDashboardPage(
            self.browser, self.course_id)
        self.instructor_dashboard_page.visit()
        self.cohort_management_page = self.instructor_dashboard_page.select_cohort_management(
        )
Example #12
0
    def test_has_access_in_preview_mode_with_group(self):
        """
        Test that a user masquerading as a member of a group sees appropriate content in preview mode.
        """
        # Note about UserPartition and UserPartition Group IDs: these must not conflict with IDs used
        # by dynamic user partitions.
        partition_id = MINIMUM_STATIC_PARTITION_ID
        group_0_id = MINIMUM_STATIC_PARTITION_ID + 1
        group_1_id = MINIMUM_STATIC_PARTITION_ID + 2
        user_partition = UserPartition(
            partition_id, 'Test User Partition', '',
            [Group(group_0_id, 'Group 1'), Group(group_1_id, 'Group 2')],
            scheme_id='cohort'
        )
        self.course.user_partitions.append(user_partition)
        self.course.cohort_config = {'cohorted': True}

        chapter = ItemFactory.create(category="chapter", parent_location=self.course.location)
        chapter.group_access = {partition_id: [group_0_id]}

        modulestore().update_item(self.course, ModuleStoreEnum.UserID.test)

        # User should not be able to preview when masquerading as student (and not in the group above).
        with patch('lms.djangoapps.courseware.access.get_user_role') as mock_user_role:
            mock_user_role.return_value = 'student'
            assert not bool(access.has_access(self.global_staff, 'load', chapter, course_key=self.course.id))

        # Should be able to preview when in staff or instructor role.
        for mocked_role in ['staff', 'instructor']:
            with patch('lms.djangoapps.courseware.access.get_user_role') as mock_user_role:
                mock_user_role.return_value = mocked_role
                assert bool(access.has_access(self.global_staff, 'load', chapter, course_key=self.course.id))

        # Now install masquerade group and set staff as a member of that.
        assert 200 == masquerade_as_group_member(self.global_staff, self.course, partition_id, group_0_id)
        # Can load the chapter since user is in the group.
        assert bool(access.has_access(self.global_staff, 'load', chapter, course_key=self.course.id))

        # Move the user to be a part of the second group.
        assert 200 == masquerade_as_group_member(self.global_staff, self.course, partition_id, group_1_id)
        # Cannot load the chapter since user is in a different group.
        assert not bool(access.has_access(self.global_staff, 'load', chapter, course_key=self.course.id))
Example #13
0
    def test_edit_warning_message_non_empty_usage(self):
        """
        Scenario: When a Group Configuration is used, ensure that there are a warning icon and message.

        Given I have a course with a Group Configuration containing two Groups
        When I edit the Group Configuration
        Then I see a warning icon and message
        """

        # Create a group configuration with an associated experiment and display edit view
        config, _ = self.create_group_configuration_experiment(
            [Group("0", "Group A"),
             Group("1", "Group B")], True)
        config.edit()
        # Check that warning icon and message are present
        self.assertTrue(config.edit_warning_icon_is_present)
        self.assertTrue(config.edit_warning_message_is_present)
        self.assertIn(
            "This configuration is currently used in content experiments. If you make changes to the groups, you may need to edit those experiments.",
            config.edit_warning_message_text)
Example #14
0
 def setUp(self):
     super(SplitTest, self).setUp()
     # This line should be called once courseFixture is installed
     self.course_fixture._update_xblock(
         self.course_fixture._course_location, {
             "metadata": {
                 u"user_partitions": [
                     create_user_partition_json(
                         0, 'Configuration alpha,beta', 'first',
                         [Group("0", 'alpha'),
                          Group("1", 'beta')]),
                     create_user_partition_json(1, 'Configuration 0,1,2',
                                                'second', [
                                                    Group("0", 'Group 0'),
                                                    Group("1", 'Group 1'),
                                                    Group("2", 'Group 2')
                                                ]),
                 ],
             },
         })
Example #15
0
    def test_user_in_deleted_group(self):
        # get a group assigned to the user - should be group 0 or 1
        old_group = RandomUserPartitionScheme.get_group_for_user(
            self.MOCK_COURSE_ID, self.user, self.user_partition)
        self.assertIn(old_group.id, [0, 1])

        # Change the group definitions! No more group 0 or 1
        groups = [Group(3, 'Group 3'), Group(4, 'Group 4')]
        user_partition = UserPartition(self.TEST_ID, 'Test Partition',
                                       'for testing purposes', groups)

        # Now, get a new group using the same call - should be 3 or 4
        new_group = RandomUserPartitionScheme.get_group_for_user(
            self.MOCK_COURSE_ID, self.user, user_partition)
        self.assertIn(new_group.id, [3, 4])

        # We should get the same group over multiple calls
        new_group_2 = RandomUserPartitionScheme.get_group_for_user(
            self.MOCK_COURSE_ID, self.user, user_partition)
        self.assertEqual(new_group, new_group_2)
 def test_from_json(self):
     test_id = 5
     name = "Grendel"
     jsonified = {
         "id": test_id,
         "name": name,
         "version": Group.VERSION
     }
     group = Group.from_json(jsonified)
     assert group.id == test_id
     assert group.name == name
Example #17
0
 def test_from_json(self):
     test_id = 5
     name = "Grendel"
     jsonified = {
         "id": test_id,
         "name": name,
         "version": Group.VERSION
     }
     group = Group.from_json(jsonified)
     self.assertEqual(group.id, test_id)
     self.assertEqual(group.name, name)
Example #18
0
    def get_user_partition(self):
        """
        Get user partition for saving in course.
        """
        groups = [
            Group(g["id"], g["name"]) for g in self.configuration["groups"]
        ]

        return UserPartition(self.configuration["id"],
                             self.configuration["name"],
                             self.configuration["description"], groups)
Example #19
0
    def setUp(self):
        """
        Regenerate a course with cohort configuration, partition and groups,
        and a student for each test.
        """
        super(TestCohortPartitionScheme, self).setUp()

        self.course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
        self.course = modulestore().get_course(self.course_key)
        config_course_cohorts(self.course, is_cohorted=True)

        self.groups = [Group(10, 'Group 10'), Group(20, 'Group 20')]
        self.user_partition = UserPartition(
            0,
            'Test Partition',
            'for testing purposes',
            self.groups,
            scheme=CohortPartitionScheme
        )
        self.student = UserFactory.create()
Example #20
0
    def test_can_cancel_editing_of_group_configuration(self):
        """
        Scenario: Ensure that editing of the group configuration can be canceled correctly.
        Given I have a course with group configuration
        When I go to the edit mode of the group configuration
        And I set new name and description
        And I click button 'Cancel'
        Then I see that new changes were discarded
        """
        self.course_fix.add_advanced_settings({
            u"user_partitions": {
                "value": [
                    UserPartition(
                        0, 'Name of the Group Configuration',
                        'Description of the group configuration.',
                        [Group("0", 'Group 0'),
                         Group("1", 'Group 1')]).to_json(),
                    UserPartition(1, 'Name of second Group Configuration',
                                  'Second group configuration.', [
                                      Group("0", 'Alpha'),
                                      Group("1", 'Beta'),
                                      Group("2", 'Gamma')
                                  ]).to_json()
                ],
            },
        })
        self.course_fix._add_advanced_settings()
        self.page.visit()

        config = self.page.group_configurations()[0]

        config.name = "New Group Configuration Name"
        config.description = "New Description of the group configuration."
        # Cancel the configuration
        config.cancel()

        self._assert_fields(
            config,
            name="Name of the Group Configuration",
            description="Description of the group configuration.",
            groups=["Group 0", "Group 1"])
Example #21
0
    def test_can_handle_duplicate_group_ids(self):
        # Create the user partitions
        self.course.user_partitions = [
            UserPartition(
                id=0,
                name='Cohort user partition 1',
                scheme=UserPartition.get_scheme('cohort'),
                description='Cohorted user partition',
                groups=[
                    Group(id=2, name="Group 1A"),
                    Group(id=3, name="Group 1B"),
                ],
            ),
            UserPartition(
                id=1,
                name='Cohort user partition 2',
                scheme=UserPartition.get_scheme('cohort'),
                description='Random user partition',
                groups=[
                    Group(id=2, name="Group 2A"),
                    Group(id=3, name="Group 2B"),
                ],
            ),
        ]
        self.store.update_item(self.course, ModuleStoreEnum.UserID.test)

        # Assign group access rules for multiple partitions, one of which is a cohorted partition
        self._create_problem_with_content_group(0, 2, name_suffix='0')
        self._create_problem_with_content_group(1, 3, name_suffix='1')

        # This used to cause an exception since the code assumed that
        # only one partition would be available.
        actual = GroupConfiguration.get_partitions_usage_info(self.store, self.course)
        self.assertEqual(list(actual.keys()), [0, 1])
        self.assertEqual(list(actual[0].keys()), [2])
        self.assertEqual(list(actual[1].keys()), [3])

        actual = GroupConfiguration.get_content_groups_items_usage_info(self.store, self.course)
        self.assertEqual(list(actual.keys()), [0, 1])
        self.assertEqual(list(actual[0].keys()), [2])
        self.assertEqual(list(actual[1].keys()), [3])
Example #22
0
    def setUp(self):
        super(GroupVisibilityTest, self).setUp()

        chapter = ItemFactory.create(category='chapter', parent_location=self.course.location)
        sequential = ItemFactory.create(category='sequential', parent_location=chapter.location)
        vertical = ItemFactory.create(category='vertical', parent_location=sequential.location)
        html = ItemFactory.create(category='html', parent_location=vertical.location)
        problem = ItemFactory.create(
            category='problem', parent_location=vertical.location, data="<problem></problem>"
        )
        self.sequential = self.store.get_item(sequential.location)
        self.vertical = self.store.get_item(vertical.location)
        self.html = self.store.get_item(html.location)
        self.problem = self.store.get_item(problem.location)

        # Add partitions to the course
        self.course.user_partitions = [
            UserPartition(
                id=0,
                name="Partition 0",
                description="Partition 0",
                scheme=UserPartition.get_scheme("random"),
                groups=[
                    Group(id=0, name="Group A"),
                    Group(id=1, name="Group B"),
                ],
            ),
            UserPartition(
                id=1,
                name="Partition 1",
                description="Partition 1",
                scheme=UserPartition.get_scheme("random"),
                groups=[
                    Group(id=0, name="Group C"),
                    Group(id=1, name="Group D"),
                ],
            ),
            UserPartition(
                id=2,
                name="Partition 2",
                description="Partition 2",
                scheme=UserPartition.get_scheme("random"),
                groups=[
                    Group(id=0, name="Group E"),
                    Group(id=1, name="Group F"),
                    Group(id=2, name="Group G"),
                    Group(id=3, name="Group H"),
                ],
            ),
        ]
        self.course = self.store.update_item(self.course, ModuleStoreEnum.UserID.test)
Example #23
0
    def setUp(self):
        """
        Set up a simple course with a grading policy, a UserPartition, and 2 sections, both graded as "homework".
        One section is pre-populated with a problem (with 2 inputs), visible to all students.
        The second section is empty. Test cases should add conditional content to it.
        """
        super(TestConditionalContent, self).setUp()

        self.user_partition_group_0 = 0
        self.user_partition_group_1 = 1
        self.partition = UserPartition(
            0,
            'first_partition',
            'First Partition',
            [
                Group(self.user_partition_group_0, 'alpha'),
                Group(self.user_partition_group_1, 'beta')
            ]
        )

        self.course = CourseFactory.create(
            display_name=self.COURSE_NAME,
            number=self.COURSE_SLUG,
            user_partitions=[self.partition]
        )

        grading_policy = {
            "GRADER": [{
                "type": "Homework",
                "min_count": 2,
                "drop_count": 0,
                "short_label": "HW",
                "weight": 1.0
            }]
        }
        self.add_grading_policy(grading_policy)

        self.homework_all = self.add_graded_section_to_course('homework1')
        self.p1_all_html_id = self.add_dropdown_to_section(self.homework_all.location, 'H1P1', 2).location.html_id()

        self.homework_conditional = self.add_graded_section_to_course('homework2')
 def setUp(self):
     """
     Create a simple course with a video component.
     """
     super(AuthoringMixinTestCase, self).setUp()  # lint-amnesty, pylint: disable=super-with-arguments
     self.course = CourseFactory.create()
     chapter = ItemFactory.create(category='chapter',
                                  parent_location=self.course.location,
                                  display_name='Test Chapter')
     sequential = ItemFactory.create(category='sequential',
                                     parent_location=chapter.location,
                                     display_name='Test Sequential')
     vertical = ItemFactory.create(category='vertical',
                                   parent_location=sequential.location,
                                   display_name='Test Vertical')
     video = ItemFactory.create(category='video',
                                parent_location=vertical.location,
                                display_name='Test Vertical')
     self.vertical_location = vertical.location
     self.video_location = video.location
     self.pet_groups = [Group(1, 'Cat Lovers'), Group(2, 'Dog Lovers')]
Example #25
0
 def setUp(self):
     super(LmsXBlockMixinTestCase, self).setUp()
     self.user_partition = UserPartition(
         0, 'first_partition', 'First Partition',
         [Group(0, 'alpha'), Group(1, 'beta')])
     self.group1 = self.user_partition.groups[0]  # pylint: disable=no-member
     self.group2 = self.user_partition.groups[1]  # pylint: disable=no-member
     self.course = CourseFactory.create(
         user_partitions=[self.user_partition])
     self.section = ItemFactory.create(parent=self.course,
                                       category='chapter',
                                       display_name='Test Section')
     self.subsection = ItemFactory.create(parent=self.section,
                                          category='sequential',
                                          display_name='Test Subsection')
     self.vertical = ItemFactory.create(parent=self.subsection,
                                        category='vertical',
                                        display_name='Test Unit')
     self.video = ItemFactory.create(parent=self.subsection,
                                     category='video',
                                     display_name='Test Video')
    def create_poorly_configured_split_instance(self):
        """
        Creates a split test instance with a missing group and an inactive group.

        Returns the container page.
        """
        unit = self.go_to_unit_page()
        add_advanced_component(unit, 0, 'split_test')
        container = self.go_to_nested_container_page()
        container.edit()
        component_editor = ComponentEditorView(self.browser, container.locator)
        component_editor.set_select_value_and_save('Group Configuration', 'Configuration alpha,beta')
        self.course_fixture._update_xblock(self.course_fixture._course_location, {
            "metadata": {
                u"user_partitions": [
                    UserPartition(0, 'Configuration alpha,beta', 'first',
                                  [Group("0", 'alpha'), Group("2", 'gamma')]).to_json()
                ],
            },
        })
        return self.go_to_nested_container_page()
Example #27
0
    def setUpClass(cls):
        super(SplitTestPosition, cls).setUpClass()
        cls.partition = UserPartition(
            0,
            'first_partition',
            'First Partition',
            [
                Group(0, 'alpha'),
                Group(1, 'beta')
            ]
        )

        cls.course = CourseFactory.create(
            user_partitions=[cls.partition]
        )

        cls.chapter = ItemFactory.create(
            parent_location=cls.course.location,
            category="chapter",
            display_name="test chapter",
        )
Example #28
0
 def build_course(self):
     """
     Build up a course tree with a UserPartition.
     """
     # pylint: disable=attribute-defined-outside-init
     self.user_partition = UserPartition(
         0,
         'first_partition',
         'First Partition',
         [
             Group(0, 'alpha'),
             Group(1, 'beta')
         ]
     )
     self.group1 = self.user_partition.groups[0]    # pylint: disable=no-member
     self.group2 = self.user_partition.groups[1]    # pylint: disable=no-member
     self.course = CourseFactory.create(user_partitions=[self.user_partition])
     self.section = ItemFactory.create(parent=self.course, category='chapter', display_name='Test Section')
     self.subsection = ItemFactory.create(parent=self.section, category='sequential', display_name='Test Subsection')
     self.vertical = ItemFactory.create(parent=self.subsection, category='vertical', display_name='Test Unit')
     self.video = ItemFactory.create(parent=self.vertical, category='video', display_name='Test Video 1')
Example #29
0
    def test_can_get_correct_usage_info_for_unit(self):
        """
        When group access is set on the unit level, the usage info should return a url to the unit, not
        the sequential parent of the unit.
        """
        self.course.user_partitions = [
            UserPartition(
                id=0,
                name='User Partition',
                scheme=UserPartition.get_scheme('cohort'),
                description='User Partition',
                groups=[
                    Group(id=0, name="Group")
                ],
            ),
        ]
        vertical, __ = self._create_problem_with_content_group(
            cid=0, group_id=0, name_suffix='0'
        )

        self.client.ajax_post(
            reverse_usage_url("xblock_handler", vertical.location),
            data={'metadata': {'group_access': {0: [0]}}}
        )

        actual = self._get_user_partition('cohort')
        # order of usage list is arbitrary, sort for reliable comparison
        actual['groups'][0]['usage'].sort(key=itemgetter('label'))
        expected = {
            'id': 0,
            'name': 'User Partition',
            'scheme': 'cohort',
            'description': 'User Partition',
            'version': UserPartition.VERSION,
            'groups': [
                {'id': 0, 'name': 'Group', 'version': 1, 'usage': [
                    {
                        'url': u"/container/{}".format(vertical.location),
                        'label': u"Test Subsection 0 / Test Unit 0"
                    },
                    {
                        'url': u"/container/{}".format(vertical.location),
                        'label': u"Test Unit 0 / Test Problem 0"
                    }
                ]},
            ],
            u'parameters': {},
            u'active': True,
        }

        self.maxDiff = None

        assert actual == expected
Example #30
0
    def setUp(self):
        """
        Regenerate a course with cohort configuration, partition and groups,
        and a student for each test.
        """
        super(TestGetCohortedUserPartition, self).setUp()
        self.course_key = SlashSeparatedCourseKey("edX", "toy", "2012_Fall")
        self.course = modulestore().get_course(self.course_key)
        self.student = UserFactory.create()

        self.random_user_partition = UserPartition(
            1,
            'Random Partition',
            'Should not be returned',
            [Group(0, 'Group 0'), Group(1, 'Group 1')],
            scheme=RandomUserPartitionScheme)

        self.cohort_user_partition = UserPartition(
            0,
            'Cohort Partition 1',
            'Should be returned',
            [Group(10, 'Group 10'),
             Group(20, 'Group 20')],
            scheme=CohortPartitionScheme)

        self.second_cohort_user_partition = UserPartition(
            2,
            'Cohort Partition 2',
            'Should not be returned',
            [Group(10, 'Group 10'), Group(1, 'Group 1')],
            scheme=CohortPartitionScheme)
Example #31
0
    def test_details_warning_validation_message(self):
        """
        Scenario: When a Content Experiment uses a Group Configuration, ensure
        that a warning validation message appears if necessary.

        Given I have a course with a Group Configuration containing three Groups
        And a Content Experiment is assigned to that Group Configuration
        When I go to the Group Configuration Page
        Then I do not see a warning icon and message in the Group Configuration details view.
        When I remove a Group
        Then I see a warning icon and message in the Group Configuration details view
        """

        # Create group configuration and associated experiment
        config, _ = self.create_group_configuration_experiment([
            Group("0", "Group A"),
            Group("1", "Group B"),
            Group("2", "Group C")
        ], True)

        # Display details view
        config.toggle()
        # Check that warning icon and message are not present
        self.assertFalse(config.details_warning_icon_is_present)
        self.assertFalse(config.details_message_is_present)

        # Remove a group
        config.toggle()
        config.edit()
        config.groups[2].remove()
        config.save()

        # Display details view
        config.toggle()
        # Check that warning icon and message are present
        self.assertTrue(config.details_warning_icon_is_present)
        self.assertTrue(config.details_message_is_present)
        self.assertIn(
            "This content experiment has issues that affect content visibility.",
            config.details_message_text)
Example #32
0
    def test_cannot_delete_used_group_configuration(self):
        """
        Scenario: Ensure that the user cannot delete unused group configuration.
        Given I have a course with group configuration that is used in the Content Experiment
        When I go to the Group Configuration page
        Then I do not see delete button and I see a note about that
        When I edit the Group Configuration
        Then I do not see delete button and I see the note about that
        """
        # Create a new group configurations
        self.course_fixture._update_xblock(
            self.course_fixture._course_location, {
                "metadata": {
                    u"user_partitions": [
                        create_user_partition_json(
                            0, "Name", "Description.",
                            [Group("0", "Group A"),
                             Group("1", "Group B")])
                    ],
                },
            })
        vertical = self.course_fixture.get_nested_xblocks(
            category="vertical")[0]
        self.course_fixture.create_xblock(
            vertical.locator,
            XBlockFixtureDesc('split_test',
                              'Test Content Experiment',
                              metadata={'user_partition_id': 0}))
        # Go to the Group Configuration Page and click unit anchor
        self.page.visit()

        config = self.page.experiment_group_configurations[0]
        self.assertTrue(config.delete_button_is_disabled)
        self.assertIn('Cannot delete when in use by an experiment',
                      config.delete_note)

        config.edit()
        self.assertTrue(config.delete_button_is_disabled)
        self.assertIn('Cannot delete when in use by an experiment',
                      config.delete_note)
    def test_render_author_view(self, group_configuration_url):
        """
        Test the rendering of the Studio author view.
        """
        def create_studio_context(root_xblock):
            """
            Context for rendering the studio "author_view".
            """
            return {
                'reorderable_items': set(),
                'root_xblock': root_xblock,
            }

        # The split_test module should render both its groups when it is the root
        context = create_studio_context(self.split_test_module)
        html = self.module_system.render(self.split_test_module, AUTHOR_VIEW,
                                         context).content
        self.assertIn('HTML FOR GROUP 0', html)
        self.assertIn('HTML FOR GROUP 1', html)

        # When rendering as a child, it shouldn't render either of its groups
        context = create_studio_context(self.course_sequence)
        html = self.module_system.render(self.split_test_module, AUTHOR_VIEW,
                                         context).content
        self.assertNotIn('HTML FOR GROUP 0', html)
        self.assertNotIn('HTML FOR GROUP 1', html)

        # The "Create Missing Groups" button should be rendered when groups are missing
        context = create_studio_context(self.split_test_module)
        self.split_test_module.user_partitions = [
            UserPartition(
                0, 'first_partition', 'First Partition',
                [Group("0", 'alpha'),
                 Group("1", 'beta'),
                 Group("2", 'gamma')])
        ]
        html = self.module_system.render(self.split_test_module, AUTHOR_VIEW,
                                         context).content
        self.assertIn('HTML FOR GROUP 0', html)
        self.assertIn('HTML FOR GROUP 1', html)