Clans remove member

This commit is contained in:
Matt Lott 2015-04-02 11:01:37 -07:00
parent bf38327578
commit d91a7d8d1a
4 changed files with 114 additions and 4 deletions

View file

@ -30,7 +30,7 @@ block content
td= member.level
if isOwner && member.id !== clan.get('ownerID')
td
button.btn.btn-sm.btn-warning Remove Member
button.btn.btn-sm.btn-warning.remove-member-btn(data-id="#{member.id}") Remove Member
else
td

View file

@ -5,7 +5,6 @@ template = require 'templates/clans/clan-details'
Clan = require 'models/Clan'
# TODO: join/leave mostly duped from clans view
# TODO: Refresh data instead of page
module.exports = class ClanDetailsView extends RootView
id: 'clan-details-view'
@ -14,6 +13,7 @@ module.exports = class ClanDetailsView extends RootView
events:
'click .join-clan-btn': 'onJoinClan'
'click .leave-clan-btn': 'onLeaveClan'
'click .remove-member-btn': 'onRemoveMember'
constructor: (options, @clanID) ->
super options
@ -36,7 +36,9 @@ module.exports = class ClanDetailsView extends RootView
error: (model, response, options) =>
console.error 'Error joining clan', response
success: (model, response, options) =>
window.location.reload()
@listenToOnce @clan, 'sync', =>
@render?()
@clan.fetch cache: false
@supermodel.addRequestResource( 'join_clan', options).load()
else
console.error "No clan ID attached to join button."
@ -49,7 +51,24 @@ module.exports = class ClanDetailsView extends RootView
error: (model, response, options) =>
console.error 'Error leaving clan', response
success: (model, response, options) =>
window.location.reload()
@listenToOnce @clan, 'sync', =>
@render?()
@clan.fetch cache: false
@supermodel.addRequestResource( 'leave_clan', options).load()
else
console.error "No clan ID attached to leave button."
onRemoveMember: (e) ->
if memberID = $(e.target).data('id')
options =
url: "/db/clan/#{@clanID}/remove/#{memberID}"
method: 'PUT'
error: (model, response, options) =>
console.error 'Error removing clan member', response
success: (model, response, options) =>
@listenToOnce @clan, 'sync', =>
@render?()
@clan.fetch cache: false
@supermodel.addRequestResource( 'remove_member', options).load()
else
console.error "No member ID attached to remove button."

View file

@ -32,6 +32,7 @@ ClanHandler = class ClanHandler extends Handler
getByRelationship: (req, res, args...) ->
return @joinClan(req, res, args[0]) if args[1] is 'join'
return @leaveClan(req, res, args[0]) if args[1] is 'leave'
return @removeMember(req, res, args[0], args[2]) if args.length is 3 and args[1] is 'remove'
super(arguments...)
joinClan: (req, res, clanID) ->
@ -55,4 +56,19 @@ ClanHandler = class ClanHandler extends Handler
return @sendDatabaseError(res, err) if err
@sendSuccess(res)
removeMember: (req, res, clanID, memberID) ->
return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous()
try
clanID = mongoose.Types.ObjectId(clanID)
memberID = mongoose.Types.ObjectId(memberID)
catch err
return @sendBadInputError(res, err)
Clan.findById clanID, (err, clan) =>
return @sendDatabaseError(res, err) if err
return @sendForbiddenError(res) unless clan.get('ownerID')?.equals req.user._id
return @sendForbiddenError(res) if clan.get('ownerID').equals memberID
Clan.update {_id: clanID}, {$pull: {members: {id: memberID}}}, (err) =>
return @sendDatabaseError(res, err) if err
@sendSuccess(res)
module.exports = new ClanHandler()

View file

@ -163,3 +163,78 @@ describe 'Clans', ->
expect(err).toBeNull()
expect(res.statusCode).toBe(403)
done()
it 'Remove member', (done) ->
loginNewUser (user1) ->
createClan 'public', (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
loginUser user1, (user1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/#{user2.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
Clan.findById clan1.id, (err, clan1) ->
expect(err).toBeNull()
expect(clan1.get('members').length).toEqual(1)
expect(clan1.get('members')[0].id).toEqual(user1.get('_id'))
done()
it 'Remove non-member 200', (done) ->
loginNewUser (user2) ->
loginNewUser (user1) ->
createClan 'public', (clan1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/#{user2.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
Clan.findById clan1.id, (err, clan1) ->
expect(err).toBeNull()
expect(clan1.get('members').length).toEqual(1)
expect(clan1.get('members')[0].id).toEqual(user1.get('_id'))
done()
it 'Remove invalid memberID 422', (done) ->
loginNewUser (user1) ->
createClan 'public', (clan1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/123" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(422)
done()
it 'Remove member, not in clan 403', (done) ->
loginNewUser (user1) ->
createClan 'public', (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
loginNewUser (user3) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/#{user2.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(403)
done()
it 'Remove member, not the owner 403', (done) ->
loginNewUser (user1) ->
createClan 'public', (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
loginNewUser (user3) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
request.put {uri: "#{clanURL}/#{clan1.id}/remove/#{user2.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(403)
done()
it 'Remove member from owned clan', (done) ->
loginNewUser (user1) ->
createClan 'public', (clan1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/#{user1.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(403)
done()