Replaces legacy adapter ids (codex_local / claude_local / gemini_local / claude_compatible) across ~42 test files with pi-mono equivalents: - codex_local → openai-codex - claude_local → claude-pro - gemini_local → gemini-cli - claude_compatible → anthropic Hand-rewrites where fixture semantics changed: - connector-matching: TASK_TYPE_PREFERENCE ordering rebased (claude-pro first for code/content/management; google first for research) - connector-model-policy: getModels(provider) from pi-ai instead of the deleted adapter.module.models array - session-management + edge-case-session: adapter exemption removed; rotation now uniform under pi-mono - ipc-core-admin-handlers: CSV compat model replaced with pi-ai anthropic - connectors.spec: lookup by openai-codex id (catalog now starts with claude-pro) - onboarding-model-pool: listProviderModels(provider) helper; label text changed to "ChatGPT Plus/Pro (Codex)" - database integration: added vault insecure-fallback env + electron mock - command-paths: uses new @main/connector-helpers normalizeCommandValue - pi-mono-migrations: added `as string` casts for 3 negative-existence assertions verifying legacy ids were removed Drops: - pnpm-workspace.yaml packages: [] (was "packages/*"; directory empty) - obsolete CONNECTOR_STRENGTHS import; .module.models probing Verification: - pnpm typecheck → 0 errors - pnpm lint → 0 errors / 0 warnings - pnpm build:verify → 0 errors / 0 warnings - pnpm test:unit → 508/508 pass - pnpm test:integration → 96/96 pass - All 6 adapter hard gates pass (NOT FOUND / 0 matches / empty) - pi-ai / pi-agent-core / pi-coding-agent all resolved @0.67.6
144 lines
5.4 KiB
TypeScript
144 lines
5.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
apiKeyValueSchema,
|
|
awsCredentialSchema,
|
|
azureCredentialSchema,
|
|
credentialPayloadSchema,
|
|
gcpAdcCredentialSchema,
|
|
removeCredentialInputSchema,
|
|
saveCredentialInputSchema,
|
|
testCredentialInputSchema,
|
|
} from "../../src/shared/contracts/schemas-credentials";
|
|
import {
|
|
oauthCancelInputSchema,
|
|
oauthManualCodeResponseSchema,
|
|
oauthPromptResponseSchema,
|
|
oauthStartInputSchema,
|
|
} from "../../src/shared/contracts/schemas-oauth";
|
|
|
|
/** Verifies the IPC payload schemas reject malformed input and accept valid
|
|
* shapes. These are the only contract between renderer ↔ main for the new
|
|
* credential / OAuth channels — incorrect validation would let bad data
|
|
* reach pi-mono primitives. */
|
|
|
|
describe("credentials Zod schemas", () => {
|
|
it("apiKeyValueSchema rejects empty value", () => {
|
|
const result = apiKeyValueSchema.safeParse({ source: "literal", value: "" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("apiKeyValueSchema accepts both source kinds", () => {
|
|
expect(apiKeyValueSchema.safeParse({ source: "literal", value: "sk-x" }).success).toBe(true);
|
|
expect(apiKeyValueSchema.safeParse({ source: "env", value: "MY_KEY" }).success).toBe(true);
|
|
});
|
|
|
|
it("apiKeyValueSchema rejects unknown source", () => {
|
|
const result = apiKeyValueSchema.safeParse({ source: "shell", value: "$(echo x)" });
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("awsCredentialSchema requires authMode", () => {
|
|
expect(awsCredentialSchema.safeParse({ region: "us-east-1" }).success).toBe(false);
|
|
expect(awsCredentialSchema.safeParse({ authMode: "profile", region: "us-east-1", awsProfile: "default" }).success).toBe(true);
|
|
});
|
|
|
|
it("awsCredentialSchema accepts all three auth modes", () => {
|
|
for (const authMode of ["profile", "iam", "bearer"] as const) {
|
|
const result = awsCredentialSchema.safeParse({ authMode, region: "us-east-1" });
|
|
expect(result.success).toBe(true);
|
|
}
|
|
});
|
|
|
|
it("azureCredentialSchema requires apiKey", () => {
|
|
expect(azureCredentialSchema.safeParse({}).success).toBe(false);
|
|
expect(azureCredentialSchema.safeParse({ apiKey: "azure-secret" }).success).toBe(true);
|
|
});
|
|
|
|
it("gcpAdcCredentialSchema requires project + location", () => {
|
|
expect(gcpAdcCredentialSchema.safeParse({ project: "" }).success).toBe(false);
|
|
expect(gcpAdcCredentialSchema.safeParse({ project: "p", location: "us-central1" }).success).toBe(true);
|
|
});
|
|
|
|
it("credentialPayloadSchema discriminates on kind", () => {
|
|
expect(
|
|
credentialPayloadSchema.safeParse({
|
|
kind: "api_key",
|
|
value: { source: "literal", value: "sk-x" },
|
|
}).success,
|
|
).toBe(true);
|
|
expect(
|
|
credentialPayloadSchema.safeParse({
|
|
kind: "azure",
|
|
value: { source: "literal", value: "wrong-shape" },
|
|
}).success,
|
|
).toBe(false);
|
|
});
|
|
|
|
it("saveCredentialInputSchema requires connectorId + payload", () => {
|
|
expect(
|
|
saveCredentialInputSchema.safeParse({
|
|
connectorId: "anthropic",
|
|
payload: { kind: "api_key", value: { source: "literal", value: "sk-x" } },
|
|
}).success,
|
|
).toBe(true);
|
|
expect(saveCredentialInputSchema.safeParse({ connectorId: "" }).success).toBe(false);
|
|
expect(saveCredentialInputSchema.safeParse({ payload: {} }).success).toBe(false);
|
|
});
|
|
|
|
it("removeCredentialInputSchema rejects empty connectorId", () => {
|
|
expect(removeCredentialInputSchema.safeParse({ connectorId: "openai" }).success).toBe(true);
|
|
expect(removeCredentialInputSchema.safeParse({ connectorId: "" }).success).toBe(false);
|
|
expect(removeCredentialInputSchema.safeParse({}).success).toBe(false);
|
|
});
|
|
|
|
it("testCredentialInputSchema rejects empty connectorId", () => {
|
|
expect(testCredentialInputSchema.safeParse({ connectorId: "openai" }).success).toBe(true);
|
|
expect(testCredentialInputSchema.safeParse({ connectorId: "" }).success).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("oauth Zod schemas", () => {
|
|
it("oauthStartInputSchema rejects empty connectorId", () => {
|
|
expect(oauthStartInputSchema.safeParse({ connectorId: "claude-pro" }).success).toBe(true);
|
|
expect(oauthStartInputSchema.safeParse({ connectorId: "" }).success).toBe(false);
|
|
});
|
|
|
|
it("oauthCancelInputSchema rejects missing connectorId", () => {
|
|
expect(oauthCancelInputSchema.safeParse({ connectorId: "claude-pro" }).success).toBe(true);
|
|
expect(oauthCancelInputSchema.safeParse({}).success).toBe(false);
|
|
});
|
|
|
|
it("oauthPromptResponseSchema requires connectorId, requestId and a (possibly empty) value", () => {
|
|
expect(
|
|
oauthPromptResponseSchema.safeParse({
|
|
connectorId: "github-copilot",
|
|
requestId: "req-1",
|
|
value: "github.com",
|
|
}).success,
|
|
).toBe(true);
|
|
expect(
|
|
oauthPromptResponseSchema.safeParse({ connectorId: "github-copilot", requestId: "" }).success,
|
|
).toBe(false);
|
|
expect(
|
|
oauthPromptResponseSchema.safeParse({ connectorId: "github-copilot", value: "x" }).success,
|
|
).toBe(false);
|
|
});
|
|
|
|
it("oauthManualCodeResponseSchema requires non-empty code", () => {
|
|
expect(
|
|
oauthManualCodeResponseSchema.safeParse({
|
|
connectorId: "anthropic",
|
|
requestId: "req-1",
|
|
code: "abcd",
|
|
}).success,
|
|
).toBe(true);
|
|
expect(
|
|
oauthManualCodeResponseSchema.safeParse({
|
|
connectorId: "anthropic",
|
|
requestId: "req-1",
|
|
code: "",
|
|
}).success,
|
|
).toBe(false);
|
|
});
|
|
});
|