UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

195 lines (167 loc) 8.06 kB
import { beforeEach, describe, expect, it, vi, Mock } from 'vitest'; import { InterceptRouteParams } from '@lobechat/electron-client-ipc'; import type { App } from '@/core/App'; import type { IpcClientEventSender } from '@/types/ipcClientEvent'; import { BrowsersIdentifiers, AppBrowsersIdentifiers } from '@/appBrowsers'; import BrowserWindowsCtr from '../BrowserWindowsCtr'; // 模拟 App 及其依赖项 const mockToggleVisible = vi.fn(); const mockShowSettingsWindowWithTab = vi.fn(); const mockCloseWindow = vi.fn(); const mockMinimizeWindow = vi.fn(); const mockMaximizeWindow = vi.fn(); const mockRetrieveByIdentifier = vi.fn(); const mockGetMainWindow = vi.fn(() => ({ toggleVisible: mockToggleVisible, })); const mockShow = vi.fn(); // mock findMatchingRoute and extractSubPath vi.mock('~common/routes', async () => ({ findMatchingRoute: vi.fn(), extractSubPath: vi.fn(), })); const { findMatchingRoute, extractSubPath } = await import('~common/routes'); const mockApp = { browserManager: { getMainWindow: mockGetMainWindow, showSettingsWindowWithTab: mockShowSettingsWindowWithTab, closeWindow: mockCloseWindow, minimizeWindow: mockMinimizeWindow, maximizeWindow: mockMaximizeWindow, retrieveByIdentifier: mockRetrieveByIdentifier.mockImplementation((identifier: AppBrowsersIdentifiers | string) => { if (identifier === BrowsersIdentifiers.settings || identifier === 'some-other-window') { return { show: mockShow }; } return { show: mockShow }; // Default mock for other identifiers }), }, } as unknown as App; describe('BrowserWindowsCtr', () => { let browserWindowsCtr: BrowserWindowsCtr; beforeEach(() => { vi.clearAllMocks(); browserWindowsCtr = new BrowserWindowsCtr(mockApp); }); describe('toggleMainWindow', () => { it('should get the main window and toggle its visibility', async () => { await browserWindowsCtr.toggleMainWindow(); expect(mockGetMainWindow).toHaveBeenCalled(); expect(mockToggleVisible).toHaveBeenCalled(); }); }); describe('openSettingsWindow', () => { it('should show the settings window with the specified tab', async () => { const tab = 'appearance'; const result = await browserWindowsCtr.openSettingsWindow(tab); expect(mockShowSettingsWindowWithTab).toHaveBeenCalledWith(tab); expect(result).toEqual({ success: true }); }); it('should return error if showing settings window fails', async () => { const errorMessage = 'Failed to show'; mockShowSettingsWindowWithTab.mockRejectedValueOnce(new Error(errorMessage)); const result = await browserWindowsCtr.openSettingsWindow('display'); expect(result).toEqual({ error: errorMessage, success: false }); }); }); const testSenderIdentifierString: string = 'test-window-event-id'; const sender: IpcClientEventSender = { identifier: testSenderIdentifierString, }; describe('closeWindow', () => { it('should close the window with the given sender identifier', () => { browserWindowsCtr.closeWindow(undefined, sender); expect(mockCloseWindow).toHaveBeenCalledWith(testSenderIdentifierString); }); }); describe('minimizeWindow', () => { it('should minimize the window with the given sender identifier', () => { browserWindowsCtr.minimizeWindow(undefined, sender); expect(mockMinimizeWindow).toHaveBeenCalledWith(testSenderIdentifierString); }); }); describe('maximizeWindow', () => { it('should maximize the window with the given sender identifier', () => { browserWindowsCtr.maximizeWindow(undefined, sender); expect(mockMaximizeWindow).toHaveBeenCalledWith(testSenderIdentifierString); }); }); describe('interceptRoute', () => { const baseParams = { source: 'link-click' as const }; it('should not intercept if no matching route is found', async () => { const params: InterceptRouteParams = { ...baseParams, path: '/unknown/route', url: 'app://host/unknown/route' }; (findMatchingRoute as Mock).mockReturnValue(undefined); const result = await browserWindowsCtr.interceptRoute(params); expect(findMatchingRoute).toHaveBeenCalledWith(params.path); expect(result).toEqual({ intercepted: false, path: params.path, source: params.source }); }); it('should show settings window if matched route target is settings', async () => { const params: InterceptRouteParams = { ...baseParams, path: '/settings/common', url: 'app://host/settings/common' }; const matchedRoute = { targetWindow: BrowsersIdentifiers.settings, pathPrefix: '/settings' }; const subPath = 'common'; (findMatchingRoute as Mock).mockReturnValue(matchedRoute); (extractSubPath as Mock).mockReturnValue(subPath); const result = await browserWindowsCtr.interceptRoute(params); expect(findMatchingRoute).toHaveBeenCalledWith(params.path); expect(extractSubPath).toHaveBeenCalledWith(params.path, matchedRoute.pathPrefix); expect(mockShowSettingsWindowWithTab).toHaveBeenCalledWith(subPath); expect(result).toEqual({ intercepted: true, path: params.path, source: params.source, subPath, targetWindow: matchedRoute.targetWindow, }); expect(mockShow).not.toHaveBeenCalled(); }); it('should open target window if matched route target is not settings', async () => { const params: InterceptRouteParams = { ...baseParams, path: '/other/page', url: 'app://host/other/page' }; const targetWindowIdentifier = 'some-other-window' as AppBrowsersIdentifiers; const matchedRoute = { targetWindow: targetWindowIdentifier, pathPrefix: '/other' }; (findMatchingRoute as Mock).mockReturnValue(matchedRoute); const result = await browserWindowsCtr.interceptRoute(params); expect(findMatchingRoute).toHaveBeenCalledWith(params.path); expect(mockRetrieveByIdentifier).toHaveBeenCalledWith(targetWindowIdentifier); expect(mockShow).toHaveBeenCalled(); expect(result).toEqual({ intercepted: true, path: params.path, source: params.source, targetWindow: matchedRoute.targetWindow, }); expect(mockShowSettingsWindowWithTab).not.toHaveBeenCalled(); }); it('should return error if processing route interception fails for settings', async () => { const params: InterceptRouteParams = { ...baseParams, path: '/settings/general', url: 'app://host/settings/general' }; const matchedRoute = { targetWindow: BrowsersIdentifiers.settings, pathPrefix: '/settings' }; const subPath = 'general'; const errorMessage = 'Processing error for settings'; (findMatchingRoute as Mock).mockReturnValue(matchedRoute); (extractSubPath as Mock).mockReturnValue(subPath); mockShowSettingsWindowWithTab.mockRejectedValueOnce(new Error(errorMessage)); const result = await browserWindowsCtr.interceptRoute(params); expect(result).toEqual({ error: errorMessage, intercepted: false, path: params.path, source: params.source, }); }); it('should return error if processing route interception fails for other window', async () => { const params: InterceptRouteParams = { ...baseParams, path: '/another/custom', url: 'app://host/another/custom' }; const targetWindowIdentifier = 'another-custom-window' as AppBrowsersIdentifiers; const matchedRoute = { targetWindow: targetWindowIdentifier, pathPrefix: '/another' }; const errorMessage = 'Processing error for other window'; (findMatchingRoute as Mock).mockReturnValue(matchedRoute); mockRetrieveByIdentifier.mockImplementationOnce(() => { throw new Error(errorMessage); }); const result = await browserWindowsCtr.interceptRoute(params); expect(result).toEqual({ error: errorMessage, intercepted: false, path: params.path, source: params.source, }); }); }); });