mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-10 19:14:58 +00:00
test(agents): dedupe patch and cli credential assertions
This commit is contained in:
@@ -13,6 +13,23 @@ async function withTempDir<T>(fn: (dir: string) => Promise<T>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildAddFilePatch(targetPath: string): string {
|
||||||
|
return `*** Begin Patch
|
||||||
|
*** Add File: ${targetPath}
|
||||||
|
+escaped
|
||||||
|
*** End Patch`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function expectOutsideWriteRejected(params: {
|
||||||
|
dir: string;
|
||||||
|
patchTargetPath: string;
|
||||||
|
outsidePath: string;
|
||||||
|
}) {
|
||||||
|
const patch = buildAddFilePatch(params.patchTargetPath);
|
||||||
|
await expect(applyPatch(patch, { cwd: params.dir })).rejects.toThrow(/Path escapes sandbox root/);
|
||||||
|
await expect(fs.readFile(params.outsidePath, "utf8")).rejects.toBeDefined();
|
||||||
|
}
|
||||||
|
|
||||||
describe("applyPatch", () => {
|
describe("applyPatch", () => {
|
||||||
it("adds a file", async () => {
|
it("adds a file", async () => {
|
||||||
await withTempDir(async (dir) => {
|
await withTempDir(async (dir) => {
|
||||||
@@ -79,14 +96,12 @@ describe("applyPatch", () => {
|
|||||||
);
|
);
|
||||||
const relativeEscape = path.relative(dir, escapedPath);
|
const relativeEscape = path.relative(dir, escapedPath);
|
||||||
|
|
||||||
const patch = `*** Begin Patch
|
|
||||||
*** Add File: ${relativeEscape}
|
|
||||||
+escaped
|
|
||||||
*** End Patch`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await expect(applyPatch(patch, { cwd: dir })).rejects.toThrow(/Path escapes sandbox root/);
|
await expectOutsideWriteRejected({
|
||||||
await expect(fs.readFile(escapedPath, "utf8")).rejects.toBeDefined();
|
dir,
|
||||||
|
patchTargetPath: relativeEscape,
|
||||||
|
outsidePath: escapedPath,
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
await fs.rm(escapedPath, { force: true });
|
await fs.rm(escapedPath, { force: true });
|
||||||
}
|
}
|
||||||
@@ -97,14 +112,12 @@ describe("applyPatch", () => {
|
|||||||
await withTempDir(async (dir) => {
|
await withTempDir(async (dir) => {
|
||||||
const escapedPath = path.join(os.tmpdir(), `openclaw-apply-patch-${Date.now()}.txt`);
|
const escapedPath = path.join(os.tmpdir(), `openclaw-apply-patch-${Date.now()}.txt`);
|
||||||
|
|
||||||
const patch = `*** Begin Patch
|
|
||||||
*** Add File: ${escapedPath}
|
|
||||||
+escaped
|
|
||||||
*** End Patch`;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await expect(applyPatch(patch, { cwd: dir })).rejects.toThrow(/Path escapes sandbox root/);
|
await expectOutsideWriteRejected({
|
||||||
await expect(fs.readFile(escapedPath, "utf8")).rejects.toBeDefined();
|
dir,
|
||||||
|
patchTargetPath: escapedPath,
|
||||||
|
outsidePath: escapedPath,
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
await fs.rm(escapedPath, { force: true });
|
await fs.rm(escapedPath, { force: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|||||||
|
|
||||||
const execSyncMock = vi.fn();
|
const execSyncMock = vi.fn();
|
||||||
const execFileSyncMock = vi.fn();
|
const execFileSyncMock = vi.fn();
|
||||||
|
const CLI_CREDENTIALS_CACHE_TTL_MS = 15 * 60 * 1000;
|
||||||
|
|
||||||
function mockExistingClaudeKeychainItem() {
|
function mockExistingClaudeKeychainItem() {
|
||||||
execFileSyncMock.mockImplementation((file: unknown, args: unknown) => {
|
execFileSyncMock.mockImplementation((file: unknown, args: unknown) => {
|
||||||
@@ -31,6 +32,16 @@ function getAddGenericPasswordCall() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function readCachedClaudeCliCredentials(allowKeychainPrompt: boolean) {
|
||||||
|
const { readClaudeCliCredentialsCached } = await import("./cli-credentials.js");
|
||||||
|
return readClaudeCliCredentialsCached({
|
||||||
|
allowKeychainPrompt,
|
||||||
|
ttlMs: CLI_CREDENTIALS_CACHE_TTL_MS,
|
||||||
|
platform: "darwin",
|
||||||
|
execSync: execSyncMock,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
describe("cli credentials", () => {
|
describe("cli credentials", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.useFakeTimers();
|
vi.useFakeTimers();
|
||||||
@@ -189,20 +200,8 @@ describe("cli credentials", () => {
|
|||||||
|
|
||||||
vi.setSystemTime(new Date("2025-01-01T00:00:00Z"));
|
vi.setSystemTime(new Date("2025-01-01T00:00:00Z"));
|
||||||
|
|
||||||
const { readClaudeCliCredentialsCached } = await import("./cli-credentials.js");
|
const first = await readCachedClaudeCliCredentials(true);
|
||||||
|
const second = await readCachedClaudeCliCredentials(false);
|
||||||
const first = readClaudeCliCredentialsCached({
|
|
||||||
allowKeychainPrompt: true,
|
|
||||||
ttlMs: 15 * 60 * 1000,
|
|
||||||
platform: "darwin",
|
|
||||||
execSync: execSyncMock,
|
|
||||||
});
|
|
||||||
const second = readClaudeCliCredentialsCached({
|
|
||||||
allowKeychainPrompt: false,
|
|
||||||
ttlMs: 15 * 60 * 1000,
|
|
||||||
platform: "darwin",
|
|
||||||
execSync: execSyncMock,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(first).toBeTruthy();
|
expect(first).toBeTruthy();
|
||||||
expect(second).toEqual(first);
|
expect(second).toEqual(first);
|
||||||
@@ -222,23 +221,11 @@ describe("cli credentials", () => {
|
|||||||
|
|
||||||
vi.setSystemTime(new Date("2025-01-01T00:00:00Z"));
|
vi.setSystemTime(new Date("2025-01-01T00:00:00Z"));
|
||||||
|
|
||||||
const { readClaudeCliCredentialsCached } = await import("./cli-credentials.js");
|
const first = await readCachedClaudeCliCredentials(true);
|
||||||
|
|
||||||
const first = readClaudeCliCredentialsCached({
|
vi.advanceTimersByTime(CLI_CREDENTIALS_CACHE_TTL_MS + 1);
|
||||||
allowKeychainPrompt: true,
|
|
||||||
ttlMs: 15 * 60 * 1000,
|
|
||||||
platform: "darwin",
|
|
||||||
execSync: execSyncMock,
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.advanceTimersByTime(15 * 60 * 1000 + 1);
|
const second = await readCachedClaudeCliCredentials(true);
|
||||||
|
|
||||||
const second = readClaudeCliCredentialsCached({
|
|
||||||
allowKeychainPrompt: true,
|
|
||||||
ttlMs: 15 * 60 * 1000,
|
|
||||||
platform: "darwin",
|
|
||||||
execSync: execSyncMock,
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(first).toBeTruthy();
|
expect(first).toBeTruthy();
|
||||||
expect(second).toBeTruthy();
|
expect(second).toBeTruthy();
|
||||||
|
|||||||
Reference in New Issue
Block a user