Skip to content
Snippets Groups Projects
Commit d4a25743 authored by Embruch, Gerd's avatar Embruch, Gerd
Browse files

finished testing route auth/request-password-reset

parent f8e0aed8
Branches
No related tags found
No related merge requests found
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`user request password reset > given the email format is invalid > should respond with a proper body 1`] = `
{
"message": "Validation errors. Please check the error messages.",
"validationErrors": {
"email": "Invalid email",
},
}
`;
exports[`user request password reset > given the email is unknown > should respond with a proper body 1`] = `
{
"message": "If the email **user@mail.local** is correct you will receive an eMail with further instructions.",
}
`;
exports[`user request password reset > given the inputs are valid > should respond with a proper body 1`] = `
{
"message": "If the email **user@mail.local** is correct you will receive an eMail with further instructions.",
}
`;
exports[`user request password reset > the request body is empty > should respond with a proper body 1`] = `
{
"message": "Validation errors. Please check the error messages.",
"validationErrors": {
"email": "Required",
},
}
`;
...@@ -2,29 +2,55 @@ ...@@ -2,29 +2,55 @@
import { vi, beforeAll, beforeEach, describe, expect, expectTypeOf, test, it, afterEach } from 'vitest'; import { vi, beforeAll, beforeEach, describe, expect, expectTypeOf, test, it, afterEach } from 'vitest';
import supertest from "supertest"; import supertest from "supertest";
import app from "../../app.js"; import app from "../../app.js";
// ignore expiration of the (self-signed) certificate
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
// set timeout
const BEFORE_ALL_TIMEOUT = 30000; // 30 sec
// set route // set route
const ROUTE = '/users/requestpasswordreset'; const ROUTE = '/auth/password-reset';
// prepare response of each test // prepare response of each test
let response; let response;
// ############################ // ############################
// OBJECTS // OBJECTS
// ############################ // ############################
const mockedVals = vi.hoisted(() => {
return {
foundUser: {
_id: '66a29da2942b3eb',
username: 'snoopy',
name: 'My User',
email: 'user@mail.local',
verified: true,
role: 0,
createdAt: '2024-07 - 25T18: 46: 58.982Z',
updatedAt: '2024-07 - 25T18: 46: 58.982Z',
__v: 0,
password: 'StrongPass1!',
// password,
id: '66a29da2942b3ebcaf047f07'
},
validInput: {
email: 'user@mail.local'
}
};
});
// ############################ // ############################
// MOCKS // MOCKS
// ############################ // ############################
// import PocketBase Service // import Database Service
import * as pbService from '../../utils/pocketbase/handlePocketBase.js'; import * as dbService from '../../utils/handleDB.js';
// mock pbService // mock dbService
vi.mock('../../utils/pocketbase/handlePocketBase.js', async (importOriginal) => { vi.mock('../../utils/handleDB.js', async (importOriginal) => {
return {
...await importOriginal(),
dbConnection: vi.fn(() => 'mocked'),
findOneRecord: vi.fn(() => mockedVals.foundUser),
updateOneRecord: vi.fn(() => { return { ...mockedVals.foundUser, resetPasswordToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2MOCKED' }; })
};
});
// mock mailer
vi.mock('../../utils/handleMailer.js', async (importOriginal) => {
return { return {
...await importOriginal(), ...await importOriginal(),
pbRequestPasswordReset: vi.fn(() => 'mocked') sendEmail: vi.fn(() => 'mocked')
}; };
}); });
...@@ -33,70 +59,73 @@ vi.mock('../../utils/pocketbase/handlePocketBase.js', async (importOriginal) => ...@@ -33,70 +59,73 @@ vi.mock('../../utils/pocketbase/handlePocketBase.js', async (importOriginal) =>
// ############################ // ############################
describe('user request password reset', () => { describe('user request password reset', () => {
describe('given the inputs are valid', async () => { describe('given the inputs are valid', async () => {
// set response by running route
beforeAll(async () => { beforeAll(async () => {
response = await supertest(app) response = await supertest(app)
.post(ROUTE) .post(ROUTE)
.send({ email: 'well.known@local.local' }); .send(mockedVals.validInput);
}, BEFORE_ALL_TIMEOUT);
it('should call required mocks', () => {
expect(pbService.pbRequestPasswordReset()).toEqual('mocked');
}); });
it('should return a proper status code', () => { it('should return a proper status code', () => {
expect(response.status).toBe(200); expect(response.status).toBe(200);
}); });
it('should respond with a proper message', () => { it('should respond with a proper body', () => {
expect(response.body.message).toEqual('If the email **well.known@local.local** is correct you will receive an eMail with further instructions.'); expect(response.body).toMatchSnapshot();
}); });
}); });
// ############################ // ############################
describe('given the email is missing', async () => { describe('given the email is unknown', async () => {
// set response by running route // set response by running route
beforeAll(async () => { beforeAll(async () => {
dbService.findOneRecord.mockImplementationOnce(() => null);
response = await supertest(app) response = await supertest(app)
.post(ROUTE); .post(ROUTE)
}, BEFORE_ALL_TIMEOUT); .send(mockedVals.validInput);
});
it('should return a proper status code', () => { it('should return a proper status code', () => {
expect(response.status).toBe(400); expect(response.status).toBe(200);
}); });
it('should respond with a proper message', () => { it('should respond with a proper body', () => {
expect(response.body.validationErrors.email).toEqual('Required'); expect(response.body).toMatchSnapshot();
}); });
}); });
// ############################ // ############################
describe('given the email format is invalid', async () => { describe('given the email format is invalid', () => {
// set response by running route
beforeAll(async () => { beforeAll(async () => {
const input = { ...mockedVals.validInput, email: 'invalid-email-format' };
response = await supertest(app) response = await supertest(app)
.post(ROUTE) .post(ROUTE)
.send({ email: 'invalid-email' }); .send(input);
}, BEFORE_ALL_TIMEOUT); });
it('should return a proper status code', () => {
it('should return a proper status code status', () => {
expect(response.status).toBe(400); expect(response.status).toBe(400);
}); });
it('should respond with a proper message', () => { it('should respond with a proper body', () => {
expect(response.body.validationErrors.email).toEqual('Invalid email'); expect(response.body).toMatchSnapshot();
}); });
}); });
// ############################ // ############################
describe('given the email is unknown', async () => { describe('the request body is empty', () => {
// set response by running route
beforeAll(async () => { beforeAll(async () => {
response = await supertest(app) response = await supertest(app)
.post(ROUTE) .post(ROUTE)
.send({ email: 'un.known@local.local' }); .send();
}, BEFORE_ALL_TIMEOUT); });
it('should return a proper status code', () => {
expect(response.status).toBe(200); it('should return a proper status code status', () => {
expect(response.status).toBe(400);
}); });
it('should respond with a proper message', () => { it('should respond with a proper body', () => {
expect(response.body.message).toEqual('If the email **un.known@local.local** is correct you will receive an eMail with further instructions.'); expect(response.body).toMatchSnapshot();
}); });
}); });
}); });
\ No newline at end of file
...@@ -27,7 +27,7 @@ const mockedVals = vi.hoisted(() => { ...@@ -27,7 +27,7 @@ const mockedVals = vi.hoisted(() => {
} }
}, },
validInput: { validInput: {
email: 'john.doe@local.local' email: 'user@mail.local'
} }
}; };
}); });
......
// import vitest, supertest & app
import { vi, beforeAll, beforeEach, describe, expect, expectTypeOf, test, it, afterEach } from 'vitest';
import supertest from "supertest";
import app from "../../app.js";
// ignore expiration of the (self-signed) certificate
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
// set timeout
const BEFORE_ALL_TIMEOUT = 30000; // 30 sec
// set route
const ROUTE = '/users/confirmemailchange';
// prepare response of each test
let response;
// ############################
// OBJECTS
// ############################
const invalidTokenOrPasswordRsponse = {
code: 400,
message: 'Something went wrong while processing your request.',
data: {
password: {
code: 'validation_invalid_password',
message: 'Missing or invalid auth record password.'
},
token: {
code: 'validation_invalid_token_payload',
message: 'Invalid token payload - newEmail must be set.'
}
}
};
// ############################
// MOCKS
// ############################
// import PocketBase Service
import * as pbService from '../../utils/pocketbase/handlePocketBase.js';
// mock pbService
vi.mock('../../utils/pocketbase/handlePocketBase.js', async (importOriginal) => {
return {
...await importOriginal(),
pbVerifyAccessToken: vi.fn().mockImplementation((req, res, next) => {
next();
}),
pbConfirmEmailChange: vi.fn(() => 'mocked')
};
});
// ############################
// TESTS
// ############################
describe('user request email reset', () => {
describe('given the inputs are valid', () => {
beforeAll(async () => {
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123valid')
.send({
token: 'validToken123',
password: 'StrongPass123!',
});
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(200);
});
it('should respond with a proper message', () => {
expect(response.body.message).toEqual('Email successfully changed.');
});
});
// ############################
describe('given the token or password is invalid', () => {
beforeAll(async () => {
let error = new Error();
error.name = 'PBError';
error.response = invalidTokenOrPasswordRsponse;
error.status = 400;
pbService.pbConfirmEmailChange.mockImplementation(() => { throw error; });
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123valid')
.send({
token: 'invalidToken123',
password: 'StrongPass123!',
});
}, BEFORE_ALL_TIMEOUT);
it('should force pbConfirmEmailChange to throw an error', () => {
expect(pbService.pbConfirmEmailChange).toThrowError();
});
it('should return a proper status code', () => {
expect(response.status).toBe(400);
});
it('should respond with a proper message', () => {
expect(response.body.validationErrors).toEqual({
"password": "Missing or invalid auth record password.",
"token": "Invalid token payload - newEmail must be set.",
});
});
});
// ############################
describe('given password is missing', () => {
beforeAll(async () => {
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123valid')
.send({
token: 'validToken123'
});
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(400);
});
it('should respond with a proper message', () => {
expect(response.body.validationErrors.password).toEqual('Required');
});
});
// ############################
describe('given token is missing', () => {
beforeAll(async () => {
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123valid')
.send({
password: 'StrongPass123!',
});
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(400);
});
it('should respond with a proper message', () => {
expect(response.body.validationErrors.token).toEqual('Required');
});
});
// // ############################
describe('given JWT is missing', () => {
beforeAll(async () => {
pbService.pbVerifyAccessToken.mockImplementation((req, res, next) => {
res.status(403).json({ message: 'You are not logged in.' });
});
response = await supertest(app)
.post(ROUTE)
.send({
token: 'validToken123',
password: 'StrongPass123!',
});
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(403);
});
it('should respond with a proper message', () => {
expect(response.body.message).toEqual('You are not logged in.');
});
});
// ############################
describe('given JWT is invalid', () => {
beforeAll(async () => {
pbService.pbVerifyAccessToken.mockImplementation((req, res, next) => {
res.status(403).json({ message: 'You are not logged in.' });
});
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123invalid')
.send({
token: 'validToken123',
password: 'StrongPass123!',
});
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(403);
});
it('should respond with a proper message', () => {
expect(response.body.message).toEqual('You are not logged in.');
});
});
});
// import vitest, supertest & app
import { vi, beforeAll, beforeEach, describe, expect, expectTypeOf, test, it, afterEach } from 'vitest';
import supertest from "supertest";
import app from "../../app.js";
// ignore expiration of the (self-signed) certificate
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
// set timeout
const BEFORE_ALL_TIMEOUT = 30000; // 30 sec
// set route
const ROUTE = '/users/requestemailchange';
// prepare response of each test
let response;
// ############################
// OBJECTS
// ############################
// ############################
// MOCKS
// ############################
// import PocketBase Service
import * as pbService from '../../utils/pocketbase/handlePocketBase.js';
// mock pbService
vi.mock('../../utils/pocketbase/handlePocketBase.js', async (importOriginal) => {
return {
...await importOriginal(),
pbVerifyAccessToken: vi.fn().mockImplementation((req, res, next) => {
next();
}),
pbRequestEmailChange: vi.fn(() => 'mocked')
};
});
// ############################
// TESTS
// ############################
describe('user request email reset', () => {
describe('given the inputs are valid', () => {
beforeAll(async () => {
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123valid')
.send({ email: 'valid.mail@local.local' });
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(200);
});
it('should respond with a proper message', () => {
expect(response.body.message).toEqual('You will receive an eMail with further instructions to your new eMail-Account.');
});
});
// ############################
describe('given the email format is invalid', () => {
beforeAll(async () => {
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123valid')
.send({ email: 'invalid-email-format' });
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(400);
});
it('should respond with a proper message', () => {
expect(response.body.validationErrors.email).toEqual('Invalid email');
});
});
// ############################
describe('given email is missing', () => {
beforeAll(async () => {
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123valid');
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(400);
});
it('should respond with a proper message', () => {
expect(response.body.validationErrors.email).toEqual('Required');
});
});
// ############################
describe('given JWT is missing', () => {
beforeAll(async () => {
pbService.pbVerifyAccessToken.mockImplementation((req, res, next) => {
res.status(403).json({ message: 'You are not logged in.' });
});
response = await supertest(app)
.post(ROUTE)
.send({ email: 'valid.mail@local.local' });
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(403);
});
it('should respond with a proper message', () => {
expect(response.body.message).toEqual('You are not logged in.');
});
});
// ############################
describe('given JWT is invalid', () => {
beforeAll(async () => {
pbService.pbVerifyAccessToken.mockImplementation((req, res, next) => {
res.status(403).json({ message: 'You are not logged in.' });
});
response = await supertest(app)
.post(ROUTE)
.set('Authorization', 'Bearer 123invalid')
.send({ email: 'valid.mail@local.local' });
}, BEFORE_ALL_TIMEOUT);
it('should return a proper status code', () => {
expect(response.status).toBe(403);
});
it('should respond with a proper message', () => {
expect(response.body.message).toEqual('You are not logged in.');
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment