chore: consolidate test files into __tests__/ dirs and clean stray engine artifacts
- Move all co-located *.test.* files into sibling __tests__/ directories so the
layout is consistent across packages (159 renames + content-rewrite moves).
Updates relative imports, vi.mock specifiers, and __dirname/import.meta.url
path resolutions where tests read fixtures from disk.
- Drop tracked tsc-emit alongside engine .ts sources (auth-storage/logger/
skill-resolver/context-limit-detector/pi.{js,d.ts,*.map}). These were
accidentally committed in a merge and the stale pi.js was masking a real
test-mock vs source mismatch (tests imported "../pi.js" and vite preferred
the stale build over pi.ts).
- Add packages/engine/.gitignore to block future src/*.{js,d.ts,map}.
- Refactor plugin pi-module seams (openclaw/paperclip/hermes) to ESM-import
createFnAgent / promptWithFallback / describeModel from @fusion/engine
instead of require()-ing packages/engine/src/pi.js. Adds @fusion/engine to
the two plugin package.jsons that were missing it; exports describeModel
from the engine public API.
- Fix engine test mocks now that they run against current pi.ts: add
ModelRegistry.create static to mocks in pi.test.ts and pi-create-fn-agent
.test.ts; switch three boundary-result toEqual assertions to toMatchObject
so the new content/isError fields don't trip exact-match comparison.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
124
packages/cli/src/commands/__tests__/provider-auth.test.ts
Normal file
124
packages/cli/src/commands/__tests__/provider-auth.test.ts
Normal file
@@ -0,0 +1,124 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import { tempWorkspace } from "@fusion/test-utils";
|
||||
import { createReadOnlyAuthFileStorage, mergeAuthStorageReads, wrapAuthStorageWithApiKeyProviders } from "../provider-auth.js";
|
||||
|
||||
function makeAuthStorage(credentials: Record<string, { type: string; key?: string; access?: string; refresh?: string; expires?: number }> = {}) {
|
||||
return {
|
||||
reload: vi.fn(),
|
||||
getOAuthProviders: vi.fn(() => []),
|
||||
hasAuth: vi.fn((provider: string) => Boolean(credentials[provider])),
|
||||
login: vi.fn(),
|
||||
logout: vi.fn(),
|
||||
set: vi.fn((provider: string, credential: { type: string; key?: string }) => {
|
||||
credentials[provider] = credential;
|
||||
}),
|
||||
remove: vi.fn((provider: string) => {
|
||||
delete credentials[provider];
|
||||
}),
|
||||
get: vi.fn((provider: string) => credentials[provider]),
|
||||
getAll: vi.fn(() => ({ ...credentials })),
|
||||
list: vi.fn(() => Object.keys(credentials)),
|
||||
getApiKey: vi.fn(async (provider: string) => credentials[provider]?.key),
|
||||
} as any;
|
||||
}
|
||||
|
||||
describe("wrapAuthStorageWithApiKeyProviders", () => {
|
||||
it("reads API keys from Fusion auth first and legacy auth fallbacks second", async () => {
|
||||
const fusionAuth = makeAuthStorage({
|
||||
openrouter: { type: "api_key", key: "fusion-key" },
|
||||
});
|
||||
const legacyAuth = makeAuthStorage({
|
||||
openrouter: { type: "api_key", key: "legacy-openrouter-key" },
|
||||
minimax: { type: "api_key", key: "legacy-minimax-key" },
|
||||
});
|
||||
const modelRegistry = { getAll: vi.fn(() => []) } as any;
|
||||
|
||||
const wrapped = wrapAuthStorageWithApiKeyProviders(fusionAuth, modelRegistry, [legacyAuth]);
|
||||
|
||||
expect(await wrapped.getApiKey("openrouter")).toBe("fusion-key");
|
||||
expect(await wrapped.getApiKey("minimax")).toBe("legacy-minimax-key");
|
||||
expect(wrapped.hasApiKey("minimax")).toBe(true);
|
||||
expect(wrapped.get("minimax")).toEqual({ type: "api_key", key: "legacy-minimax-key" });
|
||||
});
|
||||
|
||||
it("writes API keys only to Fusion auth storage", () => {
|
||||
const fusionAuth = makeAuthStorage();
|
||||
const legacyAuth = makeAuthStorage({
|
||||
openrouter: { type: "api_key", key: "legacy-key" },
|
||||
});
|
||||
const modelRegistry = { getAll: vi.fn(() => []) } as any;
|
||||
|
||||
const wrapped = wrapAuthStorageWithApiKeyProviders(fusionAuth, modelRegistry, [legacyAuth]);
|
||||
wrapped.setApiKey("openrouter", "fusion-key");
|
||||
|
||||
expect(fusionAuth.set).toHaveBeenCalledWith("openrouter", { type: "api_key", key: "fusion-key" });
|
||||
expect(legacyAuth.set).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reloads all read stores so status reflects both locations", () => {
|
||||
const fusionAuth = makeAuthStorage();
|
||||
const legacyAuth = makeAuthStorage();
|
||||
const modelRegistry = { getAll: vi.fn(() => []) } as any;
|
||||
|
||||
const wrapped = wrapAuthStorageWithApiKeyProviders(fusionAuth, modelRegistry, [legacyAuth]);
|
||||
wrapped.reload();
|
||||
|
||||
expect(fusionAuth.reload).toHaveBeenCalledTimes(1);
|
||||
expect(legacyAuth.reload).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("creates an AuthStorage-compatible merged reader for ModelRegistry", async () => {
|
||||
const fusionAuth = makeAuthStorage({
|
||||
openrouter: { type: "api_key", key: "fusion-key" },
|
||||
});
|
||||
const legacyAuth = makeAuthStorage({
|
||||
minimax: { type: "api_key", key: "legacy-minimax-key" },
|
||||
});
|
||||
|
||||
const merged = mergeAuthStorageReads(fusionAuth, [legacyAuth]);
|
||||
|
||||
expect(await merged.getApiKey("openrouter")).toBe("fusion-key");
|
||||
expect(await merged.getApiKey("minimax")).toBe("legacy-minimax-key");
|
||||
expect(merged.get("minimax")).toEqual({ type: "api_key", key: "legacy-minimax-key" });
|
||||
expect(merged.list()).toEqual(expect.arrayContaining(["openrouter", "minimax"]));
|
||||
});
|
||||
|
||||
|
||||
it("reads legacy auth JSON without creating missing files", async () => {
|
||||
const tempDir = tempWorkspace("fusion-provider-auth-");
|
||||
const legacyAgentDir = join(tempDir, ".pi", "agent");
|
||||
const legacyAgentAuth = join(legacyAgentDir, "auth.json");
|
||||
const missingLegacyAuth = join(tempDir, ".pi", "auth.json");
|
||||
mkdirSync(legacyAgentDir, { recursive: true });
|
||||
writeFileSync(legacyAgentAuth, JSON.stringify({ openrouter: { type: "api_key", key: "legacy-key" } }));
|
||||
|
||||
const storage = createReadOnlyAuthFileStorage([legacyAgentAuth, missingLegacyAuth]);
|
||||
|
||||
expect(await storage.getApiKey("openrouter")).toBe("legacy-key");
|
||||
expect(existsSync(missingLegacyAuth)).toBe(false);
|
||||
});
|
||||
|
||||
it("reads non-expired OAuth credentials from legacy auth JSON", async () => {
|
||||
const tempDir = tempWorkspace("fusion-provider-auth-oauth-");
|
||||
const legacyAgentDir = join(tempDir, ".pi", "agent");
|
||||
const legacyAgentAuth = join(legacyAgentDir, "auth.json");
|
||||
mkdirSync(legacyAgentDir, { recursive: true });
|
||||
writeFileSync(
|
||||
legacyAgentAuth,
|
||||
JSON.stringify({
|
||||
"openai-codex": {
|
||||
type: "oauth",
|
||||
access: "legacy-access-token",
|
||||
refresh: "legacy-refresh-token",
|
||||
expires: Date.now() + 60_000,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
const storage = createReadOnlyAuthFileStorage([legacyAgentAuth]);
|
||||
|
||||
expect(await storage.getApiKey("openai-codex")).toBe("legacy-access-token");
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user