Add unit tests for auth endpoints
This commit is contained in:
@@ -136,6 +136,14 @@ npm install # Install dependencies
|
||||
npm run dev # Start the dev server
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Set the `AUTH` variable to `true` in your `.env` file and use the command below to run the tests
|
||||
|
||||
```
|
||||
npm run test
|
||||
```
|
||||
|
||||
## Community
|
||||
|
||||
[Join](https://bit.ly/soul-discord) the discussion in our Discord server and help making Soul together.
|
||||
|
||||
@@ -372,7 +372,7 @@ const refreshAccessToken = async (req, res) => {
|
||||
res.cookie('accessToken', accessToken, cookieOptions);
|
||||
res.cookie('refreshToken', refreshToken, cookieOptions);
|
||||
|
||||
res.status(201).send({ message: 'Success', data: { userId: user.id } });
|
||||
res.status(200).send({ message: 'Success', data: { userId: user.id } });
|
||||
} catch (error) {
|
||||
res.status(401).send({ message: 'Invalid refresh token' });
|
||||
}
|
||||
@@ -427,7 +427,7 @@ const changePassword = async (req, res) => {
|
||||
pks: `${user.id}`,
|
||||
});
|
||||
|
||||
res.status(201).send({
|
||||
res.status(200).send({
|
||||
message: 'Password updated successfully',
|
||||
data: { id: user.id, username: user.username },
|
||||
});
|
||||
|
||||
313
src/controllers/auth.test.js
Normal file
313
src/controllers/auth.test.js
Normal file
@@ -0,0 +1,313 @@
|
||||
const supertest = require('supertest');
|
||||
|
||||
const app = require('../index');
|
||||
const config = require('../config');
|
||||
const { generateToken } = require('../utils');
|
||||
const { testData } = require('../tests/testData');
|
||||
|
||||
const requestWithSupertest = supertest(app);
|
||||
|
||||
describe('Auth Endpoints', () => {
|
||||
describe('User Endpoints', () => {
|
||||
it('POST /tables/_users/rows should register a user', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', userId: 1, isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.post('/api/tables/_users/rows')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.users.user1.username,
|
||||
password: testData.strongPassword,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(201);
|
||||
expect(res.type).toEqual(expect.stringContaining('json'));
|
||||
expect(res.body).toHaveProperty('message');
|
||||
expect(res.body.message).toBe('Row Inserted');
|
||||
});
|
||||
|
||||
it('POST /tables/_users/rows should throw 400 error if username is not passed', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.post('/api/tables/_users/rows')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: { password: testData.strongPassword },
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(400);
|
||||
expect(res.body.message).toBe('username is required');
|
||||
});
|
||||
|
||||
it('POST /tables/_users/rows should throw 400 error if the password is not strong', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.post('/api/tables/_users/rows')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.users.user2.username,
|
||||
password: testData.weakPassword,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(400);
|
||||
expect(res.body.message).toBe(
|
||||
'This password is weak, please use another password',
|
||||
);
|
||||
});
|
||||
|
||||
it('POST /tables/_users/rows should throw 409 error if the username is taken', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.post('/api/tables/_users/rows')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.users.user1.username,
|
||||
password: testData.strongPassword,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(409);
|
||||
expect(res.body.message).toBe('This username is taken');
|
||||
});
|
||||
|
||||
it('GET /tables/_users/rows should return list of users', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.get('/api/tables/_users/rows')
|
||||
.set('Cookie', [`accessToken=${accessToken}`]);
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.body.data[0]).toHaveProperty('id');
|
||||
expect(res.body.data[0]).toHaveProperty('username');
|
||||
expect(res.body.data[0]).toHaveProperty('is_superuser');
|
||||
expect(res.body.data[0]).toHaveProperty('createdAt');
|
||||
});
|
||||
|
||||
it('GET /tables/_users/rows/:id should retrive a single user', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.get('/api/tables/_users/rows/1')
|
||||
.set('Cookie', [`accessToken=${accessToken}`]);
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.body.data[0]).toHaveProperty('id');
|
||||
expect(res.body.data[0]).toHaveProperty('username');
|
||||
expect(res.body.data[0]).toHaveProperty('is_superuser');
|
||||
expect(res.body.data[0]).toHaveProperty('createdAt');
|
||||
});
|
||||
|
||||
it('PUT /tables/_users/rows/:id should update a user', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.put('/api/tables/_users/rows/1')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.users.user3.username,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
});
|
||||
|
||||
it('PUT /tables/_users/rows/:id should throw a 409 error if the username is taken', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.put('/api/tables/_users/rows/1')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.users.user1.username, //A user with user1.username is already created in the first test suite
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(409);
|
||||
expect(res.body.message).toEqual('This username is already taken');
|
||||
});
|
||||
|
||||
it('DELETE /tables/_users/rows/:id should remove a user', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.delete('/api/tables/_users/rows/2')
|
||||
.set('Cookie', [`accessToken=${accessToken}`]);
|
||||
|
||||
expect(res.status).toEqual(400);
|
||||
expect(res.body.message).toBe('FOREIGN KEY constraint failed');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Obtain Access Token Endpoint', () => {
|
||||
it('POST /auth/token/obtain should return an access token and refresh token values and a success message', async () => {
|
||||
const res = await requestWithSupertest
|
||||
.post('/api/auth/token/obtain')
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.users.user1.username,
|
||||
password: testData.strongPassword,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(201);
|
||||
expect(res.type).toEqual(expect.stringContaining('json'));
|
||||
expect(res.body).toHaveProperty('message');
|
||||
expect(res.body.message).toBe('Success');
|
||||
});
|
||||
|
||||
it('POST /auth/token/obtain should throw a 401 error if the username does not exist in the DB', async () => {
|
||||
const res = await requestWithSupertest
|
||||
.post('/api/auth/token/obtain')
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.invalidUsername,
|
||||
password: testData.strongPassword,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(401);
|
||||
expect(res.type).toEqual(expect.stringContaining('json'));
|
||||
expect(res.body).toHaveProperty('message');
|
||||
expect(res.body.message).toBe('Invalid username or password');
|
||||
});
|
||||
|
||||
it('POST /auth/token/obtain should throw a 401 error if the password is invalid', async () => {
|
||||
const res = await requestWithSupertest
|
||||
.post('/api/auth/token/obtain')
|
||||
.send({
|
||||
fields: {
|
||||
username: testData.users.user1.username,
|
||||
password: testData.invalidPassword,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(401);
|
||||
expect(res.type).toEqual(expect.stringContaining('json'));
|
||||
expect(res.body).toHaveProperty('message');
|
||||
expect(res.body.message).toBe('Invalid username or password');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Refresh Access Token Endpoint', () => {
|
||||
it('GET /auth/token/refresh should refresh the access and refresh tokens', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', userId: 1, isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const refreshToken = await generateToken(
|
||||
{ username: 'John', userId: 1, isSuperuser: true },
|
||||
config.refreshTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.get('/api/auth/token/refresh')
|
||||
.set('Cookie', [
|
||||
`accessToken=${accessToken}`,
|
||||
`refreshToken=${refreshToken}`,
|
||||
]);
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.type).toEqual(expect.stringContaining('json'));
|
||||
expect(res.body).toHaveProperty('message');
|
||||
expect(res.body.message).toBe('Success');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Change Password Endpoint', () => {
|
||||
it('PUT /auth/:userId/change-password/ should change a password', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', userId: 2, isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.put('/api/auth/2/change-password')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: {
|
||||
currentPassword: testData.strongPassword,
|
||||
newPassword: testData.strongPassword2,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(200);
|
||||
expect(res.type).toEqual(expect.stringContaining('json'));
|
||||
expect(res.body).toHaveProperty('message');
|
||||
expect(res.body.message).toBe('Password updated successfully');
|
||||
});
|
||||
|
||||
it('PUT /auth/:userId/change-password/ should throw 401 error if the current password is not valid', async () => {
|
||||
const accessToken = await generateToken(
|
||||
{ username: 'John', userId: 2, isSuperuser: true },
|
||||
config.accessTokenSecret,
|
||||
'1H',
|
||||
);
|
||||
|
||||
const res = await requestWithSupertest
|
||||
.put('/api/auth/2/change-password')
|
||||
.set('Cookie', [`accessToken=${accessToken}`])
|
||||
.send({
|
||||
fields: {
|
||||
currentPassword: testData.invalidPassword,
|
||||
newPassword: testData.strongPassword2,
|
||||
},
|
||||
});
|
||||
|
||||
expect(res.status).toEqual(401);
|
||||
expect(res.type).toEqual(expect.stringContaining('json'));
|
||||
expect(res.body).toHaveProperty('message');
|
||||
expect(res.body.message).toBe('Invalid current password');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -6,37 +6,37 @@ const testNames = [
|
||||
{
|
||||
firstName: 'Olivia',
|
||||
lastName: 'William',
|
||||
createdAt: '2012-01-08 00:00:00'
|
||||
createdAt: '2012-01-08 00:00:00',
|
||||
},
|
||||
{ firstName: 'William', lastName: 'Kim', createdAt: '2013-01-08 00:00:00' },
|
||||
{ firstName: 'Sophia', lastName: 'Singh', createdAt: '2013-02-08 00:00:00' },
|
||||
{
|
||||
firstName: 'James',
|
||||
lastName: 'Rodriguez',
|
||||
createdAt: '2013-03-08 00:00:00'
|
||||
createdAt: '2013-03-08 00:00:00',
|
||||
},
|
||||
{ firstName: 'Ava', lastName: 'Patel', createdAt: '2013-01-04 00:00:00' },
|
||||
{
|
||||
firstName: 'Benjamin',
|
||||
lastName: 'Garcia',
|
||||
createdAt: '2015-01-08 00:00:00'
|
||||
createdAt: '2015-01-08 00:00:00',
|
||||
},
|
||||
{
|
||||
firstName: 'Isabella',
|
||||
lastName: 'Nguyen',
|
||||
createdAt: '2014-01-08 00:00:00'
|
||||
createdAt: '2014-01-08 00:00:00',
|
||||
},
|
||||
{ firstName: 'Ethan', lastName: 'Lee', createdAt: '2016-01-08 00:00:00' },
|
||||
{ firstName: 'Mia', lastName: 'Wilson', createdAt: '2017-01-08 00:00:00' },
|
||||
{
|
||||
firstName: 'Alexander',
|
||||
lastName: 'William',
|
||||
createdAt: '2018-01-08 00:00:00'
|
||||
createdAt: '2018-01-08 00:00:00',
|
||||
},
|
||||
{
|
||||
firstName: 'Charlotte',
|
||||
lastName: 'Hernandez',
|
||||
createdAt: '2019-01-08 00:00:00'
|
||||
createdAt: '2019-01-08 00:00:00',
|
||||
},
|
||||
{ firstName: 'Liam', lastName: 'Gonzalez', createdAt: '2020-01-08 00:00:00' },
|
||||
{ firstName: 'Emma', lastName: 'Gomez', createdAt: '2021-01-08 00:00:00' },
|
||||
@@ -46,17 +46,30 @@ const testNames = [
|
||||
{
|
||||
firstName: 'Abigail',
|
||||
lastName: 'Williams',
|
||||
createdAt: '2023-02-10 00:00:00'
|
||||
createdAt: '2023-02-10 00:00:00',
|
||||
},
|
||||
{ firstName: 'Elijah', lastName: 'Hall', createdAt: '2023-04-02 00:00:00' },
|
||||
{ firstName: 'Mila', lastName: 'Flores', createdAt: '2023-05-13 00:00:00' },
|
||||
{
|
||||
firstName: 'Evelyn',
|
||||
lastName: 'Morales',
|
||||
createdAt: '2023-06-05 00:00:00'
|
||||
createdAt: '2023-06-05 00:00:00',
|
||||
},
|
||||
{ firstName: 'Logan', lastName: 'Collins', createdAt: '2023-06-07 00:00:00' },
|
||||
{ firstName: null, lastName: 'Flores', createdAt: '2023-06-09 00:00:00' }
|
||||
{ firstName: null, lastName: 'Flores', createdAt: '2023-06-09 00:00:00' },
|
||||
];
|
||||
|
||||
module.exports = { testNames };
|
||||
const testData = {
|
||||
strongPassword: 'HeK34#C44DMJ',
|
||||
strongPassword2: 'Mk22#c9@Cv!K',
|
||||
weakPassword: '12345678',
|
||||
invalidUsername: 'invalid_username',
|
||||
invalidPassword: 'invalid_password',
|
||||
users: {
|
||||
user1: { username: 'Jane' },
|
||||
user2: { username: 'Mike' },
|
||||
user3: { username: 'John' },
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = { testNames, testData };
|
||||
|
||||
Reference in New Issue
Block a user