Files
remanso-jetstream/tests/db_test.ts
Julien Calixte 34b8221376
All checks were successful
CI / check (push) Successful in 15s
fix(test): pass explicit did to seedWebhook in CRUD test
The webhook CRUD test combined an explicit did:plc:user webhook
with seedWebhook calls that defaulted to did:plc:test, so
listWebhooksByDid("did:plc:user") only returned the one
explicit row instead of three.
2026-06-07 22:20:52 +02:00

142 lines
4.0 KiB
TypeScript

import { assertEquals, assertFalse } from "@std/assert";
import {
addWebhookSubscription,
deleteWebhookById,
getNotes,
getNotesByDids,
getWebhooksByDidAndVerb,
listWebhooksByDid,
upsertNote,
} from "../src/data/db.ts";
import { seedNote, seedWebhook, withTestDb } from "./_helpers/db.ts";
Deno.test(
"upsertNote inserts then updates on (did, rkey) conflict",
withTestDb(() => {
upsertNote({
did: "did:plc:user",
rkey: "rkey1",
title: "First",
publishedAt: "2026-01-01T00:00:00.000Z",
createdAt: "2026-01-01T00:00:00.000Z",
});
upsertNote({
did: "did:plc:user",
rkey: "rkey1",
title: "Second",
publishedAt: "2026-02-01T00:00:00.000Z",
createdAt: "2026-01-01T00:00:00.000Z",
});
const { notes } = getNotes(undefined, 10);
assertEquals(notes.length, 1);
assertEquals(notes[0].title, "Second");
assertEquals(notes[0].publishedAt, "2026-02-01T00:00:00.000Z");
}),
);
Deno.test(
"upsertNote treats undefined discoverable as 1 and false as 0",
withTestDb(() => {
upsertNote({
did: "did:plc:user",
rkey: "default",
title: "Default",
publishedAt: "2026-01-01T00:00:00.000Z",
createdAt: "2026-01-01T00:00:00.000Z",
});
upsertNote({
did: "did:plc:user",
rkey: "hidden",
title: "Hidden",
publishedAt: "2026-01-01T00:00:00.000Z",
createdAt: "2026-01-01T00:00:00.000Z",
discoverable: false,
});
const { notes } = getNotes(undefined, 10);
const rkeys = notes.map((n) => n.rkey);
assertEquals(rkeys, ["default"]);
}),
);
Deno.test(
"getNotes paginates rkey desc and returns cursor only when page is full",
withTestDb(() => {
for (const rkey of ["a", "b", "c", "d", "e"]) {
seedNote({ rkey });
}
const firstPage = getNotes(undefined, 3);
assertEquals(firstPage.notes.map((n) => n.rkey), ["e", "d", "c"]);
assertEquals(firstPage.cursor, "c");
const secondPage = getNotes(firstPage.cursor, 3);
assertEquals(secondPage.notes.map((n) => n.rkey), ["b", "a"]);
assertEquals(secondPage.cursor, undefined);
}),
);
Deno.test(
"getNotesByDids returns empty without running SQL on empty did list",
withTestDb(() => {
seedNote({ did: "did:plc:alice", rkey: "a" });
const result = getNotesByDids([], undefined, 10);
assertEquals(result, { notes: [] });
}),
);
Deno.test(
"webhook CRUD: add omits token, list orders desc, delete by id reports hit",
withTestDb(() => {
const created = addWebhookSubscription({
did: "did:plc:user",
method: "POST",
url: "https://example.com/a",
token: "secret",
verb: "create",
});
assertEquals(created.token, undefined);
assertEquals(created.url, "https://example.com/a");
seedWebhook({
did: "did:plc:user",
url: "https://example.com/b",
verb: "create",
});
seedWebhook({
did: "did:plc:user",
url: "https://example.com/c",
verb: "delete",
});
const list = listWebhooksByDid("did:plc:user");
assertEquals(list.length, 3);
const ids = list.map((w) => w.id);
assertEquals(ids, [...ids].sort((a, b) => b - a));
assertFalse(deleteWebhookById({ did: "did:plc:user", id: 9999 }));
const deleted = deleteWebhookById({ did: "did:plc:user", id: created.id });
assertEquals(deleted, true);
assertEquals(listWebhooksByDid("did:plc:user").length, 2);
}),
);
Deno.test(
"getWebhooksByDidAndVerb filters by verb and caps at 10",
withTestDb(() => {
for (let i = 0; i < 12; i++) {
seedWebhook({ url: `https://example.com/c${i}`, verb: "create" });
}
seedWebhook({ url: "https://example.com/d", verb: "delete" });
const creates = getWebhooksByDidAndVerb("did:plc:test", "create");
assertEquals(creates.length, 10);
for (const row of creates) assertEquals(row.verb, "create");
const deletes = getWebhooksByDidAndVerb("did:plc:test", "delete");
assertEquals(deletes.length, 1);
assertEquals(deletes[0].verb, "delete");
}),
);