import { assert, assertEquals, assertRejects } from "@std/assert";
import { DatabaseSync } from "node:sqlite";
import { Auth, type Session } from "./auth.ts";
import { Hydrant } from "./hydrant.ts";
import { handler } from "./main.ts";
import { Index } from "./sync.ts";
import {
parseTitle,
publicAddress,
TitleLookup,
TitleRateLimit,
} from "./title.ts";
Deno.test("title previews prefer decoded Open Graph titles, then HTML titles", () => {
assertEquals(
parseTitle(
'
HTML title',
),
{ title: "Cerulea & friends", source: "og" },
);
assertEquals(parseTitle("A & B"), {
title: "A & B",
source: "html",
});
assertEquals(parseTitle(" "), undefined);
});
Deno.test("title lookup rejects private and non-unicast destinations", () => {
for (
const ip of [
"127.0.0.1",
"10.0.0.1",
"169.254.169.254",
"192.168.0.1",
"100.64.0.1",
"::1",
"fd00::1",
"::ffff:127.0.0.1",
"2002:c0a8:0101::",
]
) assert(!publicAddress(ip), ip);
assert(publicAddress("8.8.8.8"));
assert(publicAddress("2606:4700:4700::1111"));
});
Deno.test("title lookup is limited per signed-in account", async () => {
const db = new DatabaseSync(":memory:");
try {
let calls = 0;
const lookup = new TitleLookup(db, (url) => {
calls++;
return Promise.resolve({ title: url, source: "url" });
});
for (let i = 0; i < 10; i++) {
await lookup.lookup("did:plc:alice", "https://example.org/");
}
await assertRejects(
() => lookup.lookup("did:plc:alice", "https://example.org/"),
TitleRateLimit,
);
await lookup.lookup("did:plc:bob", "https://example.org/");
assertEquals(calls, 11);
} finally {
db.close();
}
});
Deno.test("share form previews a title and publishes the user's revision", async () => {
const db = new DatabaseSync(":memory:");
try {
const origin = "http://127.0.0.1:8000";
const auth = new Auth(db, new URL(origin));
const did = "did:plc:abcdefghij";
let published: unknown;
auth.session = () =>
Promise.resolve({
did,
csrf: "test-csrf",
id: "test-session",
oauth: {
did,
handle: (_path: string, init: RequestInit) => {
published = JSON.parse(init.body as string);
return Promise.resolve(Response.json({
uri: `at://${did}/site.hackery.stars.star/3mgabcdefghij`,
}));
},
},
} as unknown as Session);
const hydrant = new Hydrant(new URL("http://127.0.0.1:3000"));
const titles = new TitleLookup(
db,
() => Promise.resolve({ title: "Fetched title", source: "og" }),
);
const index = new Index(db, hydrant);
hydrant.track = () => Promise.resolve();
const app = { auth, hydrant, titles, index };
const request = (path: string, fields: Record) =>
new Request(origin + path, {
method: "POST",
headers: {
origin,
"content-type": "application/x-www-form-urlencoded",
},
body: new URLSearchParams({ csrf: "test-csrf", ...fields }),
});
const preview = await handler(
request("/share/title", {
url: "https://example.org/project",
comment: "Worth reading",
}),
app,
);
assertEquals(preview.status, 200);
const html = await preview.text();
assert(
html.includes('name="title" maxlength="2048" value="Fetched title"'),
);
assert(html.includes("Worth reading"));
const script = /