| |
| import { mkdtemp, rm } from "node:fs/promises"; |
| import os from "node:os"; |
| import path from "node:path"; |
| import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
| import { OpenClawSchema } from "../../config/zod-schema.js"; |
|
|
| const mocks = vi.hoisted(() => ({ |
| configPath: "", |
| workspace: "", |
| nextConfig: undefined as unknown, |
| writeOptions: undefined as unknown, |
| replaceConfigFile: vi.fn(), |
| })); |
|
|
| vi.mock("../../agents/workspace-templates.js", () => ({ |
| resolveWorkspaceTemplateSearchDirs: async () => [], |
| })); |
|
|
| vi.mock("../../agents/workspace.js", () => ({ |
| publishBootstrapFile: async () => true, |
| resolveDefaultAgentWorkspaceDir: () => mocks.workspace, |
| })); |
|
|
| vi.mock("../../commands/onboard-helpers.js", () => ({ |
| handleReset: vi.fn(), |
| })); |
|
|
| vi.mock("../../config/config.js", () => ({ |
| createConfigIO: () => ({ configPath: mocks.configPath }), |
| replaceConfigFile: (options: unknown) => mocks.replaceConfigFile(options), |
| })); |
|
|
| vi.mock("../../runtime.js", () => ({ |
| defaultRuntime: { log: vi.fn() }, |
| })); |
|
|
| vi.mock("../../utils.js", () => ({ |
| resolveUserPath: (value: string) => value, |
| shortenHomePath: (value: string) => value, |
| })); |
|
|
| const { ensureDevGatewayConfig } = await import("./dev.js"); |
|
|
| describe("ensureDevGatewayConfig", () => { |
| let tempDir = ""; |
|
|
| beforeEach(async () => { |
| tempDir = await mkdtemp(path.join(os.tmpdir(), "openclaw-dev-config-")); |
| mocks.configPath = path.join(tempDir, "openclaw.json"); |
| mocks.workspace = path.join(tempDir, "workspace"); |
| mocks.nextConfig = undefined; |
| mocks.writeOptions = undefined; |
| mocks.replaceConfigFile.mockReset(); |
| mocks.replaceConfigFile.mockImplementation(async (options: unknown) => { |
| const configOptions = options as { nextConfig: unknown; writeOptions?: unknown }; |
| mocks.nextConfig = configOptions.nextConfig; |
| mocks.writeOptions = configOptions.writeOptions; |
| }); |
| }); |
|
|
| afterEach(async () => { |
| await rm(tempDir, { recursive: true, force: true }); |
| }); |
|
|
| it("writes a config that uses the canonical keyed agent entries shape", async () => { |
| await ensureDevGatewayConfig({}); |
| const devWorkspace = `${mocks.workspace}-dev`; |
|
|
| expect(mocks.nextConfig).toEqual({ |
| gateway: { mode: "local", bind: "loopback" }, |
| agents: { |
| defaults: { workspace: devWorkspace, skipBootstrap: true }, |
| entries: { |
| dev: { |
| default: true, |
| workspace: devWorkspace, |
| identity: { name: "C3-PO", theme: "protocol droid", emoji: "🤖" }, |
| }, |
| }, |
| }, |
| }); |
| expect(OpenClawSchema.safeParse(mocks.nextConfig).success).toBe(true); |
| expect(mocks.writeOptions).toEqual({ allowedAgentRosterRemovals: ["main"] }); |
| }); |
| }); |
|
|