refactor(test): reduce auth and channel setup duplication

This commit is contained in:
Peter Steinberger
2026-02-16 16:02:18 +00:00
parent 9adcaccd0b
commit def3a3ced1
4 changed files with 59 additions and 107 deletions

View File

@@ -65,6 +65,29 @@ describe("applyAuthChoice", () => {
function createPrompter(overrides: Partial<WizardPrompter>): WizardPrompter {
return createWizardPrompter(overrides, { defaultSelect: "" });
}
function createSelectFirstOption(): WizardPrompter["select"] {
return vi.fn(async (params) => params.options[0]?.value as never);
}
function createNoopMultiselect(): WizardPrompter["multiselect"] {
return vi.fn(async () => []);
}
function createApiKeyPromptHarness(
overrides: Partial<Pick<WizardPrompter, "select" | "multiselect" | "text" | "confirm">> = {},
): {
select: WizardPrompter["select"];
multiselect: WizardPrompter["multiselect"];
prompter: WizardPrompter;
runtime: ReturnType<typeof createExitThrowingRuntime>;
} {
const select = overrides.select ?? createSelectFirstOption();
const multiselect = overrides.multiselect ?? createNoopMultiselect();
return {
select,
multiselect,
prompter: createPrompter({ ...overrides, select, multiselect }),
runtime: createExitThrowingRuntime(),
};
}
async function readAuthProfiles() {
return await readAuthProfilesForAgent<{
profiles?: Record<string, StoredAuthProfile>;
@@ -109,12 +132,7 @@ describe("applyAuthChoice", () => {
await setupTempState();
const text = vi.fn().mockResolvedValue("sk-minimax-test");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const prompter = createPrompter({ select, multiselect, text });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text });
const result = await applyAuthChoice({
authChoice: "minimax-api",
@@ -139,12 +157,7 @@ describe("applyAuthChoice", () => {
await setupTempState();
const text = vi.fn().mockResolvedValue("sk-minimax-test");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const prompter = createPrompter({ select, multiselect, text });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text });
const result = await applyAuthChoice({
authChoice: "minimax-api-key-cn",
@@ -170,12 +183,7 @@ describe("applyAuthChoice", () => {
await setupTempState();
const text = vi.fn().mockResolvedValue("sk-synthetic-test");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const prompter = createPrompter({ select, multiselect, text });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text });
const result = await applyAuthChoice({
authChoice: "synthetic-api-key",
@@ -200,12 +208,7 @@ describe("applyAuthChoice", () => {
await setupTempState();
const text = vi.fn().mockResolvedValue("hf-test-token");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const prompter = createPrompter({ select, multiselect, text });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text });
const result = await applyAuthChoice({
authChoice: "huggingface-api-key",
@@ -295,13 +298,8 @@ describe("applyAuthChoice", () => {
delete process.env.HUGGINGFACE_HUB_TOKEN;
const text = vi.fn().mockResolvedValue("should-not-be-used");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const confirm = vi.fn(async () => false);
const prompter = createPrompter({ select, multiselect, text, confirm });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text, confirm });
const result = await applyAuthChoice({
authChoice: "apiKey",
@@ -328,12 +326,7 @@ describe("applyAuthChoice", () => {
await setupTempState();
const text = vi.fn().mockResolvedValue("sk-xai-test");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const prompter = createPrompter({ select, multiselect, text });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text });
const result = await applyAuthChoice({
authChoice: "xai-api-key",
@@ -393,12 +386,7 @@ describe("applyAuthChoice", () => {
await setupTempState();
const text = vi.fn().mockResolvedValue("sk-opencode-zen-test");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const prompter = createPrompter({ select, multiselect, text });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text });
const result = await applyAuthChoice({
authChoice: "opencode-zen",
@@ -477,13 +465,8 @@ describe("applyAuthChoice", () => {
process.env.OPENROUTER_API_KEY = "sk-openrouter-test";
const text = vi.fn();
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const confirm = vi.fn(async () => true);
const prompter = createPrompter({ select, multiselect, text, confirm });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text, confirm });
const result = await applyAuthChoice({
authChoice: "openrouter-api-key",
@@ -537,13 +520,8 @@ describe("applyAuthChoice", () => {
);
const text = vi.fn();
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const confirm = vi.fn(async () => true);
const prompter = createPrompter({ select, multiselect, text, confirm });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text, confirm });
const result = await applyAuthChoice({
authChoice: "litellm-api-key",
@@ -582,13 +560,8 @@ describe("applyAuthChoice", () => {
process.env.AI_GATEWAY_API_KEY = "gateway-test-key";
const text = vi.fn();
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const confirm = vi.fn(async () => true);
const prompter = createPrompter({ select, multiselect, text, confirm });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text, confirm });
const result = await applyAuthChoice({
authChoice: "ai-gateway-api-key",
@@ -625,13 +598,8 @@ describe("applyAuthChoice", () => {
.fn()
.mockResolvedValueOnce("cf-account-id")
.mockResolvedValueOnce("cf-gateway-id");
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const confirm = vi.fn(async () => true);
const prompter = createPrompter({ select, multiselect, text, confirm });
const runtime = createExitThrowingRuntime();
const { prompter, runtime } = createApiKeyPromptHarness({ text, confirm });
const result = await applyAuthChoice({
authChoice: "cloudflare-ai-gateway-api-key",
@@ -707,11 +675,7 @@ describe("applyAuthChoice", () => {
}
return "code_manual";
});
const select: WizardPrompter["select"] = vi.fn(
async (params) => params.options[0]?.value as never,
);
const multiselect: WizardPrompter["multiselect"] = vi.fn(async () => []);
const prompter = createPrompter({ select, multiselect, text });
const { prompter } = createApiKeyPromptHarness({ text });
const result = await applyAuthChoice({
authChoice: "chutes",

View File

@@ -0,0 +1,20 @@
import { discordPlugin } from "../../extensions/discord/src/channel.js";
import { imessagePlugin } from "../../extensions/imessage/src/channel.js";
import { signalPlugin } from "../../extensions/signal/src/channel.js";
import { slackPlugin } from "../../extensions/slack/src/channel.js";
import { telegramPlugin } from "../../extensions/telegram/src/channel.js";
import { whatsappPlugin } from "../../extensions/whatsapp/src/channel.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { createTestRegistry } from "../test-utils/channel-plugins.js";
export function setDefaultChannelPluginRegistryForTests(): void {
const channels = [
{ pluginId: "discord", plugin: discordPlugin, source: "test" },
{ pluginId: "slack", plugin: slackPlugin, source: "test" },
{ pluginId: "telegram", plugin: telegramPlugin, source: "test" },
{ pluginId: "whatsapp", plugin: whatsappPlugin, source: "test" },
{ pluginId: "signal", plugin: signalPlugin, source: "test" },
{ pluginId: "imessage", plugin: imessagePlugin, source: "test" },
] as unknown as Parameters<typeof createTestRegistry>[0];
setActivePluginRegistry(createTestRegistry(channels));
}

View File

@@ -1,12 +1,5 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { discordPlugin } from "../../extensions/discord/src/channel.js";
import { imessagePlugin } from "../../extensions/imessage/src/channel.js";
import { signalPlugin } from "../../extensions/signal/src/channel.js";
import { slackPlugin } from "../../extensions/slack/src/channel.js";
import { telegramPlugin } from "../../extensions/telegram/src/channel.js";
import { whatsappPlugin } from "../../extensions/whatsapp/src/channel.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { createTestRegistry } from "../test-utils/channel-plugins.js";
import { setDefaultChannelPluginRegistryForTests } from "./channel-test-helpers.js";
import { baseConfigSnapshot, createTestRuntime } from "./test-runtime-config-helpers.js";
const configMocks = vi.hoisted(() => ({
@@ -56,16 +49,7 @@ describe("channels command", () => {
version: 1,
profiles: {},
});
setActivePluginRegistry(
createTestRegistry([
{ pluginId: "discord", plugin: discordPlugin, source: "test" },
{ pluginId: "slack", plugin: slackPlugin, source: "test" },
{ pluginId: "telegram", plugin: telegramPlugin, source: "test" },
{ pluginId: "whatsapp", plugin: whatsappPlugin, source: "test" },
{ pluginId: "signal", plugin: signalPlugin, source: "test" },
{ pluginId: "imessage", plugin: imessagePlugin, source: "test" },
]),
);
setDefaultChannelPluginRegistryForTests();
});
it("adds a non-default telegram account", async () => {

View File

@@ -1,14 +1,7 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../config/config.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { discordPlugin } from "../../extensions/discord/src/channel.js";
import { imessagePlugin } from "../../extensions/imessage/src/channel.js";
import { signalPlugin } from "../../extensions/signal/src/channel.js";
import { slackPlugin } from "../../extensions/slack/src/channel.js";
import { telegramPlugin } from "../../extensions/telegram/src/channel.js";
import { whatsappPlugin } from "../../extensions/whatsapp/src/channel.js";
import { setActivePluginRegistry } from "../plugins/runtime.js";
import { createTestRegistry } from "../test-utils/channel-plugins.js";
import { setDefaultChannelPluginRegistryForTests } from "./channel-test-helpers.js";
import { setupChannels } from "./onboard-channels.js";
import { createExitThrowingRuntime, createWizardPrompter } from "./test-wizard-helpers.js";
@@ -40,16 +33,7 @@ vi.mock("./onboard-helpers.js", () => ({
describe("setupChannels", () => {
beforeEach(() => {
setActivePluginRegistry(
createTestRegistry([
{ pluginId: "discord", plugin: discordPlugin, source: "test" },
{ pluginId: "slack", plugin: slackPlugin, source: "test" },
{ pluginId: "telegram", plugin: telegramPlugin, source: "test" },
{ pluginId: "whatsapp", plugin: whatsappPlugin, source: "test" },
{ pluginId: "signal", plugin: signalPlugin, source: "test" },
{ pluginId: "imessage", plugin: imessagePlugin, source: "test" },
]),
);
setDefaultChannelPluginRegistryForTests();
});
it("QuickStart uses single-select (no multiselect) and doesn't prompt for Telegram token when WhatsApp is chosen", async () => {
const select = vi.fn(async () => "whatsapp");