import { assert, assertEquals } from "@std/assert"; import { DatabaseSync } from "node:sqlite"; import { Auth } from "./auth.ts"; import { Hydrant } from "./hydrant.ts"; import { handler } from "./main.ts"; import { Follow, Star, starUrl } from "./records.ts"; import { Index } from "./sync.ts"; import { TitleLookup } from "./title.ts"; const did = "did:plc:abcdefghij"; const other = "did:plc:zyxwvutsrq"; Deno.test("record schemas and link rules", () => { const star = Star.build({ url: "https://example.org/post", comment: "hello", createdAt: new Date().toISOString(), }); assert(Star.validate(star).success); assert(!Star.validate({ ...star, comment: "🧡".repeat(32769) }).success); assertEquals(starUrl("javascript:alert(1)"), undefined); assertEquals(starUrl("https://username@example.org"), undefined); assert( Follow.validate( Follow.build({ subject: other, createdAt: new Date().toISOString() }), ).success, ); }); Deno.test("index feeds follow subjects, handles duplicate follows and deletions", () => { const db = new DatabaseSync(":memory:"); try { new Auth(db, new URL("http://127.0.0.1:8000")); const index = new Index(db, new Hydrant(new URL("http://127.0.0.1:3000"))); const s = (author: string, tid: string) => `at://${author}/${Star.id}/${tid}`; const follow = (tid: string) => `at://${did}/${Follow.id}/${tid}`; const record = Star.build({ url: "https://example.org/", createdAt: new Date().toISOString(), }); index.star(s(other, "3mgabcdefghij"), record); index.star(s(did, "3mgabcdefghik"), record); assertEquals(index.page(did).stars.length, 1); const f = Follow.build({ subject: other, createdAt: new Date().toISOString(), }); index.follow(follow("3mgabcdefghij"), f); index.follow(follow("3mgabcdefghik"), f); assertEquals(index.page(did).stars.length, 2); index.removeFollow(follow("3mgabcdefghij")); assertEquals(index.page(did).stars.length, 2); index.removeFollow(follow("3mgabcdefghik")); assertEquals(index.page(did).stars.length, 1); index.removeStar(s(did, "3mgabcdefghik")); assertEquals(index.page(did).stars.length, 0); } finally { db.close(); } }); Deno.test("an empty follow page completes reconciliation", async () => { const db = new DatabaseSync(":memory:"); try { new Auth(db, new URL("http://127.0.0.1:8000")); const hydrant = new Hydrant(new URL("http://127.0.0.1:3000")); hydrant.records = () => Promise.resolve({ entries: [] }); const index = new Index(db, hydrant); await index.reconcileFollows(did); assertEquals(index.following(did, other), []); } finally { db.close(); } }); Deno.test("anonymous pages are rendered without client scripts", async () => { const db = new DatabaseSync(":memory:"); try { const auth = new Auth(db, new URL("http://127.0.0.1:8000")); const hydrant = new Hydrant(new URL("http://127.0.0.1:3000")); const index = new Index(db, hydrant); const titles = new TitleLookup(db); const res = await handler(new Request("http://127.0.0.1:8000/"), { auth, hydrant, index, titles, }); assertEquals(res.status, 200); const body = await res.text(); assert(body.includes('href="/login">Sign in')); assert(!body.includes('action="/login"')); assert(!body.includes(" { const db = new DatabaseSync(":memory:"); const requested: string[] = []; const server = Deno.serve( { hostname: "127.0.0.1", port: 0, onListen() {} }, (req) => { requested.push(new URL(req.url).searchParams.get("cursor")!); const { socket, response } = Deno.upgradeWebSocket(req); socket.onopen = () => { const record = { did, collection: Star.id, rkey: "3mgabcdefghij" }; socket.send(JSON.stringify({ id: 7, type: "record", record })); socket.send(JSON.stringify({ id: 8, type: "identity" })); socket.close(); }; return response; }, ); try { new Auth(db, new URL("http://127.0.0.1:8000")); const hydrant = new Hydrant( new URL(`http://127.0.0.1:${server.addr.port}`), ); hydrant.repos = async function* () {}; hydrant.record = (uri) => Promise.resolve({ uri, value: Star.build({ url: "https://example.org/", createdAt: new Date().toISOString(), }), }); const index = new Index(db, hydrant); const stop = new AbortController(); const run = index.run(stop.signal); while (requested.length < 2) await new Promise((r) => setTimeout(r, 20)); stop.abort(); await run; assertEquals(requested, ["0", "9"]); assertEquals(index.page(did).stars.length, 1); } finally { await server.shutdown(); db.close(); } });