From eaa93bf6158ec5c5558e3ecb8482ffb7abae22bb Mon Sep 17 00:00:00 2001
From: Greg Price <gprice@edx.org>
Date: Mon, 28 Jul 2014 15:06:56 -0400
Subject: [PATCH] Hide comments in marked answers in forum questions

A link to show the comments appears in their place.
---
 common/static/coffee/spec/discussion/view/thread_response_view_spec.coffee | 31 ++++++++++++++++++++++++++++++-
 common/static/coffee/src/discussion/views/discussion_thread_view.coffee    |  8 ++++----
 common/static/coffee/src/discussion/views/thread_response_view.coffee      | 13 ++++++++++++-
 common/test/acceptance/fixtures/discussion.py                              |  8 +++++++-
 common/test/acceptance/pages/lms/discussion.py                             | 12 ++++++++++++
 common/test/acceptance/tests/test_discussion.py                            | 21 +++++++++++++++++++++
 lms/static/sass/application-extend2.scss.mako                              |  1 +
 lms/static/sass/discussion/views/_response.scss                            |  9 +++++++++
 lms/templates/discussion/_underscore_templates.html                        |  4 ++++
 9 files changed, 100 insertions(+), 7 deletions(-)
 create mode 100644 lms/static/sass/discussion/views/_response.scss

diff --git a/common/static/coffee/spec/discussion/view/thread_response_view_spec.coffee b/common/static/coffee/spec/discussion/view/thread_response_view_spec.coffee
index 9ae1b00..48a1160 100644
--- a/common/static/coffee/spec/discussion/view/thread_response_view_spec.coffee
+++ b/common/static/coffee/spec/discussion/view/thread_response_view_spec.coffee
@@ -1,8 +1,10 @@
 describe 'ThreadResponseView', ->
     beforeEach ->
+        DiscussionSpecHelper.setUpGlobals()
         setFixtures """
             <script id="thread-response-template" type="text/template">
-                <div/>
+                <a href="#" class="action-show-comments">Show comments</a>
+                <ol class="comments"></ol>
             </script>
             <div id="thread-response-fixture"/>
         """
@@ -14,6 +16,33 @@ describe 'ThreadResponseView', ->
         spyOn(ResponseCommentView.prototype, "render")
 
     describe 'renderComments', ->
+        it 'hides "show comments" link if collapseComments is not set', ->
+            @view.render()
+            expect(@view.$(".comments")).toBeVisible()
+            expect(@view.$(".action-show-comments")).not.toBeVisible()
+
+        it 'hides "show comments" link if collapseComments is set but response has no comments', ->
+            @response = new Comment { children: [] }
+            @view = new ThreadResponseView({
+                model: @response, el: $("#thread-response-fixture"),
+                collapseComments: true
+            })
+            @view.render()
+            expect(@view.$(".comments")).toBeVisible()
+            expect(@view.$(".action-show-comments")).not.toBeVisible()
+
+        it 'hides comments if collapseComments is set and shows them when "show comments" link is clicked', ->
+            @view = new ThreadResponseView({
+                model: @response, el: $("#thread-response-fixture"),
+                collapseComments: true
+            })
+            @view.render()
+            expect(@view.$(".comments")).not.toBeVisible()
+            expect(@view.$(".action-show-comments")).toBeVisible()
+            @view.$(".action-show-comments").click()
+            expect(@view.$(".comments")).toBeVisible()
+            expect(@view.$(".action-show-comments")).not.toBeVisible()
+
         it 'populates commentViews and binds events', ->
             # Ensure that edit view is set to test invocation of cancelEdit
             @view.createEditView()
diff --git a/common/static/coffee/src/discussion/views/discussion_thread_view.coffee b/common/static/coffee/src/discussion/views/discussion_thread_view.coffee
index 80675b1..be0301b 100644
--- a/common/static/coffee/src/discussion/views/discussion_thread_view.coffee
+++ b/common/static/coffee/src/discussion/views/discussion_thread_view.coffee
@@ -41,9 +41,9 @@ if Backbone?
       @$("span.timeago").timeago()
       @makeWmdEditor "reply-body"
       @renderAddResponseButton()
