42 lines
2.4 KiB
TypeScript
42 lines
2.4 KiB
TypeScript
import { readFileSync } from "node:fs";
|
|
import { runInNewContext } from "node:vm";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
|
|
function worker() {
|
|
const handlers: Record<string, (event: unknown) => void> = {};
|
|
const self = { addEventListener: (name: string, callback: (event: unknown) => void) => { handlers[name] = callback; },
|
|
location: { origin: "https://guide.example.test" },
|
|
registration: { showNotification: vi.fn().mockResolvedValue(undefined) },
|
|
clients: { matchAll: vi.fn().mockResolvedValue([]), openWindow: vi.fn().mockResolvedValue(undefined) } };
|
|
runInNewContext(readFileSync("public/commission-push-sw.js", "utf8"), { self, URL });
|
|
return { self, handlers };
|
|
}
|
|
describe("reply notification navigation", () => {
|
|
it("opens the exact root thread and reply from the notification", async () => {
|
|
const { self, handlers } = worker();
|
|
const url = "/guide/comment?reply=reply-id#comment-root-id";
|
|
let task: Promise<unknown> | undefined;
|
|
const close = vi.fn();
|
|
handlers.notificationclick({ notification: { close, data: { url } }, waitUntil: (promise: Promise<unknown>) => { task = promise; } });
|
|
await task;
|
|
expect(close).toHaveBeenCalled();
|
|
expect(self.clients.openWindow).toHaveBeenCalledWith(`https://guide.example.test${url}`);
|
|
});
|
|
it("opens the admin inbox at the notified comment", async () => {
|
|
const { self, handlers } = worker();
|
|
const url = "/admin/comments?target=stygian%3A123&comment=comment-id";
|
|
let task: Promise<unknown> | undefined;
|
|
handlers.notificationclick({ notification: { close: vi.fn(), data: { url } }, waitUntil: (promise: Promise<unknown>) => { task = promise; } });
|
|
await task;
|
|
expect(self.clients.openWindow).toHaveBeenCalledWith(`https://guide.example.test${url}`);
|
|
});
|
|
it("uses the comment icon and rejects off-site notification destinations", async () => {
|
|
const { self, handlers } = worker();
|
|
const message = { id: "comment-id", title: "Reply", body: "Text", icon: "/icon/nav/Comment.webp", url: "/guide/comment#comment-root" };
|
|
handlers.push({ data: { json: () => message }, waitUntil: () => {} });
|
|
expect(self.registration.showNotification).toHaveBeenCalledWith("Reply", expect.objectContaining({ icon: message.icon, data: { url: message.url } }));
|
|
handlers.notificationclick({ notification: { close: vi.fn(), data: { url: "https://evil.example" } }, waitUntil: vi.fn() });
|
|
expect(self.clients.openWindow).not.toHaveBeenCalled();
|
|
});
|
|
});
|