| 1 | import assert from "node:assert/strict"; |
| 2 | import { test } from "node:test"; |
| 3 | |
| 4 | import { interleave, mayChangeComment } from "./comments.ts"; |
| 5 | |
| 6 | const ana = { id: "usr_1" }; |
| 7 | |
| 8 | test("its author edits and deletes their own comment", () => { |
| 9 | const comment = { kind: "comment" as const, verdict: null, author: ana }; |
| 10 | assert.deepEqual(mayChangeComment(comment, "usr_1", false), { edit: true, delete: true }); |
| 11 | assert.deepEqual(mayChangeComment(comment, "usr_2", false), { edit: false, delete: false }); |
| 12 | assert.deepEqual(mayChangeComment(comment, null, true), { edit: false, delete: false }); |
| 13 | }); |
| 14 | |
| 15 | test("a maintainer edits and deletes anyone's", () => { |
| 16 | const comment = { kind: "comment" as const, verdict: null, author: ana }; |
| 17 | assert.deepEqual(mayChangeComment(comment, "usr_2", true), { edit: true, delete: true }); |
| 18 | }); |
| 19 | |
| 20 | test("a review is edited but never deleted, and a note is never changed", () => { |
| 21 | const review = { kind: "comment" as const, verdict: "approve" as const, author: ana }; |
| 22 | assert.deepEqual(mayChangeComment(review, "usr_1", true), { edit: true, delete: false }); |
| 23 | const note = { kind: "event" as const, verdict: null, author: ana }; |
| 24 | assert.deepEqual(mayChangeComment(note, "usr_1", true), { edit: false, delete: false }); |
| 25 | }); |
| 26 | |
| 27 | test("an agent's comment is answered for by whoever it acted for; its review is never deleted", () => { |
| 28 | const margo = { id: "agt_1" }; |
| 29 | const comment = { kind: "comment" as const, verdict: null, author: margo, actingFor: ana }; |
| 30 | assert.deepEqual(mayChangeComment(comment, "usr_1", false), { edit: true, delete: true }); |
| 31 | assert.deepEqual(mayChangeComment(comment, "agt_1", false), { edit: false, delete: false }); |
| 32 | const review = { ...comment, advisory: true }; |
| 33 | assert.deepEqual(mayChangeComment(review, "usr_1", false), { edit: true, delete: false }); |
| 34 | }); |
| 35 | |
| 36 | test("a conversation interleaves its sessions and claims where each happened, oldest first", () => { |
| 37 | const comments = [ |
| 38 | { id: "c1", createdAt: "2026-10-01T10:00:00Z" }, |
| 39 | { id: "c2", createdAt: "2026-10-01T12:00:00Z" }, |
| 40 | ]; |
| 41 | const extras = [ |
| 42 | { id: "late", at: "2026-10-02T09:00:00Z" }, |
| 43 | { id: "between", at: "2026-10-01T11:00:00Z" }, |
| 44 | { id: "first", at: "2026-10-01T09:00:00Z" }, |
| 45 | { id: "same", at: "2026-10-01T12:00:00Z" }, |
| 46 | ]; |
| 47 | const order = interleave(comments, extras).map((one) => (one.comment ? one.comment.id : one.extra.id)); |
| 48 | assert.deepEqual(order, ["first", "c1", "between", "same", "c2", "late"]); |
| 49 | assert.deepEqual( |
| 50 | interleave([], extras.slice(0, 1)).map((one) => one.extra?.id), |
| 51 | ["late"], |
| 52 | ); |
| 53 | }); |