Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
383 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
|
||
require('./io-setup'); | ||
|
||
exports['Tests'] = { | ||
env: 'node', | ||
rootPath: '../', | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
|
||
var events = require('events'); | ||
var passreset = require('../lib'); | ||
|
||
module.exports = exports = new events.EventEmitter(); | ||
|
||
passreset.lookupUsers(function(login, callback) { | ||
callback = async(callback); | ||
switch (login) { | ||
case 'valid': | ||
callback(null, { | ||
email: 'foo1@example.com', | ||
users: [{ | ||
id: 123, | ||
name: 'foo' | ||
}] | ||
}); | ||
break; | ||
case 'multivalid': | ||
callback(null, { | ||
email: 'foo2@example.com', | ||
users: [{ | ||
id: 234, | ||
name: 'bar' | ||
}, { | ||
id: 345, | ||
name: 'baz' | ||
}] | ||
}); | ||
break; | ||
case 'invalid': | ||
callback(null, false); | ||
break; | ||
default: | ||
callback('Invalid test login given'); | ||
break; | ||
} | ||
}); | ||
|
||
passreset.sendEmail(function(email, resets, callback) { | ||
exports.emit('sendEmail', email, resets); | ||
async(callback)(null, true); | ||
}); | ||
|
||
passreset.setPassword(function(id, password, callback) { | ||
callback = async(callback); | ||
switch (password) { | ||
case 'short': | ||
callback(null, false, 'Password is too short'); | ||
break; | ||
case 'goodPassword': | ||
callback(null, true); | ||
break; | ||
default: | ||
callback('Invalid test password given'); | ||
break; | ||
} | ||
}); | ||
|
||
function async(func) { | ||
return function() { | ||
var args = arguments; | ||
process.nextTick(function() { | ||
func.apply(this, args); | ||
}); | ||
}; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
|
||
var events = require('events'); | ||
|
||
// ------------------------------------------------------------------ | ||
|
||
var Request = exports.Request = function(body) { | ||
if (typeof body === 'string') { | ||
body = JSON.parse(body); | ||
} | ||
this.body = body || { }; | ||
}; | ||
|
||
// ------------------------------------------------------------------ | ||
|
||
var Response = exports.Response = function() { | ||
this.status = 200; | ||
this.response = ''; | ||
this.redirectedTo = null; | ||
}; | ||
|
||
Response.prototype = new events.EventEmitter(); | ||
|
||
Response.prototype.json = function(response, status) { | ||
if (typeof response === 'number' && ! status) { | ||
this.status = response; | ||
} else { | ||
this.response = JSON.stringify(response); | ||
this.status = status || 200; | ||
} | ||
this.emit('respond', this); | ||
}; | ||
|
||
Response.prototype.send = function(response, status) { | ||
if (typeof response === 'number' && ! status) { | ||
this.status = response; | ||
} else { | ||
this.response = String(response); | ||
this.status = status || 200; | ||
} | ||
this.emit('respond', this); | ||
}; | ||
|
||
Response.prototype.redirect = function(redirectTo, status) { | ||
this.redirectedTo = redirectTo; | ||
this.status = status || 302; | ||
this.emit('respond', this); | ||
}; | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
|
||
var buster = require('buster'); | ||
var uuid = require('uuid-v4'); | ||
var passreset = require('../../lib'); | ||
var io = require('../io-setup'); | ||
var mockhttp = require('../mock-http'); | ||
|
||
buster.testCase('Request Password Reset', { | ||
'resetPassword() should return a function': function() { | ||
buster.assert.equals(typeof passreset.resetPassword(), 'function', 'without config'); | ||
buster.assert.equals(typeof passreset.resetPassword({ }), 'function', 'with empty config'); | ||
buster.assert.equals(typeof passreset.resetPassword({ foo: 'bar' }), 'function', 'with invalid config'); | ||
buster.assert.equals(typeof passreset.resetPassword({ next: true }), 'function', 'with valid config'); | ||
}, | ||
|
||
'simple resetPassword() responses': { | ||
setUp: function() { | ||
this.routeFunction = passreset.resetPassword(); | ||
this.response = new mockhttp.Response(); | ||
}, | ||
|
||
'no request body should result in 400 error': testMissingParams(), | ||
|
||
'missing token should result in 400 error': testMissingParams( | ||
{ password: 'goodPassword', confirm: 'goodPassword' }), | ||
|
||
'missing password should result in 400 error': testMissingParams( | ||
{ token: uuid(), confirm: 'goodPassword' }), | ||
|
||
'missing confirm should result in 400 error': testMissingParams( | ||
{ token: uuid(), password: 'goodPassword' }), | ||
|
||
'invalid token should result in 401 error': function(done) { | ||
var req = new mockhttp.Request({ | ||
token: uuid(), | ||
password: 'goodPassword', | ||
confirm: 'goodPassword' | ||
}); | ||
this.response.on('respond', function(res) { | ||
buster.assert.equals(res.status, 401); | ||
var response = JSON.parse(res.response); | ||
buster.assert.equals(response.error.message, 'Request token is invalid'); | ||
done(); | ||
}); | ||
this.routeFunction(req, this.response, function() { | ||
buster.assert(false, '`next` should not be called in the case of an error'); | ||
done(); | ||
}); | ||
}, | ||
|
||
'tests with valid request token': { | ||
setUp: function() { | ||
this.token = passreset._storage.create(567); | ||
}, | ||
|
||
'unmatching passwords should result in a 400 error': function(done) { | ||
var req = new mockhttp.Request({ | ||
token: this.token, | ||
password: 'goodPassword1', | ||
confirm: 'goodPassword2' | ||
}); | ||
this.response.on('respond', function(res) { | ||
buster.assert.equals(res.status, 400); | ||
var response = JSON.parse(res.response); | ||
buster.assert.equals(response.error.message, 'Password and confirmation do not match'); | ||
done(); | ||
}); | ||
this.routeFunction(req, this.response, function() { | ||
buster.assert(false, '`next` should not be called in the case of an error'); | ||
done(); | ||
}); | ||
}, | ||
|
||
'invalid password should result in a 400 error': function(done) { | ||
var req = new mockhttp.Request({ | ||
token: this.token, | ||
password: 'short', | ||
confirm: 'short' | ||
}); | ||
this.response.on('respond', function(res) { | ||
buster.assert.equals(res.status, 400); | ||
var response = JSON.parse(res.response); | ||
buster.assert.equals(response.error.message, 'Password is too short'); | ||
done(); | ||
}); | ||
this.routeFunction(req, this.response, function() { | ||
buster.assert(false, '`next` should not be called in the case of an error'); | ||
done(); | ||
}); | ||
}, | ||
|
||
'valid password and token should result in a 200 OK': function(done) { | ||
var req = new mockhttp.Request({ | ||
token: this.token, | ||
password: 'goodPassword', | ||
confirm: 'goodPassword' | ||
}); | ||
this.response.on('respond', function(res) { | ||
buster.assert.equals(res.status, 200); | ||
buster.assert.equals(res.response, ''); | ||
done(); | ||
}); | ||
this.routeFunction(req, this.response, function() { | ||
buster.assert(false, '`next` should not be called if opts.next is false/null'); | ||
done(); | ||
}); | ||
} | ||
} | ||
} | ||
}); | ||
|
||
function testMissingParams(body) { | ||
return function(done) { | ||
var req = new mockhttp.Request(body); | ||
this.response.on('respond', function(res) { | ||
buster.assert.equals(res.status, 400); | ||
var response = JSON.parse(res.response); | ||
buster.assert.equals(response.error.message, 'Cannot attempt reset with missing params'); | ||
done(); | ||
}); | ||
this.routeFunction(req, this.response, function() { | ||
buster.assert(false, '`next` should not be called in the case of an error'); | ||
done(); | ||
}); | ||
}; | ||
} | ||
|
Oops, something went wrong.