amical/apps/desktop/tests/helpers/electron-mocks.ts
2025-11-12 17:10:28 +05:30

396 lines
9.5 KiB
TypeScript

import { vi } from "vitest";
import { EventEmitter } from "events";
import path from "node:path";
import os from "node:os";
// Create a fake BrowserWindow class
class FakeBrowserWindow extends EventEmitter {
id: number;
webContents: any;
private _isDestroyed = false;
private _bounds = { x: 0, y: 0, width: 800, height: 600 };
private _isVisible = false;
private _isMinimized = false;
private _isMaximized = false;
private _isFocused = false;
private _isFullScreen = false;
constructor(options?: any) {
super();
this.id = Math.floor(Math.random() * 1000000);
// Mock webContents
this.webContents = {
send: vi.fn(),
on: vi.fn(),
once: vi.fn(),
removeListener: vi.fn(),
session: {
clearCache: vi.fn().mockResolvedValue(undefined),
clearStorageData: vi.fn().mockResolvedValue(undefined),
},
openDevTools: vi.fn(),
closeDevTools: vi.fn(),
isDevToolsOpened: vi.fn().mockReturnValue(false),
executeJavaScript: vi.fn().mockResolvedValue(undefined),
setWindowOpenHandler: vi.fn(),
setBackgroundThrottling: vi.fn(),
};
}
loadURL(url: string) {
return Promise.resolve();
}
loadFile(filePath: string) {
return Promise.resolve();
}
show() {
this._isVisible = true;
}
hide() {
this._isVisible = false;
}
close() {
this._isDestroyed = true;
this.emit("closed");
}
destroy() {
this._isDestroyed = true;
}
isDestroyed() {
return this._isDestroyed;
}
isVisible() {
return this._isVisible;
}
isMinimized() {
return this._isMinimized;
}
isMaximized() {
return this._isMaximized;
}
isFocused() {
return this._isFocused;
}
isFullScreen() {
return this._isFullScreen;
}
focus() {
this._isFocused = true;
}
blur() {
this._isFocused = false;
}
minimize() {
this._isMinimized = true;
}
maximize() {
this._isMaximized = true;
}
restore() {
this._isMinimized = false;
this._isMaximized = false;
}
setFullScreen(flag: boolean) {
this._isFullScreen = flag;
}
getBounds() {
return { ...this._bounds };
}
setBounds(bounds: Partial<typeof this._bounds>) {
this._bounds = { ...this._bounds, ...bounds };
}
setSize(width: number, height: number) {
this._bounds.width = width;
this._bounds.height = height;
}
setPosition(x: number, y: number) {
this._bounds.x = x;
this._bounds.y = y;
}
center() {
// Mock centering
}
setResizable(resizable: boolean) {}
setMovable(movable: boolean) {}
setMinimizable(minimizable: boolean) {}
setMaximizable(maximizable: boolean) {}
setFullScreenable(fullscreenable: boolean) {}
setClosable(closable: boolean) {}
setAlwaysOnTop(flag: boolean, level?: string) {}
setVisibleOnAllWorkspaces(visible: boolean) {}
setIgnoreMouseEvents(ignore: boolean) {}
setContentProtection(enable: boolean) {}
setFocusable(focusable: boolean) {}
setParentWindow(parent: any) {}
setTitle(title: string) {}
setTitleBarOverlay(options: any) {}
setOpacity(opacity: number) {}
setShape(rects: any[]) {}
setSkipTaskbar(skip: boolean) {}
setMenu(menu: any) {}
setAutoHideMenuBar(hide: boolean) {}
setMenuBarVisibility(visible: boolean) {}
setAspectRatio(aspectRatio: number) {}
setBackgroundColor(color: string) {}
setHasShadow(hasShadow: boolean) {}
setRepresentedFilename(filename: string) {}
setDocumentEdited(edited: boolean) {}
setIcon(icon: any) {}
setProgressBar(progress: number) {}
setOverlayIcon(overlay: any, description: string) {}
setThumbarButtons(buttons: any[]) {}
setThumbnailClip(region: any) {}
setThumbnailToolTip(toolTip: string) {}
setAppDetails(options: any) {}
setVibrancy(type: string) {}
setWindowButtonVisibility(visible: boolean) {}
setTrafficLightPosition(position: { x: number; y: number }) {}
// Mock methods that return values
getTitle() {
return "Test Window";
}
getNativeWindowHandle() {
return Buffer.from("test");
}
getMediaSourceId() {
return "test-id";
}
}
// Create test directories
const testUserDataPath = path.join(os.tmpdir(), "amical-test-" + Date.now());
const testAppPath = process.cwd();
// Mock app object
const mockApp = {
getPath: vi.fn((name: string) => {
const paths: Record<string, string> = {
userData: testUserDataPath,
appData: testUserDataPath,
temp: os.tmpdir(),
home: os.homedir(),
documents: path.join(os.homedir(), "Documents"),
downloads: path.join(os.homedir(), "Downloads"),
desktop: path.join(os.homedir(), "Desktop"),
music: path.join(os.homedir(), "Music"),
pictures: path.join(os.homedir(), "Pictures"),
videos: path.join(os.homedir(), "Videos"),
logs: path.join(testUserDataPath, "logs"),
crashDumps: path.join(testUserDataPath, "crashDumps"),
};
return paths[name] || testUserDataPath;
}),
getName: vi.fn(() => "Amical"),
getVersion: vi.fn(() => "0.1.0-test"),
isPackaged: false,
isReady: vi.fn(() => true),
whenReady: vi.fn(() => Promise.resolve()),
quit: vi.fn(),
exit: vi.fn(),
relaunch: vi.fn(),
focus: vi.fn(),
hide: vi.fn(),
show: vi.fn(),
setName: vi.fn(),
setPath: vi.fn(),
getLocale: vi.fn(() => "en-US"),
getLocaleCountryCode: vi.fn(() => "US"),
getSystemLocale: vi.fn(() => "en-US"),
on: vi.fn(),
once: vi.fn(),
removeListener: vi.fn(),
removeAllListeners: vi.fn(),
emit: vi.fn(),
setLoginItemSettings: vi.fn(),
getLoginItemSettings: vi.fn(() => ({ openAtLogin: false })),
};
// Mock ipcMain
const mockIpcMain = {
handle: vi.fn(),
on: vi.fn(),
once: vi.fn(),
removeHandler: vi.fn(),
removeListener: vi.fn(),
removeAllListeners: vi.fn(),
emit: vi.fn(),
};
// Mock screen
const mockScreen = {
getPrimaryDisplay: vi.fn(() => ({
id: 1,
bounds: { x: 0, y: 0, width: 1920, height: 1080 },
workArea: { x: 0, y: 0, width: 1920, height: 1040 },
size: { width: 1920, height: 1080 },
workAreaSize: { width: 1920, height: 1040 },
scaleFactor: 1,
rotation: 0,
internal: false,
})),
getAllDisplays: vi.fn(() => [
{
id: 1,
bounds: { x: 0, y: 0, width: 1920, height: 1080 },
workArea: { x: 0, y: 0, width: 1920, height: 1040 },
size: { width: 1920, height: 1080 },
workAreaSize: { width: 1920, height: 1040 },
scaleFactor: 1,
rotation: 0,
internal: false,
},
]),
getCursorScreenPoint: vi.fn(() => ({ x: 100, y: 100 })),
getDisplayNearestPoint: vi.fn(() => ({
id: 1,
bounds: { x: 0, y: 0, width: 1920, height: 1080 },
workArea: { x: 0, y: 0, width: 1920, height: 1040 },
size: { width: 1920, height: 1080 },
workAreaSize: { width: 1920, height: 1040 },
scaleFactor: 1,
rotation: 0,
internal: false,
})),
on: vi.fn(),
removeListener: vi.fn(),
};
// Mock systemPreferences
const mockSystemPreferences = {
getMediaAccessStatus: vi.fn(() => "granted"),
askForMediaAccess: vi.fn(() => Promise.resolve(true)),
isTrustedAccessibilityClient: vi.fn(() => true),
getColor: vi.fn(() => "#000000"),
on: vi.fn(),
removeListener: vi.fn(),
};
// Mock nativeTheme
const mockNativeTheme = {
shouldUseDarkColors: false,
themeSource: "system" as const,
on: vi.fn(),
removeListener: vi.fn(),
};
// Mock Menu
const mockMenu = {
buildFromTemplate: vi.fn(() => ({})),
setApplicationMenu: vi.fn(),
getApplicationMenu: vi.fn(() => null),
};
// Mock Tray
class FakeTray extends EventEmitter {
constructor(image: any) {
super();
}
setToolTip(toolTip: string) {}
setTitle(title: string) {}
setImage(image: any) {}
setContextMenu(menu: any) {}
destroy() {}
isDestroyed() {
return false;
}
}
// Mock dialog
const mockDialog = {
showOpenDialog: vi.fn(() =>
Promise.resolve({ canceled: false, filePaths: [] }),
),
showSaveDialog: vi.fn(() =>
Promise.resolve({ canceled: false, filePath: "" }),
),
showMessageBox: vi.fn(() => Promise.resolve({ response: 0 })),
showErrorBox: vi.fn(),
showCertificateTrustDialog: vi.fn(() => Promise.resolve()),
};
// Mock shell
const mockShell = {
openExternal: vi.fn(() => Promise.resolve()),
openPath: vi.fn(() => Promise.resolve("")),
showItemInFolder: vi.fn(),
openItem: vi.fn(() => Promise.resolve(true)),
moveItemToTrash: vi.fn(() => Promise.resolve(true)),
beep: vi.fn(),
writeShortcutLink: vi.fn(() => true),
readShortcutLink: vi.fn(() => ({})),
};
// Mock globalShortcut
const mockGlobalShortcut = {
register: vi.fn(() => true),
registerAll: vi.fn(),
isRegistered: vi.fn(() => false),
unregister: vi.fn(),
unregisterAll: vi.fn(),
};
// Mock clipboard
const mockClipboard = {
readText: vi.fn(() => ""),
writeText: vi.fn(),
readHTML: vi.fn(() => ""),
writeHTML: vi.fn(),
readImage: vi.fn(() => ({})),
writeImage: vi.fn(),
clear: vi.fn(),
availableFormats: vi.fn(() => []),
};
// Mock nativeImage
const mockNativeImage = {
createEmpty: vi.fn(() => ({})),
createFromPath: vi.fn(() => ({})),
createFromBuffer: vi.fn(() => ({})),
createFromDataURL: vi.fn(() => ({})),
};
export function createElectronMocks() {
return {
app: mockApp,
ipcMain: mockIpcMain,
BrowserWindow: FakeBrowserWindow as any,
screen: mockScreen,
systemPreferences: mockSystemPreferences,
nativeTheme: mockNativeTheme,
Menu: mockMenu,
Tray: FakeTray as any,
dialog: mockDialog,
shell: mockShell,
globalShortcut: mockGlobalShortcut,
clipboard: mockClipboard,
nativeImage: mockNativeImage,
};
}
// Export test user data path for cleanup
export const TEST_USER_DATA_PATH = testUserDataPath;