Skip to content
Source
Sign inSign up

mediaSource.test.ts

119 lines4.0 KB

1import { ThreadId } from "@t3tools/contracts";
2import { describe, expect, it } from "vite-plus/test";
3​
4import { resolveMediaSource } from "./mediaSource.ts";
5​
6const threadId = ThreadId.make("thread-1");
7​
8describe("resolveMediaSource", () => {
9 describe("direct URLs", () => {
10 it.each(["https://cdn.example.com/tone.mp3", "data:audio/wav;base64,AAAA"])(
11 "keeps %s out of the image and video viewer",
12 (href) => {
13 expect(resolveMediaSource(href, { threadId })).toBeNull();
14 expect(resolveMediaSource(href, { threadId, imageEmbed: true })).toBeNull();
15 },
16 );
17​
18 it("keeps the authored URL and decodes the display name once", () => {
19 const href = "https://cdn.example.com/clip%20one%2520%2Emp4?signature=a%2fb#t=2";
20 expect(resolveMediaSource(href, { threadId })).toEqual({
21 kind: "video",
22 mimeType: "video/mp4",
23 name: "clip one%20.mp4",
24 reference: { kind: "url", url: href },
25 srcFragment: "#t=2",
26 access: "direct",
27 uri: href,
28 });
29 });
30​
31 it("accepts extensionless image embeds only when asked", () => {
32 const href = "https://cdn.example.com/render?id=42";
33 expect(resolveMediaSource(href, { threadId })).toBeNull();
34 expect(resolveMediaSource(href, { threadId, imageEmbed: true })).toMatchObject({
35 kind: "image",
36 mimeType: "image/*",
37 name: "render",
38 });
39 });
40 });
41​
42 describe("host paths", () => {
43 it.each(["tone.wav", "tone.mp3", "tone.oga", "tone.webm-audio"])(
44 "keeps workspace audio %s out of the image fallback",
45 (path) => {
46 expect(resolveMediaSource(path, { threadId, imageEmbed: true })).toBeNull();
47 expect(
48 resolveMediaSource("authored.wav", {
49 threadId,
50 imageEmbed: true,
51 resolvedFilePath: path,
52 }),
53 ).toBeNull();
54 },
55 );
56​
57 it.each([
58 ["/tmp/frame%23one.png:12", "/tmp/frame#one.png"],
59 ["/tmp/frame%2523one.png:12", "/tmp/frame%23one.png"],
60 ])("resolves %s through the environment", (href, path) => {
61 expect(resolveMediaSource(href, { threadId, workspaceRoot: "/repo" })).toEqual({
62 kind: "image",
63 mimeType: "image/png",
64 name: path.split(/[\\/]/).at(-1),
65 reference: { kind: "file", path },
66 srcFragment: "",
67 access: "environment",
68 resource: { _tag: "media-file", threadId, path },
69 });
70 });
71​
72 it("joins relative paths to the workspace and records the relative reference", () => {
73 expect(
74 resolveMediaSource("screens/logo.svg?v=2#mark", { threadId, workspaceRoot: "/repo" }),
75 ).toEqual({
76 kind: "image",
77 mimeType: "image/svg+xml",
78 name: "logo.svg",
79 reference: {
80 kind: "file",
81 path: "/repo/screens/logo.svg",
82 relativePath: "screens/logo.svg",
83 },
84 srcFragment: "#mark",
85 access: "environment",
86 resource: { _tag: "media-file", threadId, path: "/repo/screens/logo.svg", hostOnly: true },
87 });
88 });
89​
90 it("prefers a caller-resolved path over classifying the source", () => {
91 expect(
92 resolveMediaSource("logo.svg", {
93 threadId,
94 workspaceRoot: "/repo",
95 resolvedFilePath: "/repo/docs/logo.svg",
96 }),
97 ).toMatchObject({
98 access: "environment",
99 resource: { _tag: "media-file", path: "/repo/docs/logo.svg" },
100 reference: { relativePath: "docs/logo.svg" },
101 });
102 });
103​
104 it("separates a playback fragment from literal filename characters", () => {
105 expect(resolveMediaSource("/tmp/clip%23one.mp4#t=2", { threadId })).toMatchObject({
106 kind: "video",
107 srcFragment: "#t=2",
108 resource: { path: "/tmp/clip#one.mp4" },
109 });
110 });
111​
112 it("cannot be loaded without a thread to mint through", () => {
113 expect(resolveMediaSource("/tmp/clip.mp4", { threadId: undefined })).toMatchObject({
114 kind: "video",
115 access: "unavailable",
116 });
117 });
118 });
119});