add ability to delete comments on responses in discussions.
This commit is contained in:
@@ -2,7 +2,7 @@ describe 'All Content', ->
|
||||
beforeEach ->
|
||||
# TODO: figure out a better way of handling this
|
||||
# It is set up in main.coffee DiscussionApp.start
|
||||
window.$$course_id = 'mitX/999/test'
|
||||
window.$$course_id = 'edX/999/test'
|
||||
window.user = new DiscussionUser {id: '567'}
|
||||
|
||||
describe 'Content', ->
|
||||
@@ -10,7 +10,7 @@ describe 'All Content', ->
|
||||
@content = new Content {
|
||||
id: '01234567',
|
||||
user_id: '567',
|
||||
course_id: 'mitX/999/test',
|
||||
course_id: 'edX/999/test',
|
||||
body: 'this is some content',
|
||||
abuse_flaggers: ['123']
|
||||
}
|
||||
@@ -22,7 +22,7 @@ describe 'All Content', ->
|
||||
@content.initialize
|
||||
expect(Content.contents['01234567']).toEqual @content
|
||||
expect(@content.get 'id').toEqual '01234567'
|
||||
expect(@content.get 'user_url').toEqual '/courses/mitX/999/test/discussion/forum/users/567'
|
||||
expect(@content.get 'user_url').toEqual '/courses/edX/999/test/discussion/forum/users/567'
|
||||
expect(@content.get 'children').toEqual []
|
||||
expect(@content.get 'comments').toEqual(jasmine.any(Comments))
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ describe "DiscussionContentView", ->
|
||||
@threadData = {
|
||||
id: '01234567',
|
||||
user_id: '567',
|
||||
course_id: 'mitX/999/test',
|
||||
course_id: 'edX/999/test',
|
||||
body: 'this is a thread',
|
||||
created_at: '2013-04-03T20:08:39Z',
|
||||
abuse_flaggers: ['123'],
|
||||
|
||||
@@ -8,6 +8,8 @@ describe 'ResponseCommentShowView', ->
|
||||
<div class="response-body"><%- body %></div>
|
||||
<div class="discussion-flag-abuse notflagged" data-role="thread-flag" data-tooltip="report misuse">
|
||||
<i class="icon"></i><span class="flag-label"></span></div>
|
||||
<div style="display:none" class="discussion-delete-comment action-delete" data-role="comment-delete" data-tooltip="Delete Comment" role="button" aria-pressed="false" tabindex="0">
|
||||
<i class="icon icon-remove"></i><span class="sr delete-label">Delete Comment</span></div>
|
||||
<p class="posted-details">–posted <span class="timeago" title="<%- created_at %>"><%- created_at %></span> by
|
||||
<% if (obj.username) { %>
|
||||
<a href="<%- user_url %>" class="profile-link"><%- username %></a>
|
||||
@@ -18,18 +20,17 @@ describe 'ResponseCommentShowView', ->
|
||||
"""
|
||||
|
||||
# set up a model for a new Comment
|
||||
@response = new Comment {
|
||||
@comment = new Comment {
|
||||
id: '01234567',
|
||||
user_id: '567',
|
||||
course_id: 'mitX/999/test',
|
||||
course_id: 'edX/999/test',
|
||||
body: 'this is a response',
|
||||
created_at: '2013-04-03T20:08:39Z',
|
||||
abuse_flaggers: ['123']
|
||||
roles: []
|
||||
}
|
||||
@view = new ResponseCommentShowView({ model: @response })
|
||||
|
||||
# spyOn(DiscussionUtil, 'loadRoles').andReturn []
|
||||
@view = new ResponseCommentShowView({ model: @comment })
|
||||
spyOn(@view, "convertMath")
|
||||
|
||||
it 'defines the tag', ->
|
||||
expect($('#jasmine-fixtures')).toExist
|
||||
@@ -37,26 +38,36 @@ describe 'ResponseCommentShowView', ->
|
||||
expect(@view.el.tagName.toLowerCase()).toBe 'li'
|
||||
|
||||
it 'is tied to the model', ->
|
||||
expect(@view.model).toBeDefined();
|
||||
expect(@view.model).toBeDefined()
|
||||
|
||||
describe 'rendering', ->
|
||||
|
||||
beforeEach ->
|
||||
spyOn(@view, 'renderAttrs')
|
||||
spyOn(@view, 'markAsStaff')
|
||||
spyOn(@view, 'convertMath')
|
||||
|
||||
it 'produces the correct HTML', ->
|
||||
@view.render()
|
||||
expect(@view.el.innerHTML).toContain('"discussion-flag-abuse notflagged"')
|
||||
|
||||
it 'can be flagged for abuse', ->
|
||||
@response.flagAbuse()
|
||||
expect(@response.get 'abuse_flaggers').toEqual ['123', '567']
|
||||
@comment.flagAbuse()
|
||||
expect(@comment.get 'abuse_flaggers').toEqual ['123', '567']
|
||||
|
||||
it 'can be unflagged for abuse', ->
|
||||
temp_array = []
|
||||
temp_array.push(window.user.get('id'))
|
||||
@response.set("abuse_flaggers",temp_array)
|
||||
@response.unflagAbuse()
|
||||
expect(@response.get 'abuse_flaggers').toEqual []
|
||||
@comment.set("abuse_flaggers",temp_array)
|
||||
@comment.unflagAbuse()
|
||||
expect(@comment.get 'abuse_flaggers').toEqual []
|
||||
|
||||
describe 'comment deletion', ->
|
||||
|
||||
it 'triggers the delete event when the delete icon is clicked', ->
|
||||
DiscussionUtil.loadRoles []
|
||||
@comment.updateInfo {ability: {'can_delete': true}}
|
||||
triggerTarget = jasmine.createSpy()
|
||||
@view.bind "comment:_delete", triggerTarget
|
||||
@view.render()
|
||||
@view.$el.find('.action-delete').click()
|
||||
expect(triggerTarget).toHaveBeenCalled()
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
describe 'ResponseCommentView', ->
|
||||
beforeEach ->
|
||||
|
||||
@comment = new Comment {
|
||||
id: '01234567',
|
||||
user_id: '567',
|
||||
course_id: 'edX/999/test',
|
||||
body: 'this is a response',
|
||||
created_at: '2013-04-03T20:08:39Z',
|
||||
abuse_flaggers: ['123']
|
||||
roles: ['Student']
|
||||
}
|
||||
@view = new ResponseCommentView({ model: @comment })
|
||||
spyOn(@view, "render")
|
||||
|
||||
describe '_delete', ->
|
||||
beforeEach ->
|
||||
@comment.updateInfo {ability: {can_delete: true}}
|
||||
@event = jasmine.createSpyObj('event', ['preventDefault', 'target'])
|
||||
spyOn(@comment, "remove")
|
||||
spyOn(@view.$el, "remove")
|
||||
|
||||
setAjaxResult = (isSuccess) ->
|
||||
spyOn($, "ajax").andCallFake(
|
||||
(params) =>
|
||||
(if isSuccess then params.success else params.error) {}
|
||||
{always: ->}
|
||||
)
|
||||
|
||||
it 'requires confirmation before deleting', ->
|
||||
spyOn(window, "confirm").andReturn(false)
|
||||
setAjaxResult(true)
|
||||
@view._delete(@event)
|
||||
expect(window.confirm).toHaveBeenCalled()
|
||||
expect($.ajax).not.toHaveBeenCalled()
|
||||
expect(@comment.remove).not.toHaveBeenCalled()
|
||||
|
||||
it 'removes the deleted comment object', ->
|
||||
setAjaxResult(true)
|
||||
@view._delete(@event)
|
||||
expect(@comment.remove).toHaveBeenCalled()
|
||||
expect(@view.$el.remove).toHaveBeenCalled()
|
||||
|
||||
it 'calls the ajax comment deletion endpoint', ->
|
||||
setAjaxResult(true)
|
||||
@view._delete(@event)
|
||||
expect(@event.preventDefault).toHaveBeenCalled()
|
||||
expect($.ajax).toHaveBeenCalled()
|
||||
expect($.ajax.mostRecentCall.args[0].url._parts.path).toEqual('/courses/edX/999/test/discussion/comments/01234567/delete')
|
||||
|
||||
it 'handles ajax errors', ->
|
||||
spyOn(DiscussionUtil, "discussionAlert")
|
||||
setAjaxResult(false)
|
||||
@view._delete(@event)
|
||||
expect(@event.preventDefault).toHaveBeenCalled()
|
||||
expect($.ajax).toHaveBeenCalled()
|
||||
expect(@comment.remove).not.toHaveBeenCalled()
|
||||
expect(@view.$el.remove).not.toHaveBeenCalled()
|
||||
expect(DiscussionUtil.discussionAlert).toHaveBeenCalled()
|
||||
|
||||
it 'does not delete a comment if the permission is false', ->
|
||||
@comment.updateInfo {ability: {'can_delete': false}}
|
||||
spyOn(window, "confirm")
|
||||
setAjaxResult(true)
|
||||
@view._delete(@event)
|
||||
expect(window.confirm).not.toHaveBeenCalled()
|
||||
expect($.ajax).not.toHaveBeenCalled()
|
||||
expect(@comment.remove).not.toHaveBeenCalled()
|
||||
expect(@view.$el.remove).not.toHaveBeenCalled()
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
if Backbone?
|
||||
class @ResponseCommentShowView extends DiscussionContentView
|
||||
|
||||
events:
|
||||
"click .action-delete": "_delete"
|
||||
|
||||
tagName: "li"
|
||||
|
||||
initialize: ->
|
||||
super()
|
||||
@model.on "change", @updateModelDetails
|
||||
|
||||
abilityRenderer:
|
||||
can_delete:
|
||||
enable: -> @$(".action-delete").show()
|
||||
disable: -> @$(".action-delete").hide()
|
||||
|
||||
render: ->
|
||||
@template = _.template($("#response-comment-show-template").html())
|
||||
params = @model.toJSON()
|
||||
@@ -40,6 +48,8 @@ if Backbone?
|
||||
else if DiscussionUtil.isTA(@model.get("user_id"))
|
||||
@$el.find("a.profile-link").after('<span class="community-ta-label">' + gettext('Community TA') + '</span>')
|
||||
|
||||
_delete: (event) ->
|
||||
@trigger "comment:_delete", event
|
||||
|
||||
renderFlagged: =>
|
||||
if window.user.id in @model.get("abuse_flaggers") or (DiscussionUtil.isFlagModerator and @model.get("abuse_flaggers").length > 0)
|
||||
|
||||
@@ -21,6 +21,7 @@ if Backbone?
|
||||
@editView = null
|
||||
|
||||
@showView = new ResponseCommentShowView(model: @model)
|
||||
@showView.bind "comment:_delete", @_delete
|
||||
|
||||
renderSubView: (view) ->
|
||||
view.setElement(@$el)
|
||||
@@ -29,3 +30,24 @@ if Backbone?
|
||||
|
||||
renderShowView: () ->
|
||||
@renderSubView(@showView)
|
||||
|
||||
_delete: (event) =>
|
||||
event.preventDefault()
|
||||
if not @model.can('can_delete')
|
||||
return
|
||||
if not confirm gettext("Are you sure you want to delete this comment?")
|
||||
return
|
||||
url = @model.urlFor('_delete')
|
||||
$elem = $(event.target)
|
||||
DiscussionUtil.safeAjax
|
||||
$elem: $elem
|
||||
url: url
|
||||
type: "POST"
|
||||
success: (response, textStatus) =>
|
||||
@model.remove()
|
||||
@$el.remove()
|
||||
error: =>
|
||||
DiscussionUtil.discussionAlert(
|
||||
gettext("Sorry"),
|
||||
gettext("We had some trouble deleting this comment. Please try again.")
|
||||
)
|
||||
|
||||
@@ -91,6 +91,7 @@ if Backbone?
|
||||
body: body
|
||||
success: (response, textStatus) ->
|
||||
comment.set(response.content)
|
||||
comment.updateInfo(response.annotated_content_info)
|
||||
view.render() # This is just to update the id for the most part, but might be useful in general
|
||||
|
||||
_delete: (event) =>
|
||||
|
||||
@@ -2529,7 +2529,7 @@ body.discussion {
|
||||
display:none;
|
||||
}
|
||||
|
||||
.discussion-flag-abuse {
|
||||
.discussion-flag-abuse, .discussion-delete-comment {
|
||||
font-size: 12px;
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
@@ -2542,7 +2542,7 @@ display:none;
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.notflagged .icon {
|
||||
display: block;
|
||||
color: #333;
|
||||
|
||||
@@ -166,6 +166,8 @@
|
||||
<div class="response-body">${'<%- body %>'}</div>
|
||||
<div class="discussion-flag-abuse notflagged" data-role="thread-flag" data-tooltip="${_('Report Misuse') | h}" role="button" aria-pressed="false" tabindex="0">
|
||||
<i class="icon icon-flag"></i><span class="sr flag-label">${_("Report Misuse")}</span></div>
|
||||
<div style="display: none" class="discussion-delete-comment action-delete" data-tooltip="${_('Delete Comment') | h}" role="button" tabindex="0">
|
||||
<i class="icon icon-remove"></i><span class="sr">${_("Delete Comment")}</span></div>
|
||||
<%
|
||||
js_block = u"""
|
||||
interpolate(
|
||||
|
||||
Reference in New Issue
Block a user