fix unit test

This commit is contained in:
jysperm
2015-03-30 02:57:35 +08:00
parent 2d303e1e3f
commit 37b3a85cba
10 changed files with 50 additions and 277 deletions

View File

@@ -1,8 +1,7 @@
language: node_js
node_js:
- 0.11
- 0.10
- 0.12
before_install:
- sudo apt-get update -qq

View File

@@ -47,7 +47,7 @@
* (新增) 帐号安全事件记录
* (新增) 兑换代码
* (新增) 管理员面板:删除账户
* (改进) 在 Token 中记录 IP, UA, 和最后使用时间
* (改进) 在 Token 中记录 IP, UA, 和最后使用时间
18 commits, 27 changed files with 366 additions and 29 deletions, by 1 contributors: jysperm.

View File

@@ -30,11 +30,10 @@ harp = require 'harp'
{_, fs, path, express} = app.libs
unless global.config
if fs.existsSync "#{__dirname}/config.coffee"
config = require './config'
else
config = require './sample/core.config.coffee'
if fs.existsSync "#{__dirname}/config.coffee"
config = require './config'
else
config = require './sample/core.config.coffee'
app.package = require './package'
utils = require './core/utils'

View File

@@ -29,7 +29,7 @@ exports.reqHelpers = (req, res, next) ->
req.createSecurityLog = (type, payload, options) ->
SecurityLog.createLog
account: options?.account ? req.account
token: token
token: options?.token ? req.token
type: type
, payload
@@ -40,12 +40,10 @@ exports.reqHelpers = (req, res, next) ->
if name?.message
name = name.message
param ?= {}
if req.method in ['GET', 'HEAD', 'OPTIONS']
res.status(status).send name.toString()
else
res.status(status).json _.extend param,
res.status(status).json _.extend {}, param,
error: name.toString()
res.createCookie = (name, value) ->
@@ -116,18 +114,13 @@ exports.csrf = ->
validator()
exports.authenticate = (req, res, next) ->
code = req.getTokenCode()
unless code
return next()
Account.authenticate(code).then ({token, account}) ->
if token and token.type == 'full_access'
Account.authenticate(req.getTokenCode()).then ({token, account}) ->
if token?.type == 'full_access'
_.extend req,
token: token
account: account
else
next()
.finally next
exports.accountHelpers = (req, res, next) ->
_.extend res,

View File

