feat(notifications) : add profile pictures and guide previews

This commit is contained in:
2026-10-12 23:58:58 +07:00 Unverified
parent 05350e7aab
commit 28517d9b29
10 changed files with 178 additions and 16 deletions
+15 -3
View File
@@ -55,19 +55,20 @@ describe("comment notifications", () => {
expect(state.send).not.toHaveBeenCalled();
});
it.each([false, true])("still sends new-comment notifications (reply: %s)", async (reply) => {
it.each([false, true])("still sends new-comment notifications with the author's profile picture (reply: %s)", async (reply) => {
const recipient = { id: reply ? "reader" : "admin", admin: !reply };
state.rows = [
[{ id, version: 1, hidden: false, deletedAt: null, authorId: "author", replyToId: reply ? "parent-id" : null, rootId: reply ? "root-id" : null }],
...(reply ? [[{ authorId: recipient.id, hidden: false, deletedAt: null }], [{ id: recipient.id, role: "user", banned: false }]] : [[{ id: recipient.id }]]),
[{ name: "Author" }], [{ text: "Original comment" }], [subscription],
[{ name: "Author", image: "https://profile.example/author.png" }], [{ text: "Original comment" }], [subscription],
];
await sendCommentPush(id, 1);
expect(state.notifications).toHaveBeenCalledWith([expect.objectContaining({ userId: recipient.id, adminOnly: !reply })], expect.objectContaining({
kind: reply ? "comment_reply" : "comment_new", eventKey: `comment:${id}`, body: "Original comment",
}));
expect(state.send).toHaveBeenCalledTimes(1);
expect(JSON.parse(state.send.mock.calls[0][1])).toMatchObject({ body: "Original comment" });
expect(JSON.parse(state.send.mock.calls[0][1])).toMatchObject({ body: "Original comment", icon: "https://profile.example/author.png" });
expect(state.notifications.mock.calls[0][1].title).toBe(reply ? "Author ตอบกลับความคิดเห็นของคุณ" : "Author แสดงความคิดเห็นใหม่ในไกด์ Test Guide");
});
it("still delivers a delayed initial notification when the comment has since been edited", async () => {
@@ -78,6 +79,17 @@ describe("comment notifications", () => {
await sendCommentPush(id, 1);
expect(state.notifications).toHaveBeenCalledWith(expect.any(Array), expect.objectContaining({ kind: "comment_new", body: "Original revision" }));
expect(state.send).toHaveBeenCalledTimes(1);
expect(JSON.parse(state.send.mock.calls[0][1]).icon).toBe("/icon/nav/Comment.webp");
});
it("keeps Stygian notification titles separate from guide titles", async () => {
state.authorize.mockResolvedValue({ destination: { target: "stygian:123", href: "/stygian/comment", name: "Test round", writable: true } });
state.rows = [
[{ id, version: 1, hidden: false, deletedAt: null, authorId: "author", replyToId: null }],
[{ id: "admin" }], [{ name: "Author" }], [{ text: "Original comment" }], [subscription],
];
await sendCommentPush(id, 1);
expect(state.notifications.mock.calls[0][1].title).toBe("Author แสดงความคิดเห็นใหม่ใน Test round");
});
it("saves edits through PATCH without scheduling a notification", async () => {