From e0d0cac91c66712f875a092b24dbbe71d645b17a Mon Sep 17 00:00:00 2001 From: xue jiahao Date: Wed, 18 Mar 2026 10:18:39 +0800 Subject: [PATCH] remove test --- AGENTS.md | 68 +++--------- package.json | 9 +- src/main/__tests__/kintone-api.test.ts | 146 ------------------------- tests/mocks/electron.ts | 142 ------------------------ tests/setup.ts | 14 --- vitest.config.ts | 25 ----- 6 files changed, 15 insertions(+), 389 deletions(-) delete mode 100644 src/main/__tests__/kintone-api.test.ts delete mode 100644 tests/mocks/electron.ts delete mode 100644 tests/setup.ts delete mode 100644 vitest.config.ts diff --git a/AGENTS.md b/AGENTS.md index aa585ad..a8fc317 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -22,17 +22,8 @@ npm run package:linux # Linux # 代码质量 npm run lint # ESLint 检查 npm run format # Prettier 格式化 - -# 测试 -npm test # 运行测试 -npm run test:watch # 监听模式 -npm run test:coverage # 测试覆盖率 ``` -**重要**: 修改 `src/main/` 目录下的文件后,必须运行 `npm test` 确保测试通过。 - -**注意**: 仅修改 `src/renderer/`(前端/UI)或 `src/preload/` 文件时,不需要运行测试,只需确保类型检查通过(`npx tsc --noEmit`)即可。 - ## 2. 项目架构 ``` @@ -41,23 +32,19 @@ src/ │ ├── index.ts # 入口,创建窗口 │ ├── ipc-handlers.ts # IPC 处理器(所有通信入口) │ ├── storage.ts # 文件存储 + 密码加密 -│ ├── kintone-api.ts # Kintone REST API 封装 -│ └── __tests__/ # 主进程测试 +│ └── kintone-api.ts # Kintone REST API 封装 ├── preload/ # Preload 脚本 │ ├── index.ts # 暴露 API 到渲染进程 │ └── index.d.ts # 类型声明 ├── shared/ # 跨进程共享代码 │ └── types/ # 共享类型定义 -├── renderer/ # React 渲染进程 -│ └── src/ -│ ├── main.tsx # React 入口 -│ ├── App.tsx # 根组件 -│ ├── components/ # React 组件 -│ ├── stores/ # Zustand Stores -│ └── locales/ # i18n 翻译文件 -└── tests/ # 测试配置 - ├── setup.ts # 测试环境设置 - └── mocks/ # Mock 文件 +└── renderer/ # React 渲染进程 + └── src/ + ├── main.tsx # React 入口 + ├── App.tsx # 根组件 + ├── components/ # React 组件 + ├── stores/ # Zustand Stores + └── locales/ # i18n 翻译文件 ``` ### 数据流 @@ -139,12 +126,14 @@ type Result = { success: true; data: T } | { success: false; error: string }; **UI Kit 优先使用 LobeHub UI** (`@lobehub/ui`),其次使用 Ant Design 6 + antd-style: ```typescript -import { Button } from '@lobehub/ui'; -import { createStyles } from 'antd-style'; +import { Button } from "@lobehub/ui"; +import { createStyles } from "antd-style"; // antd-style 仅用于自定义样式 export const useStyles = createStyles(({ token, css }) => ({ - container: css`padding: ${token.paddingLG}px;` + container: css` + padding: ${token.paddingLG}px; + `, })); ``` @@ -217,34 +206,3 @@ eval "$(fnm env --use-on-cd)" && npm run dev 3. Explain the reasoning and benefits 4. If significant, ask user for confirmation before implementing 5. Update related documentation after implementation - -## 14. 测试规范 - -### 测试框架 - -使用 **Vitest** 作为测试框架,与 Vite 原生集成。 - -### 测试文件结构 - -``` -src/main/__tests__/ # 主进程测试 -tests/ -├── setup.ts # 全局测试设置 -└── mocks/ - └── electron.ts # Electron API Mocks -``` - -### 测试要求 - -1. **修改 `src/main/` 目录下的文件后,必须运行 `npm test` 确保测试通过** -2. 新增 API 功能时,应在 `src/main/__tests__/` 中添加对应测试 -3. 测试文件命名:`*.test.ts` - -### Mock Electron API - -测试中需要 Mock Electron 的 API(如 `safeStorage`、`app` 等),已在 `tests/mocks/electron.ts` 中提供。 - -```typescript -// tests/setup.ts 中自动 Mock -vi.mock("electron", () => import("./mocks/electron")); -``` diff --git a/package.json b/package.json index 2eb3888..ef3d8a4 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,7 @@ "package:mac": "electron-vite build && electron-builder --mac", "package:linux": "electron-vite build && electron-builder --linux", "lint": "eslint . --ext .js,.jsx,.ts,.tsx", - "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,json}\"", - "test": "vitest run", - "test:watch": "vitest", - "test:coverage": "vitest run --coverage" + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,json}\"" }, "dependencies": { "@codemirror/lang-css": "^6.3.0", @@ -57,7 +54,6 @@ "@typescript-eslint/eslint-plugin": "^8.57.0", "@typescript-eslint/parser": "^8.57.0", "@vitejs/plugin-react": "^4.3.0", - "@vitest/coverage-v8": "^2.1.9", "electron": "^30.5.1", "electron-builder": "^26.0.0", "electron-vite": "^5.0.0", @@ -67,7 +63,6 @@ "prettier": "^3.2.0", "typescript": "^5.7.0", "typescript-eslint": "^8.57.0", - "vite": "^5.4.0", - "vitest": "^2.1.9" + "vite": "^5.4.0" } } diff --git a/src/main/__tests__/kintone-api.test.ts b/src/main/__tests__/kintone-api.test.ts deleted file mode 100644 index 4801a4e..0000000 --- a/src/main/__tests__/kintone-api.test.ts +++ /dev/null @@ -1,146 +0,0 @@ -/** - * Kintone API Integration Tests - * Tests actual API connectivity to verify the client works correctly - * - * Test credentials: - * - Domain: https://alicorn.cybozu.com - * - Username: maxz - * - Password: 7ld7i8vd - */ - -import { describe, expect, it, beforeAll, afterAll } from "vitest"; -import { KintoneClient, createKintoneClient } from "@main/kintone-api"; -import type { DomainWithPassword } from "@shared/types/domain"; - -// Test configuration -const TEST_CONFIG: DomainWithPassword = { - id: "test-domain-id", - name: "Test Domain", - domain: "alicorn.cybozu.com", - username: "maxz", - password: "7ld7i8vd", - createdAt: new Date().toISOString(), - updatedAt: new Date().toISOString(), -}; - -describe("SelfKintoneClient - API Integration Tests", () => { - let client: KintoneClient; - - beforeAll(() => { - // Create client with test credentials - client = createKintoneClient(TEST_CONFIG); - console.log(`Testing connection to: https://${TEST_CONFIG.domain}`); - }); - - describe("Connection Tests", () => { - it("should successfully test connection", async () => { - const result = await client.testConnection(); - - console.log("Test connection result:", result); - - expect(result).toBeDefined(); - expect(result.success).toBe(true); - expect(result.error).toBeUndefined(); - }); - - it("should return the correct domain", () => { - const domain = client.getDomain(); - expect(domain).toBe(TEST_CONFIG.domain); - }); - }); - - describe("Get Apps Tests", () => { - it("should fetch apps successfully", async () => { - const apps = await client.getApps(); - - console.log(`Fetched ${apps.length} apps`); - if (apps.length > 0) { - console.log("First app:", JSON.stringify(apps[0], null, 2)); - } - - expect(apps).toBeDefined(); - expect(Array.isArray(apps)).toBe(true); - }); - - it("should fetch apps with pagination (limit=5)", async () => { - const apps = await client.getApps({ limit: 5 }); - - console.log(`Fetched ${apps.length} apps with limit=5`); - - expect(apps).toBeDefined(); - expect(Array.isArray(apps)).toBe(true); - expect(apps.length).toBeLessThanOrEqual(5); - }); - }); - - describe("Get App Detail Tests", () => { - let firstAppId: string | null = null; - - beforeAll(async () => { - // Get an app ID to test with - const apps = await client.getApps({ limit: 1 }); - if (apps.length > 0 && apps[0].appId) { - firstAppId = String(apps[0].appId); - console.log(`Using app ID for detail test: ${firstAppId}`); - } - }); - - it("should fetch app detail if apps exist", async () => { - if (!firstAppId) { - console.log("Skipping: No apps available to test"); - return; - } - - const detail = await client.getAppDetail(firstAppId); - - console.log("App detail:", JSON.stringify(detail, null, 2).slice(0, 500)); - - expect(detail).toBeDefined(); - expect(detail.appId).toBe(firstAppId); - expect(detail.name).toBeDefined(); - expect(detail.customization).toBeDefined(); - }); - }); - - describe("Error Handling Tests", () => { - it("should handle invalid credentials gracefully", async () => { - const invalidConfig: DomainWithPassword = { - ...TEST_CONFIG, - password: "invalid-password-12345", - }; - - const invalidClient = createKintoneClient(invalidConfig); - const result = await invalidClient.testConnection(); - - console.log("Invalid credentials test result:", result); - - expect(result.success).toBe(false); - expect(result.error).toBeDefined(); - }); - - it("should handle invalid domain gracefully", async () => { - const invalidConfig: DomainWithPassword = { - ...TEST_CONFIG, - domain: "non-existent-domain-12345.cybozu.com", - }; - - const invalidClient = createKintoneClient(invalidConfig); - const result = await invalidClient.testConnection(); - - // testConnection catches errors and returns { success: false } - expect(result.success).toBe(false); - expect(result.error).toBeDefined(); - }); - }); -}); -describe("Create Kintone Client Factory", () => { - it("should create a client instance", () => { - const client = createKintoneClient(TEST_CONFIG); - expect(client).toBeInstanceOf(KintoneClient); - }); - - it("should return the correct domain", () => { - const client = createKintoneClient(TEST_CONFIG); - expect(client.getDomain()).toBe(TEST_CONFIG.domain); - }); -}); diff --git a/tests/mocks/electron.ts b/tests/mocks/electron.ts deleted file mode 100644 index 0ea9e67..0000000 --- a/tests/mocks/electron.ts +++ /dev/null @@ -1,142 +0,0 @@ -/** - * Electron API mocks for testing - * Mocks safeStorage, app, and other Electron APIs - */ - -import { vi } from "vitest"; - -// In-memory storage for encrypted passwords (simulates OS keychain) -const encryptedStore = new Map(); - -/** - * Mock safeStorage for password encryption - * In tests, we use a simple reversible encoding instead of actual encryption - */ -export const safeStorage = { - /** - * Encrypt a string (simulated) - * In production, this uses OS-specific encryption - */ - encryptString: vi.fn((plaintext: string): Buffer => { - const encoded = Buffer.from(`encrypted:${plaintext}`).toString("base64"); - return Buffer.from(encoded); - }), - - /** - * Decrypt a buffer (simulated) - */ - decryptString: vi.fn((encrypted: Buffer): string => { - const decoded = encrypted.toString(); - const base64Content = decoded.replace("encrypted:", ""); - return Buffer.from(base64Content, "base64") - .toString() - .replace("encrypted:", ""); - }), - - /** - * Check if encryption is available - */ - isEncryptionAvailable: vi.fn((): boolean => true), - - /** - * Get the current storage backend - */ - getSelectedStorageBackend: vi.fn((): string => "mock_backend"), -}; - -/** - * Mock Electron app - */ -export const app = { - getName: vi.fn(() => "Kintone Customize Manager"), - getVersion: vi.fn(() => "1.0.0"), - getPath: vi.fn((key: string): string => { - const paths: Record = { - userData: "/tmp/kintone-manager-test/userData", - home: "/tmp/kintone-manager-test/home", - temp: "/tmp/kintone-manager-test/temp", - appData: "/tmp/kintone-manager-test/appData", - desktop: "/tmp/kintone-manager-test/desktop", - documents: "/tmp/kintone-manager-test/documents", - downloads: "/tmp/kintone-manager-test/downloads", - }; - return paths[key] || "/tmp/kintone-manager-test"; - }), - whenReady: vi.fn(() => Promise.resolve()), - on: vi.fn(), - quit: vi.fn(), - isReady: vi.fn(() => true), -}; - -/** - * Mock ipcMain for IPC handler tests - */ -class IPCMainMock { - private handlers = new Map(); - - handle = vi.fn((channel: string, handler: Function) => { - this.handlers.set(channel, handler); - }); - - handleOnce = vi.fn((channel: string, handler: Function) => { - this.handlers.set(channel, handler); - }); - - removeHandler = vi.fn((channel: string) => { - this.handlers.delete(channel); - }); - - // Helper to call a handler directly in tests - async invoke(channel: string, ...args: unknown[]): Promise { - const handler = this.handlers.get(channel); - if (!handler) { - throw new Error(`No handler registered for channel: ${channel}`); - } - return handler({}, ...args); - } -} - -export const ipcMain = new IPCMainMock(); - -/** - * Mock BrowserWindow - */ -export const BrowserWindow = vi.fn().mockImplementation(() => ({ - loadURL: vi.fn(), - loadFile: vi.fn(), - on: vi.fn(), - webContents: { - on: vi.fn(), - send: vi.fn(), - openDevTools: vi.fn(), - }, - show: vi.fn(), - close: vi.fn(), -})); - -/** - * Mock dialog - */ -export const dialog = { - showOpenDialog: vi.fn().mockResolvedValue({ canceled: false, filePaths: [] }), - showMessageBox: vi.fn().mockResolvedValue({ response: 0 }), - showSaveDialog: vi.fn().mockResolvedValue({ canceled: false, filePath: "" }), -}; - -/** - * Mock clipboard - */ -export const clipboard = { - writeText: vi.fn(), - readText: vi.fn(() => ""), -}; - -// Default export with all mocked APIs -export default { - app, - safeStorage, - ipcMain, - BrowserWindow, - dialog, - clipboard, -}; diff --git a/tests/setup.ts b/tests/setup.ts deleted file mode 100644 index 2a90a1a..0000000 --- a/tests/setup.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Test setup file - * Configures mocks before tests run - */ - -import { vi } from "vitest"; - -// Mock electron module before any imports -vi.mock("electron", () => { - return import("./mocks/electron"); -}); - -// Increase timeout for integration tests -vi.setConfig({ testTimeout: 30000 }); diff --git a/vitest.config.ts b/vitest.config.ts deleted file mode 100644 index 5254a9b..0000000 --- a/vitest.config.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { defineConfig } from "vitest/config"; -import { resolve } from "path"; - -export default defineConfig({ - test: { - globals: true, - environment: "node", - setupFiles: ["./tests/setup.ts"], - include: ["src/**/*.test.ts", "tests/**/*.test.ts"], - testTimeout: 30000, // 30 seconds for API calls - coverage: { - provider: "v8", - reporter: ["text", "json", "html"], - exclude: ["node_modules/", "tests/", "**/*.d.ts", "**/*.config.*"], - }, - }, - resolve: { - alias: { - "@main": resolve(__dirname, "src/main"), - "@preload": resolve(__dirname, "src/preload"), - "@renderer": resolve(__dirname, "src/renderer/src"), - "@shared": resolve(__dirname, "src/shared"), - }, - }, -});