mirror of
https://github.com/bluewave-labs/Checkmate.git
synced 2026-01-19 08:09:45 -06:00
Merge pull request #1145 from bluewave-labs/feat/be/tests-recovery-module
feat/be/tests-recovery-module
This commit is contained in:
171
Server/tests/db/recoveryModule.test.js
Normal file
171
Server/tests/db/recoveryModule.test.js
Normal file
@@ -0,0 +1,171 @@
|
||||
import sinon from "sinon";
|
||||
import RecoveryToken from "../../db/models/RecoveryToken.js";
|
||||
import User from "../../db/models/User.js";
|
||||
import {
|
||||
requestRecoveryToken,
|
||||
validateRecoveryToken,
|
||||
resetPassword,
|
||||
} from "../../db/mongo/modules/recoveryModule.js";
|
||||
import { errorMessages } from "../../utils/messages.js";
|
||||
|
||||
const mockRecoveryToken = {
|
||||
email: "test@test.com",
|
||||
token: "1234567890",
|
||||
};
|
||||
|
||||
const mockUser = {
|
||||
email: "test@test.com",
|
||||
password: "oldPassword",
|
||||
};
|
||||
|
||||
const mockUserWithoutPassword = {
|
||||
email: "test@test.com",
|
||||
};
|
||||
|
||||
// Create a query builder that logs
|
||||
const createQueryChain = (finalResult, comparePasswordResult = false) => ({
|
||||
select: () => ({
|
||||
select: async () => {
|
||||
if (finalResult === mockUser) {
|
||||
// Return a new object with all required methods
|
||||
return {
|
||||
email: "test@test.com",
|
||||
password: "oldPassword",
|
||||
comparePassword: sinon.stub().resolves(comparePasswordResult),
|
||||
save: sinon.stub().resolves(),
|
||||
};
|
||||
}
|
||||
return finalResult;
|
||||
},
|
||||
}),
|
||||
// Add methods to the top level too
|
||||
comparePassword: sinon.stub().resolves(comparePasswordResult),
|
||||
save: sinon.stub().resolves(),
|
||||
});
|
||||
|
||||
describe("recoveryModule", () => {
|
||||
let deleteManyStub,
|
||||
saveStub,
|
||||
findOneStub,
|
||||
userCompareStub,
|
||||
userSaveStub,
|
||||
userFindOneStub;
|
||||
let req, res;
|
||||
beforeEach(() => {
|
||||
req = {
|
||||
body: { email: "test@test.com" },
|
||||
};
|
||||
deleteManyStub = sinon.stub(RecoveryToken, "deleteMany");
|
||||
saveStub = sinon.stub(RecoveryToken.prototype, "save");
|
||||
findOneStub = sinon.stub(RecoveryToken, "findOne");
|
||||
userCompareStub = sinon.stub(User.prototype, "comparePassword");
|
||||
userSaveStub = sinon.stub(User.prototype, "save");
|
||||
userFindOneStub = sinon.stub().resolves();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
describe("requestRecoveryToken", () => {
|
||||
it("should return a recovery token", async () => {
|
||||
deleteManyStub.resolves();
|
||||
saveStub.resolves(mockRecoveryToken);
|
||||
const result = await requestRecoveryToken(req, res);
|
||||
expect(result.email).to.equal(mockRecoveryToken.email);
|
||||
});
|
||||
it("should handle an error", async () => {
|
||||
const err = new Error("Test error");
|
||||
deleteManyStub.rejects(err);
|
||||
try {
|
||||
await requestRecoveryToken(req, res);
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error).to.deep.equal(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
describe("validateRecoveryToken", () => {
|
||||
it("should return a recovery token if found", async () => {
|
||||
findOneStub.resolves(mockRecoveryToken);
|
||||
const result = await validateRecoveryToken(req, res);
|
||||
expect(result).to.deep.equal(mockRecoveryToken);
|
||||
});
|
||||
it("should thrown an error if a token is not found", async () => {
|
||||
findOneStub.resolves(null);
|
||||
try {
|
||||
await validateRecoveryToken(req, res);
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.message).to.equal(errorMessages.DB_TOKEN_NOT_FOUND);
|
||||
}
|
||||
});
|
||||
it("should handle DB errors", async () => {
|
||||
const err = new Error("Test error");
|
||||
findOneStub.rejects(err);
|
||||
try {
|
||||
await validateRecoveryToken(req, res);
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error).to.deep.equal(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("resetPassword", () => {
|
||||
beforeEach(() => {
|
||||
req.body = {
|
||||
password: "test",
|
||||
newPassword: "test1",
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
sinon.restore();
|
||||
});
|
||||
|
||||
it("should thrown an error if a recovery token is not found", async () => {
|
||||
findOneStub.resolves(null);
|
||||
try {
|
||||
await resetPassword(req, res);
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.message).to.equal(errorMessages.DB_TOKEN_NOT_FOUND);
|
||||
}
|
||||
});
|
||||
it("should throw an error if a user is not found", async () => {
|
||||
findOneStub.resolves(mockRecoveryToken);
|
||||
userFindOneStub = sinon.stub(User, "findOne").resolves(null);
|
||||
try {
|
||||
await resetPassword(req, res);
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.message).to.equal(errorMessages.DB_USER_NOT_FOUND);
|
||||
}
|
||||
});
|
||||
it("should throw an error if the passwords match", async () => {
|
||||
findOneStub.resolves(mockRecoveryToken);
|
||||
saveStub.resolves();
|
||||
userFindOneStub = sinon
|
||||
.stub(User, "findOne")
|
||||
.returns(createQueryChain(mockUser, true));
|
||||
try {
|
||||
await resetPassword(req, res);
|
||||
} catch (error) {
|
||||
expect(error).to.exist;
|
||||
expect(error.message).to.equal(errorMessages.DB_RESET_PASSWORD_BAD_MATCH);
|
||||
}
|
||||
});
|
||||
it("should return a user without password if successful", async () => {
|
||||
findOneStub.resolves(mockRecoveryToken);
|
||||
saveStub.resolves();
|
||||
userFindOneStub = sinon
|
||||
.stub(User, "findOne")
|
||||
.returns(createQueryChain(mockUser)) // First call will resolve to mockUser
|
||||
.onSecondCall()
|
||||
.returns(createQueryChain(mockUserWithoutPassword));
|
||||
const result = await resetPassword(req, res);
|
||||
expect(result).to.deep.equal(mockUserWithoutPassword);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user