Add unit tests for auth endpoints

This commit is contained in:
AbegaM
2024-03-05 19:41:48 +03:00
parent f8bbdae7bc
commit ff632facd3
4 changed files with 346 additions and 12 deletions

View File

@@ -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.

View File

@@ -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 },
});

View 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');
});
});
});

View File

@@ -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 };