Add touched/unread inbox issue semantics

This commit is contained in:
Dotta
2026-03-06 08:21:03 -06:00
parent 3369a9e685
commit 38b9a55eab
13 changed files with 6059 additions and 46 deletions

View File

@@ -0,0 +1,75 @@
import { describe, expect, it } from "vitest";
import { deriveIssueUserContext } from "../services/issues.ts";
function makeIssue(overrides?: Partial<{
createdByUserId: string | null;
assigneeUserId: string | null;
createdAt: Date;
updatedAt: Date;
}>) {
return {
createdByUserId: null,
assigneeUserId: null,
createdAt: new Date("2026-03-06T10:00:00.000Z"),
updatedAt: new Date("2026-03-06T11:00:00.000Z"),
...overrides,
};
}
describe("deriveIssueUserContext", () => {
it("marks issue unread when external comments are newer than my latest comment", () => {
const context = deriveIssueUserContext(
makeIssue({ createdByUserId: "user-1" }),
"user-1",
{
myLastCommentAt: new Date("2026-03-06T12:00:00.000Z"),
lastExternalCommentAt: new Date("2026-03-06T13:00:00.000Z"),
},
);
expect(context.myLastTouchAt?.toISOString()).toBe("2026-03-06T12:00:00.000Z");
expect(context.lastExternalCommentAt?.toISOString()).toBe("2026-03-06T13:00:00.000Z");
expect(context.isUnreadForMe).toBe(true);
});
it("marks issue read when my latest comment is newest", () => {
const context = deriveIssueUserContext(
makeIssue({ createdByUserId: "user-1" }),
"user-1",
{
myLastCommentAt: new Date("2026-03-06T14:00:00.000Z"),
lastExternalCommentAt: new Date("2026-03-06T13:00:00.000Z"),
},
);
expect(context.isUnreadForMe).toBe(false);
});
it("uses issue creation time as fallback touch point for creator", () => {
const context = deriveIssueUserContext(
makeIssue({ createdByUserId: "user-1", createdAt: new Date("2026-03-06T09:00:00.000Z") }),
"user-1",
{
myLastCommentAt: null,
lastExternalCommentAt: new Date("2026-03-06T10:00:00.000Z"),
},
);
expect(context.myLastTouchAt?.toISOString()).toBe("2026-03-06T09:00:00.000Z");
expect(context.isUnreadForMe).toBe(true);
});
it("uses issue updated time as fallback touch point for assignee", () => {
const context = deriveIssueUserContext(
makeIssue({ assigneeUserId: "user-1", updatedAt: new Date("2026-03-06T15:00:00.000Z") }),
"user-1",
{
myLastCommentAt: null,
lastExternalCommentAt: new Date("2026-03-06T14:59:00.000Z"),
},
);
expect(context.myLastTouchAt?.toISOString()).toBe("2026-03-06T15:00:00.000Z");
expect(context.isUnreadForMe).toBe(false);
});
});