mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-02-17 08:50:58 -05:00
Covered general patches with tests
This commit is contained in:
parent
2394bd8129
commit
cde87e4fe5
5 changed files with 100 additions and 18 deletions
|
@ -165,13 +165,33 @@ _.extend UserSchema.properties,
|
|||
data: c.object {description: 'Cached LinkedIn data slurped from profile.', additionalProperties: true}
|
||||
points: {type: 'number'}
|
||||
activity: {type: 'object', description: 'Summary statistics about user activity', additionalProperties: c.activity}
|
||||
stats: c.object {additionalProperties: true}, # TODO set to false after dev
|
||||
gamesCompleted: type: 'integer'
|
||||
articleEdits: type: 'integer'
|
||||
levelEdits: type: 'integer'
|
||||
levelSystemEdits: type: 'integer'
|
||||
levelComponentEdits: type: 'integer'
|
||||
thangTypeEdits: type: 'integer'
|
||||
stats: c.object {additionalProperties: false},
|
||||
gamesCompleted: c.int()
|
||||
articleEdits: c.int()
|
||||
levelEdits: c.int()
|
||||
levelSystemEdits: c.int()
|
||||
levelComponentEdits: c.int()
|
||||
thangTypeEdits: c.int()
|
||||
'stats.patchesSubmitted': c.int
|
||||
description: 'Amount of patches submitted, not necessarily accepted'
|
||||
'stats.patchesContributed': c.int
|
||||
description: 'Amount of patches submitted and accepted'
|
||||
'stats.patchesAccepted': c.int
|
||||
description: 'Amount of patches accepted by the user as owner'
|
||||
# The below patches only apply to those that actually got accepted
|
||||
'stats.totalTranslationPatches': c.int()
|
||||
'stats.totalMiscPatches': c.int()
|
||||
'stats.articleTranslationPatches': c.int()
|
||||
'stats.articleMiscPatches': c.int()
|
||||
'stats.levelTranslationPatches': c.int()
|
||||
'stats.levelMiscPatches': c.int()
|
||||
'stats.levelComponentTranslationPatches': c.int()
|
||||
'stats.levelComponentMiscPatches': c.int()
|
||||
'stats.levelSystemTranslationPatches': c.int()
|
||||
'stats.levelSystemMiscPatches': c.int()
|
||||
'stats.thangTypeTranslationPatches': c.int()
|
||||
'stats.thangTypeMiscPatches': c.int()
|
||||
|
||||
|
||||
c.extendBasicProperties UserSchema, 'user'
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ me.date = (ext) -> combine({type: ['object', 'string'], format: 'date-time'}, ex
|
|||
# should just be string (Mongo ID), but sometimes mongoose turns them into objects representing those, so we are lenient
|
||||
me.objectId = (ext) -> schema = combine({type: ['object', 'string']}, ext)
|
||||
me.url = (ext) -> combine({type: 'string', format: 'url', pattern: urlPattern}, ext)
|
||||
me.int = (ext) -> if ext then combine {type: 'integer'}, ext else {type: 'integer'}
|
||||
|
||||
PointSchema = me.object {title: 'Point', description: 'An {x, y} coordinate point.', format: 'point2d', required: ['x', 'y']},
|
||||
x: {title: 'x', description: 'The x coordinate.', type: 'number', 'default': 15}
|
||||
|
|
|
@ -26,10 +26,12 @@ whenAllFinished = ->
|
|||
process.exit()
|
||||
|
||||
async.series [
|
||||
(c) -> report UserHandler.recalculateAsync, 'gamesCompleted', c
|
||||
(c) -> report UserHandler.recalculateAsync, 'articleEdits', c
|
||||
(c) -> report UserHandler.recalculateAsync, 'levelEdits', c
|
||||
(c) -> report UserHandler.recalculateAsync, 'levelComponentEdits', c
|
||||
(c) -> report UserHandler.recalculateAsync, 'levelSystemEdits', c
|
||||
(c) -> report UserHandler.recalculateAsync, 'thangTypeEdits', c
|
||||
# Misc
|
||||
(c) -> report UserHandler.recalculateStats, 'gamesCompleted', c
|
||||
# Edits
|
||||
(c) -> report UserHandler.recalculateStats, 'articleEdits', c
|
||||
(c) -> report UserHandler.recalculateStats, 'levelEdits', c
|
||||
(c) -> report UserHandler.recalculateStats, 'levelComponentEdits', c
|
||||
(c) -> report UserHandler.recalculateStats, 'levelSystemEdits', c
|
||||
(c) -> report UserHandler.recalculateStats, 'thangTypeEdits', c
|
||||
], whenAllFinished
|
||||
|
|
|
@ -393,9 +393,10 @@ UserHandler = class UserHandler extends Handler
|
|||
return done(new Error 'Could not resolve statKey for model') unless statKey?
|
||||
User.find {}, (err, users) ->
|
||||
async.eachSeries users, ((user, doneWithUser) ->
|
||||
userID = user.get('_id').toHexString()
|
||||
userObjectID = user.get('_id')
|
||||
userStringID = userObjectID.toHexString()
|
||||
|
||||
model.count {creator: userID}, (err, count) ->
|
||||
model.count {$or: [creator: userObjectID, creator: userStringID]}, (err, count) ->
|
||||
if count
|
||||
update = $set: {}
|
||||
update.$set[statKey] = count
|
||||
|
@ -442,7 +443,38 @@ UserHandler = class UserHandler extends Handler
|
|||
ThangType = require '../levels/thangs/ThangType'
|
||||
countEdits ThangType, done
|
||||
|
||||
recalculateAsync: (statName, done) =>
|
||||
patchesContributed: (done) ->
|
||||
Patch = require '../patches/Patch'
|
||||
|
||||
User.find {}, (err, users) ->
|
||||
async.eachSeries users, ((user, doneWithUser) ->
|
||||
userObjectID = user.get('_id')
|
||||
userStringID = userObjectID.toHexString()
|
||||
|
||||
Patch.count {$or: [{creator: userObjectID}, {creator: userStringID}], 'status': 'accepted'}, (err, count) ->
|
||||
update = if count then {$set: 'stats.patchesContributed': count} else {$unset: 'stats.patchesContributed': ''}
|
||||
User.findByIdAndUpdate user.get('_id'), update, (err) ->
|
||||
log.error err if err?
|
||||
doneWithUser()
|
||||
), done
|
||||
|
||||
patchesSubmitted: (done) ->
|
||||
Patch = require '../patches/Patch'
|
||||
|
||||
User.find {}, (err, users) ->
|
||||
async.eachSeries users, ((user, doneWithUser) ->
|
||||
userObjectID = user.get('_id')
|
||||
userStringID = userObjectID.toHexString()
|
||||
|
||||
Patch.count {$or: [{creator: userObjectID}, {creator: userStringID}]}, (err, count) ->
|
||||
update = if count then {$set: 'stats.patchesSubmitted': count} else {$unset: 'stats.patchesSubmitted': ''}
|
||||
User.findByIdAndUpdate user.get('_id'), update, (err) ->
|
||||
log.error err if err?
|
||||
doneWithUser()
|
||||
), done
|
||||
|
||||
|
||||
recalculateStats: (statName, done) =>
|
||||
return new Error 'Recalculation handler not found' unless statName of @statRecalculators
|
||||
@statRecalculators[statName] done
|
||||
|
||||
|
@ -450,7 +482,7 @@ UserHandler = class UserHandler extends Handler
|
|||
return @sendForbiddenError(res) unless req.user.isAdmin()
|
||||
log.debug 'recalculate'
|
||||
return @sendNotFoundError(res) unless statName of @statRecalculators
|
||||
@recalculateAsync statName
|
||||
@recalculateStats statName
|
||||
@sendAccepted res, {}
|
||||
|
||||
module.exports = new UserHandler()
|
||||
|
|
|
@ -2,6 +2,9 @@ require '../common'
|
|||
|
||||
describe '/db/patch', ->
|
||||
request = require 'request'
|
||||
async = require 'async'
|
||||
UserHandler = require '../../../server/users/user_handler'
|
||||
|
||||
it 'clears the db first', (done) ->
|
||||
clearModels [User, Article, Patch], (err) ->
|
||||
throw err if err
|
||||
|
@ -112,7 +115,7 @@ describe '/db/patch', ->
|
|||
|
||||
it 'keeps track of amount of submitted and accepted patches', (done) ->
|
||||
loginJoe (joe) ->
|
||||
User.findById joe.get('id'), (err, guy) ->
|
||||
User.findById joe.get('_id'), (err, guy) ->
|
||||
expect(err).toBeNull()
|
||||
expect(guy.get 'stats.patchesSubmitted').toBe 1
|
||||
expect(guy.get 'stats.patchesContributed').toBe 1
|
||||
|
@ -121,6 +124,25 @@ describe '/db/patch', ->
|
|||
expect(guy.get 'stats.totalTranslationPatches').toBeUndefined()
|
||||
done()
|
||||
|
||||
it 'recalculates amount of submitted and accepted patches', (done) ->
|
||||
loginJoe (joe) ->
|
||||
console.log joe
|
||||
User.findById joe.get('_id'), (err, joe) ->
|
||||
expect(joe.get 'stats.patchesSubmitted').toBe 1
|
||||
joe.update {$unset: stats: ''}, (err) ->
|
||||
UserHandler.modelClass.findById joe.get('_id'), (err, joe) ->
|
||||
expect(err).toBeNull()
|
||||
expect(joe.get 'stats').toBeUndefined()
|
||||
async.parallel [
|
||||
(done) -> UserHandler.recalculateStats 'patchesContributed', done
|
||||
(done) -> UserHandler.recalculateStats 'patchesSubmitted', done
|
||||
], (err) ->
|
||||
expect(err).toBeNull()
|
||||
UserHandler.modelClass.findById joe.get('_id'), (err, joe) ->
|
||||
expect(joe.get 'stats.patchesContributed').toBe 1
|
||||
expect(joe.get 'stats.patchesSubmitted').toBe 1
|
||||
done()
|
||||
|
||||
it 'does not allow the recipient to withdraw the pull request', (done) ->
|
||||
loginAdmin ->
|
||||
statusURL = getURL("/db/patch/#{patches[0]._id}/status")
|
||||
|
@ -129,3 +151,8 @@ describe '/db/patch', ->
|
|||
Patch.findOne({}).exec (err, article) ->
|
||||
expect(article.get('status')).toBe 'accepted'
|
||||
done()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue