96 lines
3.5 KiB
TypeScript
96 lines
3.5 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
|
const getSubscriptionMock = vi.hoisted(() => vi.fn());
|
|
const claimNotificationsMock = vi.hoisted(() => vi.fn());
|
|
const acknowledgeNotificationsMock = vi.hoisted(() => vi.fn());
|
|
const getTokenMock = vi.hoisted(() => vi.fn());
|
|
const getPermissionMock = vi.hoisted(() => vi.fn());
|
|
const showNotificationMock = vi.hoisted(() => vi.fn());
|
|
|
|
vi.mock("../api/desktopNotifications", () => ({
|
|
getDesktopNotificationSubscription: getSubscriptionMock,
|
|
claimDesktopNotifications: claimNotificationsMock,
|
|
acknowledgeDesktopNotifications: acknowledgeNotificationsMock,
|
|
}));
|
|
|
|
vi.mock("../utils/auth", () => ({
|
|
getToken: getTokenMock,
|
|
}));
|
|
|
|
vi.mock("../runtime", () => ({
|
|
getNotificationPermission: getPermissionMock,
|
|
isTauriRuntime: () => true,
|
|
showSystemNotification: showNotificationMock,
|
|
}));
|
|
|
|
describe("desktop notification manager", () => {
|
|
beforeEach(() => {
|
|
vi.useFakeTimers();
|
|
getTokenMock.mockReturnValue("session-token");
|
|
getPermissionMock.mockResolvedValue("granted");
|
|
getSubscriptionMock.mockResolvedValue({ data: { enabled: true } });
|
|
claimNotificationsMock.mockResolvedValue({
|
|
data: {
|
|
claim_token: "claim-token",
|
|
items: [
|
|
{ id: "notification-1" },
|
|
{ id: "notification-2" },
|
|
],
|
|
},
|
|
});
|
|
acknowledgeNotificationsMock.mockResolvedValue({ data: {} });
|
|
showNotificationMock.mockResolvedValue(true);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
const { stopDesktopNotificationManager } = await import("./desktopNotificationManager");
|
|
stopDesktopNotificationManager();
|
|
vi.clearAllTimers();
|
|
vi.useRealTimers();
|
|
vi.resetModules();
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
it("acknowledges displayed notifications and leaves failed deliveries for retry", async () => {
|
|
showNotificationMock
|
|
.mockResolvedValueOnce(true)
|
|
.mockRejectedValueOnce(new Error("notification failed"));
|
|
const { initDesktopNotificationManager, triggerDesktopNotificationPoll } = await import("./desktopNotificationManager");
|
|
|
|
initDesktopNotificationManager();
|
|
triggerDesktopNotificationPoll();
|
|
await vi.runOnlyPendingTimersAsync();
|
|
|
|
expect(showNotificationMock).toHaveBeenCalledTimes(2);
|
|
expect(acknowledgeNotificationsMock).toHaveBeenCalledWith("claim-token", ["notification-1"]);
|
|
expect(acknowledgeNotificationsMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("does not acknowledge notifications when the system dispatch does not happen", async () => {
|
|
showNotificationMock
|
|
.mockResolvedValueOnce(false)
|
|
.mockResolvedValueOnce(true);
|
|
const { initDesktopNotificationManager, triggerDesktopNotificationPoll } = await import("./desktopNotificationManager");
|
|
|
|
initDesktopNotificationManager();
|
|
triggerDesktopNotificationPoll();
|
|
await vi.runOnlyPendingTimersAsync();
|
|
|
|
expect(showNotificationMock).toHaveBeenCalledTimes(2);
|
|
expect(acknowledgeNotificationsMock).toHaveBeenCalledWith("claim-token", ["notification-2"]);
|
|
expect(acknowledgeNotificationsMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("does not claim notifications before operating system permission is granted", async () => {
|
|
getPermissionMock.mockResolvedValue("prompt");
|
|
const { initDesktopNotificationManager, triggerDesktopNotificationPoll } = await import("./desktopNotificationManager");
|
|
|
|
initDesktopNotificationManager();
|
|
triggerDesktopNotificationPoll();
|
|
await vi.runOnlyPendingTimersAsync();
|
|
|
|
expect(claimNotificationsMock).not.toHaveBeenCalled();
|
|
expect(acknowledgeNotificationsMock).not.toHaveBeenCalled();
|
|
});
|
|
});
|