100 lines
2.8 KiB
TypeScript
100 lines
2.8 KiB
TypeScript
// @vitest-environment node
|
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
import {
|
|
relatedFurniture,
|
|
type SourceAssetItem,
|
|
} from "@/lib/furni/source-assets";
|
|
import { inspectSourceAssets, probeAsset } from "./furniture-source-assets";
|
|
|
|
const source: SourceAssetItem = {
|
|
id: 1,
|
|
classname: "h25_monkeybzn_pole",
|
|
name: "Jungle flags",
|
|
description: "Flags",
|
|
type: "flooritem",
|
|
revision: 73253,
|
|
category: "other",
|
|
};
|
|
const alternative = {
|
|
...source,
|
|
id: 2,
|
|
classname: "br_c25_monkeybzn_pole",
|
|
revision: 73257,
|
|
};
|
|
afterEach(() => vi.unstubAllGlobals());
|
|
describe("source asset preflight", () => {
|
|
it("suggests reachable alternatives for unavailable source files", async () => {
|
|
const fetchMock = vi.fn(
|
|
async (url: string) =>
|
|
new Response(null, { status: url.includes("/73257/") ? 200 : 404 }),
|
|
);
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
const result = await inspectSourceAssets(source, [source, alternative]);
|
|
expect(result.state).toBe("missing");
|
|
expect(result.alternatives).toEqual([alternative]);
|
|
});
|
|
it("does not describe blocked or unreachable servers as missing files", async () => {
|
|
vi.stubGlobal(
|
|
"fetch",
|
|
vi.fn(async () => new Response(null, { status: 403 })),
|
|
);
|
|
const result = await inspectSourceAssets(
|
|
{ ...source, classname: "blocked_test" },
|
|
[alternative],
|
|
);
|
|
expect(result.state).toBe("unknown");
|
|
expect(result.alternatives).toEqual([]);
|
|
});
|
|
it("accepts an available configured Nitro source", async () => {
|
|
vi.stubGlobal(
|
|
"fetch",
|
|
vi.fn(
|
|
async (url: string) =>
|
|
new Response(null, { status: url.endsWith(".nitro") ? 200 : 404 }),
|
|
),
|
|
);
|
|
const result = await inspectSourceAssets(
|
|
{ ...source, classname: "custom_test" },
|
|
[],
|
|
{
|
|
id: "custom",
|
|
name: "Custom",
|
|
hotel: "",
|
|
furnidataUrl: "https://source.example/data.json",
|
|
nitroBaseUrl: "https://source.example/furniture",
|
|
iconBaseUrl: "",
|
|
},
|
|
);
|
|
expect(result.state).toBe("available");
|
|
});
|
|
it("bounds suggestions and excludes different furniture types", () => {
|
|
expect(
|
|
relatedFurniture(source, [source, { ...alternative, type: "wallitem" }]),
|
|
).toEqual([]);
|
|
expect(
|
|
relatedFurniture(
|
|
source,
|
|
Array.from({ length: 20 }, (_, id) => ({
|
|
...alternative,
|
|
id,
|
|
classname: `f${id}_monkeybzn_pole`,
|
|
})),
|
|
),
|
|
).toHaveLength(5);
|
|
});
|
|
it("handles unnamed source entries while finding related assets", () => {
|
|
expect(
|
|
relatedFurniture(source, [
|
|
{ ...alternative, name: null as unknown as string },
|
|
]),
|
|
).toHaveLength(1);
|
|
});
|
|
it("caches a probe to avoid repeating CDN requests", async () => {
|
|
const fetchMock = vi.fn(async () => new Response(null, { status: 200 }));
|
|
vi.stubGlobal("fetch", fetchMock);
|
|
await probeAsset("https://example.test/cache.nitro");
|
|
await probeAsset("https://example.test/cache.nitro");
|
|
expect(fetchMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|