@@ -74,14 +74,27 @@ Account = mabolo.model 'Account',
type: Date
default: -> new Date()
Account.ensureIndex
username: 1
,
unique: true
Account.ensureIndex
email: 1
,
unique: true
Account.ensureIndex
'tokens.code': 1
,
unique: true
Token::revoke = ->
@parent().update
$pull:
tokens:
code: @code
Account.ensureIndex
Account.register = ({username, email, password}) ->
password_salt = utils.randomSalt()
password = utils.hashPassword password, password_salt
@@ -89,7 +102,7 @@ Account.register = ({username, email, password}) ->
avatar_url = '//cdn.v2ex.com/gravatar/' + utils.md5(email)
account = new Account
email: email
email: email.toLowerCase()
username: username
password: password
password_salt: password_salt
@@ -120,7 +133,7 @@ Account.search = (identification) ->
Account.authenticate = (token_code) ->
@findOneAndUpdate(
'tokens.token': token_code
'tokens.code': token_code
,
$set:
'tokens.$.updated_at': new Date()

View File

@@ -26,7 +26,7 @@ exports.get '/session_info/', (req, res) ->
if req.account
_.extend response,
id: req.account.id
account_id: req.account._id
username: req.account.username
preferences: req.account.preferences
@@ -35,11 +35,17 @@ exports.get '/session_info/', (req, res) ->
exports.post '/register', (req, res) ->
Account.register(req.body).then (account) ->
res.createToken account
.catch res.error
.catch (err) ->
if err.message.match /duplicate.*username/
res.error 'username_exist'
else if err.message.match /Validating.*email/
res.error 'invalid_email'
else
res.error err
exports.post '/login', (req, res) ->
Account.search(req.body.username).then (account) ->
if account?.matchPassword req.body.password
unless account?.matchPassword req.body.password
throw new Error 'wrong_password'
res.createCookie 'language', account.preferences.language
@@ -49,7 +55,11 @@ exports.post '/login', (req, res) ->
account: account
token: token
.catch res.error
.catch (err) ->
if err.message.match /must be a/
res.error 'wrong_password'
else
res.error err
exports.post '/logout', requireAuthenticate, (req, res) ->
req.token.revoke().then ->

View File

@@ -1,4 +1,4 @@
describe 'account.register.test', ->
describe 'account.register', ->
agent = null
csrf_token = null
@@ -28,7 +28,7 @@ describe 'account.register.test', ->
.expect 200
.end (err, res) ->
res.body.csrf_token.should.be.exist
csrf_token = res.body.csrf_token
{csrf_token} = res.body
done err
it 'POST register', (done) ->
@@ -45,8 +45,8 @@ describe 'account.register.test', ->
.expect 200
.expect 'set-cookie', /token=/
.end (err, res) ->
res.body.id.should.have.length 24
account_id = res.body.id
res.body.account_id.should.have.length 24
{account_id} = res.body
done err
it 'POST register with existed username', (done) ->
@@ -82,7 +82,7 @@ describe 'account.register.test', ->
.expect 200
.expect 'set-cookie', /token=/
.end (err, res) ->
res.body.id.should.be.equal account_id
res.body.account_id.should.be.equal account_id
res.body.token.should.be.exist
done err
@@ -99,7 +99,7 @@ describe 'account.register.test', ->
agent.post '/account/logout'
.send
csrf_token: csrf_token
.expect 200
.expect 204
.expect 'set-cookie', /token=;/
.end done
@@ -112,7 +112,7 @@ describe 'account.register.test', ->
.expect 200
.expect 'set-cookie', /token=/
.end (err, res) ->
res.body.id.should.be.equal account_id
res.body.account_id.should.be.equal account_id
res.body.token.should.be.exist
done err

View File

@@ -1,75 +0,0 @@
describe 'cache', ->
cache = null
redis = null
before ->
{cache, redis} = app
describe 'hashKey', ->
it 'should success', ->
cache.hashKey('cache_key').should.be.equal 'RP:cache_key'
cache.hashKey({param: 'value'}).should.equal 'RP:{"param":"value"}'
cache.hashKey({a: 'b', c: 'd', e: 2}).should.equal 'RP:{"a":"b","c":"d","e":2}'
cache.hashKey({e: 2, a: 'b', c: 'd'}).should.equal 'RP:{"a":"b","c":"d","e":2}'
describe 'try', ->
it 'should success when cache not exist', (done) ->
cache.try 'test_key', (SET, key) ->
key.should.be.equal 'test_key'
SET 'test_key_value'
, (value) ->
value.should.be.equal 'test_key_value'
redis.get 'RP:test_key', (err, value) ->
value.should.be.equal 'test_key_value'
done err
it 'should success when cache exist', (done) ->
cache.try 'test_key', ->
throw new Error 'should not be called'
, (value) ->
value.should.be.equal 'test_key_value'
done()
it 'should success with param', (done) ->
cache.try
key: 'test2'
object_id: 10
, (SET, key) ->
key.object_id.should.be.equal 10
SET 100
, (value) ->
value.should.be.equal 100
done()
it 'should success with JSON and SETEX', (done) ->
cache.try 'test_key3', (SETEX) ->
SETEX
value_of: 'test_key3'
, 60
, (value) ->
value.value_of.should.be.equal 'test_key3'
redis.ttl 'RP:test_key3', (err, seconds) ->
seconds.should.above 0
cache.refresh 'test_key3', done
describe 'refresh', ->
it 'should success', (done) ->
cache.refresh 'test_key', ->
redis.get 'RP:test_key', (err, value) ->
expect(value).to.not.exist
done()
it 'should success with param', (done) ->
cache.refresh
key: 'test2'
object_id: 10
, ->
redis.get
key: 'test2'
object_id: 10
, (err, value) ->
expect(value).to.not.exist
done()

View File

@@ -1,98 +0,0 @@
express = require 'express'
bodyParser = require 'body-parser'
cookieParser = require 'cookie-parser'
Account = null
middleware = null
describe 'middleware', ->
before ->
require '../../app'
{middleware} = app
{Account} = app.models
describe 'errorHandling', ->
it 'should work with param', (done) ->
server = express()
server.use middleware.errorHandling
server.use (req, res) ->
res.error 'error_name',
message: 'error_message'
supertest server
.get '/'
.expect 400
.end (err, res) ->
res.body.error.should.be.equal 'error_name'
res.body.message.should.be.equal 'error_message'
done err
it 'should work with status code', (done) ->
server = express()
server.use middleware.errorHandling
server.use (req, res) ->
res.error 403, 'error_name'
supertest server
.get '/'
.expect 403
.end (err, res) ->
res.body.error.should.be.equal 'error_name'
done err
describe 'session', ->
it 'session should be available', (done) ->
server = express()
server.use middleware.session()
server.use (req, res, next) ->
req.session.should.be.exist
req.session.test_field = 'test_value'
next()
server.use (req, res) ->
req.session.test_field.should.be.equal 'test_value'
res.send()
supertest server
.get '/'
.expect 200
.end done
describe 'csrf', ->
server = express()
agent = supertest.agent server
token = null
before ->
server.use bodyParser.json()
server.use cookieParser()
server.use middleware.session()
server.use middleware.errorHandling
server.use middleware.csrf()
server.use (req, res) ->
req.session.csrf_token.should.be.exist
res.json
csrf_token: req.session.csrf_token
it 'should ignore GET request', (done) ->
agent.get '/'
.expect 200
.end (err, res) ->
token = res.body.csrf_token
done err
it 'should reject with no token', (done) ->
agent.post '/'
.expect 403
.end done
it 'should success with token', (done) ->
agent.post '/'
.send
csrf_token: token
.expect 200
.end done

View File

@@ -44,74 +44,6 @@ describe 'utils', ->
utils.rx.url.test('https://jysperm.me/about').should.be.ok
utils.rx.url.test('ssh://jysperm.me').should.not.be.ok
it 'sha256', ->
expect(utils.sha256()).to.be.not.exist
sha256 = '0554af0347e02ce032a1c6a292ed7e704c734ce338e71b39e21a73fa9b4d8fea'
utils.sha256('jysperm').should.be.equal sha256
it 'md5', ->
expect(utils.md5()).to.be.not.exist
utils.md5('jysperm').should.be.equal 'ff42fce67bcd7dd060293d3cb42638ba'
it 'randomSalt', ->
random1 = utils.randomSalt()
random2 = utils.randomSalt()
random1.should.have.length 64
random1.should.be.not.equal random2
it 'randomString', ->
random1 = utils.randomString 10
random2 = utils.randomString 10
random3 = utils.randomString 20
random1.should.have.length 10
random1.should.be.not.equal random2
random3.should.have.length 20
it 'hashPassword', ->
sha256 = '016899230b83a136fea361680e3a0c687440cd866ae67448fa72b007b04269dc'
utils.hashPassword('passwd', 'salt').should.be.equal sha256
describe 'wrapAsync', ->
it 'should work with basic usage', (done) ->
func = (callback) ->
callback 'result'
utils.wrapAsync(func) (err, result) ->
expect(err).to.be.not.exist
result.should.be.equal 'result'
done()
it 'should work with async', (done) ->
func = (callback) ->
callback 'result'
async.parallel [
utils.wrapAsync func
utils.wrapAsync func
], (err, result) ->
expect(err).to.be.not.exist
result[0].should.be.equal 'result'
result[1].should.be.equal 'result'
done()
describe 'pickErrorName', ->
it 'should work with two errors', ->
error =
errors:
email:
message: 'invalid_email'
username:
message: 'invalid_username'
expect(utils.pickErrorName(error) in [
'invalid_email', 'invalid_username'
]).to.be.ok
it 'should work with no error', ->
expect(utils.pickErrorName({})).to.be.null
expect(utils.pickErrorName({errors: {}})).to.be.null