mirror of
https://git.quad4.io/RNS-Things/MeshChatX.git
synced 2026-09-01 20:28:25 +00:00
feat(NotificationUtils): add comprehensive tests for notification handling across Electron, Android, and browser fallback
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import NotificationUtils from "../../meshchatx/src/frontend/js/NotificationUtils";
|
||||
|
||||
describe("NotificationUtils", () => {
|
||||
let originalNotification;
|
||||
let electronMock;
|
||||
let androidMock;
|
||||
|
||||
beforeEach(() => {
|
||||
originalNotification = globalThis.Notification;
|
||||
electronMock = { showNotification: vi.fn() };
|
||||
androidMock = {
|
||||
getPlatform: vi.fn().mockReturnValue("android"),
|
||||
showNotification: vi.fn(),
|
||||
showIncomingCallNotification: vi.fn(),
|
||||
showMissedCallNotification: vi.fn(),
|
||||
cancelIncomingCallNotification: vi.fn(),
|
||||
};
|
||||
globalThis.Notification = vi.fn(function (title, opts) {
|
||||
return { title, opts };
|
||||
});
|
||||
globalThis.Notification.requestPermission = vi.fn().mockResolvedValue("granted");
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
globalThis.Notification = originalNotification;
|
||||
delete globalThis.electron;
|
||||
delete globalThis.MeshChatXAndroid;
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("Electron", () => {
|
||||
beforeEach(() => {
|
||||
globalThis.electron = electronMock;
|
||||
});
|
||||
|
||||
it("showNewMessageNotification delegates to electron", () => {
|
||||
NotificationUtils.showNewMessageNotification("Alice", "hello");
|
||||
expect(electronMock.showNotification).toHaveBeenCalledWith("New Message", "Alice: hello");
|
||||
});
|
||||
|
||||
it("showIncomingCallNotification delegates to electron", () => {
|
||||
NotificationUtils.showIncomingCallNotification("Bob");
|
||||
expect(electronMock.showNotification).toHaveBeenCalledWith("Incoming Call", "Bob is calling you.");
|
||||
});
|
||||
|
||||
it("showMissedCallNotification delegates to electron", () => {
|
||||
NotificationUtils.showMissedCallNotification("Charlie");
|
||||
expect(electronMock.showNotification).toHaveBeenCalledWith(
|
||||
"Missed Call",
|
||||
"You missed a call from Charlie."
|
||||
);
|
||||
});
|
||||
|
||||
it("showNewVoicemailNotification delegates to electron", () => {
|
||||
NotificationUtils.showNewVoicemailNotification("Dave");
|
||||
expect(electronMock.showNotification).toHaveBeenCalledWith(
|
||||
"New Voicemail",
|
||||
"You have a new voicemail from Dave."
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Android", () => {
|
||||
beforeEach(() => {
|
||||
globalThis.MeshChatXAndroid = androidMock;
|
||||
});
|
||||
|
||||
it("showNewMessageNotification delegates to Android bridge", () => {
|
||||
NotificationUtils.showNewMessageNotification("Alice", "hello");
|
||||
expect(androidMock.showNotification).toHaveBeenCalledWith("New Message", "Alice: hello");
|
||||
});
|
||||
|
||||
it("showIncomingCallNotification delegates to Android bridge", () => {
|
||||
NotificationUtils.showIncomingCallNotification("Bob");
|
||||
expect(androidMock.showIncomingCallNotification).toHaveBeenCalledWith("Bob");
|
||||
});
|
||||
|
||||
it("showMissedCallNotification delegates to Android bridge", () => {
|
||||
NotificationUtils.showMissedCallNotification("Charlie");
|
||||
expect(androidMock.showMissedCallNotification).toHaveBeenCalledWith(
|
||||
"Missed Call",
|
||||
"You missed a call from Charlie."
|
||||
);
|
||||
});
|
||||
|
||||
it("showNewVoicemailNotification delegates to Android bridge", () => {
|
||||
NotificationUtils.showNewVoicemailNotification("Dave");
|
||||
expect(androidMock.showNotification).toHaveBeenCalledWith(
|
||||
"New Voicemail",
|
||||
"You have a new voicemail from Dave."
|
||||
);
|
||||
});
|
||||
|
||||
it("cancelIncomingCallNotification delegates to Android bridge", () => {
|
||||
NotificationUtils.cancelIncomingCallNotification();
|
||||
expect(androidMock.cancelIncomingCallNotification).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe("Browser fallback", () => {
|
||||
it("showNewMessageNotification uses browser Notification API", async () => {
|
||||
NotificationUtils.showNewMessageNotification("Alice", "hello");
|
||||
await new Promise((r) => setTimeout(r, 10));
|
||||
expect(globalThis.Notification).toHaveBeenCalledWith(
|
||||
"New Message",
|
||||
expect.objectContaining({ body: "Alice: hello" })
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("_isAndroid detection", () => {
|
||||
it("returns false when MeshChatXAndroid is missing", () => {
|
||||
expect(NotificationUtils._isAndroid()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when getPlatform returns non-android", () => {
|
||||
globalThis.MeshChatXAndroid = { getPlatform: () => "ios" };
|
||||
expect(NotificationUtils._isAndroid()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns true when getPlatform returns android", () => {
|
||||
globalThis.MeshChatXAndroid = androidMock;
|
||||
expect(NotificationUtils._isAndroid()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -99,4 +99,12 @@ describe("Toast.vue", () => {
|
||||
const toast = wrapper.find(".pointer-events-auto");
|
||||
expect(toast.find("button").exists()).toBe(true);
|
||||
});
|
||||
|
||||
it("positions container with mobile-safe bottom offset", () => {
|
||||
const container = wrapper.find("[class*='fixed']");
|
||||
expect(container.exists()).toBe(true);
|
||||
const cls = container.classes().join(" ");
|
||||
expect(cls).toContain("max-sm:bottom-");
|
||||
expect(cls).not.toContain("max-sm:bottom-[calc(5.75rem");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user