1import { validateAccountId } from "@/Cloudflare/Auth/AuthConfig.ts";
2import { describe, expect, it } from "alchemy-test";
3import * as Effect from "effect/Effect";
4
5/**
6 * Production traces showed 242 distinct users hitting
7 * `InvalidRoute: Could not route to /accounts/workers/scripts/...`
8 * because an empty account ID was interpolated into the API path, plus
9 * placeholder values ("-", "dummy", "test", "mock") producing the same
10 * class of failure. `validateAccountId` turns all of those into a
11 * typed `AuthError` with an actionable message before any API call.
12 */
13describe(
14 "validateAccountId",
15 {
16 tags: ["unit", "provider:cloudflare", "provider:cloudflare:auth", "local"],
17 },
18 () => {
19 const valid = "2b29022c8dbd18353220a2f637eeba33";
20
21 it.effect("accepts a valid 32-hex account ID", () =>
22 Effect.gen(function* () {
23 const id = yield* validateAccountId(valid, "test");
24 expect(id).toBe(valid);
25 }),
26 );
27
28 it.effect("trims whitespace and lowercases", () =>
29 Effect.gen(function* () {
30 const id = yield* validateAccountId(
31 ` ${valid.toUpperCase()} `,
32 "test",
33 );
34 expect(id).toBe(valid);
35 }),
36 );
37
38 it.effect("rejects undefined with an actionable message", () =>
39 Effect.gen(function* () {
40 const error = yield* validateAccountId(undefined, "test").pipe(
41 Effect.flip,
42 );
43 expect(error._tag).toBe("AuthError");
44 expect(error.message).toContain("missing");
45 expect(error.message).toContain("--reconfigure Cloudflare");
46 }),
47 );
48
49 it.effect("rejects the empty string", () =>
50 Effect.gen(function* () {
51 const error = yield* validateAccountId("", "test").pipe(Effect.flip);
52 expect(error.message).toContain("missing");
53 }),
54 );
55
56 it.effect("rejects whitespace-only values", () =>
57 Effect.gen(function* () {
58 const error = yield* validateAccountId(" ", "test").pipe(Effect.flip);
59 expect(error.message).toContain("missing");
60 }),
61 );
62
63 for (const placeholder of ["-", "dummy", "test", "mock", "abc123"]) {
64 it.effect(`rejects the placeholder value '${placeholder}'`, () =>
65 Effect.gen(function* () {
66 const error = yield* validateAccountId(placeholder, "test").pipe(
67 Effect.flip,
68 );
69 expect(error._tag).toBe("AuthError");
70 expect(error.message).toContain(placeholder);
71 expect(error.message).toContain("32 hex characters");
72 }),
73 );
74 }
75
76 it.effect("names the source of the bad value in the message", () =>
77 Effect.gen(function* () {
78 const error = yield* validateAccountId(
79 "dummy",
80 "stored for profile 'ci'",
81 ).pipe(Effect.flip);
82 expect(error.message).toContain("stored for profile 'ci'");
83 }),
84 );
85 },
86);