From f7983a07a49ecf6abd887cd985d43a239383f14c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Mon, 27 Apr 2026 23:45:18 +0100 Subject: [PATCH] refactor: move plugin runtime env helper --- .../test-utils/plugin-runtime-env.ts | 0 test/helpers/plugins/setup-wizard.ts | 344 ------------------ 2 files changed, 344 deletions(-) rename test/helpers/plugins/runtime-env.ts => src/test-utils/plugin-runtime-env.ts (100%) delete mode 100644 test/helpers/plugins/setup-wizard.ts diff --git a/test/helpers/plugins/runtime-env.ts b/src/test-utils/plugin-runtime-env.ts similarity index 100% rename from test/helpers/plugins/runtime-env.ts rename to src/test-utils/plugin-runtime-env.ts diff --git a/test/helpers/plugins/setup-wizard.ts b/test/helpers/plugins/setup-wizard.ts deleted file mode 100644 index d05af97010e..00000000000 --- a/test/helpers/plugins/setup-wizard.ts +++ /dev/null @@ -1,344 +0,0 @@ -import { vi, type Mock } from "vitest"; -import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js"; -import type { ChannelPlugin } from "../../../src/channels/plugins/types.js"; -import type { WizardPrompter } from "../../../src/wizard/prompts.js"; -import { createRuntimeEnv } from "./runtime-env.js"; - -export type { WizardPrompter } from "../../../src/wizard/prompts.js"; -type UnknownMock = Mock<(...args: unknown[]) => unknown>; -type AsyncUnknownMock = Mock<(...args: unknown[]) => Promise>; -type QueuedWizardPrompter = { - intro: AsyncUnknownMock; - outro: AsyncUnknownMock; - note: AsyncUnknownMock; - select: AsyncUnknownMock; - multiselect: AsyncUnknownMock; - text: AsyncUnknownMock; - confirm: AsyncUnknownMock; - progress: Mock<() => { update: UnknownMock; stop: UnknownMock }>; - prompter: WizardPrompter; -}; - -export async function selectFirstWizardOption(params: { - options: Array<{ value: T }>; -}): Promise { - const first = params.options[0]; - if (!first) { - throw new Error("no options"); - } - return first.value; -} - -export function createTestWizardPrompter(overrides: Partial = {}): 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, - }; -} - -export function createQueuedWizardPrompter(params?: { - selectValues?: string[]; - textValues?: string[]; - confirmValues?: boolean[]; -}): QueuedWizardPrompter { - const selectValues = [...(params?.selectValues ?? [])]; - const textValues = [...(params?.textValues ?? [])]; - const confirmValues = [...(params?.confirmValues ?? [])]; - - const intro = vi.fn(async () => undefined); - const outro = vi.fn(async () => undefined); - const note = vi.fn(async () => undefined); - const select = vi.fn(async () => selectValues.shift() ?? ""); - const multiselect = vi.fn(async () => [] as string[]); - const text = vi.fn(async () => textValues.shift() ?? ""); - const confirm = vi.fn(async () => confirmValues.shift() ?? false); - const progress = vi.fn(() => ({ - update: vi.fn(), - stop: vi.fn(), - })); - - return { - intro, - outro, - note, - select, - multiselect, - text, - confirm, - progress, - prompter: createTestWizardPrompter({ - intro, - outro, - note, - select: select as WizardPrompter["select"], - multiselect: multiselect as WizardPrompter["multiselect"], - text: text as WizardPrompter["text"], - confirm, - progress, - }), - }; -} - -type SetupWizardAdapterParams = Parameters[0]; -type SetupWizardPlugin = SetupWizardAdapterParams["plugin"]; -type SetupWizard = NonNullable; -type SetupWizardCredentialValues = Record; -type SetupWizardTestPlugin = { - id: string; - setupWizard?: ChannelPlugin["setupWizard"]; - config: Record; -} & Record; - -function isDeclarativeSetupWizard( - setupWizard: ChannelPlugin["setupWizard"], -): setupWizard is SetupWizard { - return Boolean( - setupWizard && - typeof setupWizard === "object" && - "status" in setupWizard && - "credentials" in setupWizard, - ); -} - -function requireDeclarativeSetupWizard(plugin: SetupWizardTestPlugin): SetupWizard { - const { setupWizard } = plugin; - if (!setupWizard) { - throw new Error(`${plugin.id} is missing setupWizard`); - } - if (!isDeclarativeSetupWizard(setupWizard)) { - throw new Error(`${plugin.id} setupWizard is adapter-shaped; test helper expects a wizard`); - } - return setupWizard; -} - -function resolveSetupWizardAccountContext(params: { - cfg?: TCfg; - accountId?: string; - credentialValues?: SetupWizardCredentialValues; -}) { - return { - cfg: (params.cfg ?? {}) as TCfg, - accountId: params.accountId ?? "default", - credentialValues: params.credentialValues ?? {}, - }; -} - -function resolveSetupWizardRuntime(runtime?: TRuntime): TRuntime { - return (runtime ?? createRuntimeEnv({ throwOnExit: false })) as TRuntime; -} - -function resolveSetupWizardPrompter(prompter?: WizardPrompter): WizardPrompter { - return prompter ?? createTestWizardPrompter(); -} - -function resolveSetupWizardNotePrompter(prompter?: Pick) { - return ( - prompter ?? - ({ - note: vi.fn(async () => undefined), - } satisfies Pick) - ); -} - -export function createSetupWizardAdapter(params: SetupWizardAdapterParams) { - return buildChannelSetupWizardAdapterFromSetupWizard(params); -} - -export function createPluginSetupWizardAdapter(plugin: SetupWizardTestPlugin) { - const wizard = requireDeclarativeSetupWizard(plugin); - return createSetupWizardAdapter({ - plugin: plugin as unknown as SetupWizardPlugin, - wizard, - }); -} - -export function createPluginSetupWizardConfigure(plugin: SetupWizardTestPlugin) { - return createPluginSetupWizardAdapter(plugin).configure; -} - -export function createPluginSetupWizardStatus(plugin: SetupWizardTestPlugin) { - return createPluginSetupWizardAdapter(plugin).getStatus; -} - -export async function runSetupWizardConfigure< - TCfg, - TOptions extends Record, - TAccountOverrides extends Record, - TRuntime, - TResult, ->(params: { - configure: (args: { - cfg: TCfg; - runtime: TRuntime; - prompter: WizardPrompter; - options: TOptions; - accountOverrides: TAccountOverrides; - shouldPromptAccountIds: boolean; - forceAllowFrom: boolean; - }) => Promise; - cfg?: TCfg; - runtime?: TRuntime; - prompter: WizardPrompter; - options?: TOptions; - accountOverrides?: TAccountOverrides; - shouldPromptAccountIds?: boolean; - forceAllowFrom?: boolean; -}): Promise { - return await params.configure({ - cfg: (params.cfg ?? {}) as TCfg, - runtime: (params.runtime ?? createRuntimeEnv()) as TRuntime, - prompter: params.prompter, - options: (params.options ?? {}) as TOptions, - accountOverrides: (params.accountOverrides ?? {}) as TAccountOverrides, - shouldPromptAccountIds: params.shouldPromptAccountIds ?? false, - forceAllowFrom: params.forceAllowFrom ?? false, - }); -} - -export async function runSetupWizardPrepare< - TCfg, - TOptions extends Record, - TRuntime, - TResult, ->(params: { - prepare?: (args: { - cfg: TCfg; - accountId: string; - credentialValues: Record; - runtime: TRuntime; - prompter: WizardPrompter; - options?: TOptions; - }) => Promise | TResult; - cfg?: TCfg; - accountId?: string; - credentialValues?: Record; - runtime?: TRuntime; - prompter?: WizardPrompter; - options?: TOptions; -}): Promise { - const context = resolveSetupWizardAccountContext({ - cfg: params.cfg, - accountId: params.accountId, - credentialValues: params.credentialValues, - }); - return await params.prepare?.({ - ...context, - runtime: resolveSetupWizardRuntime(params.runtime), - prompter: resolveSetupWizardPrompter(params.prompter), - options: params.options, - }); -} - -export async function runSetupWizardFinalize< - TCfg, - TOptions extends Record, - TRuntime, - TResult, ->(params: { - finalize?: (args: { - cfg: TCfg; - accountId: string; - credentialValues: Record; - runtime: TRuntime; - prompter: WizardPrompter; - options?: TOptions; - forceAllowFrom: boolean; - }) => Promise | TResult; - cfg?: TCfg; - accountId?: string; - credentialValues?: Record; - runtime?: TRuntime; - prompter?: WizardPrompter; - options?: TOptions; - forceAllowFrom?: boolean; -}): Promise { - const context = resolveSetupWizardAccountContext({ - cfg: params.cfg, - accountId: params.accountId, - credentialValues: params.credentialValues, - }); - return await params.finalize?.({ - ...context, - runtime: resolveSetupWizardRuntime(params.runtime), - prompter: resolveSetupWizardPrompter(params.prompter), - options: params.options, - forceAllowFrom: params.forceAllowFrom ?? false, - }); -} - -export async function promptSetupWizardAllowFrom(params: { - promptAllowFrom?: (args: { - cfg: TCfg; - prompter: WizardPrompter; - accountId: string; - }) => Promise | TResult; - cfg?: TCfg; - prompter?: WizardPrompter; - accountId?: string; -}): Promise { - const context = resolveSetupWizardAccountContext({ - cfg: params.cfg, - accountId: params.accountId, - }); - return await params.promptAllowFrom?.({ - cfg: context.cfg, - accountId: context.accountId, - prompter: resolveSetupWizardPrompter(params.prompter), - }); -} - -export async function resolveSetupWizardAllowFromEntries(params: { - resolveEntries?: (args: { - cfg: TCfg; - accountId: string; - credentialValues: Record; - entries: string[]; - }) => Promise | TResult; - entries: string[]; - cfg?: TCfg; - accountId?: string; - credentialValues?: SetupWizardCredentialValues; -}): Promise { - const context = resolveSetupWizardAccountContext({ - cfg: params.cfg, - accountId: params.accountId, - credentialValues: params.credentialValues, - }); - return await params.resolveEntries?.({ - ...context, - entries: params.entries, - }); -} - -export async function resolveSetupWizardGroupAllowlist(params: { - resolveAllowlist?: (args: { - cfg: TCfg; - accountId: string; - credentialValues: Record; - entries: string[]; - prompter: Pick; - }) => Promise | TResult; - entries: string[]; - cfg?: TCfg; - accountId?: string; - credentialValues?: SetupWizardCredentialValues; - prompter?: Pick; -}): Promise { - const context = resolveSetupWizardAccountContext({ - cfg: params.cfg, - accountId: params.accountId, - credentialValues: params.credentialValues, - }); - return await params.resolveAllowlist?.({ - ...context, - entries: params.entries, - prompter: resolveSetupWizardNotePrompter(params.prompter), - }); -}