-      @responses.on("add", (response) => @renderResponseToList(response, ".js-response-list"))
+      @responses.on("add", (response) => @renderResponseToList(response, ".js-response-list", {}))
       if @isQuestion()
-        @markedAnswers.on("add", (response) => @renderResponseToList(response, ".js-marked-answer-list"))
+        @markedAnswers.on("add", (response) => @renderResponseToList(response, ".js-marked-answer-list", {collapseComments: true}))
       if @mode == "tab"
         # Without a delay, jQuery doesn't add the loading extension defined in
         # utils.coffee before safeAjax is invoked, which results in an error
@@ -191,9 +191,9 @@ if Backbone?
           loadMoreButton.click((event) => @loadResponses(responseLimit, loadMoreButton))
           responsePagination.append(loadMoreButton)
 
-    renderResponseToList: (response, listSelector) =>
+    renderResponseToList: (response, listSelector, options) =>
         response.set('thread', @model)
-        view = new ThreadResponseView(model: response)
+        view = new ThreadResponseView($.extend({model: response}, options))
         view.on "comment:add", @addComment
         view.on "comment:endorse", @endorseThread
         view.render()
diff --git a/common/static/coffee/src/discussion/views/thread_response_view.coffee b/common/static/coffee/src/discussion/views/thread_response_view.coffee
index fa548df..e6a3412 100644
--- a/common/static/coffee/src/discussion/views/thread_response_view.coffee
+++ b/common/static/coffee/src/discussion/views/thread_response_view.coffee
@@ -1,6 +1,7 @@
 if Backbone?
   class @ThreadResponseView extends DiscussionContentView
     tagName: "li"
+    className: "forum-response"
 
     events:
         "click .discussion-submit-comment": "submitComment"
@@ -9,7 +10,8 @@ if Backbone?
     $: (selector) ->
       @$el.find(selector)
 
-    initialize: ->
+    initialize: (options) ->
+      @collapseComments = options.collapseComments
       @createShowView()
 
     renderTemplate: ->
@@ -65,6 +67,15 @@ if Backbone?
           collectComments(child)
       @model.get('comments').each collectComments
       comments.each (comment) => @renderComment(comment, false, null)
+      if @collapseComments && comments.length
+        @$(".comments").hide()
+        @$(".action-show-comments").on("click", (event) =>
+          event.preventDefault()
+          @$(".action-show-comments").hide()
+          @$(".comments").show()
+        )
+      else
+        @$(".action-show-comments").hide()
 
     renderComment: (comment) =>
       comment.set('thread', @model.get('thread'))
diff --git a/common/test/acceptance/fixtures/discussion.py b/common/test/acceptance/fixtures/discussion.py
index 3edcc6c..a521a36 100644
--- a/common/test/acceptance/fixtures/discussion.py
+++ b/common/test/acceptance/fixtures/discussion.py
@@ -88,7 +88,13 @@ class SingleThreadViewFixture(DiscussionContentFixture):
 
     def addResponse(self, response, comments=[]):
         response['children'] = comments
-        self.thread.setdefault('children', []).append(response)
+        if self.thread["thread_type"] == "discussion":
+            responseListAttr = "children"
+        elif response["endorsed"]:
+            responseListAttr = "endorsed_responses"
+        else:
+            responseListAttr = "non_endorsed_responses"
+        self.thread.setdefault(responseListAttr, []).append(response)
         self.thread['comments_count'] += len(comments) + 1
 
     def _get_comment_map(self):
diff --git a/common/test/acceptance/pages/lms/discussion.py b/common/test/acceptance/pages/lms/discussion.py
index 10981e7..ad94850 100644
--- a/common/test/acceptance/pages/lms/discussion.py
+++ b/common/test/acceptance/pages/lms/discussion.py
@@ -95,6 +95,18 @@ class DiscussionThreadPage(PageObject, DiscussionPageMixin):
             "Response edit started"
         ).fulfill()
 
+    def is_show_comments_visible(self, response_id):
+        """Returns true if the "show comments" link is visible for a response"""
+        return self._is_element_visible(".response_{} .action-show-comments".format(response_id))
+
+    def show_comments(self, response_id):
+        """Click the "show comments" link for a response"""
+        self._find_within(".response_{} .action-show-comments".format(response_id)).first.click()
+        EmptyPromise(
+            lambda: self._is_element_visible(".response_{} .comments".format(response_id)),
+            "Comments shown"
+        ).fulfill()
+
     def is_add_comment_visible(self, response_id):
         """Returns true if the "add comment" form is visible for a response"""
         return self._is_element_visible("#wmd-input-comment-body-{}".format(response_id))
