Commit 16847d85 by Greg Price

Add bok-choy tests for inline response pagination

parent 3af90ef2
...@@ -14,6 +14,7 @@ class StubCommentsServiceHandler(StubHttpRequestHandler): ...@@ -14,6 +14,7 @@ class StubCommentsServiceHandler(StubHttpRequestHandler):
"/api/v1/threads$": self.do_threads, "/api/v1/threads$": self.do_threads,
"/api/v1/threads/(?P<thread_id>\\w+)$": self.do_thread, "/api/v1/threads/(?P<thread_id>\\w+)$": self.do_thread,
"/api/v1/comments/(?P<comment_id>\\w+)$": self.do_comment, "/api/v1/comments/(?P<comment_id>\\w+)$": self.do_comment,
"/api/v1/(?P<commentable_id>\\w+)/threads$": self.do_commentable,
} }
path = urlparse.urlparse(self.path).path path = urlparse.urlparse(self.path).path
for pattern in pattern_handlers: for pattern in pattern_handlers:
...@@ -63,6 +64,17 @@ class StubCommentsServiceHandler(StubHttpRequestHandler): ...@@ -63,6 +64,17 @@ class StubCommentsServiceHandler(StubHttpRequestHandler):
comment = self.server.config['comments'][comment_id] comment = self.server.config['comments'][comment_id]
self.send_json_response(comment) self.send_json_response(comment)
def do_commentable(self, commentable_id):
self.send_json_response({
"collection": [
thread
for thread in self.server.config.get('threads', {}).values()
if thread.get('commentable_id') == commentable_id
],
"page": 1,
"num_pages": 1,
})
class StubCommentsService(StubHttpService): class StubCommentsService(StubHttpService):
HANDLER_CLASS = StubCommentsServiceHandler HANDLER_CLASS = StubCommentsServiceHandler
"""
Courseware page.
"""
from .course_page import CoursePage
class CoursewarePage(CoursePage):
"""
Course info.
"""
url_path = "courseware"
def is_browser_on_page(self):
return self.q(css='body.courseware').present
from bok_choy.page_object import unguarded from bok_choy.page_object import PageObject
from bok_choy.promise import EmptyPromise from bok_choy.promise import EmptyPromise
from .course_page import CoursePage from .course_page import CoursePage
class DiscussionSingleThreadPage(CoursePage): class DiscussionThreadPage(PageObject):
def __init__(self, browser, course_id, thread_id): url = None
super(DiscussionSingleThreadPage, self).__init__(browser, course_id)
self.thread_id = thread_id
def is_browser_on_page(self): def __init__(self, browser, thread_selector):
return self.q( super(DiscussionThreadPage, self).__init__(browser)
css="body.discussion .discussion-article[data-id='{thread_id}']".format(thread_id=self.thread_id) self.thread_selector = thread_selector
).present
def _find_within(self, selector):
"""
Returns a query corresponding to the given CSS selector within the scope
of this thread page
"""
return self.q(css=self.thread_selector + " " + selector)
@property def is_browser_on_page(self):
@unguarded return self.q(css=self.thread_selector).present
def url_path(self):
return "discussion/forum/dummy/threads/" + self.thread_id
def _get_element_text(self, selector): def _get_element_text(self, selector):
""" """
Returns the text of the first element matching the given selector, or Returns the text of the first element matching the given selector, or
None if no such element exists None if no such element exists
""" """
text_list = self.q(css=selector).text text_list = self._find_within(selector).text
return text_list[0] if text_list else None return text_list[0] if text_list else None
def _is_element_visible(self, selector):
query = self._find_within(selector)
return query.present and query.visible
def get_response_total_text(self): def get_response_total_text(self):
"""Returns the response count text, or None if not present""" """Returns the response count text, or None if not present"""
return self._get_element_text(".response-count") return self._get_element_text(".response-count")
def get_num_displayed_responses(self): def get_num_displayed_responses(self):
"""Returns the number of responses actually rendered""" """Returns the number of responses actually rendered"""
return len(self.q(css=".discussion-response").results) return len(self._find_within(".discussion-response"))
def get_shown_responses_text(self): def get_shown_responses_text(self):
"""Returns the shown response count text, or None if not present""" """Returns the shown response count text, or None if not present"""
...@@ -45,7 +51,7 @@ class DiscussionSingleThreadPage(CoursePage): ...@@ -45,7 +51,7 @@ class DiscussionSingleThreadPage(CoursePage):
def load_more_responses(self): def load_more_responses(self):
"""Clicks the load more responses button and waits for responses to load""" """Clicks the load more responses button and waits for responses to load"""
self.q(css=".load-response-button").first.click() self._find_within(".load-response-button").click()
def _is_ajax_finished(): def _is_ajax_finished():
return self.browser.execute_script("return jQuery.active") == 0 return self.browser.execute_script("return jQuery.active") == 0
...@@ -64,25 +70,19 @@ class DiscussionSingleThreadPage(CoursePage): ...@@ -64,25 +70,19 @@ class DiscussionSingleThreadPage(CoursePage):
Clicks the add response button and ensures that the response text Clicks the add response button and ensures that the response text
field receives focus field receives focus
""" """
self.q(css=".add-response-btn").first.click() self._find_within(".add-response-btn").first.click()
EmptyPromise( EmptyPromise(
lambda: self.q(css="#wmd-input-reply-body-{thread_id}:focus".format(thread_id=self.thread_id)), lambda: self._find_within(".discussion-reply-new textarea:focus").present,
"Response field received focus" "Response field received focus"
).fulfill() ).fulfill()
def _is_element_visible(self, selector):
return (
self.q(css=selector).present and
self.q(css=selector).visible
)
def is_response_editor_visible(self, response_id): def is_response_editor_visible(self, response_id):
"""Returns true if the response editor is present, false otherwise""" """Returns true if the response editor is present, false otherwise"""
return self._is_element_visible(".response_{} .edit-post-body".format(response_id)) return self._is_element_visible(".response_{} .edit-post-body".format(response_id))
def start_response_edit(self, response_id): def start_response_edit(self, response_id):
"""Click the edit button for the response, loading the editing view""" """Click the edit button for the response, loading the editing view"""
self.q(css=".response_{} .discussion-response .action-edit".format(response_id)).first.click() self._find_within(".response_{} .discussion-response .action-edit".format(response_id)).first.click()
EmptyPromise( EmptyPromise(
lambda: self.is_response_editor_visible(response_id), lambda: self.is_response_editor_visible(response_id),
"Response edit started" "Response edit started"
...@@ -105,7 +105,7 @@ class DiscussionSingleThreadPage(CoursePage): ...@@ -105,7 +105,7 @@ class DiscussionSingleThreadPage(CoursePage):
def delete_comment(self, comment_id): def delete_comment(self, comment_id):
with self.handle_alert(): with self.handle_alert():
self.q(css="#comment_{} div.action-delete".format(comment_id)).first.click() self._find_within("#comment_{} div.action-delete".format(comment_id)).first.click()
EmptyPromise( EmptyPromise(
lambda: not self.is_comment_visible(comment_id), lambda: not self.is_comment_visible(comment_id),
"Deleted comment was removed" "Deleted comment was removed"
...@@ -120,12 +120,12 @@ class DiscussionSingleThreadPage(CoursePage): ...@@ -120,12 +120,12 @@ class DiscussionSingleThreadPage(CoursePage):
return self._is_element_visible(".edit-comment-body[data-id='{}']".format(comment_id)) return self._is_element_visible(".edit-comment-body[data-id='{}']".format(comment_id))
def _get_comment_editor_value(self, comment_id): def _get_comment_editor_value(self, comment_id):
return self.q(css="#wmd-input-edit-comment-body-{}".format(comment_id)).text[0] return self._find_within("#wmd-input-edit-comment-body-{}".format(comment_id)).text[0]
def start_comment_edit(self, comment_id): def start_comment_edit(self, comment_id):
"""Click the edit button for the comment, loading the editing view""" """Click the edit button for the comment, loading the editing view"""
old_body = self.get_comment_body(comment_id) old_body = self.get_comment_body(comment_id)
self.q(css="#comment_{} .action-edit".format(comment_id)).first.click() self._find_within("#comment_{} .action-edit".format(comment_id)).first.click()
EmptyPromise( EmptyPromise(
lambda: ( lambda: (
self.is_comment_editor_visible(comment_id) and self.is_comment_editor_visible(comment_id) and
...@@ -137,11 +137,11 @@ class DiscussionSingleThreadPage(CoursePage): ...@@ -137,11 +137,11 @@ class DiscussionSingleThreadPage(CoursePage):
def set_comment_editor_value(self, comment_id, new_body): def set_comment_editor_value(self, comment_id, new_body):
"""Replace the contents of the comment editor""" """Replace the contents of the comment editor"""
self.q(css="#comment_{} .wmd-input".format(comment_id)).fill(new_body) self._find_within("#comment_{} .wmd-input".format(comment_id)).fill(new_body)
def submit_comment_edit(self, comment_id, new_comment_body): def submit_comment_edit(self, comment_id, new_comment_body):
"""Click the submit button on the comment editor""" """Click the submit button on the comment editor"""
self.q(css="#comment_{} .post-update".format(comment_id)).first.click() self._find_within("#comment_{} .post-update".format(comment_id)).first.click()
EmptyPromise( EmptyPromise(
lambda: ( lambda: (
not self.is_comment_editor_visible(comment_id) and not self.is_comment_editor_visible(comment_id) and
...@@ -153,7 +153,7 @@ class DiscussionSingleThreadPage(CoursePage): ...@@ -153,7 +153,7 @@ class DiscussionSingleThreadPage(CoursePage):
def cancel_comment_edit(self, comment_id, original_body): def cancel_comment_edit(self, comment_id, original_body):
"""Click the cancel button on the comment editor""" """Click the cancel button on the comment editor"""
self.q(css="#comment_{} .post-cancel".format(comment_id)).first.click() self._find_within("#comment_{} .post-cancel".format(comment_id)).first.click()
EmptyPromise( EmptyPromise(
lambda: ( lambda: (
not self.is_comment_editor_visible(comment_id) and not self.is_comment_editor_visible(comment_id) and
...@@ -162,3 +162,72 @@ class DiscussionSingleThreadPage(CoursePage): ...@@ -162,3 +162,72 @@ class DiscussionSingleThreadPage(CoursePage):
), ),
"Comment edit was canceled" "Comment edit was canceled"
).fulfill() ).fulfill()
class DiscussionTabSingleThreadPage(CoursePage):
def __init__(self, browser, course_id, thread_id):
super(DiscussionTabSingleThreadPage, self).__init__(browser, course_id)
self.thread_page = DiscussionThreadPage(
browser,
"body.discussion .discussion-article[data-id='{thread_id}']".format(thread_id=thread_id)
)
self.url_path = "discussion/forum/dummy/threads/" + thread_id
def is_browser_on_page(self):
return self.thread_page.is_browser_on_page()
def __getattr__(self, name):
return getattr(self.thread_page, name)
class InlineDiscussionPage(PageObject):
url = None
def __init__(self, browser, discussion_id):
super(InlineDiscussionPage, self).__init__(browser)
self._discussion_selector = (
"body.courseware .discussion-module[data-discussion-id='{discussion_id}'] ".format(
discussion_id=discussion_id
)
)
def _find_within(self, selector):
"""
Returns a query corresponding to the given CSS selector within the scope
of this discussion page
"""
return self.q(css=self._discussion_selector + " " + selector)
def is_browser_on_page(self):
return self.q(css=self._discussion_selector).present
def is_discussion_expanded(self):
return self._find_within(".discussion").present
def expand_discussion(self):
"""Click the link to expand the discussion"""
self._find_within(".discussion-show").first.click()
EmptyPromise(
self.is_discussion_expanded,
"Discussion expanded"
).fulfill()
def get_num_displayed_threads(self):
return len(self._find_within(".discussion-thread"))
class InlineDiscussionThreadPage(DiscussionThreadPage):
def __init__(self, browser, thread_id):
super(InlineDiscussionThreadPage, self).__init__(
browser,
"body.courseware .discussion-module #thread_{thread_id}".format(thread_id=thread_id)
)
def expand(self):
"""Clicks the link to expand the thread"""
self._find_within(".expand-post").first.click()
EmptyPromise(
lambda: bool(self.get_response_total_text()),
"Thread expanded"
).fulfill()
...@@ -2,96 +2,132 @@ ...@@ -2,96 +2,132 @@
Tests for discussion pages Tests for discussion pages
""" """
from uuid import uuid4
from .helpers import UniqueCourseTest from .helpers import UniqueCourseTest
from ..pages.studio.auto_auth import AutoAuthPage from ..pages.studio.auto_auth import AutoAuthPage
from ..pages.lms.discussion_single_thread import DiscussionSingleThreadPage from ..pages.lms.courseware import CoursewarePage
from ..fixtures.course import CourseFixture from ..pages.lms.discussion import (
DiscussionTabSingleThreadPage,
InlineDiscussionPage,
InlineDiscussionThreadPage
)
from ..fixtures.course import CourseFixture, XBlockFixtureDesc
from ..fixtures.discussion import SingleThreadViewFixture, Thread, Response, Comment from ..fixtures.discussion import SingleThreadViewFixture, Thread, Response, Comment
class DiscussionSingleThreadTest(UniqueCourseTest): class DiscussionResponsePaginationTestMixin(object):
""" """
Tests for the discussion page displaying a single thread A mixin containing tests for response pagination for use by both inline
discussion and the discussion tab
""" """
def setUp(self): def setup_thread(self, num_responses, **thread_kwargs):
super(DiscussionSingleThreadTest, self).setUp() """
Create a test thread with the given number of responses, passing all
keyword arguments through to the Thread fixture, then invoke
setup_thread_page.
"""
thread_id = "test_thread_{}".format(uuid4().hex)
thread_fixture = SingleThreadViewFixture(
Thread(id=thread_id, commentable_id=self.discussion_id, **thread_kwargs)
)
for i in range(num_responses):
thread_fixture.addResponse(Response(id=str(i), body=str(i)))
thread_fixture.push()
self.setup_thread_page(thread_id)
def assert_response_display_correct(self, response_total, displayed_responses):
"""
Assert that various aspects of the display of responses are all correct:
* Text indicating total number of responses
* Presence of "Add a response" button
* Number of responses actually displayed
* Presence and text of indicator of how many responses are shown
* Presence and text of button to load more responses
"""
self.assertEqual(
self.thread_page.get_response_total_text(),
str(response_total) + " responses"
)
self.assertEqual(self.thread_page.has_add_response_button(), response_total != 0)
self.assertEqual(self.thread_page.get_num_displayed_responses(), displayed_responses)
self.assertEqual(
self.thread_page.get_shown_responses_text(),
(
None if response_total == 0 else
"Showing all responses" if response_total == displayed_responses else
"Showing first {} responses".format(displayed_responses)
)
)
self.assertEqual(
self.thread_page.get_load_responses_button_text(),
(
None if response_total == displayed_responses else
"Load all responses" if response_total - displayed_responses < 100 else
"Load next 100 responses"
)
)
def test_pagination_no_responses(self):
self.setup_thread(0)
self.assert_response_display_correct(0, 0)
def test_pagination_few_responses(self):
self.setup_thread(5)
self.assert_response_display_correct(5, 5)
def test_pagination_two_response_pages(self):
self.setup_thread(50)
self.assert_response_display_correct(50, 25)
self.thread_page.load_more_responses()
self.assert_response_display_correct(50, 50)
def test_pagination_exactly_two_response_pages(self):
self.setup_thread(125)
self.assert_response_display_correct(125, 25)
self.thread_page.load_more_responses()
self.assert_response_display_correct(125, 125)
def test_pagination_three_response_pages(self):
self.setup_thread(150)
self.assert_response_display_correct(150, 25)
self.thread_page.load_more_responses()
self.assert_response_display_correct(150, 125)
self.thread_page.load_more_responses()
self.assert_response_display_correct(150, 150)
# Create a course to register for def test_add_response_button(self):
CourseFixture(**self.course_info).install() self.setup_thread(5)
self.assertTrue(self.thread_page.has_add_response_button())
self.thread_page.click_add_response_button()
self.user_id = AutoAuthPage(self.browser, course_id=self.course_id).visit().get_user_id() def test_add_response_button_closed_thread(self):
self.setup_thread(5, closed=True)
self.assertFalse(self.thread_page.has_add_response_button())
def setup_thread(self, thread, num_responses):
view = SingleThreadViewFixture(thread=thread)
for i in range(num_responses):
view.addResponse(Response(id=str(i), body=str(i)))
view.push()
def test_no_responses(self): class DiscussionTabSingleThreadTest(UniqueCourseTest, DiscussionResponsePaginationTestMixin):
self.setup_thread(Thread(id="0_responses"), 0) """
page = DiscussionSingleThreadPage(self.browser, self.course_id, "0_responses") Tests for the discussion page displaying a single thread
page.visit() """
self.assertEqual(page.get_response_total_text(), "0 responses")
self.assertFalse(page.has_add_response_button())
self.assertEqual(page.get_num_displayed_responses(), 0)
self.assertEqual(page.get_shown_responses_text(), None)
self.assertIsNone(page.get_load_responses_button_text())
def test_few_responses(self):
self.setup_thread(Thread(id="5_responses"), 5)
page = DiscussionSingleThreadPage(self.browser, self.course_id, "5_responses")
page.visit()
self.assertEqual(page.get_response_total_text(), "5 responses")
self.assertEqual(page.get_num_displayed_responses(), 5)
self.assertEqual(page.get_shown_responses_text(), "Showing all responses")
self.assertIsNone(page.get_load_responses_button_text())
def test_two_response_pages(self):
self.setup_thread(Thread(id="50_responses"), 50)
page = DiscussionSingleThreadPage(self.browser, self.course_id, "50_responses")
page.visit()
self.assertEqual(page.get_response_total_text(), "50 responses")
self.assertEqual(page.get_num_displayed_responses(), 25)
self.assertEqual(page.get_shown_responses_text(), "Showing first 25 responses")
self.assertEqual(page.get_load_responses_button_text(), "Load all responses")
page.load_more_responses()
self.assertEqual(page.get_num_displayed_responses(), 50)
self.assertEqual(page.get_shown_responses_text(), "Showing all responses")
self.assertEqual(page.get_load_responses_button_text(), None)
def test_three_response_pages(self):
self.setup_thread(Thread(id="150_responses"), 150)
page = DiscussionSingleThreadPage(self.browser, self.course_id, "150_responses")
page.visit()
self.assertEqual(page.get_response_total_text(), "150 responses")
self.assertEqual(page.get_num_displayed_responses(), 25)
self.assertEqual(page.get_shown_responses_text(), "Showing first 25 responses")
self.assertEqual(page.get_load_responses_button_text(), "Load next 100 responses")
page.load_more_responses() def setUp(self):
self.assertEqual(page.get_num_displayed_responses(), 125) super(DiscussionTabSingleThreadTest, self).setUp()
self.assertEqual(page.get_shown_responses_text(), "Showing first 125 responses") self.discussion_id = "test_discussion_{}".format(uuid4().hex)
self.assertEqual(page.get_load_responses_button_text(), "Load all responses")
page.load_more_responses() # Create a course to register for
self.assertEqual(page.get_num_displayed_responses(), 150) CourseFixture(**self.course_info).install()
self.assertEqual(page.get_shown_responses_text(), "Showing all responses")
self.assertEqual(page.get_load_responses_button_text(), None)
def test_add_response_button(self): AutoAuthPage(self.browser, course_id=self.course_id).visit()
self.setup_thread(Thread(id="5_responses"), 5)
page = DiscussionSingleThreadPage(self.browser, self.course_id, "5_responses")
page.visit()
self.assertTrue(page.has_add_response_button())
page.click_add_response_button()
def test_add_response_button_closed_thread(self): def setup_thread_page(self, thread_id):
self.setup_thread(Thread(id="5_responses_closed", closed=True), 5) self.thread_page = DiscussionTabSingleThreadPage(self.browser, self.course_id, thread_id) # pylint:disable=W0201
page = DiscussionSingleThreadPage(self.browser, self.course_id, "5_responses_closed") self.thread_page.visit()
page.visit()
self.assertFalse(page.has_add_response_button())
class DiscussionCommentDeletionTest(UniqueCourseTest): class DiscussionCommentDeletionTest(UniqueCourseTest):
...@@ -119,7 +155,7 @@ class DiscussionCommentDeletionTest(UniqueCourseTest): ...@@ -119,7 +155,7 @@ class DiscussionCommentDeletionTest(UniqueCourseTest):
def test_comment_deletion_as_student(self): def test_comment_deletion_as_student(self):
self.setup_user() self.setup_user()
self.setup_view() self.setup_view()
page = DiscussionSingleThreadPage(self.browser, self.course_id, "comment_deletion_test_thread") page = DiscussionTabSingleThreadPage(self.browser, self.course_id, "comment_deletion_test_thread")
page.visit() page.visit()
self.assertTrue(page.is_comment_deletable("comment_self_author")) self.assertTrue(page.is_comment_deletable("comment_self_author"))
self.assertTrue(page.is_comment_visible("comment_other_author")) self.assertTrue(page.is_comment_visible("comment_other_author"))
...@@ -129,7 +165,7 @@ class DiscussionCommentDeletionTest(UniqueCourseTest): ...@@ -129,7 +165,7 @@ class DiscussionCommentDeletionTest(UniqueCourseTest):
def test_comment_deletion_as_moderator(self): def test_comment_deletion_as_moderator(self):
self.setup_user(roles=['Moderator']) self.setup_user(roles=['Moderator'])
self.setup_view() self.setup_view()
page = DiscussionSingleThreadPage(self.browser, self.course_id, "comment_deletion_test_thread") page = DiscussionTabSingleThreadPage(self.browser, self.course_id, "comment_deletion_test_thread")
page.visit() page.visit()
self.assertTrue(page.is_comment_deletable("comment_self_author")) self.assertTrue(page.is_comment_deletable("comment_self_author"))
self.assertTrue(page.is_comment_deletable("comment_other_author")) self.assertTrue(page.is_comment_deletable("comment_other_author"))
...@@ -168,7 +204,7 @@ class DiscussionCommentEditTest(UniqueCourseTest): ...@@ -168,7 +204,7 @@ class DiscussionCommentEditTest(UniqueCourseTest):
def test_edit_comment_as_student(self): def test_edit_comment_as_student(self):
self.setup_user() self.setup_user()
self.setup_view() self.setup_view()
page = DiscussionSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread") page = DiscussionTabSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread")
page.visit() page.visit()
self.assertTrue(page.is_comment_editable("comment_self_author")) self.assertTrue(page.is_comment_editable("comment_self_author"))
self.assertTrue(page.is_comment_visible("comment_other_author")) self.assertTrue(page.is_comment_visible("comment_other_author"))
...@@ -178,7 +214,7 @@ class DiscussionCommentEditTest(UniqueCourseTest): ...@@ -178,7 +214,7 @@ class DiscussionCommentEditTest(UniqueCourseTest):
def test_edit_comment_as_moderator(self): def test_edit_comment_as_moderator(self):
self.setup_user(roles=["Moderator"]) self.setup_user(roles=["Moderator"])
self.setup_view() self.setup_view()
page = DiscussionSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread") page = DiscussionTabSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread")
page.visit() page.visit()
self.assertTrue(page.is_comment_editable("comment_self_author")) self.assertTrue(page.is_comment_editable("comment_self_author"))
self.assertTrue(page.is_comment_editable("comment_other_author")) self.assertTrue(page.is_comment_editable("comment_other_author"))
...@@ -188,7 +224,7 @@ class DiscussionCommentEditTest(UniqueCourseTest): ...@@ -188,7 +224,7 @@ class DiscussionCommentEditTest(UniqueCourseTest):
def test_cancel_comment_edit(self): def test_cancel_comment_edit(self):
self.setup_user() self.setup_user()
self.setup_view() self.setup_view()
page = DiscussionSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread") page = DiscussionTabSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread")
page.visit() page.visit()
self.assertTrue(page.is_comment_editable("comment_self_author")) self.assertTrue(page.is_comment_editable("comment_self_author"))
original_body = page.get_comment_body("comment_self_author") original_body = page.get_comment_body("comment_self_author")
...@@ -200,7 +236,7 @@ class DiscussionCommentEditTest(UniqueCourseTest): ...@@ -200,7 +236,7 @@ class DiscussionCommentEditTest(UniqueCourseTest):
"""Only one editor should be visible at a time within a single response""" """Only one editor should be visible at a time within a single response"""
self.setup_user(roles=["Moderator"]) self.setup_user(roles=["Moderator"])
self.setup_view() self.setup_view()
page = DiscussionSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread") page = DiscussionTabSingleThreadPage(self.browser, self.course_id, "comment_edit_test_thread")
page.visit() page.visit()
self.assertTrue(page.is_comment_editable("comment_self_author")) self.assertTrue(page.is_comment_editable("comment_self_author"))
self.assertTrue(page.is_comment_editable("comment_other_author")) self.assertTrue(page.is_comment_editable("comment_other_author"))
...@@ -224,3 +260,44 @@ class DiscussionCommentEditTest(UniqueCourseTest): ...@@ -224,3 +260,44 @@ class DiscussionCommentEditTest(UniqueCourseTest):
page.cancel_comment_edit("comment_self_author", original_body) page.cancel_comment_edit("comment_self_author", original_body)
self.assertFalse(page.is_comment_editor_visible("comment_self_author")) self.assertFalse(page.is_comment_editor_visible("comment_self_author"))
self.assertTrue(page.is_add_comment_visible("response1")) self.assertTrue(page.is_add_comment_visible("response1"))
class InlineDiscussionTest(UniqueCourseTest, DiscussionResponsePaginationTestMixin):
"""
Tests for inline discussions
"""
def setUp(self):
super(InlineDiscussionTest, self).setUp()
self.discussion_id = "test_discussion_{}".format(uuid4().hex)
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()
AutoAuthPage(self.browser, course_id=self.course_id).visit()
CoursewarePage(self.browser, self.course_id).visit()
self.discussion_page = InlineDiscussionPage(self.browser, self.discussion_id)
def setup_thread_page(self, thread_id):
self.discussion_page.expand_discussion()
self.assertEqual(self.discussion_page.get_num_displayed_threads(), 1)
self.thread_page = InlineDiscussionThreadPage(self.browser, thread_id) # pylint:disable=W0201
self.thread_page.expand()
def test_initial_render(self):
self.assertFalse(self.discussion_page.is_discussion_expanded())
def test_expand_discussion_empty(self):
self.discussion_page.expand_discussion()
self.assertEqual(self.discussion_page.get_num_displayed_threads(), 0)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment