diff --git a/apps/backend/src/app/api/latest/internal/changelog/route.tsx b/apps/backend/src/app/api/latest/internal/changelog/route.tsx index 3ef9948a4..6698d0f9c 100644 --- a/apps/backend/src/app/api/latest/internal/changelog/route.tsx +++ b/apps/backend/src/app/api/latest/internal/changelog/route.tsx @@ -1,6 +1,7 @@ import { createSmartRouteHandler } from "@/route-handlers/smart-route-handler"; import { yupArray, yupBoolean, yupNumber, yupObject, yupString } from "@hexclave/shared/dist/schema-fields"; import { getEnvVariable, getNodeEnvironment } from "@hexclave/shared/dist/utils/env"; +import { HexclaveAssertionError } from "@hexclave/shared/dist/utils/errors"; import * as fs from "fs/promises"; import * as path from "path"; @@ -131,11 +132,10 @@ export const GET = createSmartRouteHandler({ method: yupString().oneOf(["GET"]).defined(), }), response: yupObject({ - statusCode: yupNumber().oneOf([200, 502]).defined(), + statusCode: yupNumber().oneOf([200]).defined(), bodyType: yupString().oneOf(["json"]).defined(), body: yupObject({ - entries: yupArray(changelogEntrySchema).optional(), - error: yupString().optional(), + entries: yupArray(changelogEntrySchema).defined(), }).defined(), }), handler: async () => { @@ -179,11 +179,7 @@ export const GET = createSmartRouteHandler({ }); if (!response.ok) { - return { - statusCode: 502, - bodyType: "json", - body: { error: "Failed to download changelog" }, - } as const; + throw new HexclaveAssertionError(`Changelog fetch failed with status ${response.status}`, { changelogUrl }); } const content = await response.text(); diff --git a/apps/e2e/tests/backend/endpoints/api/v1/internal/changelog.test.ts b/apps/e2e/tests/backend/endpoints/api/v1/internal/changelog.test.ts new file mode 100644 index 000000000..49a965183 --- /dev/null +++ b/apps/e2e/tests/backend/endpoints/api/v1/internal/changelog.test.ts @@ -0,0 +1,36 @@ +import { describe } from "vitest"; +import { it } from "../../../../../helpers"; +import { niceBackendFetch } from "../../../../backend-helpers"; + +describe("GET /api/v1/internal/changelog", () => { + it("should return changelog entries with expected structure", async ({ expect }) => { + const response = await niceBackendFetch("/api/v1/internal/changelog", { + method: "GET", + }); + + expect(response.status).toBe(200); + expect(response.body).toHaveProperty("entries"); + expect(Array.isArray(response.body.entries)).toBe(true); + expect(response.body.entries.length).toBeGreaterThan(0); + + const entry = response.body.entries[0]; + expect(entry).toHaveProperty("version"); + expect(entry).toHaveProperty("type"); + expect(entry).toHaveProperty("markdown"); + expect(entry).toHaveProperty("bulletCount"); + expect(typeof entry.version).toBe("string"); + expect(["major", "minor", "patch"]).toContain(entry.type); + expect(typeof entry.markdown).toBe("string"); + expect(typeof entry.bulletCount).toBe("number"); + expect(entry.bulletCount).toBeGreaterThanOrEqual(0); + }); + + it("should return at most 8 entries", async ({ expect }) => { + const response = await niceBackendFetch("/api/v1/internal/changelog", { + method: "GET", + }); + + expect(response.status).toBe(200); + expect(response.body.entries.length).toBeLessThanOrEqual(8); + }); +});