import { describe, it, before, after } from "node:test"; import assert from "node:assert/strict"; import type { DbInterface } from "../../src/db/types/DbInterface.js"; import { NotFoundAbodeError, InvalidAbodeError, } from "../../src/db/types/errors.js"; import { hashPassword } from "../../src/util/hash.js"; export function runResidentTests( name: string, getDb: () => Promise<{ db: DbInterface; close(): void }>, ): void { describe(`${name}: residents`, async () => { let db: DbInterface; let close: () => void; let uid: string; let aid: string; let ctxUid: string; before(async () => { ({ db, close } = await getDb()); const pw = await hashPassword("resident-pw"); // ctx user (creator of abode) const ctx = await db.createUser({ email: `res-ctx-${Date.now()}@test.example`, name: "Resident Ctx", password: pw, flags: {}, }); ctxUid = ctx.uid; // the resident user const resUser = await db.createUser({ email: `resident-${Date.now()}@test.example`, name: "Resident User", password: pw, flags: {}, }); uid = resUser.uid; const abode = await db.createAbode( { name: `Resident Abode ${Date.now()}` }, { uid: ctxUid }, ); aid = abode.aid; await db.createResident({ uid, aid, flags: {} }, { uid: ctxUid }); }); after(() => close()); it("getResidentById returns the created resident", async () => { const found = await db.getResidentById(uid, aid); assert.equal(found.uid, uid); assert.equal(found.aid, aid); assert.ok(found.created_at); }); it("getResidentById throws NotFoundAbodeError for unknown pair", async () => { await assert.rejects( () => db.getResidentById( "00000000-0000-0000-0000-000000000000", "00000000-0000-0000-0000-000000000001", ), (err) => { assert.ok(err instanceof NotFoundAbodeError); return true; }, ); }); it("listResidents includes the created resident", async () => { const residents = await db.listResidents(); assert.ok(Array.isArray(residents)); const found = residents.find((r) => r.uid === uid && r.aid === aid); assert.ok(found, "created resident appears in listResidents"); }); it("listResidentsByUserId filters by uid", async () => { const results = await db.listResidentsByUserId(uid); assert.ok(results.every((r) => r.uid === uid)); assert.ok(results.some((r) => r.aid === aid)); }); it("listResidentsByAbodeId filters by aid", async () => { const results = await db.listResidentsByAbodeId(aid); assert.ok(results.every((r) => r.aid === aid)); assert.ok(results.some((r) => r.uid === uid)); }); it("listUsersByAbodeId returns users in the abode", async () => { const users = await db.listUsersByAbodeId(aid); assert.ok(Array.isArray(users)); const found = users.find((u) => u.uid === uid); assert.ok(found, "resident user appears in listUsersByAbodeId"); }); it("listAbodesByUserId returns abodes for user", async () => { const abodes = await db.listAbodesByUserId(uid); assert.ok(Array.isArray(abodes)); const found = abodes.find((a) => a.aid === aid); assert.ok(found, "abode appears in listAbodesByUserId"); }); it("updateResident updates flags", async () => { const updated = await db.updateResident( { uid, aid, flags: { admin: true } }, { uid: ctxUid }, ); assert.equal(updated.uid, uid); assert.deepEqual(updated.flags, { admin: true }); }); it("updateResident with no fields throws InvalidAbodeError", async () => { await assert.rejects( () => db.updateResident({ uid, aid }, { uid: ctxUid }), (err) => { assert.ok(err instanceof InvalidAbodeError); return true; }, ); }); it("deleteResidentById removes the resident then throws on re-fetch", async () => { const pw = await hashPassword("del-res-pw"); const user2 = await db.createUser({ email: `del-res-${Date.now()}@test.example`, name: "Del Res User", password: pw, flags: {}, }); const abode2 = await db.createAbode( { name: "Del Abode" }, { uid: ctxUid }, ); await db.createResident( { uid: user2.uid, aid: abode2.aid, flags: {} }, { uid: ctxUid }, ); await db.deleteResidentById(user2.uid, abode2.aid); await assert.rejects( () => db.getResidentById(user2.uid, abode2.aid), (err) => { assert.ok(err instanceof NotFoundAbodeError); return true; }, ); }); it("deleteResidentById throws NotFoundAbodeError for unknown pair", async () => { await assert.rejects( () => db.deleteResidentById( "00000000-0000-0000-0000-000000000002", "00000000-0000-0000-0000-000000000003", ), (err) => { assert.ok(err instanceof NotFoundAbodeError); return true; }, ); }); }); }