import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { buyHabibCoinPackages, copyToClipboard, downloadFile, isInFlutterWebView, openConsultantPage, openExternalUrl, postActionToFlutter, uploadFile, } from "./webview-actions"; describe("webview-actions", () => { const originalHabibApp = window.HabibApp; beforeEach(() => { vi.restoreAllMocks(); }); afterEach(() => { window.HabibApp = originalHabibApp; }); describe("isInFlutterWebView", () => { it("returns true when window.HabibApp.postMessage is defined", () => { window.HabibApp = { postMessage: vi.fn() }; expect(isInFlutterWebView()).toBe(true); }); it("returns false when window.HabibApp is undefined", () => { delete (window as any).HabibApp; expect(isInFlutterWebView()).toBe(false); }); }); describe("postActionToFlutter", () => { it("sends message without data when data is omitted", () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = postActionToFlutter("custom_action"); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledTimes(1); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "custom_action" }), ); }); it("sends message with data when data is provided", () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = postActionToFlutter("custom_action", { foo: "bar" }); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "custom_action", data: { foo: "bar" } }), ); }); it("returns false and does not throw when not in flutter webview", () => { delete (window as any).HabibApp; const result = postActionToFlutter("custom_action"); expect(result).toBe(false); }); }); describe("buyHabibCoinPackages", () => { it("dispatches buy_coin action to Flutter and returns true", () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = buyHabibCoinPackages(); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledTimes(1); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "buy_coin" }), ); }); it("returns false when not running in Flutter WebView", () => { delete (window as any).HabibApp; const result = buyHabibCoinPackages(); expect(result).toBe(false); }); }); describe("downloadFile", () => { it("dispatches download_file action with options", () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = downloadFile({ url: "https://example.com/file.pdf", fileName: "file.pdf", mimeType: "application/pdf", fileType: "document", }); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "download_file", data: { url: "https://example.com/file.pdf", fileName: "file.pdf", mimeType: "application/pdf", fileType: "document", }, }), ); }); }); describe("copyToClipboard", () => { it("dispatches copy_to_clipboard in Flutter WebView", async () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = await copyToClipboard("sample text", "invite_code"); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "copy_to_clipboard", data: { text: "sample text", label: "invite_code", showToast: true, }, }), ); }); it("falls back to navigator.clipboard.writeText when outside WebView", async () => { delete (window as any).HabibApp; const writeTextMock = vi.fn().mockResolvedValue(undefined); Object.assign(navigator, { clipboard: { writeText: writeTextMock }, }); const result = await copyToClipboard("sample text"); expect(result).toBe(true); expect(writeTextMock).toHaveBeenCalledWith("sample text"); }); }); describe("openExternalUrl", () => { it("dispatches open_external_url action to Flutter", () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = openExternalUrl({ url: "https://habibapp.com" }); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "open_external_url", data: { mode: "externalApplication", showErrorToast: true, url: "https://habibapp.com", }, }), ); }); }); describe("uploadFile", () => { it("dispatches upload_file action with options to Flutter", () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = uploadFile({ mediaType: "image", source: "gallery", returnAs: "upload", uploadUrl: "/api/upload", }); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "upload_file", data: { mediaType: "image", source: "gallery", returnAs: "upload", uploadUrl: "/api/upload", }, }), ); }); }); describe("openConsultantPage", () => { it("dispatches open_consultant_page action with username", () => { const mockPostMessage = vi.fn(); window.HabibApp = { postMessage: mockPostMessage }; const result = openConsultantPage("sara_marriage_advisor"); expect(result).toBe(true); expect(mockPostMessage).toHaveBeenCalledWith( JSON.stringify({ action: "open_consultant_page", data: { consultant: "sara_marriage_advisor", }, }), ); }); it("returns false when not in flutter webview", () => { delete (window as any).HabibApp; const result = openConsultantPage("sara_marriage_advisor"); expect(result).toBe(false); }); }); });