greenrhombus/tests/utils/cgiParser.test.js

130 lines
4.2 KiB
JavaScript

const createCGIParser = require("../../src/utils/cgiParser.js");
jest.mock("http"); // Mocking HTTP to simulate the response behavior
describe("createCGIParser", () => {
let req, res, handler, defaultHeaders, software, dataHandler;
beforeEach(() => {
req = {};
res = {
writeHead: jest.fn(),
write: jest.fn(),
finished: false,
error: jest.fn()
};
handler = {
stdout: {
removeAllListeners: jest.fn(),
pipe: jest.fn(),
on: jest.fn()
},
removeAllListeners: jest.fn()
};
defaultHeaders = { "X-Test-Header": "TestValue" };
software = "TestSoftware";
});
test("should parse headers and write response correctly", () => {
const inputHeaders =
"Status: 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 13\r\n\r\nHello, world!";
const buffer = Buffer.from(inputHeaders, "latin1");
dataHandler = createCGIParser(req, res, handler, defaultHeaders, software);
dataHandler(buffer);
expect(res.writeHead).toHaveBeenCalledWith(200, "OK", {
"Content-Type": "text/plain",
"Content-Length": "13",
"X-Test-Header": "TestValue"
});
expect(res.write).toHaveBeenCalledWith(
Buffer.from("Hello, world!", "latin1")
);
});
test("should handle status headers without protocol", () => {
const inputHeaders =
"Status: 200 OK\r\nContent-Type: text/html\r\n\r\n<body>Success</body>";
const buffer = Buffer.from(inputHeaders, "latin1");
dataHandler = createCGIParser(req, res, handler, defaultHeaders, software);
dataHandler(buffer);
expect(res.writeHead).toHaveBeenCalledWith(200, "OK", {
"Content-Type": "text/html",
"X-Test-Header": "TestValue"
});
expect(res.write).toHaveBeenCalledWith(
Buffer.from("<body>Success</body>", "latin1")
);
});
test("should handle malformed status line", () => {
const inputHeaders =
"Content-Type: text/plain\r\n\r\nMalformed status line.";
const buffer = Buffer.from(inputHeaders, "latin1");
dataHandler = createCGIParser(req, res, handler, defaultHeaders, software);
dataHandler(buffer);
expect(res.writeHead).toHaveBeenCalledWith(200, "OK", {
"Content-Type": "text/plain",
"X-Test-Header": "TestValue"
});
expect(res.write).toHaveBeenCalledWith(
Buffer.from("Malformed status line.", "latin1")
);
});
test("should handle redirection logic for Location header", () => {
const inputHeaders = "Status: 302 Found\r\nLocation: /new-location\r\n\r\n";
const buffer = Buffer.from(inputHeaders, "latin1");
dataHandler = createCGIParser(req, res, handler, defaultHeaders, software);
dataHandler(buffer);
expect(res.writeHead).toHaveBeenCalledWith(302, "Found", {
Location: "/new-location",
"X-Test-Header": "TestValue"
});
expect(res.write).toHaveBeenCalledWith(Buffer.from("", "latin1"));
});
test("should handle Set-Cookie headers correctly", () => {
const inputHeaders =
"Status: 200 OK\r\nSet-Cookie: sessionId=abc123; HttpOnly\r\nSet-Cookie: theme=dark; Secure\r\n\r\nBody content";
const buffer = Buffer.from(inputHeaders, "latin1");
dataHandler = createCGIParser(req, res, handler, defaultHeaders, software);
dataHandler(buffer);
expect(res.writeHead).toHaveBeenCalledWith(200, "OK", {
"Set-Cookie": ["sessionId=abc123; HttpOnly", "theme=dark; Secure"],
"X-Test-Header": "TestValue"
});
expect(res.write).toHaveBeenCalledWith(
Buffer.from("Body content", "latin1")
);
});
test("should call res.error on failure to writeHead or write", () => {
res.writeHead.mockImplementation(() => {
throw new Error("writeHead error");
});
const inputHeaders =
"Status: 500 Internal Server Error\r\n\r\nError occurred.";
const buffer = Buffer.from(inputHeaders, "latin1");
dataHandler = createCGIParser(req, res, handler, defaultHeaders, software);
dataHandler(buffer);
expect(res.error).toHaveBeenCalledWith(
500,
"TestSoftware",
expect.any(Error)
);
expect(handler.removeAllListeners).toHaveBeenCalled();
expect(handler.stdout.removeAllListeners).toHaveBeenCalled();
});
});