mirror of
https://github.com/gethomepage/homepage.git
synced 2026-02-08 00:40:52 +08:00
test: add remaining API route coverage
This commit is contained in:
@@ -9,6 +9,10 @@ export default async function handler(req, res) {
|
||||
|
||||
const provider = Object.values(searchProviders).find(({ name }) => name === providerName);
|
||||
|
||||
if (!provider) {
|
||||
return res.json([query, []]);
|
||||
}
|
||||
|
||||
if (provider.name === "Custom") {
|
||||
const widgets = await widgetsFromConfig();
|
||||
const searchWidget = widgets.find((w) => w.type === "search");
|
||||
|
||||
106
src/pages/api/search/searchSuggestion.test.js
Normal file
106
src/pages/api/search/searchSuggestion.test.js
Normal file
@@ -0,0 +1,106 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import createMockRes from "test-utils/create-mock-res";
|
||||
|
||||
const { providers, getSettings, widgetsFromConfig, cachedRequest } = vi.hoisted(() => ({
|
||||
providers: {
|
||||
custom: { name: "Custom", url: false, suggestionUrl: null },
|
||||
google: { name: "Google", url: "https://google?q=", suggestionUrl: "https://google/suggest?q=" },
|
||||
empty: { name: "NoSuggest", url: "x", suggestionUrl: null },
|
||||
},
|
||||
getSettings: vi.fn(),
|
||||
widgetsFromConfig: vi.fn(),
|
||||
cachedRequest: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("components/widgets/search/search", () => ({
|
||||
searchProviders: {
|
||||
custom: providers.custom,
|
||||
google: providers.google,
|
||||
empty: providers.empty,
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("utils/config/config", () => ({
|
||||
getSettings,
|
||||
}));
|
||||
|
||||
vi.mock("utils/config/widget-helpers", () => ({
|
||||
widgetsFromConfig,
|
||||
}));
|
||||
|
||||
vi.mock("utils/proxy/http", () => ({
|
||||
cachedRequest,
|
||||
}));
|
||||
|
||||
import handler from "./searchSuggestion";
|
||||
|
||||
describe("pages/api/search/searchSuggestion", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
// Reset provider objects since handler mutates the Custom provider.
|
||||
providers.custom.url = false;
|
||||
providers.custom.suggestionUrl = null;
|
||||
});
|
||||
|
||||
it("returns empty suggestions when providerName is unknown", async () => {
|
||||
const req = { query: { query: "hello", providerName: "Unknown" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res.body).toEqual(["hello", []]);
|
||||
});
|
||||
|
||||
it("returns empty suggestions when provider has no suggestionUrl", async () => {
|
||||
const req = { query: { query: "hello", providerName: "NoSuggest" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res.body).toEqual(["hello", []]);
|
||||
});
|
||||
|
||||
it("calls cachedRequest for a standard provider", async () => {
|
||||
cachedRequest.mockResolvedValueOnce(["q", ["a"]]);
|
||||
|
||||
const req = { query: { query: "hello world", providerName: "Google" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(cachedRequest).toHaveBeenCalledWith("https://google/suggest?q=hello%20world", 5, "Mozilla/5.0");
|
||||
expect(res.body).toEqual(["q", ["a"]]);
|
||||
});
|
||||
|
||||
it("resolves Custom provider suggestionUrl from widgets.yaml when present", async () => {
|
||||
widgetsFromConfig.mockResolvedValueOnce([
|
||||
{ type: "search", options: { url: "https://custom?q=", suggestionUrl: "https://custom/suggest?q=" } },
|
||||
]);
|
||||
cachedRequest.mockResolvedValueOnce(["q", ["x"]]);
|
||||
|
||||
const req = { query: { query: "hello", providerName: "Custom" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(cachedRequest).toHaveBeenCalledWith("https://custom/suggest?q=hello", 5, "Mozilla/5.0");
|
||||
expect(res.body).toEqual(["q", ["x"]]);
|
||||
});
|
||||
|
||||
it("falls back to quicklaunch custom settings when no search widget is configured", async () => {
|
||||
widgetsFromConfig.mockResolvedValueOnce([]);
|
||||
getSettings.mockReturnValueOnce({
|
||||
quicklaunch: { provider: "custom", url: "https://ql?q=", suggestionUrl: "https://ql/suggest?q=" },
|
||||
});
|
||||
cachedRequest.mockResolvedValueOnce(["q", ["y"]]);
|
||||
|
||||
const req = { query: { query: "hello", providerName: "Custom" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(cachedRequest).toHaveBeenCalledWith("https://ql/suggest?q=hello", 5, "Mozilla/5.0");
|
||||
});
|
||||
});
|
||||
103
src/pages/api/siteMonitor.test.js
Normal file
103
src/pages/api/siteMonitor.test.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import createMockRes from "test-utils/create-mock-res";
|
||||
|
||||
const { getServiceItem, httpProxy, perf, logger } = vi.hoisted(() => ({
|
||||
getServiceItem: vi.fn(),
|
||||
httpProxy: vi.fn(),
|
||||
perf: { now: vi.fn() },
|
||||
logger: { debug: vi.fn() },
|
||||
}));
|
||||
|
||||
vi.mock("perf_hooks", () => ({
|
||||
performance: perf,
|
||||
}));
|
||||
|
||||
vi.mock("utils/config/service-helpers", () => ({
|
||||
getServiceItem,
|
||||
}));
|
||||
|
||||
vi.mock("utils/proxy/http", () => ({
|
||||
httpProxy,
|
||||
}));
|
||||
|
||||
vi.mock("utils/logger", () => ({
|
||||
default: () => logger,
|
||||
}));
|
||||
|
||||
import handler from "./siteMonitor";
|
||||
|
||||
describe("pages/api/siteMonitor", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("returns 400 when the service item is missing", async () => {
|
||||
getServiceItem.mockResolvedValueOnce(null);
|
||||
|
||||
const req = { query: { groupName: "g", serviceName: "s" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res.statusCode).toBe(400);
|
||||
expect(res.body.error).toContain("Unable to find service");
|
||||
});
|
||||
|
||||
it("returns 400 when the monitor URL is missing", async () => {
|
||||
getServiceItem.mockResolvedValueOnce({ siteMonitor: "" });
|
||||
|
||||
const req = { query: { groupName: "g", serviceName: "s" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res.statusCode).toBe(400);
|
||||
expect(res.body.error).toBe("No http monitor URL given");
|
||||
});
|
||||
|
||||
it("uses HEAD and returns status + latency when the response is OK", async () => {
|
||||
getServiceItem.mockResolvedValueOnce({ siteMonitor: "http://example.com" });
|
||||
perf.now.mockReturnValueOnce(1).mockReturnValueOnce(11);
|
||||
httpProxy.mockResolvedValueOnce([200]);
|
||||
|
||||
const req = { query: { groupName: "g", serviceName: "s" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(httpProxy).toHaveBeenCalledWith("http://example.com", { method: "HEAD" });
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.body.status).toBe(200);
|
||||
expect(res.body.latency).toBe(10);
|
||||
});
|
||||
|
||||
it("falls back to GET when HEAD is rejected", async () => {
|
||||
getServiceItem.mockResolvedValueOnce({ siteMonitor: "http://example.com" });
|
||||
perf.now.mockReturnValueOnce(1).mockReturnValueOnce(2).mockReturnValueOnce(5).mockReturnValueOnce(15);
|
||||
httpProxy.mockResolvedValueOnce([500]).mockResolvedValueOnce([200]);
|
||||
|
||||
const req = { query: { groupName: "g", serviceName: "s" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(httpProxy).toHaveBeenNthCalledWith(1, "http://example.com", { method: "HEAD" });
|
||||
expect(httpProxy).toHaveBeenNthCalledWith(2, "http://example.com");
|
||||
expect(res.statusCode).toBe(200);
|
||||
expect(res.body).toEqual({ status: 200, latency: 10 });
|
||||
});
|
||||
|
||||
it("returns 400 when httpProxy throws", async () => {
|
||||
getServiceItem.mockResolvedValueOnce({ siteMonitor: "http://example.com" });
|
||||
httpProxy.mockRejectedValueOnce(new Error("nope"));
|
||||
|
||||
const req = { query: { groupName: "g", serviceName: "s" } };
|
||||
const res = createMockRes();
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res.statusCode).toBe(400);
|
||||
expect(res.body.error).toContain("Error attempting http monitor");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user