Add clan description field

This commit is contained in:
Matt Lott 2015-04-03 14:09:43 -07:00
parent db1e8f0cb4
commit 5ae93cd6ab
9 changed files with 72 additions and 46 deletions

View file

@ -4,9 +4,10 @@ ClanSchema = c.object {title: 'Clan', required: ['name', 'type']}
c.extendNamedProperties ClanSchema # name first
_.extend ClanSchema.properties,
type: {type: 'string', 'enum': ['public']}
ownerID: c.objectId()
description: {type: 'string'}
members: c.array {title: 'Members'}, c.objectId()
ownerID: c.objectId()
type: {type: 'string', 'enum': ['public']}
c.extendBasicProperties ClanSchema, 'Clan'

View file

@ -1 +1,4 @@
// #clan-details-view
#clan-details-view
.clan-description
margin-left: 10px

View file

@ -3,3 +3,6 @@
.clan-title
cursor: pointer
.create-clan-description
width: 50%

View file

@ -4,6 +4,19 @@ block content
if clan
h1= clan.get('name')
if clan.get('description')
.clan-description
each line in clan.get('description').split('\n')
p= line
p
if isOwner
button.btn.btn-sm.btn-warning.delete-clan-btn Delete Clan
else if isMember
button.btn.btn-sm.btn-warning.leave-clan-btn Leave Clan
else
button.btn.btn-sm.btn-success.join-clan-btn Join Clan
if owner
p
span.spr Chieftain:
@ -13,14 +26,6 @@ block content
if stats.totalAchievements
p Total achievements earned: #{stats.totalAchievements}
div
if isOwner
button.btn.btn-sm.btn-warning.delete-clan-btn Delete Clan
else if isMember
button.btn.btn-sm.btn-warning.leave-clan-btn Leave Clan
else
button.btn.btn-sm.btn-success.join-clan-btn Join Clan
if members
h3 Heroes (#{members.length})
table.table.table-striped.table-condensed

View file

@ -4,6 +4,8 @@ block content
p
input.create-clan-name(type='text' placeholder='New clan name')
p
textarea.create-clan-description(rows=2, placeholder='New clan description')
p
button.btn.btn-sm.btn-success.create-clan-btn Create New Clan

View file

@ -38,13 +38,11 @@ module.exports = class MainAdminView extends RootView
sortClanList = (a, b) ->
if a.get('members').length isnt b.get('members').length
a.get('members').length < b.get('members').length
if a.get('members').length < b.get('members').length then 1 else -1
else
b.id.localeCompare(a.id)
@publicClans = new CocoCollection([], { url: '/db/clan/-/public', model: Clan, comparator: sortClanList })
@listenTo @publicClans, 'sync', =>
for clan in @publicClans.models
console.log clan.get('name')
@refreshNames @publicClans.models
@render?()
@supermodel.loadCollection(@publicClans, 'public_clans', {cache: false})
@ -71,6 +69,7 @@ module.exports = class MainAdminView extends RootView
clan = new Clan()
clan.set 'type', 'public'
clan.set 'name', name
clan.set 'description', description if description = $('.create-clan-description').val()
clan.save {},
error: (model, response, options) =>
console.error 'Error saving clan', response.status

View file

@ -16,13 +16,16 @@ ClanSchema.pre 'save', (next) ->
ClanSchema.statics.privateProperties = []
ClanSchema.statics.editableProperties = [
'type'
'name'
'description'
'members'
'name'
'type'
]
ClanSchema.plugin plugins.NamedPlugin
ClanSchema.plugin plugins.SearchablePlugin, {searchable: ['name']}
# TODO: Do we need this?
# ClanSchema.plugin plugins.SearchablePlugin, {searchable: ['name']}
ClanSchema.statics.jsonSchema = jsonSchema

View file

@ -17,6 +17,7 @@ ClanHandler = class ClanHandler extends Handler
false
hasAccessToDocument: (req, document, method=null) ->
return false unless document?
method = (method or req.method).toLowerCase()
return true if req.user?.isAdmin()
return true if method is 'get'
@ -57,13 +58,11 @@ ClanHandler = class ClanHandler extends Handler
clanID = mongoose.Types.ObjectId(clanID)
catch err
return @sendNotFoundError(res, err)
Clan.findById clanID, (err, clan) =>
Clan.update {_id: clanID}, {$addToSet: {members: req.user._id}}, (err) =>
return @sendDatabaseError(res, err) if err
Clan.update {_id: clanID}, {$addToSet: {members: req.user._id}}, (err) =>
User.update {_id: req.user._id}, {$addToSet: {clans: clanID}}, (err) =>
return @sendDatabaseError(res, err) if err
User.update {_id: req.user._id}, {$addToSet: {clans: clanID}}, (err) =>
return @sendDatabaseError(res, err) if err
@sendSuccess(res)
@sendSuccess(res)
leaveClan: (req, res, clanID) ->
return @sendForbiddenError(res) unless req.user? and not req.user.isAnonymous()
@ -73,6 +72,7 @@ ClanHandler = class ClanHandler extends Handler
return @sendNotFoundError(res, err)
Clan.findById clanID, (err, clan) =>
return @sendDatabaseError(res, err) if err
return @sendDatabaseError(res, err) unless clan
return @sendForbiddenError(res) if clan.get('ownerID')?.equals req.user._id
Clan.update {_id: clanID}, {$pull: {members: req.user._id}}, (err) =>
return @sendDatabaseError(res, err) if err
@ -84,6 +84,7 @@ ClanHandler = class ClanHandler extends Handler
# TODO: add tests
Clan.findById clanID, (err, clans) =>
return @sendDatabaseError(res, err) if err
return @sendDatabaseError(res, err) unless clans
memberIDs = _.map clans.get('members') ? [], (memberID) -> memberID.toHexString()
EarnedAchievement.find {user: {$in: memberIDs}}, (err, documents) =>
return @sendDatabaseError(res, err) if err?
@ -96,6 +97,7 @@ ClanHandler = class ClanHandler extends Handler
clanIDs = req.user.get('clans') ? []
Clan.findById clanID, (err, clans) =>
return @sendDatabaseError(res, err) if err
return @sendDatabaseError(res, err) unless clans
memberIDs = clans.get('members') ? []
User.find {_id: {$in: memberIDs}}, (err, users) =>
return @sendDatabaseError(res, err) if err
@ -105,11 +107,13 @@ ClanHandler = class ClanHandler extends Handler
getPublicClans: (req, res) ->
# Return 100 public clans, sorted by member count, created date
query = [{ $match : {type : 'public'} }]
query.push {$project : {_id: 1, name: 1, slug: 1, type: 1, members: 1, memberCount: {$size: "$members"}, ownerID: 1}}
query.push {$project : {_id: 1, name: 1, slug: 1, type: 1, description: 1, members: 1, memberCount: {$size: "$members"}, ownerID: 1}}
query.push {$sort: { memberCount: -1, _id: -1 }}
query.push {$limit: 100}
Clan.aggregate(query).exec (err, documents) =>
return @sendDatabaseError(res, err) if err
for doc in documents
console.log doc.memberCount, doc.name
@sendSuccess(res, documents)
removeMember: (req, res, clanID, memberID) ->
@ -121,6 +125,7 @@ ClanHandler = class ClanHandler extends Handler
return @sendNotFoundError(res, err)
Clan.findById clanID, (err, clan) =>
return @sendDatabaseError(res, err) if err
return @sendDatabaseError(res, err) unless clan
return @sendForbiddenError res unless @hasAccessToDocument(req, clan)
return @sendForbiddenError(res) if clan.get('ownerID').equals memberID
Clan.update {_id: clanID}, {$pull: {members: memberID}}, (err) =>

View file

@ -10,19 +10,24 @@ describe 'Clans', ->
clanCount = 0
createClanName = (name) -> name + clanCount++
createClan = (user, type, done) ->
createClan = (user, type, description, done) ->
name = createClanName 'myclan'
requestBody =
type: type
name: name
requestBody.description = description if description?
request.post {uri: clanURL, json: requestBody }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
expect(body.type).toEqual(type)
expect(body.name).toEqual(name)
expect(body.description).toEqual(description) if description?
expect(body.members?.length).toEqual(1)
expect(body.members?[0]).toEqual(user.id)
Clan.findById body._id, (err, clan) ->
expect(clan.get('type')).toEqual(type)
expect(clan.get('name')).toEqual(name)
expect(clan.get('description')).toEqual(description) if description?
expect(clan.get('members')?.length).toEqual(1)
expect(clan.get('members')?[0]).toEqual(user._id)
User.findById user.id, (err, user) ->
@ -38,7 +43,7 @@ describe 'Clans', ->
it 'Create clan', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan) ->
createClan user1, 'public', 'test description', (clan) ->
done()
it 'Anonymous create clan 401', (done) ->
@ -71,8 +76,8 @@ describe 'Clans', ->
it 'Get public clans', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', (clan2) ->
createClan user1, 'public', null, (clan1) ->
createClan user1, 'public', 'the second clan', (clan2) ->
request.get {uri: "#{clanURL}/-/public" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
@ -81,8 +86,8 @@ describe 'Clans', ->
it 'Get public clans anonymous', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', (clan2) ->
createClan user1, 'public', null, (clan1) ->
createClan user1, 'public', null, (clan2) ->
logoutUser ->
request.get {uri: "#{clanURL}/-/public" }, (err, res, body) ->
expect(err).toBeNull()
@ -92,7 +97,7 @@ describe 'Clans', ->
it 'Join clan', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -109,7 +114,7 @@ describe 'Clans', ->
it 'Join invalid clan 404', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/1234/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -118,7 +123,7 @@ describe 'Clans', ->
it 'Join clan anonymous 401', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
logoutUser ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -127,7 +132,7 @@ describe 'Clans', ->
it 'Join clan twice 200', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -142,7 +147,7 @@ describe 'Clans', ->
it 'Leave clan', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', 'do not stay too long', (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -160,7 +165,7 @@ describe 'Clans', ->
it 'Leave clan not member 200', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/leave" }, (err, res, body) ->
expect(err).toBeNull()
@ -172,7 +177,7 @@ describe 'Clans', ->
it 'Leave owned clan 403', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/leave" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(403)
@ -180,7 +185,7 @@ describe 'Clans', ->
it 'Remove member', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -201,7 +206,7 @@ describe 'Clans', ->
it 'Remove non-member 200', (done) ->
loginNewUser (user2) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/#{user2.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(200)
@ -213,7 +218,7 @@ describe 'Clans', ->
it 'Remove invalid memberID 404', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/123" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(404)
@ -221,7 +226,7 @@ describe 'Clans', ->
it 'Remove member, not in clan 403', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -234,7 +239,7 @@ describe 'Clans', ->
it 'Remove member, not the owner 403', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
loginNewUser (user2) ->
request.put {uri: "#{clanURL}/#{clan1.id}/join" }, (err, res, body) ->
expect(err).toBeNull()
@ -250,7 +255,7 @@ describe 'Clans', ->
it 'Remove member from owned clan 403', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan1) ->
createClan user1, 'public', null, (clan1) ->
request.put {uri: "#{clanURL}/#{clan1.id}/remove/#{user1.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(403)
@ -258,7 +263,7 @@ describe 'Clans', ->
it 'Delete clan', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan) ->
createClan user1, 'public', null, (clan) ->
request.del {uri: "#{clanURL}/#{clan.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(204)
@ -269,7 +274,7 @@ describe 'Clans', ->
it 'Delete clan anonymous 401', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan) ->
createClan user1, 'public', null, (clan) ->
logoutUser ->
request.del {uri: "#{clanURL}/#{clan.id}" }, (err, res, body) ->
expect(err).toBeNull()
@ -278,7 +283,7 @@ describe 'Clans', ->
it 'Delete clan not owner 403', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan) ->
createClan user1, 'public', null, (clan) ->
loginNewUser (user2) ->
request.del {uri: "#{clanURL}/#{clan.id}" }, (err, res, body) ->
expect(err).toBeNull()
@ -287,7 +292,7 @@ describe 'Clans', ->
it 'Delete clan no longer exists 404', (done) ->
loginNewUser (user1) ->
createClan user1, 'public', (clan) ->
createClan user1, 'public', null, (clan) ->
request.del {uri: "#{clanURL}/#{clan.id}" }, (err, res, body) ->
expect(err).toBeNull()
expect(res.statusCode).toBe(204)