fix: harden zai and ssh helper coverage

This commit is contained in:
Peter Steinberger 2026-03-13 19:15:25 +00:00
parent da2f85ae2b
commit 54728c60d5
3 changed files with 94 additions and 1 deletions

View File

@ -25,6 +25,20 @@ describe("fetchZaiUsage", () => {
expect(result.windows).toHaveLength(0);
});
it("falls back to a generic API error for blank unsuccessful messages", async () => {
const mockFetch = createProviderUsageFetch(async () =>
makeResponse(200, {
success: false,
code: 500,
msg: " ",
}),
);
const result = await fetchZaiUsage("key", 5000, mockFetch);
expect(result.error).toBe("API error");
expect(result.windows).toHaveLength(0);
});
it("parses token and monthly windows with reset times", async () => {
const tokenReset = "2026-01-08T00:00:00Z";
const minuteReset = "2026-01-08T00:30:00Z";
@ -83,4 +97,47 @@ describe("fetchZaiUsage", () => {
},
]);
});
it("clamps invalid percentages and falls back to alternate plan fields", async () => {
const mockFetch = createProviderUsageFetch(async () =>
makeResponse(200, {
success: true,
code: 200,
data: {
plan: "Pro",
limits: [
{
type: "TOKENS_LIMIT",
percentage: -5,
unit: 99,
},
{
type: "TIME_LIMIT",
percentage: 140,
},
{
type: "OTHER_LIMIT",
percentage: 50,
},
],
},
}),
);
const result = await fetchZaiUsage("key", 5000, mockFetch);
expect(result.plan).toBe("Pro");
expect(result.windows).toEqual([
{
label: "Tokens (Limit)",
usedPercent: 0,
resetAt: undefined,
},
{
label: "Monthly",
usedPercent: 100,
resetAt: undefined,
},
]);
});
});

View File

@ -46,11 +46,12 @@ export async function fetchZaiUsage(
const data = (await res.json()) as ZaiUsageResponse;
if (!data.success || data.code !== 200) {
const errorMessage = typeof data.msg === "string" ? data.msg.trim() : "";
return {
provider: "zai",
displayName: PROVIDER_LABELS.zai,
windows: [],
error: data.msg || "API error",
error: errorMessage || "API error",
};
}

View File

@ -58,6 +58,17 @@ describe("ssh-config", () => {
expect(parsed.identityFiles).toEqual(["/tmp/id"]);
});
it("ignores invalid ports and blank lines in ssh -G output", () => {
const parsed = parseSshConfigOutput(
"user bob\nhostname example.com\nport not-a-number\nidentityfile none\nidentityfile \n",
);
expect(parsed.user).toBe("bob");
expect(parsed.host).toBe("example.com");
expect(parsed.port).toBeUndefined();
expect(parsed.identityFiles).toEqual([]);
});
it("resolves ssh config via ssh -G", async () => {
const config = await resolveSshConfig({ user: "me", host: "alias", port: 22 });
expect(config?.user).toBe("steipete");
@ -68,6 +79,16 @@ describe("ssh-config", () => {
expect(args?.slice(-2)).toEqual(["--", "me@alias"]);
});
it("adds non-default port and trimmed identity arguments", async () => {
await resolveSshConfig(
{ user: "me", host: "alias", port: 2022 },
{ identity: " /tmp/custom_id " },
);
const args = spawnMock.mock.calls.at(-1)?.[1] as string[] | undefined;
expect(args).toEqual(["-G", "-p", "2022", "-i", "/tmp/custom_id", "--", "me@alias"]);
});
it("returns null when ssh -G fails", async () => {
spawnMock.mockImplementationOnce(
(_command: string, _args: readonly string[], _options: SpawnOptions): ChildProcess => {
@ -82,4 +103,18 @@ describe("ssh-config", () => {
const config = await resolveSshConfig({ user: "me", host: "bad-host", port: 22 });
expect(config).toBeNull();
});
it("returns null when the ssh process emits an error", async () => {
spawnMock.mockImplementationOnce(
(_command: string, _args: readonly string[], _options: SpawnOptions): ChildProcess => {
const { child } = createMockSpawnChild();
process.nextTick(() => {
child.emit("error", new Error("spawn boom"));
});
return child as unknown as ChildProcess;
},
);
await expect(resolveSshConfig({ user: "me", host: "bad-host", port: 22 })).resolves.toBeNull();
});
});