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
@@ -38,4 +38,10 @@ describe("reply notification navigation", () => {
handlers.notificationclick({ notification: { close: vi.fn(), data: { url: "https://evil.example" } }, waitUntil: vi.fn() });
expect(self.clients.openWindow).not.toHaveBeenCalled();
});
it("displays the comment author's profile picture supplied by the push sender", () => {
const { self, handlers } = worker();
const icon = "https://profile.example/author.png";
handlers.push({ data: { json: () => ({ id: "comment-id", title: "New comment", body: "Text", icon, url: "/admin/comments" }) }, waitUntil: () => {} });
expect(self.registration.showNotification).toHaveBeenCalledWith("New comment", expect.objectContaining({ icon }));
});
});
+4 -1
View File
@@ -544,11 +544,13 @@ describeDatabase("guide comments against PostgreSQL", { timeout: 30000 }, () =>
expect(pushTransport.sendNotification).not.toHaveBeenCalled();
});
it("persists comment notifications without push permission and keeps history scoped to its owner", async () => {
const authorImage = "https://profile.example/comment-author.png";
await getDb().update(schema.users).set({ image: authorImage }).where(eq(schema.users.id, author.id));
const root = await post("Bell root");
await sendCommentPush(root.id);
const adminUser = { ...admin, role: "admin", emailVerified: true };
const authorUser = { ...author, role: "user", emailVerified: true };
expect((await listNotifications(adminUser)).items[0]).toMatchObject({ commentId: root.id, kind: "comment_new", readAt: null });
expect((await listNotifications(adminUser)).items[0]).toMatchObject({ commentId: root.id, kind: "comment_new", readAt: null, authorName: "Reader", authorImage });
expect((await listNotifications(authorUser)).unread).toBe(0);
const reply = await publishComment(request("Bell reply", { reply: root.id }), other, { target });
const key = process.env.WEB_PUSH_PUBLIC_KEY;
@@ -556,6 +558,7 @@ describeDatabase("guide comments against PostgreSQL", { timeout: 30000 }, () =>
try { await sendCommentPush(reply.id); await sendCommentPush(reply.id); } finally { process.env.WEB_PUSH_PUBLIC_KEY = key; }
const inbox = await listNotifications(authorUser);
expect(inbox.unread).toBe(1); expect(inbox.items).toHaveLength(1);
expect(inbox.items[0]).toMatchObject({ authorName: "Reader", authorImage: null });
await readNotifications(other.id, inbox.items[0].id);
expect((await listNotifications(authorUser)).unread).toBe(1);
await readNotifications(author.id, inbox.items[0].id);