refactor(ui): align /api/health with IETF health-check format (#11206)

This commit is contained in:
Adrián Peña
2026-05-19 09:19:34 +02:00
committed by GitHub
parent 4c0a3f477f
commit a1848747a3
3 changed files with 44 additions and 18 deletions
@@ -80,6 +80,7 @@ jobs:
registry-1.docker.io:443
auth.docker.io:443
production.cloudflare.docker.com:443
production.cloudfront.docker.com:443
registry.npmjs.org:443
dl-cdn.alpinelinux.org:443
fonts.googleapis.com:443
+32 -12
View File
@@ -3,8 +3,11 @@ import { afterEach, describe, expect, it, vi } from "vitest";
import { GET } from "./route";
interface HealthResponse {
status: "healthy";
service: "prowler-ui";
status: "pass";
version: string;
releaseId: string;
serviceId: "prowler-ui";
description: string;
}
const parseHealthResponse = async (response: Response) =>
@@ -16,12 +19,9 @@ describe("GET /api/health", () => {
vi.unstubAllGlobals();
});
it("should return a healthy response when the Next.js route handler responds", async () => {
it("should return an IETF-shaped healthy response when the Next.js route handler responds", async () => {
// Given
const expectedBody: HealthResponse = {
status: "healthy",
service: "prowler-ui",
};
vi.stubEnv("NEXT_PUBLIC_PROWLER_RELEASE_VERSION", "1.28.0");
// When
const response = await GET();
@@ -29,8 +29,30 @@ describe("GET /api/health", () => {
// Then
expect(response.status).toBe(200);
expect(response.headers.get("Content-Type")).toBe(
"application/health+json",
);
expect(response.headers.get("Cache-Control")).toBe("no-store");
expect(body).toEqual(expectedBody);
expect(body).toEqual({
status: "pass",
version: "1",
releaseId: "1.28.0",
serviceId: "prowler-ui",
description: "Prowler UI",
});
});
it("should fall back to 'unknown' when the release version env var is missing", async () => {
// Given
vi.stubEnv("NEXT_PUBLIC_PROWLER_RELEASE_VERSION", "");
// When
const response = await GET();
const body = await parseHealthResponse(response);
// Then
expect(response.status).toBe(200);
expect(body.releaseId).toBe("unknown");
});
it("should not call fetch while evaluating UI liveness", async () => {
@@ -60,10 +82,8 @@ describe("GET /api/health", () => {
// Then
expect(response.status).toBe(200);
expect(body).toEqual({
status: "healthy",
service: "prowler-ui",
});
expect(body.status).toBe("pass");
expect(body.serviceId).toBe("prowler-ui");
expect(fetchMock).not.toHaveBeenCalled();
});
});
+11 -6
View File
@@ -1,13 +1,18 @@
const healthResponse = {
status: "healthy",
service: "prowler-ui",
} as const;
export const dynamic = "force-dynamic";
export async function GET() {
return Response.json(healthResponse, {
const body = {
status: "pass",
version: "1",
releaseId: process.env.NEXT_PUBLIC_PROWLER_RELEASE_VERSION || "unknown",
serviceId: "prowler-ui",
description: "Prowler UI",
};
return new Response(JSON.stringify(body), {
status: 200,
headers: {
"Content-Type": "application/health+json",
"Cache-Control": "no-store",
},
});