Skip to content

Commit

Permalink
Api tests for refreshTokens endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
hagopj13 committed Nov 5, 2019
1 parent 47dfede commit 692cd34
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 18 deletions.
5 changes: 3 additions & 2 deletions src/services/token.service.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,19 @@ const AppError = require('../utils/AppError');
const generateToken = (userId, expires, secret = config.jwt.secret) => {
const payload = {
sub: userId,
iat: moment().unix(),
iat: moment().valueOf(),
exp: expires.unix(),
};
return jwt.sign(payload, secret);
};

const saveToken = async (token, userId, expires, type) => {
const saveToken = async (token, userId, expires, type, blacklisted = false) => {
const tokenDoc = await Token.create({
token,
user: userId,
expires: expires.toDate(),
type,
blacklisted,
});
return tokenDoc;
};
Expand Down
15 changes: 0 additions & 15 deletions tests/fixtures/token.fixture.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,13 @@
const moment = require('moment');
const config = require('../../src/config/config');
const Token = require('../../src/models/token.model');
const tokenService = require('../../src/services/token.service');
const { userOne, admin } = require('./user.fixture');

const accessTokenExpires = moment().add(config.jwt.accessExpirationMinutes, 'minutes');
const userOneAccessToken = tokenService.generateToken(userOne._id, accessTokenExpires);
const adminAccessToken = tokenService.generateToken(admin._id, accessTokenExpires);

const refreshTokenExpires = moment().add(config.jwt.refreshExpirationDays, 'days');
const userOneRefreshTokenDoc = {
token: tokenService.generateToken(userOne._id, refreshTokenExpires),
user: userOne._id,
type: 'refresh',
expires: refreshTokenExpires.toDate(),
};

const insertTokenDoc = async tokenDoc => {
await Token.create(tokenDoc);
};

module.exports = {
userOneAccessToken,
adminAccessToken,
userOneRefreshTokenDoc,
insertTokenDoc,
};
92 changes: 91 additions & 1 deletion tests/integration/auth.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const auth = require('../../src/middlewares/auth');
const tokenService = require('../../src/services/token.service');
const AppError = require('../../src/utils/AppError');
const setupDatabase = require('../utils/setupDatabase');
const { User } = require('../../src/models');
const { User, Token } = require('../../src/models');
const { roleRights } = require('../../src/config/roles');
const { userOne, admin, insertUsers } = require('../fixtures/user.fixture');
const { userOneAccessToken, adminAccessToken } = require('../fixtures/token.fixture');
Expand Down Expand Up @@ -147,6 +147,96 @@ describe('Auth routes', () => {
expect(res.body).toEqual({ code: httpStatus.UNAUTHORIZED, message: 'Incorrect email or password' });
});
});

describe('POST /v1/auth/refreshTokens', () => {
test('should return 200 and new auth tokens if refresh token is valid', async () => {
await insertUsers([userOne]);
const expires = moment().add(config.jwt.refreshExpirationDays, 'days');
const refreshToken = tokenService.generateToken(userOne._id, expires);
await tokenService.saveToken(refreshToken, userOne._id, expires, 'refresh');

const res = await request(app)
.post('/v1/auth/refreshTokens')
.send({ refreshToken })
.expect(httpStatus.OK);

expect(res.body).toEqual({
access: { token: expect.anything(), expires: expect.anything() },
refresh: { token: expect.anything(), expires: expect.anything() },
});

const dbRefreshTokenDoc = await Token.findOne({ token: res.body.refresh.token });
expect(dbRefreshTokenDoc).toMatchObject({ type: 'refresh', user: userOne._id, blacklisted: false });

const oldDbRefreshTokenDoc = await Token.findOne({ token: refreshToken });
expect(oldDbRefreshTokenDoc).toBeNull();
});

test('should return 400 error if refresh token is missing from request body', async () => {
await request(app)
.post('/v1/auth/refreshTokens')
.send()
.expect(httpStatus.BAD_REQUEST);
});

test('should return 401 error if refresh token is signed using an invalid secret', async () => {
await insertUsers([userOne]);
const expires = moment().add(config.jwt.refreshExpirationDays, 'days');
const refreshToken = tokenService.generateToken(userOne._id, expires, 'invalidSecret');
await tokenService.saveToken(refreshToken, userOne._id, expires, 'refresh');

await request(app)
.post('/v1/auth/refreshTokens')
.send({ refreshToken })
.expect(httpStatus.UNAUTHORIZED);
});

test('should return 401 error if refresh token is not found in the database', async () => {
await insertUsers([userOne]);
const expires = moment().add(config.jwt.refreshExpirationDays, 'days');
const refreshToken = tokenService.generateToken(userOne._id, expires);

await request(app)
.post('/v1/auth/refreshTokens')
.send({ refreshToken })
.expect(httpStatus.UNAUTHORIZED);
});

test('should return 401 error if refresh token is blacklisted', async () => {
await insertUsers([userOne]);
const expires = moment().add(config.jwt.refreshExpirationDays, 'days');
const refreshToken = tokenService.generateToken(userOne._id, expires);
await tokenService.saveToken(refreshToken, userOne._id, expires, 'refresh', true);

await request(app)
.post('/v1/auth/refreshTokens')
.send({ refreshToken })
.expect(httpStatus.UNAUTHORIZED);
});

test('should return 401 error if refresh token is expired', async () => {
await insertUsers([userOne]);
const expires = moment().subtract(1, 'minutes');
const refreshToken = tokenService.generateToken(userOne._id, expires);
await tokenService.saveToken(refreshToken, userOne._id, expires, 'refresh');

await request(app)
.post('/v1/auth/refreshTokens')
.send({ refreshToken })
.expect(httpStatus.UNAUTHORIZED);
});

test('should return 401 error if user is not found', async () => {
const expires = moment().add(config.jwt.refreshExpirationDays, 'days');
const refreshToken = tokenService.generateToken(userOne._id, expires);
await tokenService.saveToken(refreshToken, userOne._id, expires, 'refresh');

await request(app)
.post('/v1/auth/refreshTokens')
.send({ refreshToken })
.expect(httpStatus.UNAUTHORIZED);
});
});
});

describe('Auth middleware', () => {
Expand Down

0 comments on commit 692cd34

Please sign in to comment.