test: push coverage to 90%+ on lines for all files except execute.ts (FAR-85)

Overall before: 80.36% lines / 79.06% statements
Overall after:  94.65% lines / 93.30% statements

Per-file lines coverage (all targets ≥90% except execute.ts):

| File              | Before | After  |
|-------------------|--------|--------|
| ui-parser.ts      | 93.63% | 99.09% |
| cli/format-event  | 59.85% | 99.27% |
| server/execute    | 81.47% | 89.64% |
| server/job-mfst   | 90.30% | 98.78% |
| server/k8s-client | 37.50% | 95.83% |
| server/log-dedup  | 97.77% | 97.77% |
| server/parse      | 89.85% | 98.55% |
| server/skills     | 100%   | 100%   |

New tests added:

- k8s-client.test.ts: getSelfPodInfo (env-var inheritance, secret volumes,
  PVC discovery, dnsConfig, all error paths) + kubeconfig file branch
- format-event.test.ts: parseStdoutLine (cli) — full event-type matrix,
  tool_use status branches, errorText fallback paths
- ui-parser.test.ts: errorText edge cases, empty event paths
- parse.test.ts: errorText fallback to data.message, name, code, JSON
- job-manifest.test.ts: workspace context env wiring, linkedIssueIds,
  paperclipWorkspaces/RuntimeServices JSON, authToken, inherited URLs,
  prompt-secret + data PVC + secret-volume mount paths
- execute.test.ts: parseModelProvider, completionWithGrace,
  instructionsFilePath read failure, ensureAgentDbPvc throw paths,
  large-prompt secret create failure, step-limit detection,
  waitForPod no-pod messaging, init-container ImagePullBackOff /
  CrashLoopBackOff, main-container CrashLoopBackOff, all-inits-done
  happy path, skill bundle source loading (SKILL.md + flat-file
  fallback), SIGTERM handler full body via vi.resetModules()

