add: unit and integration testing

This commit is contained in:
odweta
2026-09-07 18:09:36 +02:00
parent 76fde42334
commit 52a25aeaf5
7230 changed files with 561560 additions and 135112 deletions
+131
View File
@@ -0,0 +1,131 @@
const { handleSearch } = require("../src/search");
describe("handleSearch", () => {
let req;
let res;
beforeEach(() => {
req = {
query: {}
};
// using .mockReturnThis() because of chainable methods
res = {
status: jest.fn().mockReturnThis(),
send: jest.fn().mockReturnThis(),
setHeader: jest.fn()
};
});
// clean up the observed data after each test
afterEach(() => {
jest.restoreAllMocks();
});
test("returns 400 when query is missing", async () => {
global.fetch = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue({
results: [
{
url: "https://example.com",
title: "Example",
content: "Content",
irrelevant: "removed"
}
]
})
});
await handleSearch(req, res);
expect(res.status).toHaveBeenCalledWith(400);
expect(res.send).toHaveBeenCalledWith("Missing search query");
expect(global.fetch).not.toHaveBeenCalled();
});
test("fetches search results and sends filtered JSON", async () => {
req.query.query = "nodejs testing";
global.fetch = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue({
results: [
{
url: "https://example.com",
title: "Example",
content: "Content",
score: 0.8
}
]
})
});
await handleSearch(req, res);
expect(global.fetch).toHaveBeenCalledTimes(1);
const [url, options] = global.fetch.mock.calls[0];
expect(url).toContain("/search?");
expect(url).toContain("q=nodejs+testing");
expect(url).toContain("engines=startpage");
expect(url).toContain("format=json");
expect(url).not.toContain("score=0.8");
expect(options).toEqual({
headers: {
Accept: "application/json"
}
});
expect(res.setHeader).toHaveBeenCalledWith(
"Content-Type",
"application/json; charset=utf-8"
);
expect(res.setHeader).toHaveBeenCalledWith(
"Content-Disposition",
'attachment; filename="output.json"'
);
expect(res.send).toHaveBeenCalledWith(
JSON.stringify(
[
{
url: "https://example.com",
title: "Example",
content: "Content"
}
],
null,
2
)
);
});
test("uses an empty array when the API omits results", async () => {
req.query.query = "empty";
global.fetch = jest.fn().mockResolvedValue({
json: jest.fn().mockResolvedValue({})
});
await handleSearch(req, res);
expect(res.send).toHaveBeenCalledWith("[]");
});
test("returns 500 when fetch fails", async () => {
req.query.query = "error";
global.fetch = jest
.fn()
.mockRejectedValue(new Error("SearxNG unavailable"));
await handleSearch(req, res);
expect(res.status).toHaveBeenCalledWith(500);
expect(res.send).toHaveBeenCalledWith(
"<p><b>Search failed!<br>See the console for the error.</b></p>"
);
});
});