pi-mono/packages/coding-agent/test/provider-matching.test.ts
Vegard Stikbakke 9b9cb30ae1 feat(coding-agent): add pi auth login and logout
pi auth login <provider> logs in from the shell without starting a
session, like pi mcp login. Account sign-in is the default and takes
the provider's browser method; when the provider has another method,
it prints a hint to rerun with --no-browser. --no-browser skips the
browser method and uses the other one, such as device code, asking
only when there are several. --api-key saves an API key instead and
cannot be combined with --no-browser. After logging in, it fetches the
provider's model catalog, and for Radius it points the Radius MCP
server in the global mcp.json at the login without asking.

pi auth logout <provider> removes the stored credentials like /logout
and succeeds when nothing is stored. For MCP servers that use provider
credentials, pi mcp login and logout now refer to these commands
instead of /login and /logout.

/login shares the check for the Radius MCP server entry and the web
URL helpers with the new command.
2026-11-05 12:07:14 +01:00

35 lines
1.5 KiB
TypeScript

import { describe, expect, test } from "vitest";
import { findMatchingProviders } from "../src/core/provider-matching.ts";
const providers = [
{ id: "first", name: "Shared Name", authType: "oauth" },
{ id: "first", name: "Shared Name", authType: "api_key" },
{ id: "other", name: "FIRST", authType: "api_key" },
{ id: "second", name: "Second Provider", authType: "oauth" },
];
describe("provider reference matching", () => {
test("matches IDs and display names case-insensitively with surrounding whitespace", () => {
expect(findMatchingProviders(providers, " sEcOnD ")).toEqual([providers[3]]);
expect(findMatchingProviders(providers, "\tSECOND PROVIDER\n")).toEqual([providers[3]]);
});
test("keeps all matching providers and auth methods in input order", () => {
const matched = findMatchingProviders(providers, "first");
expect(matched).toEqual(providers.slice(0, 3));
expect(matched[0]).toBe(providers[0]);
expect(matched[1]?.authType).toBe("api_key");
expect(findMatchingProviders(providers, "shared name")).toEqual(providers.slice(0, 2));
});
test("does not fuzzy-match unknown or partial references", () => {
expect(findMatchingProviders(providers, "unknown")).toEqual([]);
expect(findMatchingProviders(providers, "sec")).toEqual([]);
expect(findMatchingProviders([], "first")).toEqual([]);
});
test("never matches an empty reference, even against empty display names", () => {
expect(findMatchingProviders([{ id: "unnamed", name: "" }], "")).toEqual([]);
expect(findMatchingProviders(providers, " \t ")).toEqual([]);
});
});