-
Notifications
You must be signed in to change notification settings - Fork 78
Expand file tree
/
Copy pathresolve-media-urls-owner-prefix.test.ts
More file actions
86 lines (75 loc) · 2.96 KB
/
Copy pathresolve-media-urls-owner-prefix.test.ts
File metadata and controls
86 lines (75 loc) · 2.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/**
* Regression: `asset_id` refs used to resolve to pre-migration flat keys
* (`<assetId>.<ext>`) while the bytes are written owner-prefixed by
* `storeAssetWithThumbnail`. `/api/storage` only falls back prefixed → flat,
* so every assistant-generated image 404'd on re-serve.
*/
import { describe, it, expect, vi } from "vitest";
import { pathToFileURL } from "node:url";
// pathToFileURL prefixes the current drive on Windows; build expectations
// the same way the source does.
const fileUri = (key: string) => pathToFileURL(`/var/assets/${key}`).href;
const fsMocks = vi.hoisted(() => ({ existing: new Set<string>() }));
vi.mock("@nodetool-ai/config", () => ({
buildAssetUrl: (key: string) => `/api/storage/${key}`,
getAssetFilePath: (key: string) => `/var/assets/${key}`
}));
vi.mock("node:fs", async (orig) => {
const actual = await orig<typeof import("node:fs")>();
return {
...actual,
existsSync: (p: string) => fsMocks.existing.has(String(p))
};
});
import {
resolveContentUrls,
resolveContentForProvider
} from "../src/resolve-media-urls.js";
type Block = { image: { uri: string } };
describe("resolveContentUrls with a known owner", () => {
it("builds the owner-prefixed key the bytes were written under", () => {
const content = [
{ type: "image", image: { asset_id: "abc", mimeType: "image/png" } }
];
const out = resolveContentUrls(content, "user-1") as Block[];
expect(out[0].image.uri).toBe("/api/storage/user-1/abc.png");
});
it("keeps the flat legacy key when no owner is known", () => {
const content = [
{ type: "image", image: { asset_id: "abc", mimeType: "image/png" } }
];
const out = resolveContentUrls(content) as Block[];
expect(out[0].image.uri).toBe("/api/storage/abc.png");
});
it("prefixes video and audio refs too", () => {
const out = resolveContentUrls(
[
{ type: "video", video: { asset_id: "v" } },
{ type: "audio", audio: { asset_id: "a" } }
],
"user-1"
) as Array<{ video?: { uri: string }; audio?: { uri: string } }>;
expect(out[0].video?.uri).toBe("/api/storage/user-1/v.mp4");
expect(out[1].audio?.uri).toBe("/api/storage/user-1/a.wav");
});
});
describe("resolveContentForProvider with a known owner", () => {
it("points at the owner-prefixed path", () => {
fsMocks.existing.clear();
fsMocks.existing.add("/var/assets/user-1/abc.png");
const out = resolveContentForProvider(
[{ type: "image", image: { asset_id: "abc", mimeType: "image/png" } }],
"user-1"
) as Block[];
expect(out[0].image.uri).toBe(fileUri("user-1/abc.png"));
});
it("falls back to the flat legacy path for pre-migration objects", () => {
fsMocks.existing.clear();
fsMocks.existing.add("/var/assets/abc.png");
const out = resolveContentForProvider(
[{ type: "image", image: { asset_id: "abc", mimeType: "image/png" } }],
"user-1"
) as Block[];
expect(out[0].image.uri).toBe(fileUri("abc.png"));
});
});