Commit 7d773df5 by Eric Fischer

Merge pull request #11171 from edx/andya/fix-discussion-more-icons

Fix bug with discussion response "More..." actions
parents fa74b9f1 d1ef73e9
...@@ -12,13 +12,40 @@ describe "DiscussionThreadView", -> ...@@ -12,13 +12,40 @@ describe "DiscussionThreadView", ->
spyOn(DiscussionThreadShowView.prototype, "convertMath") spyOn(DiscussionThreadShowView.prototype, "convertMath")
spyOn(DiscussionContentView.prototype, "makeWmdEditor") spyOn(DiscussionContentView.prototype, "makeWmdEditor")
spyOn(DiscussionUtil, "makeWmdEditor") spyOn(DiscussionUtil, "makeWmdEditor")
spyOn(ThreadResponseView.prototype, "renderShowView") spyOn(DiscussionUtil, "setWmdContent")
spyOn(ThreadResponseShowView.prototype, "convertMath")
renderWithContent = (view, content) -> renderWithContent = (view, content) ->
DiscussionViewSpecHelper.setNextResponseContent(content) $.ajax.andCallFake((params) =>
params.success(
createAjaxResponseJson(content, false),
'success'
)
{always: ->}
)
view.render() view.render()
jasmine.Clock.tick(100) jasmine.Clock.tick(100)
renderWithTestResponses = (view, count, options) ->
renderWithContent(
view,
_.extend(
{
resp_total: count,
children: if count > 0 then (createTestResponseJson(index) for index in [1..count]) else []
},
options
)
)
createTestResponseJson = (index) ->
{
user_id: window.user.id,
body: "Response " + index,
id: "id_" + index,
created_at: "2015-01-01T22:20:28Z"
}
assertContentVisible = (view, selector, visible) -> assertContentVisible = (view, selector, visible) ->
content = view.$el.find(selector) content = view.$el.find(selector)
expect(content.length).toBeGreaterThan(0) expect(content.length).toBeGreaterThan(0)
...@@ -42,6 +69,34 @@ describe "DiscussionThreadView", -> ...@@ -42,6 +69,34 @@ describe "DiscussionThreadView", ->
else else
expect(view.$el.find(".load-response-button").length).toEqual(0) expect(view.$el.find(".load-response-button").length).toEqual(0)
createAjaxResponseJson = (content, can_act) ->
{
content: content,
annotated_content_info: {
ability: {
editable: can_act,
can_delete: can_act,
can_reply: can_act,
can_vote: can_act
}
}
}
postResponse = (view, index) ->
testResponseJson = createTestResponseJson(index)
responseText = testResponseJson.body
spyOn(view, "getWmdContent").andReturn(responseText)
$.ajax.andCallFake((params) =>
expect(params.type).toEqual("POST")
expect(params.data.body).toEqual(responseText)
params.success(
createAjaxResponseJson(testResponseJson, true),
'success'
)
{always: ->}
)
view.$(".discussion-submit-post").click()
describe "closed and open Threads", -> describe "closed and open Threads", ->
createDiscussionThreadView = (originallyClosed, mode) -> createDiscussionThreadView = (originallyClosed, mode) ->
...@@ -54,12 +109,12 @@ describe "DiscussionThreadView", -> ...@@ -54,12 +109,12 @@ describe "DiscussionThreadView", ->
mode: mode mode: mode
course_settings: DiscussionSpecHelper.makeCourseSettings() course_settings: DiscussionSpecHelper.makeCourseSettings()
) )
renderWithContent(view, {resp_total: 1, children: [{}]}) renderWithTestResponses(view, 1)
if mode == "inline" if mode == "inline"
view.expand() view.expand()
spyOn(DiscussionUtil, "updateWithUndo").andCallFake( spyOn(DiscussionUtil, "updateWithUndo").andCallFake(
(model, updates, safeAjaxParams, errorMsg) -> (model, updates, safeAjaxParams, errorMsg) ->
model.set(updates) model.set(updates)
) )
view view
...@@ -73,24 +128,24 @@ describe "DiscussionThreadView", -> ...@@ -73,24 +128,24 @@ describe "DiscussionThreadView", ->
checkVoteDisplay = (originallyClosed, mode) -> checkVoteDisplay = (originallyClosed, mode) ->
view = createDiscussionThreadView(originallyClosed, mode) view = createDiscussionThreadView(originallyClosed, mode)
expect(view.$('.action-vote').is(":visible")).toBe(not originallyClosed) expect(view.$('.forum-thread-main-wrapper .action-vote').is(":visible")).toBe(not originallyClosed)
expect(view.$('.display-vote').is(":visible")).toBe(originallyClosed) expect(view.$('.forum-thread-main-wrapper .display-vote').is(":visible")).toBe(originallyClosed)
view.$(".action-close").click() view.$(".action-close").click()
expect(view.$('.action-vote').is(":visible")).toBe(originallyClosed) expect(view.$('.action-vote').is(":visible")).toBe(originallyClosed)
expect(view.$('.display-vote').is(":visible")).toBe(not originallyClosed) expect(view.$('.display-vote').is(":visible")).toBe(not originallyClosed)
_.each(["tab", "inline"], (mode) => _.each(["tab", "inline"], (mode) =>
it "Test that in #{mode} mode when a closed thread is opened the comment form is displayed", -> it "Test that in #{mode} mode when a closed thread is opened the comment form is displayed", ->
checkCommentForm(true, mode) checkCommentForm(true, mode)
it "Test that in #{mode} mode when a open thread is closed the comment form is hidden", -> it "Test that in #{mode} mode when a open thread is closed the comment form is hidden", ->
checkCommentForm(false, mode) checkCommentForm(false, mode)
it "Test that in #{mode} mode when a closed thread is opened the vote button is displayed and vote count is hidden", -> it "Test that in #{mode} mode when a closed thread is opened the vote button is displayed and vote count is hidden", ->
checkVoteDisplay(true, mode) checkVoteDisplay(true, mode)
it "Test that in #{mode} mode when a open thread is closed the vote button is hidden and vote count is displayed", -> it "Test that in #{mode} mode when a open thread is closed the vote button is hidden and vote count is displayed", ->
checkVoteDisplay(false, mode) checkVoteDisplay(false, mode)
) )
describe "tab mode", -> describe "tab mode", ->
...@@ -102,40 +157,66 @@ describe "DiscussionThreadView", -> ...@@ -102,40 +157,66 @@ describe "DiscussionThreadView", ->
course_settings: DiscussionSpecHelper.makeCourseSettings() course_settings: DiscussionSpecHelper.makeCourseSettings()
) )
describe "responses", ->
it "can post a first response", ->
# Initially render a test post (made by someone else) with zero responses
renderWithTestResponses(@view, 0)
postResponse(@view, 1)
expect(@view.$(".forum-response").length).toBe(1)
# At this point, there are 2 DiscussionContentViews, the main post and the response.
# Each an .action-edit button, but only 1 (the response) should be available.
expect(@view.$(".post-actions-list").find(".action-edit").parent(".is-hidden").length).toBe(1)
expect(@view.$(".response-actions-list").find(".action-edit").parent().not(".is-hidden").length).toBe(1)
it "can post a second response", ->
# Initially render a test post (made by someone else) with a single response (made by the current learner)
renderWithTestResponses(@view, 1)
expect(@view.$(".forum-response").length).toBe(1)
# Post should not be editable, response should be
expect(@view.$(".post-actions-list").find(".action-edit").parent(".is-hidden").length).toBe(1)
expect(@view.$(".response-actions-list").find(".action-edit").parent().not(".is-hidden").length).toBe(1)
# Now make a second response. Prior to TNL-3788, a bug would hide the edit button for the first response
postResponse(@view, 2)
expect(@view.$(".forum-response").length).toBe(2)
# Post should not be editable, responses should be
expect(@view.$(".post-actions-list").find(".action-edit").parent(".is-hidden").length).toBe(1)
expect(@view.$(".response-actions-list").find(".action-edit").parent().not(".is-hidden").length).toBe(2)
describe "response count and pagination", -> describe "response count and pagination", ->
it "correctly render for a thread with no responses", -> it "correctly render for a thread with no responses", ->
renderWithContent(@view, {resp_total: 0, children: []}) renderWithTestResponses(@view, 0)
assertResponseCountAndPaginationCorrect(@view, "0 responses", null, null) assertResponseCountAndPaginationCorrect(@view, "0 responses", null, null)
it "correctly render for a thread with one response", -> it "correctly render for a thread with one response", ->
renderWithContent(@view, {resp_total: 1, children: [{}]}) renderWithTestResponses(@view, 1)
assertResponseCountAndPaginationCorrect(@view, "1 response", "Showing all responses", null) assertResponseCountAndPaginationCorrect(@view, "1 response", "Showing all responses", null)
it "correctly render for a thread with one additional page", -> it "correctly render for a thread with one additional page", ->
renderWithContent(@view, {resp_total: 2, children: [{}]}) renderWithTestResponses(@view, 1, {resp_total: 2})
assertResponseCountAndPaginationCorrect(@view, "2 responses", "Showing first response", "Load all responses") assertResponseCountAndPaginationCorrect(@view, "2 responses", "Showing first response", "Load all responses")
it "correctly render for a thread with multiple additional pages", -> it "correctly render for a thread with multiple additional pages", ->
renderWithContent(@view, {resp_total: 111, children: [{}, {}]}) renderWithTestResponses(@view, 2, {resp_total: 111})
assertResponseCountAndPaginationCorrect(@view, "111 responses", "Showing first 2 responses", "Load next 100 responses") assertResponseCountAndPaginationCorrect(@view, "111 responses", "Showing first 2 responses", "Load next 100 responses")
describe "on clicking the load more button", -> describe "on clicking the load more button", ->
beforeEach -> beforeEach ->
renderWithContent(@view, {resp_total: 5, children: [{}]}) renderWithTestResponses(@view, 1, {resp_total: 5})
assertResponseCountAndPaginationCorrect(@view, "5 responses", "Showing first response", "Load all responses") assertResponseCountAndPaginationCorrect(@view, "5 responses", "Showing first response", "Load all responses")
it "correctly re-render when all threads have loaded", -> it "correctly re-render when all threads have loaded", ->
DiscussionViewSpecHelper.setNextResponseContent({resp_total: 5, children: [{}, {}, {}, {}]}) renderWithTestResponses(@view, 5, {resp_total: 5})
@view.$el.find(".load-response-button").click() @view.$el.find(".load-response-button").click()
assertResponseCountAndPaginationCorrect(@view, "5 responses", "Showing all responses", null) assertResponseCountAndPaginationCorrect(@view, "5 responses", "Showing all responses", null)
it "correctly re-render when one page remains", -> it "correctly re-render when one page remains", ->
DiscussionViewSpecHelper.setNextResponseContent({resp_total: 42, children: [{}, {}]}) renderWithTestResponses(@view, 3, {resp_total: 42})
@view.$el.find(".load-response-button").click() @view.$el.find(".load-response-button").click()
assertResponseCountAndPaginationCorrect(@view, "42 responses", "Showing first 3 responses", "Load all responses") assertResponseCountAndPaginationCorrect(@view, "42 responses", "Showing first 3 responses", "Load all responses")
it "correctly re-render when multiple pages remain", -> it "correctly re-render when multiple pages remain", ->
DiscussionViewSpecHelper.setNextResponseContent({resp_total: 111, children: [{}, {}]}) renderWithTestResponses(@view, 3, {resp_total: 111})
@view.$el.find(".load-response-button").click() @view.$el.find(".load-response-button").click()
assertResponseCountAndPaginationCorrect(@view, "111 responses", "Showing first 3 responses", "Load next 100 responses") assertResponseCountAndPaginationCorrect(@view, "111 responses", "Showing first 3 responses", "Load next 100 responses")
...@@ -247,9 +328,10 @@ describe "DiscussionThreadView", -> ...@@ -247,9 +328,10 @@ describe "DiscussionThreadView", ->
course_settings: DiscussionSpecHelper.makeCourseSettings() course_settings: DiscussionSpecHelper.makeCourseSettings()
) )
generateContent = (idStart, idEnd) ->
_.map(_.range(idStart, idEnd), (i) -> createTestResponseJson(i))
renderTestCase = (view, numEndorsed, numNonEndorsed) -> renderTestCase = (view, numEndorsed, numNonEndorsed) ->
generateContent = (idStart, idEnd) ->
_.map(_.range(idStart, idEnd), (i) -> {"id": "#{i}"})
renderWithContent( renderWithContent(
view, view,
{ {
...@@ -278,15 +360,15 @@ describe "DiscussionThreadView", -> ...@@ -278,15 +360,15 @@ describe "DiscussionThreadView", ->
renderWithContent( renderWithContent(
@view, @view,
{ {
endorsed_responses: [{id: "1"}, {id: "2"}], endorsed_responses: generateContent(0, 2),
non_endorsed_responses: [{id: "3"}, {id: "4"}, {id: "5"}], non_endorsed_responses: generateContent(3, 6),
non_endorsed_resp_total: 42 non_endorsed_resp_total: 42
} }
) )
DiscussionViewSpecHelper.setNextResponseContent({ DiscussionViewSpecHelper.setNextResponseContent({
# Add an endorsed response; it should be rendered # Add an endorsed response; it should be rendered
endorsed_responses: [{id: "1"}, {id: "2"}, {id: "6"}], endorsed_responses: generateContent(0, 3),
non_endorsed_responses: [{id: "7"}, {id: "8"}, {id: "9"}], non_endorsed_responses: generateContent(6, 9),
non_endorsed_resp_total: 41 non_endorsed_resp_total: 41
}) })
@view.$el.find(".load-response-button").click() @view.$el.find(".load-response-button").click()
......
...@@ -14,6 +14,12 @@ class @DiscussionViewSpecHelper ...@@ -14,6 +14,12 @@ class @DiscussionViewSpecHelper
body: "", body: "",
title: "dummy title", title: "dummy title",
created_at: "2014-08-18T01:02:03Z" created_at: "2014-08-18T01:02:03Z"
ability: {
can_delete: false,
can_reply: true,
can_vote: false,
editable: false,
}
} }
$.extend(thread, props) $.extend(thread, props)
...@@ -72,7 +78,7 @@ class @DiscussionViewSpecHelper ...@@ -72,7 +78,7 @@ class @DiscussionViewSpecHelper
spy.reset() spy.reset()
button.trigger($.Event("keydown", {which: 32})) button.trigger($.Event("keydown", {which: 32}))
expect(spy).toHaveBeenCalled() expect(spy).toHaveBeenCalled()
@checkVoteButtonEvents = (view) -> @checkVoteButtonEvents = (view) ->
@checkButtonEvents(view, "toggleVote", ".action-vote") @checkButtonEvents(view, "toggleVote", ".action-vote")
......
if Backbone? if Backbone?
class @DiscussionContentView extends Backbone.View class @DiscussionContentView extends Backbone.View
events: events:
"click .discussion-flag-abuse": "toggleFlagAbuse" "click .discussion-flag-abuse": "toggleFlagAbuse"
"keydown .discussion-flag-abuse": "keydown .discussion-flag-abuse":
(event) -> DiscussionUtil.activateOnSpace(event, @toggleFlagAbuse) (event) -> DiscussionUtil.activateOnSpace(event, @toggleFlagAbuse)
attrRenderer: attrRenderer:
ability: (ability) -> ability: (ability) ->
for action, selector of @abilityRenderer for action, selector of @abilityRenderer
...@@ -56,7 +56,7 @@ if Backbone? ...@@ -56,7 +56,7 @@ if Backbone?
setWmdContent: (cls_identifier, text) => setWmdContent: (cls_identifier, text) =>
DiscussionUtil.setWmdContent @$el, $.proxy(@$, @), cls_identifier, text DiscussionUtil.setWmdContent @$el, $.proxy(@$, @), cls_identifier, text
initialize: -> initialize: ->
@model.bind('change', @renderPartialAttrs, @) @model.bind('change', @renderPartialAttrs, @)
......
...@@ -278,7 +278,6 @@ if Backbone? ...@@ -278,7 +278,6 @@ if Backbone?
comment = new Comment(body: body, created_at: (new Date()).toISOString(), username: window.user.get("username"), votes: { up_count: 0 }, abuse_flaggers:[], endorsed: false, user_id: window.user.get("id")) comment = new Comment(body: body, created_at: (new Date()).toISOString(), username: window.user.get("username"), votes: { up_count: 0 }, abuse_flaggers:[], endorsed: false, user_id: window.user.get("id"))
comment.set('thread', @model.get('thread')) comment.set('thread', @model.get('thread'))
@renderResponseToList(comment, ".js-response-list") @renderResponseToList(comment, ".js-response-list")
@renderAttrs()
@model.addComment() @model.addComment()
@renderAddResponseButton() @renderAddResponseButton()
......
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