You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

217 lines
6.4 KiB

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);
});
});
});