Files
matrix-backend/tests/services/db/database.service.test.ts
T
StarAppeal 0aafe74a74 fix test
2025-09-25 23:16:23 +02:00

141 lines
5.1 KiB
TypeScript

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import mongoose from "mongoose";
vi.mock("mongoose", async (importOriginal) => {
const originalMongoose = await importOriginal<typeof mongoose>();
return {
default: {
...originalMongoose.default,
connect: vi.fn(),
disconnect: vi.fn(),
connection: {
on: vi.fn(),
},
},
};
});
const mockedMongooseConnect = vi.mocked(mongoose.connect);
const mockedMongooseDisconnect = vi.mocked(mongoose.disconnect);
const mockedConnectionOn = vi.mocked(mongoose.connection.on);
describe("database.service", () => {
let connectToDatabase: any;
let disconnectFromDatabase: any;
beforeEach(async () => {
vi.resetModules();
vi.clearAllMocks();
const dbService = await import("../../../src/services/db/database.service");
connectToDatabase = dbService.connectToDatabase;
disconnectFromDatabase = dbService.disconnectFromDatabase;
});
afterEach(() => {
vi.restoreAllMocks();
});
const TEST_DB_NAME = "testdb";
const TEST_DB_CONN_STRING = "mongodb://test-host/testdb";
describe("connectToDatabase", () => {
it("should attempt to connect to MongoDB with correct options", async () => {
mockedMongooseConnect.mockResolvedValue(undefined as any);
await connectToDatabase(TEST_DB_NAME, TEST_DB_CONN_STRING);
expect(mockedMongooseConnect).toHaveBeenCalledOnce();
expect(mockedMongooseConnect).toHaveBeenCalledWith(
TEST_DB_CONN_STRING,
expect.objectContaining({
dbName: TEST_DB_NAME,
family: 4,
})
);
});
it("should correctly set up event listeners on the connection", async () => {
mockedMongooseConnect.mockResolvedValue(undefined as any);
await connectToDatabase(TEST_DB_NAME, TEST_DB_CONN_STRING);
expect(mockedConnectionOn).toHaveBeenCalledWith("connected", expect.any(Function));
expect(mockedConnectionOn).toHaveBeenCalledWith("disconnected", expect.any(Function));
expect(mockedConnectionOn).toHaveBeenCalledWith("error", expect.any(Function));
expect(mockedConnectionOn).toHaveBeenCalledTimes(3);
});
it("should only attempt to connect once when called multiple times (singleton pattern)", async () => {
mockedMongooseConnect.mockResolvedValue(undefined as any);
const promise1 = connectToDatabase(TEST_DB_NAME, TEST_DB_CONN_STRING);
const promise2 = connectToDatabase(TEST_DB_NAME, TEST_DB_CONN_STRING);
await Promise.all([promise1, promise2]);
expect(mockedMongooseConnect).toHaveBeenCalledOnce();
});
describe("Retry Logic", () => {
beforeEach(() => {
vi.useFakeTimers();
});
afterEach(() => {
vi.useRealTimers();
});
it("should retry connecting after a 5-second delay if the first attempt fails", async () => {
const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {});
const connectionError = new Error("Database unavailable");
mockedMongooseConnect.mockRejectedValueOnce(connectionError).mockResolvedValueOnce(undefined as any);
const connectionPromise = connectToDatabase(TEST_DB_NAME, TEST_DB_CONN_STRING);
await vi.runAllTicks();
expect(mockedMongooseConnect).toHaveBeenCalledOnce();
expect(consoleErrorSpy).toHaveBeenCalledWith(
"Failed to connect to MongoDB. Retrying in 5 seconds...",
connectionError
);
await vi.advanceTimersByTimeAsync(5000);
expect(mockedMongooseConnect).toHaveBeenCalledTimes(2);
await expect(connectionPromise).resolves.toBeUndefined();
consoleErrorSpy.mockRestore();
});
});
});
describe("disconnectFromDatabase", () => {
it("should call mongoose.disconnect if the connection is established", async () => {
mockedMongooseConnect.mockResolvedValue(undefined as any);
mockedMongooseDisconnect.mockResolvedValue(undefined as any);
await connectToDatabase(TEST_DB_NAME, TEST_DB_CONN_STRING);
const connectedCallback = mockedConnectionOn.mock.calls.find((call) => call[0] === "connected")?.[1];
if (typeof connectedCallback === "function") {
connectedCallback();
} else {
throw new Error("Connected callback was not found or is not a function");
}
await disconnectFromDatabase();
expect(mockedMongooseDisconnect).toHaveBeenCalledOnce();
});
it("should not call mongoose.disconnect if the connection was never established", async () => {
await disconnectFromDatabase();
expect(mockedMongooseDisconnect).not.toHaveBeenCalled();
});
});
});