Files
paperclip-adapter-opencode-k8s/src/server/session.test.ts
T
Chris Farhood 61d2a42a66 feat: inherit valueFrom/envFrom env from Deployment; prefer paperclip container
- SelfPodInfo gains inheritedEnvValueFrom (V1EnvVar[]) and inheritedEnvFrom (V1EnvFromSource[])
- Container selection now prefers the container named "paperclip", falls back to first
- buildJobManifest appends valueFrom env vars (skipping names already overridden)
  and sets envFrom on the opencode container when present
- Tests updated: mock updated, 5 new cases covering secretKeyRef forwarding,
  dedup, envFrom passthrough, and empty-envFrom omission

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-24 22:12:31 +00:00

238 lines
7.8 KiB
TypeScript

import { describe, it, expect } from "vitest";
import { sessionCodec } from "./session.js";
describe("sessionCodec.deserialize", () => {
it("returns null for null input", () => {
expect(sessionCodec.deserialize(null)).toBeNull();
});
it("returns null for string input", () => {
expect(sessionCodec.deserialize("string")).toBeNull();
});
it("returns null for number input", () => {
expect(sessionCodec.deserialize(42)).toBeNull();
});
it("returns null for array input", () => {
expect(sessionCodec.deserialize([])).toBeNull();
});
it("returns null when sessionId is absent", () => {
expect(sessionCodec.deserialize({ cwd: "/foo" })).toBeNull();
});
it("returns null when sessionId is empty string", () => {
expect(sessionCodec.deserialize({ sessionId: "" })).toBeNull();
});
it("returns null when sessionId is whitespace only", () => {
expect(sessionCodec.deserialize({ sessionId: " " })).toBeNull();
});
it("reads canonical sessionId", () => {
const result = sessionCodec.deserialize({ sessionId: "ses_abc" });
expect(result?.sessionId).toBe("ses_abc");
});
it("reads legacy session_id field", () => {
const result = sessionCodec.deserialize({ session_id: "ses_legacy" });
expect(result?.sessionId).toBe("ses_legacy");
});
it("reads legacy sessionID field", () => {
const result = sessionCodec.deserialize({ sessionID: "ses_ID" });
expect(result?.sessionId).toBe("ses_ID");
});
it("prefers sessionId over session_id", () => {
const result = sessionCodec.deserialize({ sessionId: "canonical", session_id: "legacy" });
expect(result?.sessionId).toBe("canonical");
});
it("prefers session_id over sessionID", () => {
const result = sessionCodec.deserialize({ session_id: "mid", sessionID: "last" });
expect(result?.sessionId).toBe("mid");
});
it("trims whitespace from sessionId", () => {
const result = sessionCodec.deserialize({ sessionId: " ses_123 " });
expect(result?.sessionId).toBe("ses_123");
});
it("reads cwd field", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", cwd: "/work/dir" });
expect(result?.cwd).toBe("/work/dir");
});
it("reads workdir as cwd fallback", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", workdir: "/workdir" });
expect(result?.cwd).toBe("/workdir");
});
it("reads folder as cwd fallback", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", folder: "/folder" });
expect(result?.cwd).toBe("/folder");
});
it("prefers cwd over workdir", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", cwd: "/cwd", workdir: "/workdir" });
expect(result?.cwd).toBe("/cwd");
});
it("prefers workdir over folder", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", workdir: "/workdir", folder: "/folder" });
expect(result?.cwd).toBe("/workdir");
});
it("reads workspaceId field", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", workspaceId: "ws-1" });
expect(result?.workspaceId).toBe("ws-1");
});
it("reads workspace_id as workspaceId fallback", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", workspace_id: "ws-legacy" });
expect(result?.workspaceId).toBe("ws-legacy");
});
it("reads repoUrl field", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", repoUrl: "https://github.com/org/repo" });
expect(result?.repoUrl).toBe("https://github.com/org/repo");
});
it("reads repo_url as repoUrl fallback", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", repo_url: "https://github.com/org/repo" });
expect(result?.repoUrl).toBe("https://github.com/org/repo");
});
it("reads repoRef field", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", repoRef: "main" });
expect(result?.repoRef).toBe("main");
});
it("reads repo_ref as repoRef fallback", () => {
const result = sessionCodec.deserialize({ sessionId: "s1", repo_ref: "feature/branch" });
expect(result?.repoRef).toBe("feature/branch");
});
it("omits absent optional fields from result", () => {
const result = sessionCodec.deserialize({ sessionId: "s1" });
expect(result).toEqual({ sessionId: "s1" });
expect(result && "cwd" in result).toBe(false);
expect(result && "workspaceId" in result).toBe(false);
expect(result && "repoUrl" in result).toBe(false);
expect(result && "repoRef" in result).toBe(false);
});
it("includes all fields when all are present", () => {
const result = sessionCodec.deserialize({
sessionId: "ses_full",
cwd: "/work",
workspaceId: "ws-1",
repoUrl: "https://github.com/org/repo",
repoRef: "main",
});
expect(result).toEqual({
sessionId: "ses_full",
cwd: "/work",
workspaceId: "ws-1",
repoUrl: "https://github.com/org/repo",
repoRef: "main",
});
});
});
describe("sessionCodec.serialize", () => {
it("returns null for null input", () => {
expect(sessionCodec.serialize(null)).toBeNull();
});
it("returns null when sessionId is missing", () => {
expect(sessionCodec.serialize({ cwd: "/foo" })).toBeNull();
});
it("returns null when sessionId is empty string", () => {
expect(sessionCodec.serialize({ sessionId: "" })).toBeNull();
});
it("serializes canonical fields", () => {
const result = sessionCodec.serialize({
sessionId: "ses_abc",
cwd: "/work",
workspaceId: "ws-1",
repoUrl: "https://github.com/org/repo",
repoRef: "main",
});
expect(result).toEqual({
sessionId: "ses_abc",
cwd: "/work",
workspaceId: "ws-1",
repoUrl: "https://github.com/org/repo",
repoRef: "main",
});
});
it("reads legacy session_id field", () => {
const result = sessionCodec.serialize({ session_id: "ses_legacy" });
expect(result?.sessionId).toBe("ses_legacy");
});
it("reads legacy workdir as cwd", () => {
const result = sessionCodec.serialize({ sessionId: "s1", workdir: "/workdir" });
expect(result?.cwd).toBe("/workdir");
});
it("reads legacy workspace_id", () => {
const result = sessionCodec.serialize({ sessionId: "s1", workspace_id: "ws-2" });
expect(result?.workspaceId).toBe("ws-2");
});
it("reads legacy repo_url", () => {
const result = sessionCodec.serialize({ sessionId: "s1", repo_url: "https://github.com/org/repo" });
expect(result?.repoUrl).toBe("https://github.com/org/repo");
});
it("reads legacy repo_ref", () => {
const result = sessionCodec.serialize({ sessionId: "s1", repo_ref: "develop" });
expect(result?.repoRef).toBe("develop");
});
it("omits absent optional fields", () => {
const result = sessionCodec.serialize({ sessionId: "s1" });
expect(result).toEqual({ sessionId: "s1" });
});
});
describe("sessionCodec.getDisplayId", () => {
// getDisplayId is optional in the AdapterSessionCodec interface; use non-null assertion since we know it's implemented
const getDisplayId = sessionCodec.getDisplayId!.bind(sessionCodec);
it("returns null for null input", () => {
expect(getDisplayId(null)).toBeNull();
});
it("returns sessionId", () => {
expect(getDisplayId({ sessionId: "ses_abc" })).toBe("ses_abc");
});
it("returns session_id as fallback", () => {
expect(getDisplayId({ session_id: "ses_legacy" })).toBe("ses_legacy");
});
it("returns sessionID as fallback", () => {
expect(getDisplayId({ sessionID: "ses_ID" })).toBe("ses_ID");
});
it("prefers sessionId over session_id", () => {
expect(getDisplayId({ sessionId: "canonical", session_id: "legacy" })).toBe("canonical");
});
it("returns null when no valid id field present", () => {
expect(getDisplayId({ other: "value" })).toBeNull();
});
it("returns null when sessionId is empty string", () => {
expect(getDisplayId({ sessionId: "" })).toBeNull();
});
});