add some test for account model

This commit is contained in:
jysperm
2015-06-01 08:03:53 +08:00
parent c4c85ae2c9
commit 61d7a7ee34
9 changed files with 173 additions and 145 deletions

View File

@@ -1,55 +1,42 @@
jsonStableStringify = require 'json-stable-stringify'
getParameterNames = require 'get-parameter-names'
redis = require 'redis'
_ = require 'underscore'
{EventEmitter} = require 'events'
Redis = require 'ioredis'
_ = require 'lodash'
Q = require 'q'
###
Public: Cache factory,
You can access a global instance via `root.cache`.
###
module.exports = class CacheFactory
module.exports = class CacheFactory extends EventEmitter
constructor: ({host, port, password}) ->
@redis = redis.createClient port, host,
auth_pass: password
@redis = new Redis {host, port, password}
_.extend @,
get: Q.denodeify @redis.get.bind @redis
del: Q.denodeify @redis.del.bind @redis
set: Q.denodeify @redis.set.bind @redis
setEx: Q.denodeify @redis.setex.bind @redis
hashKey: (key) ->
if _.isString key
return key
else
return jsonStableStringify key
getJSON: (key) ->
@get(@hashKey key).then (result) ->
getJSON: (keys) ->
@redis.get(keys.join ':').then (result) ->
try
return JSON.parse result
catch
return null
try: (key, setter) ->
@tryHelper key, setter, =>
@set arguments...
try: (keys, {setex}, setter) ->
hashed = keys.join ':'
tryExpire: (key, expired, setter) ->
@tryHelper key, setter, (key, value) =>
@setEx key, expired, value
@redis.get(hashed).then (value) =>
if value != undefined and value != null
try
return JSON.parse value
catch err
return result
refresh: (key) ->
@del @hashKey key
else
Q(setter keys).tap (value) =>
if _.isObject value
value = JSON.stringify value
tryHelper: (key, setter, operator) ->
hashed_key = @hashKey key
if setex
@redis.setex hashed, setex, value
else
@redis.set hashed, value
@get(hashed_key).then (value) ->
Q().then ->
if value in [undefined, null]
Q(setter()).then (value) ->
command(hashed_key, value).thenReject value
else
return value
clean: (keys) ->
client.del keys.join ':'

View File

@@ -1,4 +1,3 @@
expressBunyanLogger = require 'express-bunyan-logger'
expressSession = require 'express-session'
redisStore = require 'connect-redis'
moment = require 'moment-timezone'

View File