execute.ts remains at 89.64% lines — the residual gap is deep async/timer
paths inside streamAndAwaitJob (grace poller, keepalive ticker, log-stream
stop-signal/bail timer). Those need fake-timer scaffolding heavier than
this batch warrants; tracking separately.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
2026-04-25 22:27:04 +00:00
committed by Hugh Commit [agent]
parent 693016d1ab
commit 798b80f2f2
8 changed files with 897 additions and 5 deletions
+107
View File
@@ -406,3 +406,110 @@ describe("sanitizeLabelValue", () => {
expect(warned.length).toBe(1);
});
});
describe("buildJobManifest — env wiring branches", () => {
it("sets PAPERCLIP_WAKE_PAYLOAD_JSON when paperclipWake is provided", () => {
const ctx = { ...mockCtx, context: { ...mockCtx.context, paperclipWake: { reason: "issue_assigned", issue: { id: "x" } } } };
const result = buildJobManifest({ ctx, selfPod: mockSelfPod });
const env = result.job.spec?.template.spec?.containers[0]?.env ?? [];
expect(env.find((e) => e.name === "PAPERCLIP_WAKE_PAYLOAD_JSON")?.value).toBeTruthy();
});
it("forwards workspace context and AGENT_HOME from paperclipWorkspace", () => {
const ctx = {
...mockCtx,
context: {
...mockCtx.context,
paperclipWorkspace: {
cwd: "/work",
source: "main",
strategy: "shared",
workspaceId: "ws_1",
repoUrl: "https://example.com/r.git",
repoRef: "main",
branchName: "feature/x",
worktreePath: "/wt/x",
agentHome: "/home/agent",
},
},
};
const result = buildJobManifest({ ctx, selfPod: mockSelfPod });
const env = result.job.spec?.template.spec?.containers[0]?.env ?? [];
expect(env.find((e) => e.name === "PAPERCLIP_WORKSPACE_CWD")?.value).toBe("/work");
expect(env.find((e) => e.name === "PAPERCLIP_WORKSPACE_BRANCH")?.value).toBe("feature/x");
expect(env.find((e) => e.name === "AGENT_HOME")?.value).toBe("/home/agent");
});
it("sets PAPERCLIP_LINKED_ISSUE_IDS from non-empty issueIds array (skipping blanks)", () => {
const ctx = { ...mockCtx, context: { ...mockCtx.context, issueIds: ["a", " ", "b", null as unknown as string, "c"] } };
const result = buildJobManifest({ ctx, selfPod: mockSelfPod });
const env = result.job.spec?.template.spec?.containers[0]?.env ?? [];
expect(env.find((e) => e.name === "PAPERCLIP_LINKED_ISSUE_IDS")?.value).toBe("a,b,c");
});
it("encodes paperclipWorkspaces / paperclipRuntimeServiceIntents / paperclipRuntimeServices as JSON env", () => {
const ctx = {
...mockCtx,
context: {
...mockCtx.context,
paperclipWorkspaces: [{ id: "w1" }],
paperclipRuntimeServiceIntents: [{ name: "redis" }],
paperclipRuntimeServices: [{ name: "redis", url: "redis://r" }],
paperclipRuntimePrimaryUrl: "https://primary",
},
};
const result = buildJobManifest({ ctx, selfPod: mockSelfPod });
const env = result.job.spec?.template.spec?.containers[0]?.env ?? [];
expect(env.find((e) => e.name === "PAPERCLIP_WORKSPACES_JSON")?.value).toContain("w1");
expect(env.find((e) => e.name === "PAPERCLIP_RUNTIME_SERVICE_INTENTS_JSON")?.value).toContain("redis");
expect(env.find((e) => e.name === "PAPERCLIP_RUNTIME_SERVICES_JSON")?.value).toContain("redis://r");
expect(env.find((e) => e.name === "PAPERCLIP_RUNTIME_PRIMARY_URL")?.value).toBe("https://primary");
});
it("sets PAPERCLIP_API_KEY from ctx.authToken when provided", () => {
const ctx = { ...mockCtx, authToken: "tok_abc" };
const result = buildJobManifest({ ctx, selfPod: mockSelfPod });
const env = result.job.spec?.template.spec?.containers[0]?.env ?? [];
expect(env.find((e) => e.name === "PAPERCLIP_API_KEY")?.value).toBe("tok_abc");
});
it("inherits PAPERCLIP_API_URL and PAPERCLIP_DEV_API_KEY from selfPod inheritedEnv", () => {
const selfPod = {
...mockSelfPod,
inheritedEnv: { PAPERCLIP_API_URL: "http://api", PAPERCLIP_DEV_API_KEY: "dev_key" },
};
const result = buildJobManifest({ ctx: mockCtx, selfPod });
const env = result.job.spec?.template.spec?.containers[0]?.env ?? [];
expect(env.find((e) => e.name === "PAPERCLIP_API_URL")?.value).toBe("http://api");
expect(env.find((e) => e.name === "PAPERCLIP_DEV_API_KEY")?.value).toBe("dev_key");
});
});
describe("buildJobManifest — volume wiring branches", () => {
it("mounts the prompt secret volume when promptSecretName is provided", () => {
const result = buildJobManifest({ ctx: mockCtx, selfPod: mockSelfPod, promptSecretName: "prompt-x" });
const volumes = result.job.spec?.template.spec?.volumes ?? [];
expect(volumes.find((v) => v.name === "prompt-secret")?.secret?.secretName).toBe("prompt-x");
});
it("mounts the data PVC at /paperclip when selfPod has a pvcClaimName", () => {
const selfPod = { ...mockSelfPod, pvcClaimName: "paperclip-data" };
const result = buildJobManifest({ ctx: mockCtx, selfPod });
const volumes = result.job.spec?.template.spec?.volumes ?? [];
expect(volumes.find((v) => v.name === "data")?.persistentVolumeClaim?.claimName).toBe("paperclip-data");
const mounts = result.job.spec?.template.spec?.containers[0]?.volumeMounts ?? [];
expect(mounts.find((m) => m.name === "data")?.mountPath).toBe("/paperclip");
});
it("mounts inherited secret volumes from selfPod.secretVolumes", () => {
const selfPod = {
...mockSelfPod,
secretVolumes: [{ volumeName: "tls", secretName: "tls-secret", mountPath: "/etc/tls", defaultMode: 0o400 }],
};
const result = buildJobManifest({ ctx: mockCtx, selfPod });
const volumes = result.job.spec?.template.spec?.volumes ?? [];
expect(volumes.find((v) => v.name === "tls")?.secret?.secretName).toBe("tls-secret");
const mounts = result.job.spec?.template.spec?.containers[0]?.volumeMounts ?? [];
expect(mounts.find((m) => m.name === "tls")).toEqual({ name: "tls", mountPath: "/etc/tls", readOnly: true });
});
});