def test_easy_access_from_experiment(self): """ Scenario: When a Content Experiment uses a Group Configuration, ensure that the link to that Group Configuration works correctly. Given I have a course with two Group Configurations And Content Experiment is assigned to one Group Configuration Then I see a link to Group Configuration When I click on the Group Configuration link Then I see the Group Configurations page And I see that appropriate Group Configuration is expanded. """ # 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")] ), create_user_partition_json( 1, 'Name of second Group Configuration', 'Second group configuration.', [Group("0", 'Alpha'), Group("1", 'Beta'), Group("2", 'Gamma')] ), ], }, }) # Assign newly created group configuration to unit 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': 1}) ) unit = ContainerPage(self.browser, vertical.locator) unit.visit() experiment = unit.xblocks[0] group_configuration_link_name = experiment.group_configuration_link_name experiment.go_to_group_configuration_page() self.page.wait_for_page() # Appropriate Group Configuration is expanded. self.assertFalse(self.page.experiment_group_configurations[0].is_expanded) self.assertTrue(self.page.experiment_group_configurations[1].is_expanded) self.assertEqual( group_configuration_link_name, self.page.experiment_group_configurations[1].name )
def test_group_configurations_have_correct_data(self): """ Scenario: Ensure that the group configuration is rendered correctly in expanded/collapsed mode. Given I have a course with 2 group configurations And I go to the Group Configuration page in Studio And I work with the first group configuration And I see `name`, `id` are visible and have correct values When I expand the first group configuration Then I see `description` and `groups` appear and also have correct values And I do the same checks for the second group configuration """ 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] # no groups when the the configuration is collapsed self.assertEqual(len(config.groups), 0) self._assert_fields( config, cid="0", name="Name of the Group Configuration", description="Description of the group configuration.", groups=["Group 0", "Group 1"] ) config = self.page.experiment_group_configurations[1] self._assert_fields( config, name="Name of second Group Configuration", description="Second group configuration.", groups=["Alpha", "Beta", "Gamma"] )
def create_group_configuration_experiment(self, groups, associate_experiment): """ Creates a Group Configuration containing a list of groups. Optionally creates a Content Experiment and associates it with previous Group Configuration. Returns group configuration or (group configuration, experiment xblock) """ # 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.", groups), ], }, }) if associate_experiment: # Assign newly created group configuration to experiment vertical = self.course_fixture.get_nested_xblocks(category="vertical")[0] split_test = XBlockFixtureDesc('split_test', 'Test Content Experiment', metadata={'user_partition_id': 0}) self.course_fixture.create_xblock(vertical.locator, split_test) # Go to the Group Configuration Page self.page.visit() config = self.page.experiment_group_configurations[0] if associate_experiment: return config, split_test return config
def test_group_configuration_empty_usage(self): """ Scenario: When group configuration is not used, ensure that the link to outline page works correctly. Given I have a course without group configurations And I create new group configuration with 2 default groups Then I see a link to the outline page When I click on the outline link Then I see the outline page """ # 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")] ), ], }, }) # Go to the Group Configuration Page and click on outline anchor self.page.visit() config = self.page.experiment_group_configurations[0] config.toggle() config.click_outline_anchor() # Waiting for the page load and verify that we've landed on course outline page self.outline_page.wait_for_page()
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": [ create_user_partition_json( 0, 'Configuration alpha,beta', 'first', [Group("0", 'alpha'), Group("2", 'gamma')] ) ], }, }) return self.go_to_nested_container_page()
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"] )
def test_can_delete_unused_group_configuration(self): """ Scenario: Ensure that the user can delete unused group configuration. Given I have a course with 2 group configurations And I go to the Group Configuration page When I delete the Group Configuration with name "Configuration 1" Then I see that there is one Group Configuration When I edit the Group Configuration with name "Configuration 2" And I delete the Group Configuration with name "Configuration 2" Then I see that the are no Group Configurations """ self.course_fixture._update_xblock(self.course_fixture._course_location, { "metadata": { u"user_partitions": [ create_user_partition_json( 0, 'Configuration 1', 'Description of the group configuration.', [Group("0", 'Group 0'), Group("1", 'Group 1')] ), create_user_partition_json( 1, 'Configuration 2', 'Second group configuration.', [Group("0", 'Alpha'), Group("1", 'Beta'), Group("2", 'Gamma')] ) ], }, }) self.page.visit() self.assertEqual(len(self.page.experiment_group_configurations), 2) config = self.page.experiment_group_configurations[1] # Delete first group configuration via detail view config.delete() self.assertEqual(len(self.page.experiment_group_configurations), 1) config = self.page.experiment_group_configurations[0] config.edit() self.assertFalse(config.delete_button_is_disabled) # Delete first group configuration via edit view config.delete() self.assertEqual(len(self.page.experiment_group_configurations), 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')] ), ], }, })
def test_group_configuration_non_empty_usage(self): """ Scenario: When group configuration is used, ensure that the links to units using a group configuration work correctly. Given I have a course without group configurations And I create new group configuration with 2 default groups And I create a unit and assign the newly created group configuration And open the Group Configuration page Then I see a link to the newly created unit When I click on the unit link Then I see correct unit page """ # 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")] ), ], }, }) # Assign newly created group configuration to unit 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}) ) unit = CourseOutlineUnit(self.browser, vertical.locator) # Go to the Group Configuration Page and click unit anchor self.page.visit() config = self.page.experiment_group_configurations[0] config.toggle() usage = config.usages[0] config.click_unit_anchor() unit = ContainerPage(self.browser, vertical.locator) # Waiting for the page load and verify that we've landed on the unit page EmptyPromise( lambda: unit.is_browser_on_page(), "loaded page {!r}".format(unit), timeout=30 ).fulfill() self.assertIn(unit.name, usage)
def setUp(self): super(CourseWithContentGroupsTest, self).setUp() # pylint: disable=protected-access self.course_fixture._update_xblock(self.course_fixture._course_location, { "metadata": { u"user_partitions": [ create_user_partition_json( 0, 'Configuration alpha,beta', 'Content Group Partition', [Group("0", 'alpha'), Group("1", 'beta')], scheme="cohort" ) ], }, })
def _create_group_configuration(self): """ Create a group configuration for course """ # pylint: disable=protected-access self.course_fixture._update_xblock(self.course_fixture._course_location, { "metadata": { u"user_partitions": [ create_user_partition_json( 0, "Configuration A/B", "Content Group Partition.", [Group("0", "Group A"), Group("1", "Group B")] ) ] } })
def test_missing_content_group(self): """ Scenario: In a course with content groups, if a cohort is associated with a content group that no longer exists, a warning message is shown Given I have a course with a cohort defined and content groups defined When I create a new cohort and link it to a content group And I delete that content group from the course And I reload the page And I view the cohort in the instructor dashboard and select settings Then the settings display a message that the content group no longer exists And when I select a different content group and save Then the error message goes away """ new_cohort = "linked to missing content group" self._create_new_cohort_linked_to_content_group(new_cohort, "Apples") 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("2", 'Pears'), Group("1", 'Bananas')], scheme="cohort" ) ], }, }) self.browser.refresh() self.cohort_management_page.wait_for_page() self.cohort_management_page.select_cohort(new_cohort) self.assertEqual("Deleted Content Group", self.cohort_management_page.get_cohort_associated_content_group()) self.assertEquals( ["Bananas", "Pears", "Deleted Content Group"], self.cohort_management_page.get_all_content_groups() ) self.assertEqual( "Warning:\nThe previously selected content group was deleted. Select another content group.", self.cohort_management_page.get_cohort_related_content_group_message() ) self.cohort_management_page.set_cohort_associated_content_group("Pears") confirmation_messages = self.cohort_management_page.get_cohort_settings_messages() self.assertEqual(["Saved cohort"], confirmation_messages) self.assertIsNone(self.cohort_management_page.get_cohort_related_content_group_message()) self.assertEquals(["Bananas", "Pears"], self.cohort_management_page.get_all_content_groups())
def test_cannot_delete_used_content_group(self): """ Scenario: Ensure that the user cannot delete used content group. Given I have a course with 1 Content Group And I go to the Group Configuration page When I try to delete the Content Group with name "New Content Group" Then I see the delete button is disabled. """ self.course_fixture._update_xblock( self.course_fixture._course_location, { "metadata": { u"user_partitions": [ create_user_partition_json(0, 'Configuration alpha,', 'Content Group Partition', [Group("0", 'alpha')], scheme="cohort") ], }, }) problem_data = dedent(""" <problem markdown="Simple Problem" max_attempts="" weight=""> <p>Choose Yes.</p> <choiceresponse> <checkboxgroup> <choice correct="true">Yes</choice> </checkboxgroup> </choiceresponse> </problem> """) vertical = self.course_fixture.get_nested_xblocks( category="vertical")[0] self.course_fixture.create_xblock( vertical.locator, XBlockFixtureDesc('problem', "VISIBLE TO ALPHA", data=problem_data, metadata={"group_access": { 0: [0] }}), ) self.group_configurations_page.visit() config = self.group_configurations_page.content_groups[0] self.assertTrue(config.delete_button_is_disabled)
def setUp(self): super(CourseWithContentGroupsTest, self).setUp() # pylint: disable=protected-access self.course_fixture._update_xblock( self.course_fixture._course_location, { "metadata": { u"user_partitions": [ create_user_partition_json( MINIMUM_STATIC_PARTITION_ID, 'Configuration alpha,beta', 'Content Group Partition', [ Group(MINIMUM_STATIC_PARTITION_ID + 1, 'alpha'), Group(MINIMUM_STATIC_PARTITION_ID + 2, 'beta') ], scheme="cohort") ], }, })
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( )
def test_cannot_delete_used_content_group(self): """ Scenario: Ensure that the user cannot delete used content group. Given I have a course with 1 Content Group And I go to the Group Configuration page When I try to delete the Content Group with name "New Content Group" Then I see the delete button is disabled. """ self.course_fixture._update_xblock( self.course_fixture._course_location, { "metadata": { "user_partitions": [ create_user_partition_json( 0, "Configuration alpha,", "Content Group Partition", [Group("0", "alpha")], scheme="cohort" ) ] } }, ) problem_data = dedent( """ <problem markdown="Simple Problem" max_attempts="" weight=""> <p>Choose Yes.</p> <choiceresponse> <checkboxgroup> <choice correct="true">Yes</choice> </checkboxgroup> </choiceresponse> </problem> """ ) vertical = self.course_fixture.get_nested_xblocks(category="vertical")[0] self.course_fixture.create_xblock( vertical.locator, XBlockFixtureDesc("problem", "VISIBLE TO ALPHA", data=problem_data, metadata={"group_access": {0: [0]}}), ) self.group_configurations_page.visit() config = self.group_configurations_page.content_groups[0] self.assertTrue(config.delete_button_is_disabled)
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_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 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()
def test_container_page_active_verticals_names_are_synced(self): """ Scenario: Ensure that the Content Experiment display synced vertical names and correct groups. Given I have a course with group configuration And I go to the Group Configuration page in Studio And I edit the name of the group configuration, add new group and remove old one And I change the name for the group "New group" to "Second Group" And I go to the Container page in Studio And I edit the Content Experiment Then I see the group configuration name is changed in `Group Configuration` dropdown And the group configuration name is changed on container page And I see the module has 2 active groups and one inactive And I see "Add missing groups" link exists When I click on "Add missing groups" link The I see the module has 3 active groups and one inactive """ 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 A'), Group("1", 'Group B'), Group("2", 'Group C')] ), ], }, }) # Add split test to vertical and assign newly created group configuration to it split_test = self._add_split_test_to_vertical(number=0, group_configuration_metadata={'user_partition_id': 0}) self.page.visit() config = self.page.experiment_group_configurations[0] config.edit() config.name = "Second Group Configuration Name" # `Group C` -> `Second Group` config.groups[2].name = "Second Group" # Add new group config.add_group() # Group D # Remove Group A config.groups[0].remove() # Save the configuration config.save() container = ContainerPage(self.browser, split_test.locator) container.visit() container.edit() component_editor = ComponentEditorView(self.browser, container.locator) self.assertEqual( "Second Group Configuration Name", component_editor.get_selected_option_text('Group Configuration') ) component_editor.cancel() self.assertIn( "Second Group Configuration Name", container.get_xblock_information_message() ) self.verify_groups( container, ['Group B', 'Second Group'], ['Group ID 0'], verify_missing_groups_not_present=False ) # Click the add button and verify that the groups were added on the page container.add_missing_groups() self.verify_groups(container, ['Group B', 'Second Group', 'Group D'], ['Group ID 0'])
def test_container_page_active_verticals_names_are_synced(self): """ Scenario: Ensure that the Content Experiment display synced vertical names and correct groups. Given I have a course with group configuration And I go to the Group Configuration page in Studio And I edit the name of the group configuration, add new group and remove old one And I change the name for the group "New group" to "Second Group" And I go to the Container page in Studio And I edit the Content Experiment Then I see the group configuration name is changed in `Group Configuration` dropdown And the group configuration name is changed on container page And I see the module has 2 active groups and one inactive And I see "Add missing groups" link exists When I click on "Add missing groups" link The I see the module has 3 active groups and one inactive """ 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 A'), Group("1", 'Group B'), Group("2", 'Group C') ]), ], }, }) # Add split test to vertical and assign newly created group configuration to it split_test = self._add_split_test_to_vertical( number=0, group_configuration_metadata={'user_partition_id': 0}) self.page.visit() config = self.page.experiment_group_configurations[0] config.edit() config.name = "Second Group Configuration Name" # `Group C` -> `Second Group` config.groups[2].name = "Second Group" # Add new group config.add_group() # Group D # Remove Group A config.groups[0].remove() # Save the configuration config.save() container = ContainerPage(self.browser, split_test.locator) container.visit() container.edit() component_editor = XBlockEditorView(self.browser, container.locator) self.assertEqual( "Second Group Configuration Name", component_editor.get_selected_option_text('Group Configuration')) component_editor.cancel() self.assertIn("Second Group Configuration Name", container.get_xblock_information_message()) self.verify_groups(container, ['Group B', 'Second Group'], ['Group ID 0'], verify_missing_groups_not_present=False) # Click the add button and verify that the groups were added on the page container.add_missing_groups() self.verify_groups(container, ['Group B', 'Second Group', 'Group D'], ['Group ID 0'])