@@ -121,6 +121,7 @@ Account.ensureIndex
Account.ensureIndex
'tokens.code': 1
,
sparse: true
unique: true
###
@@ -167,13 +168,13 @@ Account.search = (identify) ->
Return {Promise} resolve with `{account: Account, token: Token}` or `{}`.
###
Account.authenticate = (tokenCode) ->
@findOneAndUpdate(
@findOneAndUpdate
'tokens.code': tokenCode
,
$set:
'tokens.$.updated_at': new Date()
).then (account) ->
.then (account) ->
return {
account: account
@@ -251,7 +252,7 @@ Account.register = ({username, email, password}) ->
Public: Create token for this account.
* `type` {String} Type of {Token}
* `options` {Object} Options of {Token}
* `options` (optional) {Object} Options of {Token}
Return {Promise} resolve with create {Token}.
###
@@ -263,11 +264,10 @@ Account::createToken = (type, options) ->
created_at: new Date()
updated_at: new Date()
@update(
@update
$push:
tokens: token
).then ->
return token
.thenResolve token
###
Public: Remove all token and create a new one just for reset password.

View File

@@ -0,0 +1,44 @@
describe 'model.account', ->
Account = null
before ->
{Account} = root
describe '.register', ->
it 'should success', ->
{username, email, password} = randomAccount()
Account.register({username, email, password}).then (account) ->
account.username.should.be.equal username
describe '.search', ->
{id, email, username} = {}
before ->
createAccount().then (account) ->
{_id: id, email, username} = account
it 'search by id', ->
Account.search(id.toString()).then (account) ->
account.username.should.be.equal username
it 'search by email', ->
Account.search(email).then (account) ->
account.username.should.be.equal username
it 'search by username', ->
Account.search(username).then (account) ->
account._id.toString().should.be.equal id.toString()
it 'search undefined account', ->
Account.search(randomAccount().username).then (account) ->
expect(account).to.not.exists
describe '#createToken', ->
it 'should success', ->
createAccount().then (account) ->
account.createToken('full_access').then ({code}) ->
Account.findOne('tokens.code': code).then (account) ->
_.findWhere(account.tokens,
code: code
).type.should.be.equal 'full_access'

View File

@@ -14,16 +14,10 @@ validator.extend 'isPassword', (password) ->
return /^.+$/.test password
exports.sha256 = (data) ->
if data
return crypto.createHash('sha256').update(data).digest('hex')
else
return null
return crypto.createHash('sha256').update(data ? '').digest 'hex'
exports.md5 = (data) ->
if data
return crypto.createHash('md5').update(data).digest('hex')
else
return null
return crypto.createHash('md5').update(data ? '').digest 'hex'
exports.randomSalt = ->
return exports.sha256 crypto.randomBytes 256
@@ -38,17 +32,3 @@ exports.randomString = (length) ->
exports.hashPassword = (password, password_salt) ->
return exports.sha256 password_salt + exports.sha256(password)
exports.pickErrorName = (error) ->
unless error and error.errors
return null
if _.isEmpty error.errors
return null
err = error.errors[_.first(_.keys(error.errors))]
if err.message == 'unique_validation_error'
return "#{err.path}_exist"
return err.message

View File

@@ -39,7 +39,6 @@
"express": "^4.10.4",
"express-bunyan-logger": "^1.1.0",
"express-session": "^1.9.2",
"get-parameter-names": "^0.2.0",
"insight": "^0.5.3",
"jade": "^1.9.2",
"json-stable-stringify": "^1.0.0",
@@ -59,7 +58,8 @@
"semver": "^4.1.0",
"ssh2": "^0.3.6",
"underscore": "^1.7.0",
"validator": "^3.37.0"
"validator": "^3.37.0",
"ioredis": "^1.3.6"
},
"devDependencies": {
"chai": "^1.10.0",

78
test/agent.coffee Normal file
View File

@@ -0,0 +1,78 @@
request = require 'request'
chai = require 'chai'
_ = require 'lodash'
Q = require 'q'
expect = chai.expect
methods = ['get', 'post', 'delete', 'put', 'patch', 'head', 'options']
module.exports = createAgent = (agent_options) ->
if _.isNumber config.web.listen
prefix = "http://127.0.0.1:#{config.web.listen}"
else
prefix = "http://unix:#{config.web.listen}:"
agent = {}
methods.forEach (method) ->
agent[method] = (url, options, asserts) ->
options = _.merge
url: url
json: true
method: method
followRedirect: false
, options, agent_options
if options.baseUrl
options.baseUrl = prefix + options.baseUrl
else
options.baseUrl = prefix + '/'
Q.nfcall(request, options).then ([res]) ->
return res
.tap (res) ->
{status, headers, body, error} = asserts ? {}
message = printHttpResponse res
if status
expect(res.statusCode).to.equal status, message
else if !error
expect(res.statusCode).to.within 200, 300, message
if error
expect(res.body.error).to.equal error, message
assertObjectFields = (data, asserts) ->
for field, pattern of asserts ? {}
if pattern instanceof RegExp
expect(data[field]).to.match pattern, message
else
expect(data[field]).to.equal pattern, message
assertObjectFields res.headers, headers
assertObjectFields res.body, body
return agent
module.exports.methods = methods
printHttpResponse = ({httpVersion, statusCode, statusMessage, headers, body}) ->
message = """
Response:
HTTP/#{httpVersion} #{statusCode} #{statusMessage}\n
"""
for name, value of headers
message += "#{name}: #{value}\n"
if headers['content-type']?.match /text\/html/
body = body.replace / /g, ' '
body = body.replace /<br>/g, '\n'
else if headers['content-type']?.match /application\/json/
body = JSON.stringify body, null, ' '
message += "\n#{body}"
return message

View File

@@ -1,10 +1,16 @@
process.env.NODE_ENV = 'test'
_ = require 'lodash'
Root = require '../core'
snippet = require './snippet'
global.config = require '../sample/core.config.coffee'
global.root = new Root config
root.start()
require './snippet'
_.extend global, snippet
chai.should()
chai.config.includeStack = true

View File

@@ -1,18 +1,13 @@
request = require 'request'
chai = require 'chai'
url = require 'url'
_ = require 'lodash'
Q = require 'q'
utils = require '../core/utils'
createAgent = require './agent'
expect = chai.expect
chai.should()
chai.config.includeStack = true
methods = ['get', 'post', 'delete', 'put', 'patch', 'head', 'options']
ifEnabled = (name) ->
if name in _.keys config.plugins
return describe
@@ -35,60 +30,14 @@ randomAccount = ->
email: 'test' + randomLowerCase(6) + '@gmail.com'
}
createAgent = (agent_options) ->
if _.isNumber config.web.listen
prefix = "http://127.0.0.1:#{config.web.listen}"
else
prefix = "http://unix:#{config.web.listen}:"
agent = {}
methods.map (method) ->
agent[method] = (url, options, asserts) ->
options = _.merge
url: url
json: true
method: method
followRedirect: false
, options, agent_options
if options.baseUrl
options.baseUrl = prefix + options.baseUrl
else
options.baseUrl = prefix + '/'
Q.nfcall(request, options).then ([res]) ->
return res
.tap (res) ->
{status, headers, body, error} = asserts ? {}
message = printHttpResponse res
if status
expect(res.statusCode).to.equal status, message
else if !error
expect(res.statusCode).to.within 200, 300, message
if error
expect(res.body.error).to.equal error, message
assertObjectFields = (data, asserts) ->
for field, pattern of asserts ? {}
if pattern instanceof RegExp
expect(data[field]).to.match pattern, message
else
expect(data[field]).to.equal pattern, message
assertObjectFields res.headers, headers
assertObjectFields res.body, body
return agent
createAccount = ->
root.Account.register randomAccount()
createLoggedAgent = (options) ->
ready = null
agent = {}
methods.map (method) ->
createAgent.methods.map (method) ->
agent[method] = (args...) ->
ready ?= createAgent().post '/account/register',
json: randomAccount()
@@ -101,32 +50,17 @@ createLoggedAgent = (options) ->
return agent
_.extend global, {
module.exports = {
_
chai
utils
expect
ifEnabled
unlessTravis
randomAccount
createAccount
createAgent
createLoggedAgent
}
printHttpResponse = ({httpVersion, statusCode, statusMessage, headers, body}) ->
message = """
Response:
HTTP/#{httpVersion} #{statusCode} #{statusMessage}\n
"""
for name, value of headers
message += "#{name}: #{value}\n"
if headers['content-type']?.match /text\/html/
body = body.replace /&nbsp;/g, ' '
body = body.replace /<br>/g, '\n'
else if headers['content-type']?.match /application\/json/
body = JSON.stringify body, null, ' '
message += "\n#{body}"
return message