test(http,immich): prove User-Agent fix at the wire level
Add two regression tests that fail on v1.76.0 and pass with the fix: - wire-level test: a Headers instance (the shape @immich/sdk hands over) must reach the remote server with all headers intact - real-SDK e2e: getServerStatistics through fetchWithTrustedCertificatesAsync against a live local server must deliver x-api-key
This commit is contained in:
1 parent
31e218295d
commit
b6f3aba23e
2 files changed
+90
-2
No files matched your search
@@ -1,6 +1,18 @@
|
||||
import { describe, expect, test } from "vitest";
|
||||
// @vitest-environment node
|
||||
|
||||
import { mergeHeadersWithUserAgent } from "@homarr/core/infrastructure/http";
|
||||
import { createServer } from "node:http";
|
||||
import type { Server } from "node:http";
|
||||
import type { AddressInfo } from "node:net";
|
||||
import type { RequestInit } from "undici";
|
||||
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { fetchWithTrustedCertificatesAsync, mergeHeadersWithUserAgent } from "@homarr/core/infrastructure/http";
|
||||
|
||||
vi.mock("@homarr/core/infrastructure/certificates", () => ({
|
||||
getAllTrustedCertificatesAsync: vi.fn(async () => []),
|
||||
getTrustedCertificateHostnamesAsync: vi.fn(async () => []),
|
||||
}));
|
||||
|
||||
describe("mergeHeadersWithUserAgent", () => {
|
||||
test("should keep existing headers when given a Headers instance", () => {
|
||||
@@ -48,3 +60,42 @@ describe("mergeHeadersWithUserAgent", () => {
|
||||
expect(merged.get("user-agent")).toContain("Homarr/");
|
||||
});
|
||||
});
|
||||
|
||||
const startCaptureServerAsync = async (): Promise<{
|
||||
server: Server;
|
||||
getReceivedHeaders: () => Record<string, string | string[] | undefined>;
|
||||
port: number;
|
||||
}> => {
|
||||
let receivedHeaders: Record<string, string | string[] | undefined> = {};
|
||||
const server = createServer((req, res) => {
|
||||
receivedHeaders = req.headers;
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end("{}");
|
||||
});
|
||||
await new Promise<void>((resolve) => server.listen(0, resolve));
|
||||
const port = (server.address() as AddressInfo).port;
|
||||
return {
|
||||
server,
|
||||
port,
|
||||
getReceivedHeaders: () => receivedHeaders,
|
||||
};
|
||||
};
|
||||
|
||||
describe("fetchWithTrustedCertificatesAsync", () => {
|
||||
test("should deliver a Headers instance with all headers to the remote server", async () => {
|
||||
// Arrange - the @immich/sdk hands over a Headers instance after merging its defaults
|
||||
const { server, port, getReceivedHeaders } = await startCaptureServerAsync();
|
||||
const headers = new Headers({ "x-api-key": "immich-api-key", Accept: "application/json" });
|
||||
|
||||
// Act
|
||||
const response = await fetchWithTrustedCertificatesAsync(`http://127.0.0.1:${port}/api/server/statistics`, {
|
||||
headers: headers as unknown as RequestInit["headers"],
|
||||
});
|
||||
server.close();
|
||||
|
||||
// Assert
|
||||
expect(response.status).toBe(200);
|
||||
expect(getReceivedHeaders()["x-api-key"]).toBe("immich-api-key");
|
||||
expect(getReceivedHeaders()["user-agent"]).toContain("Homarr/");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
// @vitest-environment node
|
||||
|
||||
import { createServer } from "node:http";
|
||||
import type { AddressInfo } from "node:net";
|
||||
|
||||
import { getServerStatistics, init } from "@immich/sdk";
|
||||
import { describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/core/infrastructure/http";
|
||||
|
||||
vi.mock("@homarr/core/infrastructure/certificates", () => ({
|
||||
getAllTrustedCertificatesAsync: vi.fn(async () => []),
|
||||
getTrustedCertificateHostnamesAsync: vi.fn(async () => []),
|
||||
}));
|
||||
|
||||
describe("real @immich/sdk end-to-end through fetchWithTrustedCertificatesAsync", () => {
|
||||
test("x-api-key set via init() reaches the server", async () => {
|
||||
let receivedXApiKey: string | string[] | undefined;
|
||||
const server = createServer((req, res) => {
|
||||
receivedXApiKey = req.headers["x-api-key"];
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ usage: 1000, photos: 5, videos: 2 }));
|
||||
});
|
||||
await new Promise<void>((resolve) => server.listen(0, resolve));
|
||||
const port = (server.address() as AddressInfo).port;
|
||||
|
||||
init({ baseUrl: `http://127.0.0.1:${port}/api`, apiKey: "sdk-configured-key" });
|
||||
const stats = await getServerStatistics({
|
||||
fetch: fetchWithTrustedCertificatesAsync as unknown as typeof fetch,
|
||||
});
|
||||
|
||||
server.close();
|
||||
|
||||
expect(receivedXApiKey).toBe("sdk-configured-key");
|
||||
expect(stats).toMatchObject({ usage: 1000, photos: 5, videos: 2 });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user