Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Complete code coverage #23

Merged
merged 4 commits into from Nov 11, 2016
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions tests/index.js
@@ -1,4 +1,6 @@
require('./unit/set-test')
require('./unit/validate-password-test')
require('./unit/validate-session-test')
require('./unit/utils/admin-hash-to-doc-test')
require('./unit/utils/hash-password-test')
require('./integration/factory-test')
46 changes: 45 additions & 1 deletion tests/integration/factory-test.js
@@ -1,16 +1,21 @@
var PouchDB = require('pouchdb-core')
.plugin(require('pouchdb-adapter-memory'))
var test = require('tape')
var Promise = require('lie')
var format = require('util').format
var hashPassword = require('../../lib/utils/hash-password')
var generateSalt = require('../../lib/utils/generate-salt')

var plugin = require('../../index')

test('db.admins({secret: "secret123"})', function (t) {
t.plan(20)
t.plan(22)

PouchDB.plugin(plugin)
var db = new PouchDB('foo')
t.is(typeof db.admins, 'function', 'db.admins is a function')

var preinitializedAdmins
var admins = db.admins({secret: 'secret123'})
t.is(typeof admins.get, 'function', 'admins.get is a function')
t.is(typeof admins.set, 'function', 'admins.set is a function')
Expand Down Expand Up @@ -77,4 +82,43 @@ test('db.admins({secret: "secret123"})', function (t) {
})

.catch(t.error)

.then(function () {
return new Promise(function (resolve, reject) {
var salt = generateSalt()
hashPassword('mysecret', salt, 10, function (error, hash) {
if (error) {
return reject(error)
}

return resolve(format(
'-%s-%s,%s,%s',
'pbkdf2',
hash,
salt,
10
))
})
})
})
.then(function (userEntry) {
preinitializedAdmins = db.admins({secret: 'secretXYZ', admins: {'foo': userEntry}})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need to dynamically generate userEntry here or can we directly use a pre-generated key?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we need to run generateSalt or hashPassword for code coverage, I鈥檇 rather make unit tests

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, no need to run generateSalt or hashPassword, it was just for convenience rather than hardcoding in a pre-generated key at the time; but it probably makes sense to pregenerate it. Changing now.

return preinitializedAdmins.get('foo');
})
.catch(function () {
t.fail("Password should be successfully hashed")
})
.then(function (doc) {
t.ok(doc, "fetching preinitialized admins works")
return preinitializedAdmins.validatePassword('foo', 'mysecret')
})
.catch(function (error) {
t.fail(error, "trying to retrieve a preinitialized admin should not error")
})
.then(function () {
t.is(arguments[0], undefined, 'validating password of preinitialized admin resolves without argument')
})
.catch(function () {
t.fail("trying to validate the password of a preinitialized admin should not error")
})
})
30 changes: 30 additions & 0 deletions tests/unit/utils/hash-password-test.js
@@ -0,0 +1,30 @@
var simple = require('simple-mock')
var test = require('tape')
var proxyquire = require('proxyquire').noCallThru().noPreserveCache()

test('hash-password', function (group) {
group.test('when pbkdf2 errors', function(t) {
var pbkdf2Stub = simple.stub()
var callbackStub = simple.stub()

var hashPassword = proxyquire('../../../lib/utils/hash-password', {
crypto: {
pbkdf2: pbkdf2Stub
}
})

t.plan(3)

var error = new Error('pbkdf2 error')
pbkdf2Stub.callbackAtIndex(4, error)

t.doesNotThrow(function () {
hashPassword('password', 'salt', 10, callbackStub)
}, error, "does not throw the pbkdf2 error")

t.equal(callbackStub.callCount, 1, "calls the callback once only")
t.equal(callbackStub.lastCall.args[0], error, "with the error returned from pbkdf2")
})

group.end()
})
42 changes: 42 additions & 0 deletions tests/unit/validate-session-test.js
@@ -0,0 +1,42 @@
var simple = require('simple-mock')
var test = require('tape')
var proxyquire = require('proxyquire').noCallThru().noPreserveCache()

test('validate-session', function (group) {
group.test('when session does not validate', function(t) {
var getAdminStub = simple.stub()
var calculateSessionIdStub = simple.stub()
var decodeSessionIdStub = simple.stub()

var unauthorized = new Error("Invalid Session")
var validateSession = proxyquire('../../lib/validate-session', {
'./get': getAdminStub,
'couchdb-calculate-session-id': calculateSessionIdStub,
'./utils/couchdb-decode-session-id': decodeSessionIdStub,
'pouchdb-errors': {UNAUTHORIZED: unauthorized}
})

t.plan(1)

getAdminStub.resolveWith({
salt: 'im-salty'
})

decodeSessionIdStub.returnWith({
username: 'a-user',
timestamp: 987654321
})

calculateSessionIdStub.returnWith('validSessionId')

validateSession({}, 'invalidSessionId')
.then(function () {
t.fail("should not resolve")
})
.catch(function (caughtError) {
t.equal(caughtError, unauthorized, "should reject the returned promise with pouchdb's UNAUTHORIZED error")
})
})

group.end()
})