import React from "react"; import { beforeEach, describe, expect, it, vi } from "vitest"; import { act, create, type ReactTestRenderer } from "react-test-renderer"; import { readFileSync } from "node:fs"; import { setCurrentLanguage } from "../i18n"; const storeState = { addConnection: vi.fn(), updateConnection: vi.fn(), theme: "light", languagePreference: "zh-CN", setLanguagePreference: vi.fn((languagePreference: "zh-CN" | "en-US") => { storeState.languagePreference = languagePreference; setCurrentLanguage(languagePreference); notifyStoreSubscribers(); }), appearance: { uiVersion: "legacy", opacity: 1 }, }; const storeSubscribers = new Set<() => void>(); const notifyStoreSubscribers = () => { storeSubscribers.forEach((subscriber) => subscriber()); }; let mockFormValues: Record = {}; const antdMessage = vi.hoisted(() => ({ error: vi.fn(), warning: vi.fn(), success: vi.fn(), destroy: vi.fn(), })); const backendApp = { DBGetDatabases: vi.fn(), GetDriverStatusList: vi.fn(), MongoDiscoverMembers: vi.fn(), TestConnection: vi.fn(), RedisConnect: vi.fn(), SelectDatabaseFile: vi.fn(), SelectCertificateFile: vi.fn(), SelectSSHKeyFile: vi.fn(), TestJVMConnection: vi.fn(), }; const textContent = (node: any): string => { if (node === null || node === undefined) return ""; if (typeof node === "string") return node; if (Array.isArray(node)) { return node.map((item) => textContent(item)).join(""); } return [node.props?.placeholder, textContent(node.children || [])] .filter(Boolean) .join(""); }; const findButton = (renderer: ReactTestRenderer, text: string) => renderer.root.findAll((node) => node.type === "button" && textContent(node).includes(text))[0]; const findButtonByAnyText = (renderer: ReactTestRenderer, texts: string[]) => renderer.root.findAll( (node) => node.type === "button" && texts.some((text) => textContent(node).includes(text)), )[0]; const findClickableByAnyText = (renderer: ReactTestRenderer, texts: string[]) => renderer.root.findAll( (node) => typeof node.props?.onClick === "function" && texts.some((text) => textContent(node).includes(text)), )[0]; const findClickableCard = (renderer: ReactTestRenderer, text: string) => renderer.root.findAll((node) => node.props?.role === "button" && textContent(node).includes(text))[0]; const flushConnectionTestTick = async () => { await new Promise((resolve) => setTimeout(resolve, 0)); await Promise.resolve(); }; const source = readFileSync(new URL("./ConnectionModal.tsx", import.meta.url), "utf8"); const step2Source = readFileSync(new URL("./connectionModal/ConnectionModalStep2.tsx", import.meta.url), "utf8"); const networkSecuritySource = readFileSync( new URL("./connectionModal/ConnectionModalNetworkSecuritySection.tsx", import.meta.url), "utf8", ); const uriSource = readFileSync(new URL("./connectionModal/connectionModalUri.ts", import.meta.url), "utf8"); const typeCatalogSource = readFileSync(new URL("../utils/connectionTypeCatalog.ts", import.meta.url), "utf8"); const combinedConnectionModalSource = [ source, step2Source, networkSecuritySource, uriSource, ].join("\n"); const initialConnection = (type: string, config: Record = {}) => ({ id: `${type}-conn`, name: `${type} connection`, type, config: { type, host: "localhost", port: 3306, user: "user", ...config, }, }) as any; vi.mock("../store", () => ({ useStore: (selector: (state: typeof storeState) => unknown) => React.useSyncExternalStore( (subscriber) => { storeSubscribers.add(subscriber); return () => { storeSubscribers.delete(subscriber); }; }, () => selector(storeState), () => selector(storeState), ), })); vi.mock("../../wailsjs/go/app/App", () => backendApp); vi.mock("../utils/overlayWorkbenchTheme", () => ({ buildOverlayWorkbenchTheme: () => ({ shellBg: "#fff", shellBorder: "1px solid #eee", shellShadow: "none", shellBackdropFilter: "none", sectionBorder: "1px solid #eee", sectionBg: "#fff", mutedText: "#666", titleText: "#111", iconBg: "#f5f5f5", iconColor: "#111", }), })); vi.mock("./DatabaseIcons", () => ({ getDbIcon: (type: string) => {type}, getDbDefaultColor: () => "#1677ff", getDbIconLabel: (type: string) => type, DB_ICON_TYPES: ["mysql", "postgres"], PRESET_ICON_COLORS: ["#1677ff", "#52c41a"], })); vi.mock("@ant-design/icons", () => { const Icon = () => ; return { DatabaseOutlined: Icon, FileTextOutlined: Icon, CloudOutlined: Icon, CheckCircleFilled: Icon, CloseCircleFilled: Icon, LinkOutlined: Icon, EditOutlined: Icon, AppstoreOutlined: Icon, BgColorsOutlined: Icon, ApiOutlined: Icon, ClusterOutlined: Icon, CodeOutlined: Icon, GatewayOutlined: Icon, SafetyCertificateOutlined: Icon, ThunderboltOutlined: Icon, }; }); vi.mock("antd", () => { const Button: any = ({ children, disabled, loading, onClick, ...rest }: any) => ( ); Button.Group = ({ children }: any) =>
{children}
; const Input: any = ({ children, value, onChange, placeholder, ...rest }: any) => ( {children} ); Input.Password = ({ value, onChange, placeholder, ...rest }: any) => ( ); Input.TextArea = ({ value, onChange, placeholder, ...rest }: any) => (