feat: add extensive test suite
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
import { describe, expect, mock, test } from "bun:test";
|
||||
import { createActiveHandler } from "./handler";
|
||||
|
||||
function dependencies() {
|
||||
return {
|
||||
file: {
|
||||
exists: mock(async () => true),
|
||||
text: mock(async () => "stored-version"),
|
||||
write: mock(async () => {}),
|
||||
},
|
||||
randomUUID: mock(() => "new-version"),
|
||||
isDevelopment: mock(() => false),
|
||||
stream: mock(
|
||||
async (_options: {
|
||||
motd: { data: string; event: string };
|
||||
signal: AbortSignal;
|
||||
}) => new Response("stream"),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
describe("active handler", () => {
|
||||
test("emits DEV without reading the version file in development", async () => {
|
||||
const deps = dependencies();
|
||||
deps.isDevelopment.mockReturnValue(true);
|
||||
const request = new Request("https://buzz.test/api/active");
|
||||
await createActiveHandler(deps)(request);
|
||||
expect(deps.file.exists).not.toHaveBeenCalled();
|
||||
expect(deps.stream).toHaveBeenCalledWith({
|
||||
motd: { data: "DEV", event: "version" },
|
||||
signal: request.signal,
|
||||
});
|
||||
});
|
||||
|
||||
test("emits an existing persisted version", async () => {
|
||||
const deps = dependencies();
|
||||
await createActiveHandler(deps)(
|
||||
new Request("https://buzz.test/api/active"),
|
||||
);
|
||||
expect(deps.file.text).toHaveBeenCalled();
|
||||
expect(deps.file.write).not.toHaveBeenCalled();
|
||||
expect(deps.stream.mock.calls[0]?.[0].motd.data).toBe("stored-version");
|
||||
});
|
||||
|
||||
test("persists and emits the same UUID when the file is absent", async () => {
|
||||
const deps = dependencies();
|
||||
deps.file.exists.mockResolvedValue(false);
|
||||
await createActiveHandler(deps)(
|
||||
new Request("https://buzz.test/api/active"),
|
||||
);
|
||||
expect(deps.randomUUID).toHaveBeenCalledTimes(1);
|
||||
expect(deps.file.write).toHaveBeenCalledWith("new-version");
|
||||
expect(deps.stream.mock.calls[0]?.[0].motd.data).toBe("new-version");
|
||||
});
|
||||
|
||||
test("replaces an empty file with one UUID", async () => {
|
||||
const deps = dependencies();
|
||||
deps.file.text.mockResolvedValue("");
|
||||
await createActiveHandler(deps)(
|
||||
new Request("https://buzz.test/api/active"),
|
||||
);
|
||||
expect(deps.randomUUID).toHaveBeenCalledTimes(1);
|
||||
expect(deps.file.write).toHaveBeenCalledWith("new-version");
|
||||
expect(deps.stream.mock.calls[0]?.[0].motd.data).toBe("new-version");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
type VersionFile = {
|
||||
exists: () => Promise<boolean>;
|
||||
text: () => Promise<string>;
|
||||
write: (value: string) => Promise<unknown>;
|
||||
};
|
||||
|
||||
export function createActiveHandler(dependencies: {
|
||||
file: VersionFile;
|
||||
randomUUID: () => string;
|
||||
isDevelopment: () => boolean;
|
||||
stream: (options: {
|
||||
motd: { data: string; event: string };
|
||||
signal: AbortSignal;
|
||||
}) => Response | Promise<Response>;
|
||||
}) {
|
||||
return async function GET(req: Request) {
|
||||
let version = "DEV";
|
||||
if (!dependencies.isDevelopment()) {
|
||||
if (!(await dependencies.file.exists())) {
|
||||
version = dependencies.randomUUID();
|
||||
await dependencies.file.write(version);
|
||||
} else {
|
||||
version = await dependencies.file.text();
|
||||
if (!version) {
|
||||
version = dependencies.randomUUID();
|
||||
await dependencies.file.write(version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dependencies.stream({
|
||||
motd: { data: version, event: "version" },
|
||||
signal: req.signal,
|
||||
});
|
||||
};
|
||||
}
|
||||
+11
-23
@@ -1,27 +1,15 @@
|
||||
import { sse } from "@/lib/db/sse-endpoints";
|
||||
import { createActiveHandler } from "./handler";
|
||||
|
||||
const version = Bun.file(".version");
|
||||
|
||||
export async function GET(req: Request) {
|
||||
if (process.env.ENVIRONMENT === "development")
|
||||
return sse.active.stream({
|
||||
motd: {
|
||||
data: "DEV",
|
||||
event: "version",
|
||||
},
|
||||
signal: req.signal,
|
||||
});
|
||||
if (!(await version.exists())) await version.write(crypto.randomUUID());
|
||||
let ver = await version.text();
|
||||
if (!ver) {
|
||||
ver = crypto.randomUUID();
|
||||
await version.write(crypto.randomUUID());
|
||||
}
|
||||
return sse.active.stream({
|
||||
motd: {
|
||||
data: ver,
|
||||
event: "version",
|
||||
},
|
||||
signal: req.signal,
|
||||
});
|
||||
}
|
||||
export const GET = createActiveHandler({
|
||||
file: version,
|
||||
randomUUID: crypto.randomUUID,
|
||||
isDevelopment: () => process.env.ENVIRONMENT === "development",
|
||||
stream: (options) => {
|
||||
const response = sse.active.stream(options);
|
||||
if (!response) throw new Error("SSE is unavailable");
|
||||
return response;
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user