perf: speed up auth choice tests

This commit is contained in:
Peter Steinberger
2026-04-25 08:31:36 +01:00
parent 5fe333ada8
commit e9b27ed2a6
4 changed files with 86 additions and 50 deletions

View File

@@ -255,6 +255,10 @@ const SOURCE_TEST_TARGETS = new Map([
["extensions/google-meet/src/oauth.ts", ["extensions/google-meet/src/oauth.test.ts"]],
["src/commands/doctor-memory-search.ts", ["src/commands/doctor-memory-search.test.ts"]],
["src/agents/live-model-turn-probes.ts", ["src/agents/live-model-turn-probes.test.ts"]],
[
"src/plugins/provider-auth-choice.ts",
["src/commands/auth-choice.apply.plugin-provider.test.ts", "src/commands/auth-choice.test.ts"],
],
[
"src/memory-host-sdk/host/embedding-defaults.ts",
["src/memory-host-sdk/host/embeddings.test.ts"],

View File

@@ -5,6 +5,7 @@ import { resolveAgentDir } from "../agents/agent-scope.js";
import type { OpenClawConfig } from "../config/config.js";
import { resolveAgentModelPrimaryValue } from "../config/model-input.js";
import type { ModelProviderConfig } from "../config/types.models.js";
import { __testing as providerAuthChoiceTesting } from "../plugins/provider-auth-choice.js";
import * as providerAuthChoices from "../plugins/provider-auth-choices.js";
import type { ProviderAuthMethod, ProviderAuthResult, ProviderPlugin } from "../plugins/types.js";
import type { WizardPrompter } from "../wizard/prompts.js";
@@ -25,43 +26,10 @@ const ZAI_CODING_CN_BASE_URL = "https://open.bigmodel.cn/api/coding/paas/v4";
const resolvePluginProviders = vi.hoisted(() => vi.fn<() => ProviderPlugin[]>(() => []));
const runProviderModelSelectedHook = vi.hoisted(() => vi.fn(async () => {}));
vi.mock("../plugins/provider-auth-choice.runtime.js", () => {
const normalizeProviderId = (value: string) => value.trim().toLowerCase();
return {
resolvePluginProviders,
resolveProviderPluginChoice: (params: { providers: ProviderPlugin[]; choice: string }) => {
const choice = params.choice.trim();
if (!choice) {
return null;
}
if (choice.startsWith("provider-plugin:")) {
const payload = choice.slice("provider-plugin:".length);
const separator = payload.indexOf(":");
const providerId = separator >= 0 ? payload.slice(0, separator) : payload;
const methodId = separator >= 0 ? payload.slice(separator + 1) : undefined;
const provider = params.providers.find(
(entry) => normalizeProviderId(entry.id) === normalizeProviderId(providerId),
);
const method = methodId
? provider?.auth.find((entry) => entry.id === methodId)
: provider?.auth[0];
return provider && method ? { provider, method } : null;
}
for (const provider of params.providers) {
for (const method of provider.auth) {
if (method.wizard?.choiceId === choice) {
return { provider, method, wizard: method.wizard };
}
}
if (normalizeProviderId(provider.id) === normalizeProviderId(choice) && provider.auth[0]) {
return { provider, method: provider.auth[0] };
}
}
return null;
},
runProviderModelSelectedHook,
};
});
vi.mock("../plugins/provider-install-catalog.js", () => ({
resolveProviderInstallCatalogEntry: vi.fn(() => undefined),
}));
vi.mock("./auth-choice.apply.api-providers.js", () => {
const normalizeProviderId = (value: string) => value.trim().toLowerCase();
@@ -208,6 +176,41 @@ function normalizeText(value: unknown): string {
return typeof value === "string" ? value.trim() : "";
}
function normalizeProviderId(value: string): string {
return value.trim().toLowerCase();
}
function resolveProviderPluginChoice(params: { providers: ProviderPlugin[]; choice: string }) {
const choice = params.choice.trim();
if (!choice) {
return null;
}
if (choice.startsWith("provider-plugin:")) {
const payload = choice.slice("provider-plugin:".length);
const separator = payload.indexOf(":");
const providerId = separator >= 0 ? payload.slice(0, separator) : payload;
const methodId = separator >= 0 ? payload.slice(separator + 1) : undefined;
const provider = params.providers.find(
(entry) => normalizeProviderId(entry.id) === normalizeProviderId(providerId),
);
const method = methodId
? provider?.auth.find((entry) => entry.id === methodId)
: provider?.auth[0];
return provider && method ? { provider, method } : null;
}
for (const provider of params.providers) {
for (const method of provider.auth) {
if (method.wizard?.choiceId === choice) {
return { provider, method, wizard: method.wizard };
}
}
if (normalizeProviderId(provider.id) === normalizeProviderId(choice) && provider.auth[0]) {
return { provider, method: provider.auth[0] };
}
}
return null;
}
function providerConfigPatch(
providerId: string,
patch: Record<string, unknown>,
@@ -618,9 +621,17 @@ describe("applyAuthChoice", () => {
authTestRoot = (await setupAuthTestEnv("openclaw-auth-")).stateDir;
defaultProviderPlugins = await createDefaultProviderPlugins();
resolvePluginProviders.mockReturnValue(defaultProviderPlugins);
providerAuthChoiceTesting.setDepsForTest({
loadPluginProviderRuntime: async () => ({
resolvePluginProviders,
resolveProviderPluginChoice,
runProviderModelSelectedHook,
}),
});
});
afterAll(async () => {
providerAuthChoiceTesting.resetDepsForTest();
if (authTestRoot) {
await fs.rm(authTestRoot, { recursive: true, force: true });
}
@@ -693,17 +704,26 @@ describe("applyAuthChoice", () => {
});
it("fails fast when a removed provider auth choice is passed to the interactive flow", async () => {
await expect(
applyAuthChoice({
authChoice: "openai-codex-import",
config: {},
prompter: createPrompter({}),
runtime: createExitThrowingRuntime(),
setDefaultModel: true,
}),
).rejects.toThrow(
'Auth choice "openai-codex-import" is no longer supported. Use "openai-codex" instead.',
);
const spy = vi
.spyOn(providerAuthChoices, "resolveManifestDeprecatedProviderAuthChoice")
.mockReturnValueOnce({
choiceId: "openai-codex",
} as never);
try {
await expect(
applyAuthChoice({
authChoice: "openai-codex-import",
config: {},
prompter: createPrompter({}),
runtime: createExitThrowingRuntime(),
setDefaultModel: true,
}),
).rejects.toThrow(
'Auth choice "openai-codex-import" is no longer supported. Use "openai-codex" instead.',
);
} finally {
spy.mockRestore();
}
});
it("escapes removed provider auth choice guidance for terminal output", async () => {

View File

@@ -6,12 +6,10 @@ import {
} from "../agents/agent-scope.js";
import { upsertAuthProfile } from "../agents/auth-profiles.js";
import { resolveDefaultAgentWorkspaceDir } from "../agents/workspace.js";
import { ensureOnboardingPluginInstalled } from "../commands/onboarding-plugin-install.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import type { RuntimeEnv } from "../runtime.js";
import { sanitizeTerminalText } from "../terminal/safe-text.js";
import type { WizardPrompter } from "../wizard/prompts.js";
import { clearPluginDiscoveryCache } from "./discovery.js";
import { enablePluginInConfig } from "./enable.js";
import {
applyProviderAuthConfigPatch,
@@ -290,6 +288,10 @@ export async function applyAuthChoiceLoadedPluginProvider(
choice: params.authChoice,
});
if (!resolved && installCatalogEntry) {
const [{ ensureOnboardingPluginInstalled }, { clearPluginDiscoveryCache }] = await Promise.all([
import("../commands/onboarding-plugin-install.js"),
import("./discovery.js"),
]);
const installResult = await ensureOnboardingPluginInstalled({
cfg: nextConfig,
entry: {

View File

@@ -339,6 +339,16 @@ describe("scripts/test-projects changed-target routing", () => {
});
});
it("routes provider auth choice edits to focused auth-choice tests", () => {
expect(resolveChangedTestTargetPlan(["src/plugins/provider-auth-choice.ts"])).toEqual({
mode: "targets",
targets: [
"src/commands/auth-choice.apply.plugin-provider.test.ts",
"src/commands/auth-choice.test.ts",
],
});
});
it("routes changed utils and shared files to their light scoped lanes", () => {
const plans = buildVitestRunPlans(["--changed", "origin/main"], process.cwd(), () => [
"src/shared/string-normalization.ts",