server/packages/log-manager/tests/log-manager.test.ts

222 lines
6.9 KiB
TypeScript
Raw Normal View History

2024-03-09 02:25:17 +01:00
import {
2024-04-07 07:30:49 +02:00
type Mock,
beforeEach,
describe,
expect,
it,
jest,
mock,
test,
2024-03-09 02:25:17 +01:00
} from "bun:test";
2024-04-07 07:30:49 +02:00
import type fs from "node:fs/promises";
2024-03-09 02:25:17 +01:00
import type { BunFile } from "bun";
2024-04-07 07:30:49 +02:00
// FILEPATH: /home/jessew/Dev/lysand/packages/log-manager/log-manager.test.ts
import { LogLevel, LogManager, MultiLogManager } from "../index";
2024-03-09 02:25:17 +01:00
describe("LogManager", () => {
2024-04-07 07:30:49 +02:00
let logManager: LogManager;
let mockOutput: BunFile;
let mockAppend: Mock<typeof fs.appendFile>;
beforeEach(async () => {
mockOutput = Bun.file("test.log");
mockAppend = jest.fn();
2024-04-07 12:18:21 +02:00
await mock.module("node:fs/promises", () => ({
2024-04-07 07:30:49 +02:00
appendFile: mockAppend,
}));
logManager = new LogManager(mockOutput);
});
2024-04-07 15:03:33 +02:00
/* it("should initialize and write init log", () => {
2024-04-07 12:18:21 +02:00
new LogManager(mockOutput);
2024-04-07 07:30:49 +02:00
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
expect.stringContaining("--- INIT LogManager at"),
);
});
2024-04-07 15:03:33 +02:00
*/
2024-04-07 07:30:49 +02:00
it("should log message with timestamp", async () => {
await logManager.log(LogLevel.INFO, "TestEntity", "Test message");
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
expect.stringContaining("[INFO] TestEntity: Test message"),
);
});
it("should log message without timestamp", async () => {
await logManager.log(
LogLevel.INFO,
"TestEntity",
"Test message",
false,
);
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
"[INFO] TestEntity: Test message\n",
);
});
test.skip("should write to stdout", async () => {
logManager = new LogManager(Bun.stdout);
await logManager.log(LogLevel.INFO, "TestEntity", "Test message");
const writeMock = jest.fn();
await mock.module("Bun", () => ({
stdout: Bun.stdout,
write: writeMock,
}));
expect(writeMock).toHaveBeenCalledWith(
Bun.stdout,
expect.stringContaining("[INFO] TestEntity: Test message"),
);
});
it("should log error message", async () => {
const error = new Error("Test error");
await logManager.logError(LogLevel.ERROR, "TestEntity", error);
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
expect.stringContaining("[ERROR] TestEntity: Test error"),
);
});
it("should log basic request details", async () => {
const req = new Request("http://localhost/test", { method: "GET" });
await logManager.logRequest(req, "127.0.0.1");
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
expect.stringContaining("127.0.0.1: GET http://localhost/test"),
);
});
describe("Request logger", () => {
it("should log all request details for JSON content type", async () => {
const req = new Request("http://localhost/test", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ test: "value" }),
});
await logManager.logRequest(req, "127.0.0.1", true);
const expectedLog = `127.0.0.1: POST http://localhost/test
[Headers]
content-type: application/json
[Body]
{
"test": "value"
}
`;
2024-04-07 07:30:49 +02:00
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
expect.stringContaining(expectedLog),
);
});
it("should log all request details for text content type", async () => {
const req = new Request("http://localhost/test", {
method: "POST",
headers: { "Content-Type": "text/plain" },
body: "Test body",
});
await logManager.logRequest(req, "127.0.0.1", true);
const expectedLog = `127.0.0.1: POST http://localhost/test
[Headers]
content-type: text/plain
[Body]
Test body
`;
2024-04-07 07:30:49 +02:00
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
expect.stringContaining(expectedLog),
);
});
it("should log all request details for FormData content-type", async () => {
const formData = new FormData();
formData.append("test", "value");
const req = new Request("http://localhost/test", {
method: "POST",
body: formData,
});
await logManager.logRequest(req, "127.0.0.1", true);
const expectedLog = `127.0.0.1: POST http://localhost/test
[Headers]
content-type: multipart/form-data; boundary=${
2024-04-07 07:30:49 +02:00
req.headers.get("Content-Type")?.split("boundary=")[1] ?? ""
}
[Body]
test: value
`;
2024-04-07 07:30:49 +02:00
expect(mockAppend).toHaveBeenCalledWith(
mockOutput.name,
expect.stringContaining(
expectedLog.replace("----", expect.any(String)),
),
);
});
});
});
describe("MultiLogManager", () => {
2024-04-07 07:30:49 +02:00
let multiLogManager: MultiLogManager;
let mockLogManagers: LogManager[];
let mockLog: jest.Mock;
let mockLogError: jest.Mock;
let mockLogRequest: jest.Mock;
beforeEach(() => {
mockLog = jest.fn();
mockLogError = jest.fn();
mockLogRequest = jest.fn();
mockLogManagers = [
{
log: mockLog,
logError: mockLogError,
logRequest: mockLogRequest,
},
{
log: mockLog,
logError: mockLogError,
logRequest: mockLogRequest,
},
] as unknown as LogManager[];
multiLogManager = MultiLogManager.fromLogManagers(...mockLogManagers);
});
it("should log message to all logManagers", async () => {
await multiLogManager.log(LogLevel.INFO, "TestEntity", "Test message");
expect(mockLog).toHaveBeenCalledTimes(2);
expect(mockLog).toHaveBeenCalledWith(
LogLevel.INFO,
"TestEntity",
"Test message",
true,
);
});
it("should log error to all logManagers", async () => {
const error = new Error("Test error");
await multiLogManager.logError(LogLevel.ERROR, "TestEntity", error);
expect(mockLogError).toHaveBeenCalledTimes(2);
expect(mockLogError).toHaveBeenCalledWith(
LogLevel.ERROR,
"TestEntity",
error,
);
});
it("should log request to all logManagers", async () => {
const req = new Request("http://localhost/test", { method: "GET" });
await multiLogManager.logRequest(req, "127.0.0.1", true);
expect(mockLogRequest).toHaveBeenCalledTimes(2);
expect(mockLogRequest).toHaveBeenCalledWith(req, "127.0.0.1", true);
});
2024-03-09 02:25:17 +01:00
});