mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-18 13:30:48 +00:00
refactor(tests): share setup wizard prompter
This commit is contained in:
@@ -1,31 +1,10 @@
|
||||
import type { OpenClawConfig, WizardPrompter } from "openclaw/plugin-sdk/googlechat";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/googlechat";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter, type WizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
import { googlechatPlugin } from "./channel.js";
|
||||
|
||||
const selectFirstOption = async <T>(params: { options: Array<{ value: T }> }): Promise<T> => {
|
||||
const first = params.options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
};
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: selectFirstOption as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const googlechatConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: googlechatPlugin,
|
||||
wizard: googlechatPlugin.setupWizard!,
|
||||
@@ -33,7 +12,7 @@ const googlechatConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard
|
||||
|
||||
describe("googlechat setup wizard", () => {
|
||||
it("configures service-account auth and webhook audience", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Service account JSON path") {
|
||||
return "/tmp/googlechat-service-account.json";
|
||||
|
||||
@@ -1,32 +1,11 @@
|
||||
import type { RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/irc";
|
||||
import type { RuntimeEnv } from "openclaw/plugin-sdk/irc";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter, type WizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
import { ircPlugin } from "./channel.js";
|
||||
import type { CoreConfig } from "./types.js";
|
||||
|
||||
const selectFirstOption = async <T>(params: { options: Array<{ value: T }> }): Promise<T> => {
|
||||
const first = params.options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
};
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: selectFirstOption as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const ircConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: ircPlugin,
|
||||
wizard: ircPlugin.setupWizard!,
|
||||
@@ -34,7 +13,7 @@ const ircConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
|
||||
describe("irc setup wizard", () => {
|
||||
it("configures host and nick via setup prompts", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "IRC server host") {
|
||||
return "irc.libera.chat";
|
||||
@@ -93,7 +72,7 @@ describe("irc setup wizard", () => {
|
||||
});
|
||||
|
||||
it("writes DM allowFrom to top-level config for non-default account prompts", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "IRC allowFrom (nick or nick!user@host)") {
|
||||
return "Alice, Bob!ident@example.org";
|
||||
|
||||
@@ -6,30 +6,10 @@ import {
|
||||
resolveDefaultLineAccountId,
|
||||
resolveLineAccount,
|
||||
} from "../../../src/line/accounts.js";
|
||||
import type { WizardPrompter } from "../../../src/wizard/prompts.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter, type WizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
import { lineSetupAdapter, lineSetupWizard } from "./setup-surface.js";
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter> = {}): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: vi.fn(async ({ options }: { options: Array<{ value: string }> }) => {
|
||||
const first = options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
}) as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const lineConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: {
|
||||
id: "line",
|
||||
@@ -47,7 +27,7 @@ const lineConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
|
||||
describe("line setup wizard", () => {
|
||||
it("configures token and secret for the default account", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Enter LINE channel access token") {
|
||||
return "line-token";
|
||||
|
||||
@@ -1,30 +1,10 @@
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/nostr";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import type { WizardPrompter } from "../../../src/wizard/prompts.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter, type WizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
import { nostrPlugin } from "./channel.js";
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: vi.fn(async ({ options }: { options: Array<{ value: string }> }) => {
|
||||
const first = options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
}) as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const nostrConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: nostrPlugin,
|
||||
wizard: nostrPlugin.setupWizard!,
|
||||
@@ -32,7 +12,7 @@ const nostrConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
|
||||
describe("nostr setup wizard", () => {
|
||||
it("configures a private key and relay URLs", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Nostr private key (nsec... or hex)") {
|
||||
return "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
||||
|
||||
@@ -1,31 +1,11 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import type { OpenClawConfig } from "../../../src/config/config.js";
|
||||
import type { WizardPrompter } from "../../../src/wizard/prompts.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter, type WizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
import { synologyChatPlugin } from "./channel.js";
|
||||
import { synologyChatSetupWizard } from "./setup-surface.js";
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter> = {}): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: vi.fn(async ({ options }: { options: Array<{ value: string }> }) => {
|
||||
const first = options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
}) as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const synologyChatConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: synologyChatPlugin,
|
||||
wizard: synologyChatSetupWizard,
|
||||
@@ -33,7 +13,7 @@ const synologyChatConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWiza
|
||||
|
||||
describe("synology-chat setup wizard", () => {
|
||||
it("configures token and incoming webhook for the default account", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Enter Synology Chat outgoing webhook token") {
|
||||
return "synology-token";
|
||||
@@ -67,7 +47,7 @@ describe("synology-chat setup wizard", () => {
|
||||
});
|
||||
|
||||
it("records allowed user ids when setup forces allowFrom", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Enter Synology Chat outgoing webhook token") {
|
||||
return "synology-token";
|
||||
|
||||
28
extensions/test-utils/setup-wizard.ts
Normal file
28
extensions/test-utils/setup-wizard.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import { vi } from "vitest";
|
||||
import type { WizardPrompter } from "../../src/wizard/prompts.js";
|
||||
|
||||
export type { WizardPrompter } from "../../src/wizard/prompts.js";
|
||||
|
||||
export async function selectFirstWizardOption<T>(params: {
|
||||
options: Array<{ value: T }>;
|
||||
}): Promise<T> {
|
||||
const first = params.options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
}
|
||||
|
||||
export function createTestWizardPrompter(overrides: Partial<WizardPrompter> = {}): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: selectFirstWizardOption as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
@@ -1,31 +1,10 @@
|
||||
import type { OpenClawConfig, RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/tlon";
|
||||
import type { OpenClawConfig, RuntimeEnv } from "openclaw/plugin-sdk/tlon";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter, type WizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
import { tlonPlugin } from "./channel.js";
|
||||
|
||||
const selectFirstOption = async <T>(params: { options: Array<{ value: T }> }): Promise<T> => {
|
||||
const first = params.options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
};
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: selectFirstOption as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const tlonConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: tlonPlugin,
|
||||
wizard: tlonPlugin.setupWizard!,
|
||||
@@ -33,7 +12,7 @@ const tlonConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
|
||||
describe("tlon setup wizard", () => {
|
||||
it("configures ship, auth, and discovery settings", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Ship name") {
|
||||
return "sampel-palnet";
|
||||
|
||||
@@ -1,23 +1,10 @@
|
||||
import type { OpenClawConfig, RuntimeEnv, WizardPrompter } from "openclaw/plugin-sdk/zalo";
|
||||
import type { OpenClawConfig, RuntimeEnv } from "openclaw/plugin-sdk/zalo";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter, type WizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
import { zaloPlugin } from "./channel.js";
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: vi.fn(async () => "plaintext") as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const zaloConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: zaloPlugin,
|
||||
wizard: zaloPlugin.setupWizard!,
|
||||
@@ -25,7 +12,8 @@ const zaloConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
|
||||
describe("zalo setup wizard", () => {
|
||||
it("configures a polling token flow", async () => {
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
select: vi.fn(async () => "plaintext") as WizardPrompter["select"],
|
||||
text: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Enter Zalo bot token") {
|
||||
return "12345689:abc-xyz";
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import type { OpenClawConfig, WizardPrompter } from "openclaw/plugin-sdk/zalouser";
|
||||
import type { OpenClawConfig } from "openclaw/plugin-sdk/zalouser";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import { createRuntimeEnv } from "../../test-utils/runtime-env.js";
|
||||
import { createTestWizardPrompter } from "../../test-utils/setup-wizard.js";
|
||||
|
||||
vi.mock("./zalo-js.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("./zalo-js.js")>();
|
||||
@@ -28,28 +29,6 @@ vi.mock("./zalo-js.js", async (importOriginal) => {
|
||||
|
||||
import { zalouserPlugin } from "./channel.js";
|
||||
|
||||
const selectFirstOption = async <T>(params: { options: Array<{ value: T }> }): Promise<T> => {
|
||||
const first = params.options[0];
|
||||
if (!first) {
|
||||
throw new Error("no options");
|
||||
}
|
||||
return first.value;
|
||||
};
|
||||
|
||||
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
|
||||
return {
|
||||
intro: vi.fn(async () => {}),
|
||||
outro: vi.fn(async () => {}),
|
||||
note: vi.fn(async () => {}),
|
||||
select: selectFirstOption as WizardPrompter["select"],
|
||||
multiselect: vi.fn(async () => []),
|
||||
text: vi.fn(async () => "") as WizardPrompter["text"],
|
||||
confirm: vi.fn(async () => false),
|
||||
progress: vi.fn(() => ({ update: vi.fn(), stop: vi.fn() })),
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const zalouserConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
plugin: zalouserPlugin,
|
||||
wizard: zalouserPlugin.setupWizard!,
|
||||
@@ -58,7 +37,7 @@ const zalouserConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
describe("zalouser setup wizard", () => {
|
||||
it("enables the account without forcing QR login", async () => {
|
||||
const runtime = createRuntimeEnv();
|
||||
const prompter = createPrompter({
|
||||
const prompter = createTestWizardPrompter({
|
||||
confirm: vi.fn(async ({ message }: { message: string }) => {
|
||||
if (message === "Login via QR code now?") {
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user