import { afterAll, beforeAll, describe, expect, test } from "bun:test"; import { mkdir, rm, writeFile } from "node:fs/promises"; import { tmpdir } from "node:os"; import { join } from "node:path"; import type { ResolvedWsTarget } from "../../../../../src/server/checker/runner/ws/types"; import { loadConfig } from "../../../../../src/server/checker/config-loader"; describe("loadConfig with ws checker", () => { let tempDir: string; beforeAll(async () => { tempDir = join(tmpdir(), `ws-cfg-test-${Date.now()}`); await mkdir(tempDir, { recursive: true }); }); afterAll(async () => { await rm(tempDir, { force: true, recursive: true }); }); test("解析最简 ws 配置", async () => { const configPath = join(tempDir, "minimal-ws.yaml"); await writeFile( configPath, `targets: - id: "ws-test" type: ws ws: url: "ws://example.com/ws" `, ); const config = await loadConfig(configPath); expect(config.targets).toHaveLength(1); const t = config.targets[0]! as ResolvedWsTarget; expect(t.type).toBe("ws"); expect(t.id).toBe("ws-test"); expect(t.ws.url).toBe("ws://example.com/ws"); expect(t.ws.headers).toEqual({}); expect(t.ws.ignoreSSL).toBe(false); expect(t.ws.maxMessageBytes).toBe(4096); expect(t.ws.receiveTimeout).toBe(5000); expect(t.ws.send).toBeUndefined(); expect(t.ws.subprotocols).toEqual([]); expect(t.expect).toEqual({ connected: true }); }); test("解析带 send 的 ws 配置", async () => { const configPath = join(tempDir, "ws-send.yaml"); await writeFile( configPath, `targets: - id: "ws-echo" name: "WS Echo 检查" type: ws ws: url: "wss://api.example.com/ws" headers: Authorization: "Bearer token" subprotocols: - "json" ignoreSSL: true send: "ping" receiveTimeout: 3000 maxMessageBytes: "8KB" expect: message: - contains: "pong" durationMs: lte: 5000 `, ); const config = await loadConfig(configPath); expect(config.targets).toHaveLength(1); const t = config.targets[0]! as ResolvedWsTarget; expect(t.type).toBe("ws"); expect(t.ws.url).toBe("wss://api.example.com/ws"); expect(t.ws.headers).toEqual({ Authorization: "Bearer token" }); expect(t.ws.ignoreSSL).toBe(true); expect(t.ws.maxMessageBytes).toBe(8192); expect(t.ws.receiveTimeout).toBe(3000); expect(t.ws.send).toBe("ping"); expect(t.ws.subprotocols).toEqual(["json"]); expect(t.expect?.connected).toBe(true); expect(t.expect?.message).toBeDefined(); expect(t.expect?.durationMs).toEqual({ lte: 5000 }); }); test("ws 缺少 url 抛出错误", async () => { const configPath = join(tempDir, "ws-no-url.yaml"); await writeFile( configPath, `targets: - id: "t" type: ws ws: {} `, ); let error: unknown; try { await loadConfig(configPath); } catch (caught) { error = caught; } expect(error).toBeInstanceOf(Error); expect((error as Error).message).toContain("ws.url"); }); test("ws url 非 ws/wss 协议抛出错误", async () => { const configPath = join(tempDir, "ws-bad-url.yaml"); await writeFile( configPath, `targets: - id: "t" type: ws ws: url: "http://example.com" `, ); let error: unknown; try { await loadConfig(configPath); } catch (caught) { error = caught; } expect(error).toBeInstanceOf(Error); expect((error as Error).message).toContain("ws:// 或 wss://"); }); test("ws expect.message 未配置 send 抛出错误", async () => { const configPath = join(tempDir, "ws-no-send.yaml"); await writeFile( configPath, `targets: - id: "t" type: ws ws: url: "ws://example.com" expect: message: - contains: "pong" `, ); let error: unknown; try { await loadConfig(configPath); } catch (caught) { error = caught; } expect(error).toBeInstanceOf(Error); expect((error as Error).message).toContain("send"); }); });