All checks were successful
Build and Publish Docker Image / build-and-push (push) Successful in 50s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
122 lines
3.6 KiB
TypeScript
122 lines
3.6 KiB
TypeScript
import {
|
|
BASE_URL,
|
|
createUser,
|
|
insertDump,
|
|
insertPlaylist,
|
|
test,
|
|
} from "../helpers.ts";
|
|
import { assertEquals, assertFalse, assertStringIncludes } from "@std/assert";
|
|
import { Application } from "@oak/oak";
|
|
import { ogMiddleware } from "../../middleware/og.ts";
|
|
|
|
async function handle(
|
|
app: Application,
|
|
path: string,
|
|
headers: HeadersInit = {},
|
|
) {
|
|
const res = await app.handle(new Request(`${BASE_URL}${path}`, { headers }));
|
|
if (!res) throw new Error("no response");
|
|
return { res, text: await res.text() };
|
|
}
|
|
|
|
function ogApp() {
|
|
const app = new Application();
|
|
app.use(ogMiddleware);
|
|
app.use((ctx) => {
|
|
ctx.response.body = "fallthrough";
|
|
});
|
|
return app;
|
|
}
|
|
|
|
test("ogMiddleware: dump pages get escaped OG tags", async () => {
|
|
const user = await createUser();
|
|
const dump = insertDump({
|
|
userId: user.id,
|
|
title: `Tom & "Jerry" <script>`,
|
|
comment: "A comment",
|
|
richContent: {
|
|
type: "generic",
|
|
url: "x",
|
|
thumbnailUrl: "https://img.test/a.jpg",
|
|
},
|
|
});
|
|
const { res, text } = await handle(ogApp(), `/dumps/${dump.slug}`);
|
|
assertEquals(res.headers.get("content-type"), "text/html; charset=utf-8");
|
|
assertStringIncludes(
|
|
text,
|
|
`<meta property="og:title" content="Tom & "Jerry" <script>" />`,
|
|
);
|
|
assertStringIncludes(
|
|
text,
|
|
`<title>Tom & "Jerry" <script></title>`,
|
|
);
|
|
assertStringIncludes(
|
|
text,
|
|
`<meta property="og:description" content="A comment" />`,
|
|
);
|
|
assertStringIncludes(
|
|
text,
|
|
`<meta property="og:image" content="https://img.test/a.jpg" />`,
|
|
);
|
|
assertStringIncludes(text, `content="summary_large_image"`);
|
|
assertStringIncludes(
|
|
text,
|
|
`<meta property="og:url" content="${BASE_URL}/dumps/${dump.slug}" />`,
|
|
);
|
|
// The index's own title is replaced, not duplicated.
|
|
assertEquals(text.match(/<title>/g)?.length, 1);
|
|
assertFalse(text.includes("__SITE_NAME__"));
|
|
});
|
|
|
|
test("ogMiddleware: no artwork falls back to the site icon as a small card", async () => {
|
|
const user = await createUser();
|
|
const dump = insertDump({ userId: user.id, title: "Plain" });
|
|
const { text } = await handle(ogApp(), `/dumps/${dump.id}`);
|
|
assertStringIncludes(text, `content="${BASE_URL}/apple-touch-icon.png"`);
|
|
assertStringIncludes(text, `<meta name="twitter:card" content="summary" />`);
|
|
const file = insertDump({
|
|
userId: user.id,
|
|
fileName: "a.png",
|
|
fileMime: "image/png",
|
|
});
|
|
assertStringIncludes(
|
|
(await handle(ogApp(), `/dumps/${file.id}`)).text,
|
|
`content="${BASE_URL}/api/files/${file.id}"`,
|
|
);
|
|
});
|
|
|
|
test("ogMiddleware: users and public playlists; private things fall through", async () => {
|
|
const user = await createUser();
|
|
const app = ogApp();
|
|
assertStringIncludes(
|
|
(await handle(app, `/users/${user.username}/~/votes`)).text,
|
|
`<meta property="og:title" content="${user.username}" />`,
|
|
);
|
|
const pub = insertPlaylist({ userId: user.id, title: "Open list" });
|
|
assertStringIncludes(
|
|
(await handle(app, `/playlists/${pub.slug}`)).text,
|
|
"Open list",
|
|
);
|
|
const priv = insertPlaylist({
|
|
userId: user.id,
|
|
title: "Closed",
|
|
isPublic: false,
|
|
});
|
|
assertEquals(
|
|
(await handle(app, `/playlists/${priv.slug}`)).text,
|
|
"fallthrough",
|
|
);
|
|
const secret = insertDump({
|
|
userId: user.id,
|
|
title: "Secret",
|
|
isPrivate: true,
|
|
});
|
|
assertEquals((await handle(app, `/dumps/${secret.id}`)).text, "fallthrough");
|
|
assertEquals((await handle(app, `/dumps/nope`)).text, "fallthrough");
|
|
assertEquals(
|
|
(await handle(app, `/api/dumps/${secret.id}`)).text,
|
|
"fallthrough",
|
|
);
|
|
assertEquals((await handle(app, `/favicon.ico`)).text, "fallthrough");
|
|
});
|