diff --git a/common/test/acceptance/tests/test_discussion.py b/common/test/acceptance/tests/test_discussion.py
index 3e4a36a..8c5fe95 100644
--- a/common/test/acceptance/tests/test_discussion.py
+++ b/common/test/acceptance/tests/test_discussion.py
@@ -144,6 +144,27 @@ class DiscussionTabSingleThreadTest(UniqueCourseTest, DiscussionResponsePaginati
         self.thread_page = DiscussionTabSingleThreadPage(self.browser, self.course_id, thread_id)  # pylint:disable=W0201
         self.thread_page.visit()
 
+    def test_marked_answer_comments(self):
+        thread_id = "test_thread_{}".format(uuid4().hex)
+        response_id = "test_response_{}".format(uuid4().hex)
+        comment_id = "test_comment_{}".format(uuid4().hex)
+        thread_fixture = SingleThreadViewFixture(
+            Thread(id=thread_id, commentable_id=self.discussion_id, thread_type="question")
+        )
+        thread_fixture.addResponse(
+            Response(id=response_id, endorsed=True),
+            [Comment(id=comment_id)]
+        )
+        thread_fixture.push()
+        self.setup_thread_page(thread_id)
+        self.assertFalse(self.thread_page.is_comment_visible(comment_id))
+        self.assertFalse(self.thread_page.is_add_comment_visible(response_id))
+        self.assertTrue(self.thread_page.is_show_comments_visible(response_id))
+        self.thread_page.show_comments(response_id)
+        self.assertTrue(self.thread_page.is_comment_visible(comment_id))
+        self.assertTrue(self.thread_page.is_add_comment_visible(response_id))
+        self.assertFalse(self.thread_page.is_show_comments_visible(response_id))
+
 
 @attr('shard_1')
 class DiscussionCommentDeletionTest(UniqueCourseTest):
diff --git a/lms/static/sass/application-extend2.scss.mako b/lms/static/sass/application-extend2.scss.mako
index 1fa6338..5981daf 100644
--- a/lms/static/sass/application-extend2.scss.mako
+++ b/lms/static/sass/application-extend2.scss.mako
@@ -55,6 +55,7 @@
 @import "discussion/elements/editor";
 @import "discussion/elements/navigation";
 @import "discussion/views/thread";
+@import "discussion/views/response";
 @import 'discussion/utilities/developer';
 @import 'discussion/utilities/shame';
 
diff --git a/lms/static/sass/discussion/views/_response.scss b/lms/static/sass/discussion/views/_response.scss
new file mode 100644
index 0000000..72ea60c
--- /dev/null
+++ b/lms/static/sass/discussion/views/_response.scss
@@ -0,0 +1,9 @@
+.forum-response .action-show-comments {
+  @include box-sizing(border-box);
+  @include font-size(13);
+  display: block;
+  padding: ($baseline/2) $baseline;
+  width: 100%;
+  background: $gray-l6;
+  box-shadow: 0 1px 3px -1px $shadow inset;
+}
diff --git a/lms/templates/discussion/_underscore_templates.html b/lms/templates/discussion/_underscore_templates.html
index 80976bb..3c413be 100644
--- a/lms/templates/discussion/_underscore_templates.html
+++ b/lms/templates/discussion/_underscore_templates.html
@@ -133,6 +133,10 @@
 
 <script aria-hidden="true" type="text/template" id="thread-response-template">
     <div class="discussion-response"></div>
+    <a href="#" class="action-show-comments">
+        ${u"<%- interpolate('{}', {{num_comments: comments.length}}, true) %>".format(escapejs(_("Show Comments (%(num_comments)s)")))}
+        <i class="icon icon-caret-down"></i>
+    </a>
     <ol class="comments">
         <li class="new-comment">
             % if course is UNDEFINED or has_permission(user, 'create_sub_comment', course.id):
--
libgit2 0.26.0