Files
2026-05-27 23:47:53 +01:00

144 lines
4.7 KiB
TypeScript

import { readFile, stat } from "node:fs/promises";
import { fileURLToPath } from "node:url";
import { decodeWav } from "@suaveplan/audio-decode-wav";
import {
createIrRegistry,
createUriPluginCollector,
} from "@suaveplan/audio-ir-core";
import { createIrLoader } from "@suaveplan/audio-ir-loader";
import {
createStorageUriResolver,
STORAGE_URI_CODES,
StorageUriError,
type UriPlugin,
} from "@suaveplan/storage-uri";
import { fallbackUriPlugin } from "@suaveplan/storage-uri-plugin-fallback";
import type { FetchLike } from "@suaveplan/types";
/**
* Minimal `file://` `FetchLike` for Node — Node's `globalThis.fetch` rejects
* `file://` URLs, so we substitute one that round-trips via `node:fs`. Lives
* in the test file by design (no new package introduced).
*/
const nodeFileFetch: FetchLike = async (input, init) => {
const url =
typeof input === "string"
? new URL(input)
: input instanceof URL
? input
: new URL((input as Request).url);
if (url.protocol !== "file:") {
return globalThis.fetch(
input as Parameters<typeof globalThis.fetch>[0],
init
);
}
const path = fileURLToPath(url);
try {
const bytes = await readFile(path);
const meta = await stat(path);
return new Response(bytes, {
status: 200,
headers: {
"content-length": String(meta.size),
"content-type": "application/octet-stream",
},
});
} catch (err) {
const code = (err as NodeJS.ErrnoException).code;
if (code === "ENOENT") {
return new Response(null, { status: 404 });
}
throw err;
}
};
import { describe, expect, it } from "@suaveplan/testing/runner";
import { ENTRY_ID, manifest } from "../../src/manifest/manifest.js";
import { register } from "../../src/register/register.js";
/**
* Minimal in-test https `UriPlugin` wrapping `globalThis.fetch`. Lives in
* the test file by design — there is no shipped storage-uri plugin for
* https today, and the integration test must not introduce a new package.
*/
function makeHttpsPlugin(spy: { calls: number }): UriPlugin {
return {
scheme: "https",
adapter: {
async get(key: string) {
spy.calls += 1;
const url = `https://${key}`;
const res = await fetch(url);
if (res.status === 404) return undefined;
if (!res.ok) {
throw new StorageUriError(
STORAGE_URI_CODES.ADAPTER_ERROR,
`HTTP ${res.status} from ${url}`,
{ uri: url, scheme: "https" }
);
}
return new Uint8Array(await res.arrayBuffer());
},
async set() {
return;
},
async delete() {
return true;
},
async exists() {
spy.calls += 1;
return false;
},
async list() {
return { keys: [], total: 0, hasMore: false };
},
async clear() {
return;
},
},
parse(uri: string) {
const noScheme = uri.replace(/^https:\/\//, "");
return { key: noScheme };
},
};
}
describe("integration: bundle-only", () => {
it("bundle candidate wins without fetching HTTPS via foundation collector", {
timeout: 30000,
}, async () => {
const collector = createUriPluginCollector();
const registry = createIrRegistry();
register(registry, collector, { fetch: nodeFileFetch });
const spy = { calls: 0 };
const httpsPlugin = makeHttpsPlugin(spy);
collector.use(httpsPlugin);
const plugins: readonly UriPlugin[] = collector.plugins;
const innerResolver = createStorageUriResolver([...plugins]);
const fb = fallbackUriPlugin({
resolver: innerResolver,
policy: { errorClass: "any" },
});
const outerResolver = createStorageUriResolver([...plugins, fb]);
const loader = createIrLoader({
registry,
resolver: outerResolver,
decoders: { wav: decodeWav },
});
const ir = await loader.load(ENTRY_ID);
expect(ir.id).toBe(ENTRY_ID);
expect(ir.family).toBe("room");
expect(ir.channels).toBe(manifest.entries[0]?.channels);
expect(ir.sampleRate).toBe(manifest.entries[0]?.sampleRate);
expect(Object.isFrozen(ir)).toBe(true);
// Critical assertion: HTTPS adapter was never invoked.
expect(spy.calls).toBe(0);
});
});