Files
edx-platform/common/test/acceptance/tests/discussion/test_discussion_management.py
Feanil Patel 046feb0cf0 Merge pull request #22649 from edx/feanil/fix_pep8
Fix all E303 pep8 errors.
2019-12-30 13:32:26 -05:00

496 lines
22 KiB
Python

# -*- coding: utf-8 -*-
"""
End-to-end tests related to the divided discussion management on the LMS Instructor Dashboard
"""
import uuid
from common.test.acceptance.fixtures.course import CourseFixture, XBlockFixtureDesc
from common.test.acceptance.pages.common.auto_auth import AutoAuthPage
from common.test.acceptance.pages.common.utils import add_enrollment_course_modes
from common.test.acceptance.pages.lms.discussion import DiscussionTabSingleThreadPage
from common.test.acceptance.pages.lms.instructor_dashboard import InstructorDashboardPage
from common.test.acceptance.tests.discussion.helpers import BaseDiscussionMixin, CohortTestMixin
from common.test.acceptance.tests.helpers import UniqueCourseTest
from openedx.core.lib.tests import attr
class BaseDividedDiscussionTest(UniqueCourseTest, CohortTestMixin):
"""
Base class for tests related to divided discussions.
"""
def setUp(self):
"""
Set up a discussion topic
"""
super(BaseDividedDiscussionTest, self).setUp()
self.discussion_id = "test_discussion_{}".format(uuid.uuid4().hex)
self.course_fixture = CourseFixture(**self.course_info).add_children(
XBlockFixtureDesc("chapter", "Test Section").add_children(
XBlockFixtureDesc("sequential", "Test Subsection").add_children(
XBlockFixtureDesc("vertical", "Test Unit").add_children(
XBlockFixtureDesc(
"discussion",
"Test Discussion",
metadata={"discussion_id": self.discussion_id}
)
)
)
)
).install()
# create course with single cohort and two content groups (user_partition of type "cohort")
self.cohort_name = "OnlyCohort"
self.setup_cohort_config(self.course_fixture)
self.cohort_id = self.add_manual_cohort(self.course_fixture, self.cohort_name)
# login as an instructor
self.instructor_name = "instructor_user"
self.instructor_id = AutoAuthPage(
self.browser, username=self.instructor_name, email="instructor_user@example.com",
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.discussion_management_page = self.instructor_dashboard_page.select_discussion_management()
self.discussion_management_page.wait_for_page()
self.course_wide_key = 'course-wide'
self.inline_key = 'inline'
self.scheme_key = 'scheme'
def check_discussion_topic_visibility(self, visible=True):
"""
Assert that discussion topics are visible with appropriate content.
"""
self.assertEqual(visible, self.discussion_management_page.discussion_topics_visible())
if visible:
self.assertEqual(
"Course-Wide Discussion Topics",
self.discussion_management_page.divided_discussion_heading_is_visible(self.course_wide_key)
)
self.assertTrue(self.discussion_management_page.is_save_button_disabled(self.course_wide_key))
self.assertEqual(
"Content-Specific Discussion Topics",
self.discussion_management_page.divided_discussion_heading_is_visible(self.inline_key)
)
self.assertTrue(self.discussion_management_page.is_save_button_disabled(self.inline_key))
def reload_page(self, topics_visible=True):
"""
Refresh the page, then verify if the discussion topics are visible on the discussion
management instructor dashboard tab.
"""
self.browser.refresh()
self.discussion_management_page.wait_for_page()
self.instructor_dashboard_page.select_discussion_management()
self.discussion_management_page.wait_for_page()
self.check_discussion_topic_visibility(topics_visible)
def verify_save_confirmation_message(self, key):
"""
Verify that the save confirmation message for the specified portion of the page is visible.
"""
confirmation_message = self.discussion_management_page.get_divide_discussions_message(key=key)
self.assertIn("Your changes have been saved.", confirmation_message)
@attr(shard=6)
class DividedDiscussionTopicsTest(BaseDividedDiscussionTest):
"""
Tests for dividing the inline and course-wide discussion topics.
"""
def save_and_verify_discussion_topics(self, key):
"""
Saves the discussion topics and the verify the changes.
"""
# click on the inline save button.
self.discussion_management_page.save_discussion_topics(key)
# verifies that changes saved successfully.
self.verify_save_confirmation_message(key)
# save button disabled again.
self.assertTrue(self.discussion_management_page.is_save_button_disabled(key))
def verify_discussion_topics_after_reload(self, key, divided_topics):
"""
Verifies the changed topics.
"""
self.reload_page()
self.assertEqual(self.discussion_management_page.get_divided_topics_count(key), divided_topics)
def test_divide_course_wide_discussion_topic(self):
"""
Scenario: divide a course-wide discussion topic.
Given I have a course with a divide defined,
And a course-wide discussion with disabled Save button.
When I click on the course-wide discussion topic
Then I see the enabled save button
When I click on save button
Then I see success message
When I reload the page
Then I see the discussion topic selected
"""
self.check_discussion_topic_visibility()
divided_topics_before = self.discussion_management_page.get_divided_topics_count(self.course_wide_key)
self.discussion_management_page.select_discussion_topic(self.course_wide_key)
self.assertFalse(self.discussion_management_page.is_save_button_disabled(self.course_wide_key))
self.save_and_verify_discussion_topics(key=self.course_wide_key)
divided_topics_after = self.discussion_management_page.get_divided_topics_count(self.course_wide_key)
self.assertNotEqual(divided_topics_before, divided_topics_after)
self.verify_discussion_topics_after_reload(self.course_wide_key, divided_topics_after)
def test_always_divide_inline_topic_enabled(self):
"""
Scenario: Select the always_divide_inline_topics radio button
Given I have a course with a cohort defined,
And an inline discussion topic with disabled Save button.
When I click on always_divide_inline_topics
Then I see enabled save button
And I see disabled inline discussion topics
When I save the change
And I reload the page
Then I see the always_divide_inline_topics option enabled
"""
self.check_discussion_topic_visibility()
# enable always inline discussion topics and save the change
self.discussion_management_page.select_always_inline_discussion()
self.assertFalse(self.discussion_management_page.is_save_button_disabled(self.inline_key))
self.assertTrue(self.discussion_management_page.inline_discussion_topics_disabled())
self.discussion_management_page.save_discussion_topics(key=self.inline_key)
self.reload_page()
self.assertTrue(self.discussion_management_page.always_inline_discussion_selected())
def test_divide_some_inline_topics_enabled(self):
"""
Scenario: Select the divide_some_inline_topics radio button
Given I have a course with a divide defined and always_divide_inline_topics set to True
And an inline discussion topic with disabled Save button.
When I click on divide_some_inline_topics
Then I see enabled save button
And I see enabled inline discussion topics
When I save the change
And I reload the page
Then I see the divide_some_inline_topics option enabled
"""
self.check_discussion_topic_visibility()
# By default always inline discussion topics is False. Enable it (and reload the page).
self.assertFalse(self.discussion_management_page.always_inline_discussion_selected())
self.discussion_management_page.select_always_inline_discussion()
self.discussion_management_page.save_discussion_topics(key=self.inline_key)
self.reload_page()
self.assertFalse(self.discussion_management_page.divide_some_inline_discussion_selected())
# enable some inline discussion topic radio button.
self.discussion_management_page.select_divide_some_inline_discussion()
# I see that save button is enabled
self.assertFalse(self.discussion_management_page.is_save_button_disabled(self.inline_key))
# I see that inline discussion topics are enabled
self.assertFalse(self.discussion_management_page.inline_discussion_topics_disabled())
self.discussion_management_page.save_discussion_topics(key=self.inline_key)
self.reload_page()
self.assertTrue(self.discussion_management_page.divide_some_inline_discussion_selected())
def test_divide_inline_discussion_topic(self):
"""
Scenario: divide inline discussion topic.
Given I have a course with a divide defined,
And a inline discussion topic with disabled Save button
And When I click on inline discussion topic
And I see enabled save button
And When i click save button
Then I see success message
When I reload the page
Then I see the discussion topic selected
"""
self.check_discussion_topic_visibility()
divided_topics_before = self.discussion_management_page.get_divided_topics_count(self.inline_key)
# check the discussion topic.
self.discussion_management_page.select_discussion_topic(self.inline_key)
# Save button enabled.
self.assertFalse(self.discussion_management_page.is_save_button_disabled(self.inline_key))
# verifies that changes saved successfully.
self.save_and_verify_discussion_topics(key=self.inline_key)
divided_topics_after = self.discussion_management_page.get_divided_topics_count(self.inline_key)
self.assertNotEqual(divided_topics_before, divided_topics_after)
self.verify_discussion_topics_after_reload(self.inline_key, divided_topics_after)
def test_verify_that_selecting_the_final_child_selects_category(self):
"""
Scenario: Category should be selected on selecting final child.
Given I have a course with a cohort defined,
And a inline discussion with disabled Save button.
When I click on child topics
Then I see enabled saved button
Then I see parent category to be checked.
"""
self.check_discussion_topic_visibility()
# category should not be selected.
self.assertFalse(self.discussion_management_page.is_category_selected())
# check the discussion topic.
self.discussion_management_page.select_discussion_topic(self.inline_key)
# verify that category is selected.
self.assertTrue(self.discussion_management_page.is_category_selected())
def test_verify_that_deselecting_the_final_child_deselects_category(self):
"""
Scenario: Category should be deselected on deselecting final child.
Given I have a course with a cohort defined,
And a inline discussion with disabled Save button.
When I click on final child topics
Then I see enabled saved button
Then I see parent category to be deselected.
"""
self.check_discussion_topic_visibility()
# category should not be selected.
self.assertFalse(self.discussion_management_page.is_category_selected())
# check the discussion topic.
self.discussion_management_page.select_discussion_topic(self.inline_key)
# verify that category is selected.
self.assertTrue(self.discussion_management_page.is_category_selected())
# un-check the discussion topic.
self.discussion_management_page.select_discussion_topic(self.inline_key)
# category should not be selected.
self.assertFalse(self.discussion_management_page.is_category_selected())
@attr(shard=6)
class DivisionSchemeTest(BaseDividedDiscussionTest, BaseDiscussionMixin):
"""
Tests for changing the division scheme for Discussions.
"""
def add_modes_and_view_discussion_mgmt_page(self, modes):
"""
Adds enrollment modes to the course, and then goes to the
discussion tab on the instructor dashboard.
"""
add_enrollment_course_modes(self.browser, self.course_id, modes)
self.view_discussion_management_page()
def view_discussion_management_page(self):
"""
Go to the discussion tab on the instructor dashboard.
"""
self.instructor_dashboard_page.visit()
self.assertTrue(self.instructor_dashboard_page.is_discussion_management_visible())
self.instructor_dashboard_page.select_discussion_management()
self.discussion_management_page.wait_for_page()
def setup_thread_page(self, thread_id):
"""
This is called by BaseDiscussionMixin.setup_thread.
"""
self.thread_page = DiscussionTabSingleThreadPage(
self.browser, self.course_id, self.discussion_id, thread_id
)
self.thread_page.visit()
def test_not_divided_hides_discussion_topics(self):
"""
Tests that discussion topics are hidden iff discussion division is disabled.
"""
# Initially "Cohort" is the selected scheme.
self.assertTrue(
self.discussion_management_page.division_scheme_visible(self.discussion_management_page.COHORT_SCHEME)
)
self.assertEqual(
self.discussion_management_page.COHORT_SCHEME,
self.discussion_management_page.get_selected_scheme()
)
self.check_discussion_topic_visibility(visible=True)
self.discussion_management_page.select_division_scheme(self.discussion_management_page.NOT_DIVIDED_SCHEME)
self.verify_save_confirmation_message(self.scheme_key)
self.check_discussion_topic_visibility(visible=False)
# Reload the page and make sure that the change was persisted
self.reload_page(topics_visible=False)
self.assertTrue(self.discussion_management_page.division_scheme_visible(
self.discussion_management_page.COHORT_SCHEME)
)
self.assertEqual(
self.discussion_management_page.NOT_DIVIDED_SCHEME,
self.discussion_management_page.get_selected_scheme()
)
# Select "cohort" again and make sure that the discussion topics appear.
self.discussion_management_page.select_division_scheme(self.discussion_management_page.COHORT_SCHEME)
self.verify_save_confirmation_message(self.scheme_key)
self.check_discussion_topic_visibility(visible=True)
def test_disabling_cohorts(self):
"""
Test that the discussions management tab hides when there is <= 1 enrollment track, the Cohort division scheme
is not selected, and cohorts are disabled.
(even without reloading the page).
"""
self.disable_cohorting(self.course_fixture)
self.instructor_dashboard_page.visit()
self.assertFalse(self.instructor_dashboard_page.is_discussion_management_visible())
def test_disabling_cohorts_while_selected(self):
"""
Test that disabling cohorts does not hide the discussion tab when there is more than one enrollment track.
Also that the division scheme for cohorts is visible iff it was selected.
(even without reloading the page).
"""
add_enrollment_course_modes(self.browser, self.course_id, ['audit', 'verified'])
# Verify that the tab is visible, the cohort scheme is selected by default for divided discussions
self.disable_cohorting(self.course_fixture)
# Go to Discussions tab and ensure that the correct scheme options are visible
self.view_discussion_management_page()
self.assertTrue(
self.discussion_management_page.division_scheme_visible(
self.discussion_management_page.COHORT_SCHEME
)
)
def test_disabling_cohorts_while_not_selected(self):
"""
Test that disabling cohorts does not hide the discussion tab when there is more than one enrollment track.
Also that the division scheme for cohorts is not visible when cohorts are disabled and another scheme is
selected for division.
(even without reloading the page).
"""
add_enrollment_course_modes(self.browser, self.course_id, ['audit', 'verified'])
# Verify that the tab is visible
self.view_discussion_management_page()
self.discussion_management_page.select_division_scheme(self.discussion_management_page.ENROLLMENT_TRACK_SCHEME)
self.verify_save_confirmation_message(self.scheme_key)
self.disable_cohorting(self.course_fixture)
# Go to Discussions tab and ensure that the correct scheme options are visible
self.view_discussion_management_page()
self.assertFalse(
self.discussion_management_page.division_scheme_visible(
self.discussion_management_page.COHORT_SCHEME
)
)
def test_single_enrollment_mode(self):
"""
Test that the enrollment track scheme is not visible if there is a single enrollment mode.
"""
self.add_modes_and_view_discussion_mgmt_page(['audit'])
self.assertFalse(
self.discussion_management_page.division_scheme_visible(
self.discussion_management_page.ENROLLMENT_TRACK_SCHEME
)
)
def test_radio_buttons_with_multiple_enrollment_modes(self):
"""
Test that the enrollment track scheme is visible if there are multiple enrollment tracks,
and that the selection can be persisted.
Also verifies that the cohort division scheme is not presented if cohorts are disabled and cohorts
are not the selected division scheme.
"""
self.add_modes_and_view_discussion_mgmt_page(['audit', 'verified'])
self.assertTrue(
self.discussion_management_page.division_scheme_visible(
self.discussion_management_page.ENROLLMENT_TRACK_SCHEME
)
)
# And the cohort scheme is initially visible because it is selected (and cohorts are enabled).
self.assertTrue(
self.discussion_management_page.division_scheme_visible(self.discussion_management_page.COHORT_SCHEME)
)
self.discussion_management_page.select_division_scheme(self.discussion_management_page.ENROLLMENT_TRACK_SCHEME)
self.verify_save_confirmation_message(self.scheme_key)
self.check_discussion_topic_visibility(visible=True)
# Also disable cohorts so we can verify that the cohort scheme choice goes away.
self.disable_cohorting(self.course_fixture)
self.reload_page(topics_visible=True)
self.assertEqual(
self.discussion_management_page.ENROLLMENT_TRACK_SCHEME,
self.discussion_management_page.get_selected_scheme()
)
# Verify that the cohort scheme is no longer visible as cohorts are disabled.
self.assertFalse(
self.discussion_management_page.division_scheme_visible(self.discussion_management_page.COHORT_SCHEME)
)
def test_enrollment_track_discussion_visibility_label(self):
"""
If enrollment tracks are the division scheme, verifies that discussion visibility labels
correctly render.
Note that there are similar tests for cohorts in test_cohorts.py.
"""
def refresh_thread_page():
self.browser.refresh()
self.thread_page.wait_for_page()
# Make moderator for viewing all groups in discussions.
AutoAuthPage(self.browser, course_id=self.course_id, roles="Moderator", staff=True).visit()
self.add_modes_and_view_discussion_mgmt_page(['audit', 'verified'])
self.discussion_management_page.select_division_scheme(self.discussion_management_page.ENROLLMENT_TRACK_SCHEME)
self.verify_save_confirmation_message(self.scheme_key)
# Set "always divide" as the thread we will be creating will be an inline thread,
# and this way the thread does not need to be explicitly divided.
self.enable_always_divide_inline_discussions(self.course_fixture)
# Create a thread with group_id corresponding to the Audit enrollment mode.
# The Audit group ID is 1, and for the comment service group_id we negate it.
self.setup_thread(1, group_id=-1)
refresh_thread_page()
self.assertEqual(
self.thread_page.get_group_visibility_label(),
u"This post is visible only to {}.".format("Audit")
)
# Disable dividing discussions and verify that the post now shows as visible to everyone.
self.view_discussion_management_page()
self.discussion_management_page.select_division_scheme(self.discussion_management_page.NOT_DIVIDED_SCHEME)
self.verify_save_confirmation_message(self.scheme_key)
self.thread_page.visit()
self.assertEqual(self.thread_page.get_group_visibility_label(), "This post is visible to everyone.")