mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-03 18:54:06 +00:00
180 lines
5.3 KiB
TypeScript
180 lines
5.3 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { fetchProofComments } from "../../scripts/github/real-behavior-proof-check.mjs";
|
|
|
|
function stalledResponse() {
|
|
let keepAlive: ReturnType<typeof setTimeout> | undefined;
|
|
const reader = {
|
|
read: () =>
|
|
new Promise<ReadableStreamReadResult<Uint8Array>>(() => {
|
|
keepAlive = setTimeout(() => {}, 10_000);
|
|
}),
|
|
cancel: vi.fn(() => {
|
|
if (keepAlive) {
|
|
clearTimeout(keepAlive);
|
|
}
|
|
return Promise.resolve();
|
|
}),
|
|
releaseLock: vi.fn(),
|
|
};
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
headers: new Headers(),
|
|
body: {
|
|
getReader: () => reader,
|
|
},
|
|
};
|
|
}
|
|
|
|
function contentLengthResponse(contentLength: number) {
|
|
const cancel = vi.fn(() => Promise.resolve());
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
headers: new Headers({ "content-length": String(contentLength) }),
|
|
body: { cancel },
|
|
cancel,
|
|
};
|
|
}
|
|
|
|
function chunkedResponse(chunks: Uint8Array[]) {
|
|
const cancel = vi.fn(() => Promise.resolve());
|
|
const read = vi.fn();
|
|
for (const chunk of chunks) {
|
|
read.mockResolvedValueOnce({ done: false, value: chunk });
|
|
}
|
|
read.mockResolvedValueOnce({ done: true, value: undefined });
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
headers: new Headers(),
|
|
body: {
|
|
getReader: () => ({
|
|
read,
|
|
cancel,
|
|
releaseLock: vi.fn(),
|
|
}),
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("real-behavior-proof-check GitHub lookups", () => {
|
|
it("aborts stalled proof comment fetches", async () => {
|
|
const fetch = vi.fn((_url: URL, init: RequestInit) => {
|
|
return new Promise((_resolve, reject) => {
|
|
init.signal?.addEventListener("abort", () => reject(init.signal?.reason));
|
|
});
|
|
});
|
|
|
|
await expect(
|
|
fetchProofComments({
|
|
fetchImpl: fetch as typeof globalThis.fetch,
|
|
issueNumber: 123,
|
|
owner: "openclaw",
|
|
repo: "openclaw",
|
|
timeoutMs: 5,
|
|
tokens: ["tok"],
|
|
}),
|
|
).rejects.toThrow(/proof comment lookup page 1 timed out after 5ms/);
|
|
});
|
|
|
|
it("times out stalled proof comment response bodies", async () => {
|
|
const fetch = vi.fn().mockResolvedValue(stalledResponse());
|
|
|
|
await expect(
|
|
fetchProofComments({
|
|
fetchImpl: fetch as typeof globalThis.fetch,
|
|
issueNumber: 123,
|
|
owner: "openclaw",
|
|
repo: "openclaw",
|
|
timeoutMs: 5,
|
|
tokens: ["tok"],
|
|
}),
|
|
).rejects.toThrow(/proof comment response page 1 timed out after 5ms/);
|
|
});
|
|
|
|
it("skips oversized proof comment bodies by content length after narrow fallback", async () => {
|
|
const response = contentLengthResponse(1024 * 1024 + 1);
|
|
const fetch = vi.fn((url: URL) => {
|
|
const perPage = url.searchParams.get("per_page");
|
|
const page = url.searchParams.get("page");
|
|
if ((perPage === "100" && page === "1") || (perPage === "1" && page === "1")) {
|
|
return Promise.resolve(response);
|
|
}
|
|
return Promise.resolve(new Response("[]", { status: 200 }));
|
|
});
|
|
|
|
await expect(
|
|
fetchProofComments({
|
|
fetchImpl: fetch as typeof globalThis.fetch,
|
|
issueNumber: 123,
|
|
owner: "openclaw",
|
|
repo: "openclaw",
|
|
tokens: ["tok"],
|
|
}),
|
|
).resolves.toEqual([]);
|
|
expect(response.cancel).toHaveBeenCalled();
|
|
});
|
|
|
|
it("skips oversized streamed proof comment bodies after narrow fallback", async () => {
|
|
const encoder = new TextEncoder();
|
|
const oversizedResponse = () =>
|
|
chunkedResponse([
|
|
encoder.encode("["),
|
|
encoder.encode(" ".repeat(1024 * 1024)),
|
|
encoder.encode("]"),
|
|
]);
|
|
const fetch = vi.fn((url: URL) => {
|
|
const perPage = url.searchParams.get("per_page");
|
|
const page = url.searchParams.get("page");
|
|
if ((perPage === "100" && page === "1") || (perPage === "1" && page === "1")) {
|
|
return Promise.resolve(oversizedResponse());
|
|
}
|
|
return Promise.resolve(new Response("[]", { status: 200 }));
|
|
});
|
|
|
|
await expect(
|
|
fetchProofComments({
|
|
fetchImpl: fetch as typeof globalThis.fetch,
|
|
issueNumber: 123,
|
|
owner: "openclaw",
|
|
repo: "openclaw",
|
|
tokens: ["tok"],
|
|
}),
|
|
).resolves.toEqual([]);
|
|
});
|
|
|
|
it("falls back to one-comment pages when a bulk comment page is oversized", async () => {
|
|
const fetch = vi.fn((url: URL) => {
|
|
const perPage = url.searchParams.get("per_page");
|
|
const page = url.searchParams.get("page");
|
|
if (perPage === "100" && page === "1") {
|
|
return Promise.resolve(contentLengthResponse(1024 * 1024 + 1));
|
|
}
|
|
if (perPage === "1" && page === "1") {
|
|
return Promise.resolve(contentLengthResponse(1024 * 1024 + 1));
|
|
}
|
|
if (perPage === "1" && page === "2") {
|
|
return Promise.resolve(new Response('[{"id":2,"body":"trusted proof"}]', { status: 200 }));
|
|
}
|
|
return Promise.resolve(new Response("[]", { status: 200 }));
|
|
});
|
|
|
|
await expect(
|
|
fetchProofComments({
|
|
fetchImpl: fetch as typeof globalThis.fetch,
|
|
issueNumber: 123,
|
|
owner: "openclaw",
|
|
repo: "openclaw",
|
|
tokens: ["tok"],
|
|
}),
|
|
).resolves.toEqual([{ id: 2, body: "trusted proof" }]);
|
|
|
|
expect(
|
|
fetch.mock.calls.map(
|
|
([url]) => `${url.searchParams.get("per_page")}:${url.searchParams.get("page")}`,
|
|
),
|
|
).toEqual(["100:1", "1:1", "1:2", "1:3"]);
|
|
});
|
|
});
|