2017-10-13 16:17:18 -04:00
|
|
|
|
process.env.NODE_ENV = 'test';
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
const app = require('../server');
|
|
|
|
|
const server = app.server;
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
const User = require('../app/models/User.js');
|
|
|
|
|
const Invite = require('../app/models/Invite.js');
|
|
|
|
|
const Upload = require('../app/models/Upload.js');
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
const util = require('./testUtil.js');
|
|
|
|
|
const canonicalize = require('../app/util/canonicalize').canonicalize;
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
describe('Users', function() {
|
|
|
|
|
beforeEach(async () => util.clearDatabase());
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
describe('/POST register', () => {
|
|
|
|
|
describe('0 Valid Request', () => {
|
|
|
|
|
async function verifySuccessfulRegister(user) {
|
|
|
|
|
await util.createTestInvite();
|
2018-07-24 19:39:55 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
const res = await util.registerUser(user);
|
2018-07-24 19:39:55 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
res.should.have.status(200);
|
|
|
|
|
res.body.should.be.a('object');
|
|
|
|
|
res.body.should.have.property('message').eql('Registration successful.');
|
2018-07-24 19:39:55 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
const userCount = await User.countDocuments({username: user.username});
|
|
|
|
|
userCount.should.eql(1);
|
|
|
|
|
|
|
|
|
|
const inviteCount = await Invite.countDocuments({code: user.invite, recipient: canonicalize(user.username)});
|
|
|
|
|
inviteCount.should.eql(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it('MUST register a valid user with a valid invite', async () =>
|
|
|
|
|
verifySuccessfulRegister({username: 'user', password: 'pass', invite: 'code'})
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
it('MUST register a username with unicode symbols and a valid invite', async () =>
|
|
|
|
|
verifySuccessfulRegister({username: 'ᴮᴵᴳᴮᴵᴿᴰ', password: 'pass', invite: 'code'})
|
|
|
|
|
);
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
describe('1 Invalid Invites', () => {
|
|
|
|
|
async function verifyRejectedInvite(invite, message) {
|
|
|
|
|
const user = {username: 'user', password: 'pass', invite: 'code'};
|
|
|
|
|
if (invite) {
|
|
|
|
|
await util.createInvite(invite);
|
|
|
|
|
user.invite = invite.code;
|
|
|
|
|
}
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
const res = await(util.registerUser(user));
|
|
|
|
|
res.should.have.status(422);
|
|
|
|
|
res.body.should.be.a('object');
|
|
|
|
|
res.body.should.have.property('message').eql(message);
|
|
|
|
|
}
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register a nonexistant invite', async () =>
|
|
|
|
|
verifyRejectedInvite(null, 'Invalid invite code.')
|
|
|
|
|
);
|
2018-07-24 19:39:55 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register a used invite', async () =>
|
|
|
|
|
verifyRejectedInvite({used: new Date()}, 'Invite already used.')
|
|
|
|
|
);
|
2018-07-24 19:39:55 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register an expired invite', async () =>
|
|
|
|
|
verifyRejectedInvite({exp: new Date()}, 'Invite expired.')
|
|
|
|
|
);
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
|
2018-07-24 19:39:55 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
describe('2 Invalid Usernames', () => {
|
|
|
|
|
async function verifyRejectedUsername(user, message) {
|
|
|
|
|
const res = await util.registerUser(user);
|
|
|
|
|
res.should.have.status(422);
|
|
|
|
|
res.body.should.be.a('object');
|
|
|
|
|
res.body.should.have.property('message').eql(message);
|
|
|
|
|
}
|
2018-07-24 19:39:55 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register a duplicate username', async () => {
|
|
|
|
|
await util.createTestInvites(2);
|
2018-07-24 19:39:55 -04:00
|
|
|
|
const user0 = {username: 'user', password: 'pass', invite: 'code0'};
|
|
|
|
|
const user1 = {username: 'user', password: 'diff', invite: 'code1'};
|
2018-07-25 18:45:38 -04:00
|
|
|
|
|
|
|
|
|
await util.registerUser(user0);
|
|
|
|
|
return verifyRejectedUsername(user1, 'Username in use.');
|
2018-07-24 19:39:55 -04:00
|
|
|
|
});
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register a username with a duplicate canonical name', async () => {
|
|
|
|
|
await util.createTestInvites(2);
|
2018-07-24 19:39:55 -04:00
|
|
|
|
const user0 = {username: 'bigbird', password: 'pass', invite: 'code0'};
|
|
|
|
|
const user1 = {username: 'ᴮᴵᴳᴮᴵᴿᴰ', password: 'diff', invite: 'code1'};
|
2018-07-25 18:45:38 -04:00
|
|
|
|
|
|
|
|
|
await util.registerUser(user0);
|
|
|
|
|
return verifyRejectedUsername(user1, 'Username in use.');
|
2018-07-24 19:39:55 -04:00
|
|
|
|
});
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register a username containing whitespace', async () => {
|
|
|
|
|
await util.createTestInvites(3);
|
2018-07-24 19:39:55 -04:00
|
|
|
|
const users = [
|
|
|
|
|
{username: 'user name', password: 'pass', invite: 'code0'},
|
|
|
|
|
{username: 'user name', password: 'pass', invite: 'code1'},
|
|
|
|
|
{username: 'user name', password: 'pass', invite: 'code2'}
|
|
|
|
|
];
|
2018-07-25 18:45:38 -04:00
|
|
|
|
|
2018-07-24 19:39:55 -04:00
|
|
|
|
const failMsg = 'Username contains invalid characters.';
|
2018-07-25 18:45:38 -04:00
|
|
|
|
return Promise.all(users.map(user => verifyRejectedUsername(user, failMsg)));
|
2018-07-24 19:39:55 -04:00
|
|
|
|
});
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register a username containing HTML', async () => {
|
|
|
|
|
await util.createTestInvite();
|
|
|
|
|
const user = {username: 'user<svg/onload=alert("XSS")>', password: 'pass', invite: 'code'};
|
|
|
|
|
return verifyRejectedUsername(user, 'Username contains invalid characters.');
|
2018-07-24 19:39:55 -04:00
|
|
|
|
});
|
2018-07-25 01:44:45 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
it('MUST NOT register a username with too many characters', async () => {
|
|
|
|
|
await util.createTestInvite();
|
|
|
|
|
const user = {username: '123456789_123456789_123456789_1234567', password: 'pass', invite: 'code'};
|
|
|
|
|
return verifyRejectedUsername(user, 'Username too long.');
|
2018-07-25 01:44:45 -04:00
|
|
|
|
})
|
2018-07-24 19:39:55 -04:00
|
|
|
|
});
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
describe('/POST login', () => {
|
|
|
|
|
async function verifySuccessfulLogin(credentials) {
|
|
|
|
|
const res = await util.login(credentials);
|
|
|
|
|
res.should.have.status(200);
|
|
|
|
|
res.body.should.be.a('object');
|
|
|
|
|
res.body.should.have.property('message').eql('Logged in.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function verifyFailedLogin(credentials) {
|
|
|
|
|
const res = await util.login(credentials);
|
|
|
|
|
res.should.have.status(401);
|
|
|
|
|
res.body.should.be.a('object');
|
|
|
|
|
res.body.should.have.property('message').eql('Unauthorized.');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
describe('0 Valid Request', () => {
|
|
|
|
|
it('SHOULD accept a valid user with a valid password', async () => {
|
|
|
|
|
await util.createTestUser();
|
|
|
|
|
return verifySuccessfulLogin({username: 'user', password: 'pass'});
|
|
|
|
|
});
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
|
|
|
|
|
describe('1 Invalid Password', () => {
|
|
|
|
|
it('SHOULD NOT accept an invalid password', async () => {
|
|
|
|
|
await util.createTestUser();
|
|
|
|
|
return verifyFailedLogin({username: 'user', password: 'bogus'});
|
|
|
|
|
});
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
describe('2 Invalid User', () => {
|
|
|
|
|
it('SHOULD NOT accept an invalid user', async () =>
|
|
|
|
|
verifyFailedLogin({username: 'bogus', password: 'bogus'})
|
|
|
|
|
);
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
/*describe('Uploads', function() {
|
2018-07-24 19:39:55 -04:00
|
|
|
|
describe('/POST upload', function() {
|
2017-10-13 16:17:18 -04:00
|
|
|
|
it('SHOULD accept logged in valid upload', function(done) {
|
2017-10-13 18:08:13 -04:00
|
|
|
|
util.verifySuccessfulUpload({
|
2017-10-13 16:17:18 -04:00
|
|
|
|
username: 'TestUser2',
|
|
|
|
|
password: 'TestPassword'
|
2017-10-13 18:08:13 -04:00
|
|
|
|
}, done);
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('SHOULD NOT accept unauthenticated valid upload', function(done) {
|
2017-10-13 18:08:13 -04:00
|
|
|
|
util.verifyFailedAuthUpload(done);
|
2017-10-13 16:17:18 -04:00
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
it('SHOULD NOT accept invalid permission, valid upload', function(done) {
|
2017-10-13 18:08:13 -04:00
|
|
|
|
util.verifyFailedPermissionUpload({
|
2017-10-13 16:17:18 -04:00
|
|
|
|
username: 'TestUser1',
|
|
|
|
|
password: 'TestPassword'
|
2017-10-13 18:08:13 -04:00
|
|
|
|
}, done);
|
|
|
|
|
});
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2017-10-13 18:08:13 -04:00
|
|
|
|
it('SHOULD NOT accept invalid size upload', function(done) {
|
|
|
|
|
util.verifyFailedSizeUpload({
|
|
|
|
|
username: 'TestUser2',
|
|
|
|
|
password: 'TestPassword'
|
|
|
|
|
}, done);
|
2017-10-13 16:17:18 -04:00
|
|
|
|
})
|
|
|
|
|
});
|
2018-07-25 18:45:38 -04:00
|
|
|
|
});*/
|
2017-10-13 16:17:18 -04:00
|
|
|
|
|
2018-07-25 18:45:38 -04:00
|
|
|
|
after(() => server.close(() => process.exit(0)));
|