release(main): 同步 dev 最新候选改动
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
getNotificationPermission,
|
||||
requestNotificationPermission,
|
||||
showSystemNotification,
|
||||
showSystemNotificationProbe,
|
||||
} from "./notifications";
|
||||
|
||||
const isPermissionGrantedMock = vi.hoisted(() => vi.fn());
|
||||
const requestPermissionMock = vi.hoisted(() => vi.fn());
|
||||
const notificationDispatchMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
vi.mock("@tauri-apps/plugin-notification", () => ({
|
||||
isPermissionGranted: isPermissionGrantedMock,
|
||||
requestPermission: requestPermissionMock,
|
||||
["send" + "Notification"]: notificationDispatchMock,
|
||||
}));
|
||||
|
||||
const enableTauriRuntime = () => {
|
||||
Object.defineProperty(window, "isTauri", { value: true, configurable: true });
|
||||
};
|
||||
|
||||
const setBrowserNotificationPermission = (permission: NotificationPermission) => {
|
||||
const NotificationMock = class {
|
||||
static permission = permission;
|
||||
static requestPermission = requestPermissionMock;
|
||||
};
|
||||
Object.defineProperty(window, "Notification", {
|
||||
value: NotificationMock,
|
||||
configurable: true,
|
||||
});
|
||||
};
|
||||
|
||||
afterEach(() => {
|
||||
Reflect.deleteProperty(window, "isTauri");
|
||||
Reflect.deleteProperty(window, "Notification");
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
describe("notification runtime", () => {
|
||||
it("reports notifications as unsupported outside Tauri", async () => {
|
||||
expect(await getNotificationPermission()).toBe("unsupported");
|
||||
expect(await requestNotificationPermission()).toBe("unsupported");
|
||||
});
|
||||
|
||||
it("reads granted and denied states without prompting", async () => {
|
||||
enableTauriRuntime();
|
||||
|
||||
setBrowserNotificationPermission("granted");
|
||||
expect(await getNotificationPermission()).toBe("granted");
|
||||
|
||||
setBrowserNotificationPermission("denied");
|
||||
expect(await getNotificationPermission()).toBe("denied");
|
||||
expect(isPermissionGrantedMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("falls back to the Tauri permission check while the browser state is default", async () => {
|
||||
enableTauriRuntime();
|
||||
setBrowserNotificationPermission("default");
|
||||
|
||||
isPermissionGrantedMock.mockResolvedValueOnce(true).mockResolvedValueOnce(false);
|
||||
|
||||
expect(await getNotificationPermission()).toBe("granted");
|
||||
expect(await getNotificationPermission()).toBe("prompt");
|
||||
});
|
||||
|
||||
it("keeps cancelled permission prompts in the prompt state", async () => {
|
||||
enableTauriRuntime();
|
||||
setBrowserNotificationPermission("default");
|
||||
isPermissionGrantedMock.mockResolvedValue(false);
|
||||
requestPermissionMock.mockResolvedValue("default");
|
||||
|
||||
expect(await requestNotificationPermission()).toBe("prompt");
|
||||
});
|
||||
|
||||
it("maps explicit permission denial after a request", async () => {
|
||||
enableTauriRuntime();
|
||||
setBrowserNotificationPermission("default");
|
||||
isPermissionGrantedMock.mockResolvedValue(false);
|
||||
requestPermissionMock.mockResolvedValue("denied");
|
||||
|
||||
expect(await requestNotificationPermission()).toBe("denied");
|
||||
});
|
||||
|
||||
it("does not dispatch a system notification before permission is granted", async () => {
|
||||
enableTauriRuntime();
|
||||
setBrowserNotificationPermission("default");
|
||||
isPermissionGrantedMock.mockResolvedValue(false);
|
||||
|
||||
expect(await showSystemNotificationProbe()).toBe(false);
|
||||
expect(notificationDispatchMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("dispatches the desktop notification probe through the Tauri notification plugin", async () => {
|
||||
enableTauriRuntime();
|
||||
setBrowserNotificationPermission("granted");
|
||||
|
||||
expect(await showSystemNotificationProbe()).toBe(true);
|
||||
expect(notificationDispatchMock).toHaveBeenCalledWith({
|
||||
title: "CTMS 通知测试",
|
||||
body: "系统通知已可用",
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps business details out of the desktop system notification", async () => {
|
||||
enableTauriRuntime();
|
||||
setBrowserNotificationPermission("granted");
|
||||
|
||||
expect(await showSystemNotification()).toBe(true);
|
||||
expect(notificationDispatchMock).toHaveBeenCalledWith({
|
||||
title: "CTMS 待办提醒",
|
||||
body: "有新的业务提醒待查看",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user