codecombat/spec/server/functional/user.spec.coffee

458 lines
16 KiB
CoffeeScript
Raw Normal View History

2014-01-03 13:32:13 -05:00
require '../common'
User = require '../../../server/users/User'
2014-01-15 14:36:59 -05:00
urlUser = '/db/user'
2014-01-03 13:32:13 -05:00
describe 'Server user object', ->
2014-06-30 22:16:26 -04:00
it 'uses the schema defaults to fill in email preferences', (done) ->
user = new User()
expect(user.isEmailSubscriptionEnabled('generalNews')).toBeTruthy()
expect(user.isEmailSubscriptionEnabled('anyNotes')).toBeTruthy()
expect(user.isEmailSubscriptionEnabled('recruitNotes')).toBeTruthy()
expect(user.isEmailSubscriptionEnabled('archmageNews')).toBeFalsy()
done()
it 'uses old subs if they\'re around', (done) ->
user = new User()
user.set 'emailSubscriptions', ['tester']
expect(user.isEmailSubscriptionEnabled('adventurerNews')).toBeTruthy()
expect(user.isEmailSubscriptionEnabled('generalNews')).toBeFalsy()
done()
it 'maintains the old subs list if it\'s around', (done) ->
user = new User()
user.set 'emailSubscriptions', ['tester']
user.setEmailSubscription('artisanNews', true)
2014-06-30 22:16:26 -04:00
expect(JSON.stringify(user.get('emailSubscriptions'))).toBe(JSON.stringify(['tester', 'level_creator']))
done()
2014-06-30 22:16:26 -04:00
describe 'User.updateServiceSettings', ->
makeMC = (callback) ->
spyOn(mc.lists, 'subscribe').and.callFake callback
it 'uses emails to determine what to send to MailChimp', (done) ->
makeMC (params) ->
expect(JSON.stringify(params.merge_vars.groupings[0].groups)).toBe(JSON.stringify(['Announcements']))
done()
2014-06-30 22:16:26 -04:00
user = new User({emailSubscriptions: ['announcement'], email: 'tester@gmail.com'})
User.updateServiceSettings(user)
2014-01-03 13:32:13 -05:00
describe 'POST /db/user', ->
2014-01-15 14:36:59 -05:00
2014-07-09 15:33:25 -04:00
createAnonNameUser = (name, done)->
request.post getURL('/auth/logout'), ->
request.get getURL('/auth/whoami'), ->
req = request.post(getURL('/db/user'), (err, response) ->
expect(response.statusCode).toBe(200)
request.get getURL('/auth/whoami'), (request, response, body) ->
res = JSON.parse(response.body)
expect(res.anonymous).toBeTruthy()
2014-07-09 15:33:25 -04:00
expect(res.name).toEqual(name)
2014-06-30 22:16:26 -04:00
done()
)
form = req.form()
2014-07-09 15:33:25 -04:00
form.append('name', name)
2014-01-15 14:36:59 -05:00
it 'preparing test : clears the db first', (done) ->
2014-01-03 13:32:13 -05:00
clearModels [User], (err) ->
throw err if err
done()
it 'converts the password into a hash', (done) ->
unittest.getNormalJoe (user) ->
expect(user).toBeTruthy()
expect(user.get('password')).toBeUndefined()
expect(user?.get('passwordHash')).not.toBeUndefined()
if user?.get('passwordHash')?
expect(user.get('passwordHash')[..5] in ['31dc3d', '948c7e']).toBeTruthy()
2014-01-03 13:32:13 -05:00
expect(user.get('permissions').length).toBe(0)
done()
it 'serves the user through /db/user/id', (done) ->
unittest.getNormalJoe (user) ->
request.post getURL('/auth/logout'), ->
url = getURL(urlUser+'/'+user._id)
request.get url, (err, res, body) ->
expect(res.statusCode).toBe(200)
user = JSON.parse(body)
expect(user.name).toBe('Joe') # Anyone should be served the username.
expect(user.email).toBeUndefined() # Shouldn't be available to just anyone.
expect(user.passwordHash).toBeUndefined()
done()
2014-01-03 13:32:13 -05:00
it 'creates admins based on passwords', (done) ->
request.post getURL('/auth/logout'), ->
unittest.getAdmin (user) ->
expect(user).not.toBeUndefined()
if user
expect(user.get('permissions').length).toBe(1)
expect(user.get('permissions')[0]).toBe('admin')
done()
it 'does not return the full user object for regular users.', (done) ->
loginJoe ->
unittest.getAdmin (user) ->
2014-01-15 14:36:59 -05:00
url = getURL(urlUser+'/'+user._id)
2014-01-03 13:32:13 -05:00
request.get url, (err, res, body) ->
expect(res.statusCode).toBe(200)
user = JSON.parse(body)
expect(user.email).toBeUndefined()
expect(user.passwordHash).toBeUndefined()
done()
it 'should allow setting anonymous user name', (done) ->
2014-07-09 15:33:25 -04:00
createAnonNameUser('Jim', done)
it 'should allow multiple anonymous users with same name', (done) ->
2014-07-09 15:33:25 -04:00
createAnonNameUser('Jim', done)
it 'should allow setting existing user name to anonymous user', (done) ->
2014-06-30 22:16:26 -04:00
req = request.post(getURL('/db/user'), (err, response, body) ->
expect(response.statusCode).toBe(200)
request.get getURL('/auth/whoami'), (request, response, body) ->
res = JSON.parse(response.body)
expect(res.anonymous).toBeFalsy()
createAnonNameUser 'Jim', done
)
form = req.form()
form.append('email', 'new@user.com')
form.append('password', 'new')
2014-01-03 13:32:13 -05:00
describe 'PUT /db/user', ->
it 'logs in as normal joe', (done) ->
request.post getURL('/auth/logout'),
loginJoe -> done()
2014-01-03 13:32:13 -05:00
it 'denies requests without any data', (done) ->
request.put getURL(urlUser),
2014-01-03 13:32:13 -05:00
(err, res) ->
expect(res.statusCode).toBe(422)
expect(res.body).toBe('No input.')
done()
2014-01-03 13:32:13 -05:00
it 'denies requests to edit someone who is not joe', (done) ->
unittest.getAdmin (admin) ->
2014-01-15 14:36:59 -05:00
req = request.put getURL(urlUser),
2014-01-03 13:32:13 -05:00
(err, res) ->
expect(res.statusCode).toBe(403)
done()
req.form().append('_id', admin.id)
it 'denies invalid data', (done) ->
unittest.getNormalJoe (joe) ->
2014-01-15 14:36:59 -05:00
req = request.put getURL(urlUser),
2014-01-03 13:32:13 -05:00
(err, res) ->
expect(res.statusCode).toBe(422)
expect(res.body.indexOf('too long')).toBeGreaterThan(-1)
done()
form = req.form()
form.append('_id', joe.id)
2014-06-30 22:16:26 -04:00
form.append('email', 'farghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlar
ghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghlfarghlarghl')
2014-01-03 13:32:13 -05:00
it 'logs in as admin', (done) ->
loginAdmin -> done()
it 'denies non-existent ids', (done) ->
2014-01-15 14:36:59 -05:00
req = request.put getURL(urlUser),
2014-01-03 13:32:13 -05:00
(err, res) ->
expect(res.statusCode).toBe(404)
done()
form = req.form()
form.append('_id', '513108d4cb8b610000000004')
2014-06-30 22:16:26 -04:00
form.append('email', 'perfectly@good.com')
2014-01-03 13:32:13 -05:00
it 'denies if the email being changed is already taken', (done) ->
unittest.getNormalJoe (joe) ->
unittest.getAdmin (admin) ->
2014-01-15 14:36:59 -05:00
req = request.put getURL(urlUser), (err, res) ->
2014-01-03 13:32:13 -05:00
expect(res.statusCode).toBe(409)
expect(res.body.indexOf('already used')).toBeGreaterThan(-1)
done()
form = req.form()
form.append('_id', String(admin._id))
form.append('email', joe.get('email').toUpperCase())
it 'does not care if you include your existing name', (done) ->
unittest.getNormalJoe (joe) ->
req = request.put getURL(urlUser+'/'+joe._id), (err, res) ->
expect(res.statusCode).toBe(200)
done()
form = req.form()
form.append('_id', String(joe._id))
form.append('name', 'Joe')
it 'accepts name and email changes', (done) ->
2014-01-03 13:32:13 -05:00
unittest.getNormalJoe (joe) ->
2014-01-15 14:36:59 -05:00
req = request.put getURL(urlUser), (err, res) ->
2014-01-03 13:32:13 -05:00
expect(res.statusCode).toBe(200)
unittest.getUser('Wilhelm', 'New@email.com', 'null', (joe) ->
2014-01-03 13:32:13 -05:00
expect(joe.get('name')).toBe('Wilhelm')
expect(joe.get('emailLower')).toBe('new@email.com')
expect(joe.get('email')).toBe('New@email.com')
done())
form = req.form()
form.append('_id', String(joe._id))
form.append('email', 'New@email.com')
form.append('name', 'Wilhelm')
it 'should not allow two users with the same name slug', (done) ->
loginSam (sam) ->
samsName = sam.get 'name'
sam.set 'name', 'admin'
request.put {uri:getURL(urlUser + '/' + sam.id), json: sam.toObject()}, (err, response) ->
expect(err).toBeNull()
expect(response.statusCode).toBe 409
# Restore Sam
sam.set 'name', samsName
done()
it 'should silently rename an anonymous user if their name conflicts upon signup', (done) ->
request.post getURL('/auth/logout'), ->
request.get getURL('/auth/whoami'), ->
req = request.post getURL('/db/user'), (err, response) ->
expect(response.statusCode).toBe(200)
request.get getURL('/auth/whoami'), (err, response) ->
expect(err).toBeNull()
guy = JSON.parse(response.body)
expect(guy.anonymous).toBeTruthy()
expect(guy.name).toEqual 'admin'
guy.email = 'blub@blub' # Email means registration
req = request.post {url: getURL('/db/user'), json: guy}, (err, response) ->
expect(err).toBeNull()
finalGuy = response.body
expect(finalGuy.anonymous).toBeFalsy()
expect(finalGuy.name).not.toEqual guy.name
expect(finalGuy.name.length).toBe guy.name.length + 1
done()
form = req.form()
form.append('name', 'admin')
it 'should be able to unset a slug by setting an empty name', (done) ->
loginSam (sam) ->
samsName = sam.get 'name'
sam.set 'name', ''
request.put {uri:getURL(urlUser + '/' + sam.id), json: sam.toObject()}, (err, response) ->
expect(err).toBeNull()
expect(response.statusCode).toBe 200
newSam = response.body
# Restore Sam
sam.set 'name', samsName
request.put {uri:getURL(urlUser + '/' + sam.id), json: sam.toObject()}, (err, response) ->
expect(err).toBeNull()
done()
2014-01-03 13:32:13 -05:00
describe 'GET /db/user', ->
2014-01-15 14:36:59 -05:00
2014-01-03 13:32:13 -05:00
it 'logs in as admin', (done) ->
req = request.post(getURL('/auth/login'), (error, response) ->
expect(response.statusCode).toBe(200)
done()
)
form = req.form()
form.append('username', 'admin@afc.com')
form.append('password', '80yqxpb38j')
it 'get schema', (done) ->
2014-06-30 22:16:26 -04:00
request.get {uri: getURL(urlUser+'/schema')}, (err, res, body) ->
expect(res.statusCode).toBe(200)
body = JSON.parse(body)
expect(body.type).toBeDefined()
done()
2015-10-09 18:54:05 -04:00
it 'is able to do a semi-sweet query', (done) ->
2014-01-03 13:32:13 -05:00
options = {
2015-10-09 18:54:05 -04:00
url: getURL(urlUser) + "?conditions[limit]=20&conditions[sort]=-dateCreated"
2014-01-03 13:32:13 -05:00
}
req = request.get(options, (error, response) ->
expect(response.statusCode).toBe(200)
res = JSON.parse(response.body)
expect(res.length).toBeGreaterThan(0)
done()
)
it 'rejects bad conditions', (done) ->
options = {
2015-10-09 18:54:05 -04:00
url: getURL(urlUser) + "?conditions[lime]=20&conditions[sort]=-dateCreated"
2014-01-03 13:32:13 -05:00
}
req = request.get(options, (error, response) ->
expect(response.statusCode).toBe(422)
done()
)
it 'can fetch myself by id completely', (done) ->
loginSam (sam) ->
request.get {url: getURL(urlUser + '/' + sam.id)}, (err, response) ->
expect(err).toBeNull()
expect(response.statusCode).toBe(200)
done()
it 'can fetch myself by slug completely', (done) ->
loginSam (sam) ->
request.get {url: getURL(urlUser + '/sam')}, (err, response) ->
expect(err).toBeNull()
expect(response.statusCode).toBe(200)
guy = JSON.parse response.body
expect(guy._id).toBe sam.get('_id').toHexString()
expect(guy.name).toBe sam.get 'name'
done()
# TODO Ruben should be able to fetch other users but probably with restricted data access
# Add to the test case above an extra data check
xit 'can fetch another user with restricted fields'
2015-06-18 18:02:15 -04:00
describe 'DELETE /db/user', ->
it 'can delete a user', (done) ->
loginNewUser (user1) ->
2015-06-18 18:17:56 -04:00
beforeDeleted = new Date()
2015-06-18 18:02:15 -04:00
request.del {uri: "#{getURL(urlUser)}/#{user1.id}"}, (err, res) ->
expect(err).toBeNull()
return done() if err
User.findById user1.id, (err, user1) ->
expect(err).toBeNull()
return done() if err
expect(user1.get('deleted')).toBe(true)
2015-06-18 18:17:56 -04:00
expect(user1.get('dateDeleted')).toBeGreaterThan(beforeDeleted)
expect(user1.get('dateDeleted')).toBeLessThan(new Date())
2015-06-18 18:02:15 -04:00
for key, value of user1.toObject()
2015-06-18 18:17:56 -04:00
continue if key in ['_id', 'deleted', 'dateDeleted']
expect(_.isEmpty(value)).toEqual(true)
2015-06-18 18:02:15 -04:00
done()
describe 'Statistics', ->
LevelSession = require '../../../server/levels/sessions/LevelSession'
Article = require '../../../server/articles/Article'
Level = require '../../../server/levels/Level'
LevelSystem = require '../../../server/levels/systems/LevelSystem'
LevelComponent = require '../../../server/levels/components/LevelComponent'
ThangType = require '../../../server/levels/thangs/ThangType'
User = require '../../../server/users/User'
UserHandler = require '../../../server/users/user_handler'
it 'keeps track of games completed', (done) ->
session = new LevelSession
name: 'Beat Gandalf'
permissions: simplePermissions
state: complete: true
unittest.getNormalJoe (joe) ->
expect(joe.get 'stats.gamesCompleted').toBeUndefined()
session.set 'creator', joe.get 'id'
session.save (err) ->
expect(err).toBeNull()
f = ->
User.findById joe.get('id'), (err, guy) ->
expect(err).toBeNull()
expect(guy.get 'id').toBe joe.get 'id'
expect(guy.get 'stats.gamesCompleted').toBe 1
done()
setTimeout f, 100
it 'recalculates games completed', (done) ->
unittest.getNormalJoe (joe) ->
loginAdmin ->
User.findByIdAndUpdate joe.get('id'), {$unset:'stats.gamesCompleted': ''}, {new: true}, (err, guy) ->
expect(err).toBeNull()
expect(guy.get 'stats.gamesCompleted').toBeUndefined()
UserHandler.statRecalculators.gamesCompleted ->
User.findById joe.get('id'), (err, guy) ->
expect(err).toBeNull()
expect(guy.get 'stats.gamesCompleted').toBe 1
done()
it 'keeps track of article edits', (done) ->
article =
name: 'My very first'
body: 'I don\'t have much to say I\'m afraid'
url = getURL('/db/article')
loginAdmin (carl) ->
expect(carl.get User.statsMapping.edits.article).toBeUndefined()
article.creator = carl.get 'id'
2015-12-16 20:09:22 -05:00
# Create major version 0.0
request.post {uri:url, json: article}, (err, res, body) ->
expect(err).toBeNull()
2015-12-16 20:09:22 -05:00
expect(res.statusCode).toBe 201
article = body
User.findById carl.get('id'), (err, guy) ->
expect(err).toBeNull()
expect(guy.get User.statsMapping.edits.article).toBe 1
2015-12-16 20:09:22 -05:00
# Create minor version 0.1
newVersionURL = "#{url}/#{article._id}/new-version"
request.post {uri:newVersionURL, json: article}, (err, res, body) ->
expect(err).toBeNull()
User.findById carl.get('id'), (err, guy) ->
expect(err).toBeNull()
expect(guy.get User.statsMapping.edits.article).toBe 2
done()
it 'recalculates article edits', (done) ->
loginAdmin (carl) ->
User.findByIdAndUpdate carl.get('id'), {$unset:'stats.articleEdits': ''}, {new: true}, (err, guy) ->
expect(err).toBeNull()
expect(guy.get User.statsMapping.edits.article).toBeUndefined()
UserHandler.statRecalculators.articleEdits ->
User.findById carl.get('id'), (err, guy) ->
expect(err).toBeNull()
expect(guy.get User.statsMapping.edits.article).toBe 2
done()
it 'keeps track of level edits', (done) ->
level = new Level
name: "King's Peak 3"
description: 'Climb a mountain.'
permissions: simplePermissions
scripts: []
thangs: []
loginAdmin (carl) ->
expect(carl.get User.statsMapping.edits.level).toBeUndefined()
level.creator = carl.get 'id'
level.save (err) ->
expect(err).toBeNull()
User.findById carl.get('id'), (err, guy) ->
expect(err).toBeNull()
expect(guy.get 'id').toBe carl.get 'id'
expect(guy.get User.statsMapping.edits.level).toBe 1
done()
it 'recalculates level edits', (done) ->
unittest.getAdmin (jose) ->
User.findByIdAndUpdate jose.get('id'), {$unset:'stats.levelEdits':''}, {new: true}, (err, guy) ->
expect(err).toBeNull()
expect(guy.get User.statsMapping.edits.level).toBeUndefined()
UserHandler.statRecalculators.levelEdits ->
User.findById jose.get('id'), (err, guy) ->
expect(err).toBeNull()
expect(guy.get User.statsMapping.edits.level).toBe 1
done()
it 'cleans up', (done) ->
clearModels [LevelSession, Article, Level, LevelSystem, LevelComponent, ThangType], (err) ->
expect(err).toBeNull()
done()