118 lines
3.6 KiB
TypeScript
118 lines
3.6 KiB
TypeScript
/**
|
|
* DTP-17 — CDN reversed-ID URL convention.
|
|
*/
|
|
|
|
import { describe, expect, it } from "@suaveplan/testing/runner";
|
|
import type { CdnFallbackConfig } from "../src/index.js";
|
|
import {
|
|
buildCdnChunkUrl,
|
|
DEFAULT_CDN_LEVELS,
|
|
DEFAULT_CDN_PADDING,
|
|
} from "../src/index.js";
|
|
|
|
const BASE: CdnFallbackConfig = {
|
|
baseUrl: "https://chunks.example.com",
|
|
pathScheme: "reverse-id",
|
|
levels: DEFAULT_CDN_LEVELS,
|
|
padding: DEFAULT_CDN_PADDING,
|
|
};
|
|
|
|
describe("DTP-17 — reverse-id URL convention", () => {
|
|
it("URL builder produces correct path for various levels and padding values", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const url = buildCdnChunkUrl(BASE, "abcdef1234567890", 47);
|
|
expect(url).toBe(
|
|
"https://chunks.example.com/0/9/8/abcdef1234567890_000000047.chunk"
|
|
);
|
|
});
|
|
|
|
it("levels override changes the directory depth", { timeout: 5000 }, () => {
|
|
const url = buildCdnChunkUrl(
|
|
{ ...BASE, levels: 1 },
|
|
"abcdef1234567890",
|
|
0
|
|
);
|
|
expect(url).toBe(
|
|
"https://chunks.example.com/0/abcdef1234567890_000000000.chunk"
|
|
);
|
|
});
|
|
|
|
it("levels=0 produces no directory prefix", { timeout: 5000 }, () => {
|
|
const url = buildCdnChunkUrl({ ...BASE, levels: 0 }, "abcdef", 0);
|
|
expect(url).toBe("https://chunks.example.com/abcdef_000000000.chunk");
|
|
});
|
|
|
|
it("padding override affects chunk-id zero-padding", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const url = buildCdnChunkUrl(
|
|
{ ...BASE, padding: 4 },
|
|
"abcdef1234567890",
|
|
12
|
|
);
|
|
expect(url).toBe(
|
|
"https://chunks.example.com/0/9/8/abcdef1234567890_0012.chunk"
|
|
);
|
|
});
|
|
|
|
it("trailing slash on baseUrl is stripped", { timeout: 5000 }, () => {
|
|
const url = buildCdnChunkUrl(
|
|
{ ...BASE, baseUrl: "https://chunks.example.com/" },
|
|
"abcdef1234567890",
|
|
1
|
|
);
|
|
expect(url.startsWith("https://chunks.example.com/0/9/8/")).toBe(true);
|
|
});
|
|
|
|
it("identical inputs produce byte-identical URLs", {
|
|
timeout: 5000,
|
|
}, () => {
|
|
const a = buildCdnChunkUrl(BASE, "abcdef", 99);
|
|
const b = buildCdnChunkUrl(BASE, "abcdef", 99);
|
|
expect(a).toBe(b);
|
|
});
|
|
|
|
it("rejects empty fileId", { timeout: 5000 }, () => {
|
|
expect(() => buildCdnChunkUrl(BASE, "", 0)).toThrow();
|
|
});
|
|
|
|
it("rejects negative chunkId", { timeout: 5000 }, () => {
|
|
expect(() => buildCdnChunkUrl(BASE, "abcdef", -1)).toThrow();
|
|
});
|
|
|
|
it("rejects non-integer chunkId", { timeout: 5000 }, () => {
|
|
expect(() => buildCdnChunkUrl(BASE, "abcdef", 1.5)).toThrow();
|
|
});
|
|
|
|
it("rejects negative levels", { timeout: 5000 }, () => {
|
|
expect(() =>
|
|
buildCdnChunkUrl({ ...BASE, levels: -1 }, "abcdef", 0)
|
|
).toThrow();
|
|
});
|
|
|
|
it("rejects non-integer levels", { timeout: 5000 }, () => {
|
|
expect(() =>
|
|
buildCdnChunkUrl({ ...BASE, levels: 1.5 }, "abcdef", 0)
|
|
).toThrow();
|
|
});
|
|
|
|
it("rejects levels > fileId length", { timeout: 5000 }, () => {
|
|
expect(() =>
|
|
buildCdnChunkUrl({ ...BASE, levels: 10 }, "abc", 0)
|
|
).toThrow();
|
|
});
|
|
|
|
it("rejects negative padding", { timeout: 5000 }, () => {
|
|
expect(() =>
|
|
buildCdnChunkUrl({ ...BASE, padding: -1 }, "abcdef", 0)
|
|
).toThrow();
|
|
});
|
|
|
|
it("rejects non-integer padding", { timeout: 5000 }, () => {
|
|
expect(() =>
|
|
buildCdnChunkUrl({ ...BASE, padding: 1.5 }, "abcdef", 0)
|
|
).toThrow();
|
|
});
|
|
});
|