Files
edx-platform/common/test/acceptance/tests/discussion/test_discussion.py
2021-03-09 18:03:34 +05:00

350 lines
17 KiB
Python

"""
Tests for discussion pages
"""
from uuid import uuid4
import pytest
from common.test.acceptance.fixtures.course import CourseFixture # lint-amnesty, pylint: disable=unused-import
from common.test.acceptance.fixtures.discussion import (
Comment,
Response,
SingleThreadViewFixture,
Thread,
)
from common.test.acceptance.pages.common.auto_auth import AutoAuthPage
from common.test.acceptance.pages.lms.discussion import (
DiscussionTabHomePage,
DiscussionTabSingleThreadPage,
)
from common.test.acceptance.tests.discussion.helpers import BaseDiscussionMixin, BaseDiscussionTestCase
from common.test.acceptance.tests.helpers import UniqueCourseTest
from openedx.core.lib.tests import attr
THREAD_CONTENT_WITH_LATEX = """Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt # lint-amnesty, pylint: disable=line-too-long
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
\n\n----------\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur. (b).\n\n
**(a)** $H_1(e^{j\\omega}) = \\sum_{n=-\\infty}^{\\infty}h_1[n]e^{-j\\omega n} =
\\sum_{n=-\\infty} ^{\\infty}h[n]e^{-j\\omega n}+\\delta_2e^{-j\\omega n_0}$
$= H(e^{j\\omega})+\\delta_2e^{-j\\omega n_0}=A_e (e^{j\\omega}) e^{-j\\omega n_0}
+\\delta_2e^{-j\\omega n_0}=e^{-j\\omega n_0} (A_e(e^{j\\omega})+\\delta_2)
$H_3(e^{j\\omega})=A_e(e^{j\\omega})+\\delta_2$. Dummy $A_e(e^{j\\omega})$ dummy post $.
$A_e(e^{j\\omega}) \\ge -\\delta_2$, it follows that $H_3(e^{j\\omega})$ is real and
$H_3(e^{j\\omega})\\ge 0$.\n\n**(b)** Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.\n\n
**Case 1:** If $re^{j\\theta}$ is a Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
\n\n**Case 3:** Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
Lorem $H_3(e^{j\\omega}) = P(cos\\omega)(cos\\omega - cos\\theta)^k$,
Lorem Lorem Lorem Lorem Lorem Lorem $P(cos\\omega)$ has no
$(cos\\omega - cos\\theta)$ factor.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
$P(cos\\theta) \\neq 0$. Since $P(cos\\omega)$ this is a dummy data post $\\omega$,
dummy $\\delta > 0$ such that for all $\\omega$ dummy $|\\omega - \\theta|
< \\delta$, $P(cos\\omega)$ Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit sse cillum dolore
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
reprehenderit in voluptate velit sse cillum dolore eu fugiat nulla pariatur.
"""
@attr(shard=2)
class DiscussionHomePageTest(BaseDiscussionTestCase):
"""
Tests for the discussion home page.
"""
SEARCHED_USERNAME = "gizmo"
def setUp(self):
super().setUp()
AutoAuthPage(self.browser, course_id=self.course_id).visit()
self.page = DiscussionTabHomePage(self.browser, self.course_id)
self.page.visit()
@attr('a11y')
def test_page_accessibility(self):
self.page.a11y_audit.config.set_rules({
"ignore": [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865
'region' # TODO: AC-932
]
})
self.page.a11y_audit.check_for_accessibility_errors()
class DiscussionTabMultipleThreadTest(BaseDiscussionTestCase, BaseDiscussionMixin):
"""
Tests for the discussion page with multiple threads
"""
def setUp(self):
super().setUp()
AutoAuthPage(self.browser, course_id=self.course_id).visit()
self.thread_count = 2
self.thread_ids = []
self.setup_multiple_threads(thread_count=self.thread_count)
self.thread_page_1 = DiscussionTabSingleThreadPage(
self.browser,
self.course_id,
self.discussion_id,
self.thread_ids[0]
)
self.thread_page_2 = DiscussionTabSingleThreadPage(
self.browser,
self.course_id,
self.discussion_id,
self.thread_ids[1]
)
self.thread_page_1.visit()
@attr('a11y')
def test_page_accessibility(self):
self.thread_page_1.a11y_audit.config.set_rules({
"ignore": [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865
'region', # TODO: AC-932
]
})
self.thread_page_1.a11y_audit.check_for_accessibility_errors()
self.thread_page_2.a11y_audit.config.set_rules({
"ignore": [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'region' # TODO: AC-932
]
})
self.thread_page_2.a11y_audit.check_for_accessibility_errors()
class DiscussionOpenClosedThreadTest(BaseDiscussionTestCase):
"""
Tests for checking the display of attributes on open and closed threads
"""
def setUp(self):
super().setUp()
self.thread_id = f"test_thread_{uuid4().hex}"
def setup_user(self, roles=[]): # lint-amnesty, pylint: disable=dangerous-default-value
roles_str = ','.join(roles)
self.user_id = AutoAuthPage(self.browser, course_id=self.course_id, roles=roles_str).visit().get_user_id() # lint-amnesty, pylint: disable=attribute-defined-outside-init
def setup_view(self, **thread_kwargs): # lint-amnesty, pylint: disable=missing-function-docstring
thread_kwargs.update({'commentable_id': self.discussion_id})
view = SingleThreadViewFixture(
Thread(id=self.thread_id, **thread_kwargs)
)
view.addResponse(Response(id="response1"))
view.push()
def setup_openclosed_thread_page(self, closed=False): # lint-amnesty, pylint: disable=missing-function-docstring
self.setup_user(roles=['Moderator'])
if closed:
self.setup_view(closed=True)
else:
self.setup_view()
page = self.create_single_thread_page(self.thread_id)
page.visit()
page.close_open_thread()
return page
@attr('a11y')
def test_page_accessibility(self):
page = self.setup_openclosed_thread_page()
page.a11y_audit.config.set_rules({
'ignore': [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'color-contrast', # Commented out for now because they reproducibly fail on Jenkins but not locally
'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865
'region', # TODO: AC-932
]
})
page.a11y_audit.check_for_accessibility_errors()
page = self.setup_openclosed_thread_page(True)
page.a11y_audit.config.set_rules({
'ignore': [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'color-contrast', # Commented out for now because they reproducibly fail on Jenkins but not locally
'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865
'region', # TODO: AC-932
]
})
page.a11y_audit.check_for_accessibility_errors()
class DiscussionResponseEditTest(BaseDiscussionTestCase):
"""
Tests for editing responses displayed beneath thread in the single thread view.
"""
def setup_user(self, roles=[]): # lint-amnesty, pylint: disable=dangerous-default-value
roles_str = ','.join(roles)
self.user_id = AutoAuthPage(self.browser, course_id=self.course_id, roles=roles_str).visit().get_user_id() # lint-amnesty, pylint: disable=attribute-defined-outside-init
def setup_view(self): # lint-amnesty, pylint: disable=missing-function-docstring
view = SingleThreadViewFixture(Thread(id="response_edit_test_thread", commentable_id=self.discussion_id))
view.addResponse(
Response(id="response_other_author", user_id="other", thread_id="response_edit_test_thread"),
)
view.addResponse(
Response(id="response_self_author", user_id=self.user_id, thread_id="response_edit_test_thread"),
)
view.push()
@attr('a11y')
def test_page_accessibility(self):
self.setup_user()
self.setup_view()
page = self.create_single_thread_page("response_edit_test_thread")
page.a11y_audit.config.set_rules({
'ignore': [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865
'region', # TODO: AC-932
]
})
page.visit()
page.a11y_audit.check_for_accessibility_errors()
class DiscussionCommentEditTest(BaseDiscussionTestCase):
"""
Tests for editing comments displayed beneath responses in the single thread view.
"""
def setup_user(self, roles=[]): # lint-amnesty, pylint: disable=dangerous-default-value
roles_str = ','.join(roles)
self.user_id = AutoAuthPage(self.browser, course_id=self.course_id, roles=roles_str).visit().get_user_id() # lint-amnesty, pylint: disable=attribute-defined-outside-init
def setup_view(self): # lint-amnesty, pylint: disable=missing-function-docstring
view = SingleThreadViewFixture(Thread(id="comment_edit_test_thread", commentable_id=self.discussion_id))
view.addResponse(
Response(id="response1"),
[Comment(id="comment_other_author", user_id="other"), Comment(id="comment_self_author", user_id=self.user_id)]) # lint-amnesty, pylint: disable=line-too-long
view.push()
@attr('a11y')
def test_page_accessibility(self):
self.setup_user()
self.setup_view()
page = self.create_single_thread_page("comment_edit_test_thread")
page.visit()
page.a11y_audit.config.set_rules({
'ignore': [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865
'region', # TODO: AC-932
]
})
page.a11y_audit.check_for_accessibility_errors()
@attr('a11y')
@pytest.mark.skip(reason='This test is too flaky to run at all. TNL-6215')
def test_inline_a11y(self):
"""
Tests Inline Discussion for accessibility issues.
"""
self.setup_multiple_threads(thread_count=3)
# First test the a11y of the expanded list of threads
self.discussion_page.expand_discussion()
self.discussion_page.a11y_audit.config.set_rules({
'ignore': [
'section'
]
})
self.discussion_page.a11y_audit.check_for_accessibility_errors()
# Now show the first thread and test the a11y again
self.discussion_page.show_thread(self.thread_ids[0])
self.discussion_page.a11y_audit.check_for_accessibility_errors()
# Finally show the new post form and test its a11y
self.discussion_page.click_new_post_button()
self.discussion_page.a11y_audit.check_for_accessibility_errors()
class DiscussionSearchAlertTest(UniqueCourseTest):
"""
Tests for spawning and dismissing alerts related to user search actions and their results.
"""
SEARCHED_USERNAME = "gizmo"
def setUp(self):
super().setUp()
CourseFixture(**self.course_info).install()
# first auto auth call sets up a user that we will search for in some tests
self.searched_user_id = AutoAuthPage(
self.browser,
username=self.SEARCHED_USERNAME,
course_id=self.course_id
).visit().get_user_id()
# this auto auth call creates the actual session user
AutoAuthPage(self.browser, course_id=self.course_id).visit()
self.page = DiscussionTabHomePage(self.browser, self.course_id)
self.page.visit()
@attr('a11y')
def test_page_accessibility(self):
self.page.a11y_audit.config.set_rules({
'ignore': [
'section', # TODO: AC-491
'aria-required-children', # TODO: AC-534
'aria-valid-attr', # TODO: LEARNER-6611 & LEARNER-6865
'region', # TODO: AC-932
]
})
self.page.a11y_audit.check_for_accessibility_errors()