mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-18 20:24:46 +00:00
test: clear codex command broad matchers
This commit is contained in:
@@ -83,6 +83,28 @@ function escapeRegExp(value: string): string {
|
||||
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
}
|
||||
|
||||
function requireResultText(result: PluginCommandResult): string {
|
||||
if (typeof result.text !== "string") {
|
||||
throw new Error("expected command result text");
|
||||
}
|
||||
return result.text;
|
||||
}
|
||||
|
||||
function expectResultTextContains(result: PluginCommandResult, expected: string): void {
|
||||
expect(requireResultText(result)).toContain(expected);
|
||||
}
|
||||
|
||||
function requireRecord(value: unknown, message: string): Record<string, unknown> {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
||||
throw new Error(message);
|
||||
}
|
||||
return value as Record<string, unknown>;
|
||||
}
|
||||
|
||||
function requireRequestParams(call: unknown[] | undefined): Record<string, unknown> {
|
||||
return requireRecord(call?.[2], "expected request params object");
|
||||
}
|
||||
|
||||
function expectedDiagnosticsTargetBlock(params: {
|
||||
index?: number;
|
||||
channel?: string;
|
||||
@@ -190,17 +212,18 @@ describe("codex command", () => {
|
||||
|
||||
it("shows model ids from Codex app-server", async () => {
|
||||
const config = { auth: { order: { "openai-codex": ["openai-codex:work"] } } };
|
||||
const listCodexAppServerModels = vi.fn(async (_options?: { config?: unknown }) => ({
|
||||
models: [
|
||||
{
|
||||
id: "gpt-5.4",
|
||||
model: "gpt-5.4",
|
||||
inputModalities: ["text"],
|
||||
supportedReasoningEfforts: ["medium"],
|
||||
},
|
||||
],
|
||||
}));
|
||||
const deps = createDeps({
|
||||
listCodexAppServerModels: vi.fn(async () => ({
|
||||
models: [
|
||||
{
|
||||
id: "gpt-5.4",
|
||||
model: "gpt-5.4",
|
||||
inputModalities: ["text"],
|
||||
supportedReasoningEfforts: ["medium"],
|
||||
},
|
||||
],
|
||||
})),
|
||||
listCodexAppServerModels,
|
||||
});
|
||||
|
||||
await expect(
|
||||
@@ -209,7 +232,8 @@ describe("codex command", () => {
|
||||
text: "Codex models:\n- gpt-5.4",
|
||||
});
|
||||
expect(deps.requestOptions).toHaveBeenCalledWith(undefined, 100, config);
|
||||
expect(deps.listCodexAppServerModels).toHaveBeenCalledWith(expect.objectContaining({ config }));
|
||||
const modelsRequest = listCodexAppServerModels.mock.calls[0]?.[0];
|
||||
expect(modelsRequest?.config).toBe(config);
|
||||
});
|
||||
|
||||
it("shows when Codex app-server model output is truncated", async () => {
|
||||
@@ -428,12 +452,10 @@ describe("codex command", () => {
|
||||
.mockResolvedValueOnce(limits),
|
||||
});
|
||||
|
||||
await expect(handleCodexCommand(createContext("status"), { deps })).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Rate limits: Codex: primary 42%"),
|
||||
});
|
||||
await expect(handleCodexCommand(createContext("account"), { deps })).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Rate limits: Codex: primary 42%"),
|
||||
});
|
||||
const statusResult = await handleCodexCommand(createContext("status"), { deps });
|
||||
expectResultTextContains(statusResult, "Rate limits: Codex: primary 42%");
|
||||
const accountResult = await handleCodexCommand(createContext("account"), { deps });
|
||||
expectResultTextContains(accountResult, "Rate limits: Codex: primary 42%");
|
||||
});
|
||||
|
||||
it("rejects extra operands for read-only Codex commands", async () => {
|
||||
@@ -515,9 +537,13 @@ describe("codex command", () => {
|
||||
|
||||
expect(result.text).toContain("Account: codex@example.com");
|
||||
expect(result.text).toContain("Rate limits: Codex: primary 50%, resets in");
|
||||
expect(readRecentCodexRateLimits()).toMatchObject({
|
||||
rateLimits: { limitId: "codex" },
|
||||
});
|
||||
const cachedLimits = requireRecord(
|
||||
readRecentCodexRateLimits(),
|
||||
"expected cached Codex rate limits",
|
||||
);
|
||||
expect(requireRecord(cachedLimits.rateLimits, "expected rate limits object").limitId).toBe(
|
||||
"codex",
|
||||
);
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledWith(undefined, CODEX_CONTROL_METHODS.account, {
|
||||
refreshToken: false,
|
||||
});
|
||||
@@ -721,30 +747,26 @@ describe("codex command", () => {
|
||||
"Computer Use is installed, but the computer-use plugin is disabled. Run /codex computer-use install or enable computerUse.autoInstall to re-enable it.",
|
||||
}));
|
||||
|
||||
await expect(
|
||||
handleCodexCommand(createContext("computer-use status"), {
|
||||
deps: createDeps({ readCodexComputerUseStatus }),
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
text: expect.stringContaining("Plugin: computer-use (installed, disabled)"),
|
||||
const result = await handleCodexCommand(createContext("computer-use status"), {
|
||||
deps: createDeps({ readCodexComputerUseStatus }),
|
||||
});
|
||||
|
||||
expectResultTextContains(result, "Plugin: computer-use (installed, disabled)");
|
||||
});
|
||||
|
||||
it("installs Codex Computer Use from command overrides", async () => {
|
||||
const installCodexComputerUse = vi.fn(async () => computerUseReadyStatus());
|
||||
|
||||
await expect(
|
||||
handleCodexCommand(
|
||||
createContext(
|
||||
"computer-use install --source github:example/desktop-tools --marketplace desktop-tools",
|
||||
),
|
||||
{
|
||||
deps: createDeps({ installCodexComputerUse }),
|
||||
},
|
||||
const result = await handleCodexCommand(
|
||||
createContext(
|
||||
"computer-use install --source github:example/desktop-tools --marketplace desktop-tools",
|
||||
),
|
||||
).resolves.toEqual({
|
||||
text: expect.stringContaining("Computer Use: ready"),
|
||||
});
|
||||
{
|
||||
deps: createDeps({ installCodexComputerUse }),
|
||||
},
|
||||
);
|
||||
|
||||
expectResultTextContains(result, "Computer Use: ready");
|
||||
expect(installCodexComputerUse).toHaveBeenCalledWith({
|
||||
pluginConfig: undefined,
|
||||
forceEnable: true,
|
||||
@@ -758,13 +780,11 @@ describe("codex command", () => {
|
||||
it("shows help when Computer Use option values are missing", async () => {
|
||||
const installCodexComputerUse = vi.fn(async () => computerUseReadyStatus());
|
||||
|
||||
await expect(
|
||||
handleCodexCommand(createContext("computer-use install --source"), {
|
||||
deps: createDeps({ installCodexComputerUse }),
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
text: expect.stringContaining("Usage: /codex computer-use"),
|
||||
const result = await handleCodexCommand(createContext("computer-use install --source"), {
|
||||
deps: createDeps({ installCodexComputerUse }),
|
||||
});
|
||||
|
||||
expectResultTextContains(result, "Usage: /codex computer-use");
|
||||
expect(installCodexComputerUse).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -772,13 +792,11 @@ describe("codex command", () => {
|
||||
const readCodexComputerUseStatus = vi.fn(async () => computerUseReadyStatus());
|
||||
const installCodexComputerUse = vi.fn(async () => computerUseReadyStatus());
|
||||
|
||||
await expect(
|
||||
handleCodexCommand(createContext("computer-use status install"), {
|
||||
deps: createDeps({ readCodexComputerUseStatus, installCodexComputerUse }),
|
||||
}),
|
||||
).resolves.toEqual({
|
||||
text: expect.stringContaining("Usage: /codex computer-use"),
|
||||
const result = await handleCodexCommand(createContext("computer-use status install"), {
|
||||
deps: createDeps({ readCodexComputerUseStatus, installCodexComputerUse }),
|
||||
});
|
||||
|
||||
expectResultTextContains(result, "Usage: /codex computer-use");
|
||||
expect(readCodexComputerUseStatus).not.toHaveBeenCalled();
|
||||
expect(installCodexComputerUse).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -833,7 +851,7 @@ describe("codex command", () => {
|
||||
"This request expires in 5 minutes.",
|
||||
].join("\n"),
|
||||
);
|
||||
expect(request.interactive).toMatchObject({
|
||||
expect(request.interactive).toEqual({
|
||||
blocks: [
|
||||
{
|
||||
type: "buttons",
|
||||
@@ -843,7 +861,11 @@ describe("codex command", () => {
|
||||
value: `/codex diagnostics confirm ${token}`,
|
||||
style: "danger",
|
||||
},
|
||||
{ label: "Cancel", value: `/codex diagnostics cancel ${token}` },
|
||||
{
|
||||
label: "Cancel",
|
||||
value: `/codex diagnostics cancel ${token}`,
|
||||
style: "secondary",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -926,11 +948,11 @@ describe("codex command", () => {
|
||||
});
|
||||
expect(safeCodexControlRequest).not.toHaveBeenCalled();
|
||||
|
||||
await expect(
|
||||
handleCodexCommand(createContext(`diagnostics confirm ${token}`, sessionFile), { deps }),
|
||||
).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const confirmResult = await handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${token}`, sessionFile),
|
||||
{ deps },
|
||||
);
|
||||
expectResultTextContains(confirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -1112,18 +1134,16 @@ describe("codex command", () => {
|
||||
].join("\n"),
|
||||
});
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledTimes(2);
|
||||
expect(safeCodexControlRequest).toHaveBeenNthCalledWith(
|
||||
1,
|
||||
undefined,
|
||||
CODEX_CONTROL_METHODS.feedback,
|
||||
expect.objectContaining({ threadId: "thread-111", includeLogs: true }),
|
||||
);
|
||||
expect(safeCodexControlRequest).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
undefined,
|
||||
CODEX_CONTROL_METHODS.feedback,
|
||||
expect.objectContaining({ threadId: "thread-222", includeLogs: true }),
|
||||
);
|
||||
expect(safeCodexControlRequest.mock.calls[0]?.[0]).toBeUndefined();
|
||||
expect(safeCodexControlRequest.mock.calls[0]?.[1]).toBe(CODEX_CONTROL_METHODS.feedback);
|
||||
const firstFeedbackParams = requireRequestParams(safeCodexControlRequest.mock.calls[0]);
|
||||
expect(firstFeedbackParams.threadId).toBe("thread-111");
|
||||
expect(firstFeedbackParams.includeLogs).toBe(true);
|
||||
expect(safeCodexControlRequest.mock.calls[1]?.[0]).toBeUndefined();
|
||||
expect(safeCodexControlRequest.mock.calls[1]?.[1]).toBe(CODEX_CONTROL_METHODS.feedback);
|
||||
const secondFeedbackParams = requireRequestParams(safeCodexControlRequest.mock.calls[1]);
|
||||
expect(secondFeedbackParams.threadId).toBe("thread-222");
|
||||
expect(secondFeedbackParams.includeLogs).toBe(true);
|
||||
});
|
||||
|
||||
it("requires an owner for Codex diagnostics feedback uploads", async () => {
|
||||
@@ -1251,9 +1271,8 @@ describe("codex command", () => {
|
||||
});
|
||||
|
||||
releaseFirstConfirmBindingRead();
|
||||
await expect(firstConfirm).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const firstConfirmResult = await firstConfirm;
|
||||
expectResultTextContains(firstConfirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -1304,10 +1323,12 @@ describe("codex command", () => {
|
||||
`${sessionFile}.codex-app-server.json`,
|
||||
JSON.stringify({ schemaVersion: 1, threadId: "thread-private", cwd: "/repo" }),
|
||||
);
|
||||
const safeCodexControlRequest = vi.fn(async () => ({
|
||||
ok: true as const,
|
||||
value: { threadId: "thread-private" },
|
||||
}));
|
||||
const safeCodexControlRequest = vi.fn(
|
||||
async (_pluginConfig: unknown, _method: string, _requestParams: unknown) => ({
|
||||
ok: true as const,
|
||||
value: { threadId: "thread-private" },
|
||||
}),
|
||||
);
|
||||
const deps = createDeps({ safeCodexControlRequest });
|
||||
|
||||
const request = await handleCodexCommand(
|
||||
@@ -1342,15 +1363,12 @@ describe("codex command", () => {
|
||||
"Included Codex logs and spawned Codex subthreads when available.",
|
||||
].join("\n"),
|
||||
});
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledWith(
|
||||
undefined,
|
||||
CODEX_CONTROL_METHODS.feedback,
|
||||
expect.objectContaining({
|
||||
classification: "bug",
|
||||
threadId: "thread-private",
|
||||
includeLogs: true,
|
||||
}),
|
||||
);
|
||||
expect(safeCodexControlRequest.mock.calls[0]?.[0]).toBeUndefined();
|
||||
expect(safeCodexControlRequest.mock.calls[0]?.[1]).toBe(CODEX_CONTROL_METHODS.feedback);
|
||||
const feedbackParams = requireRequestParams(safeCodexControlRequest.mock.calls[0]);
|
||||
expect(feedbackParams.classification).toBe("bug");
|
||||
expect(feedbackParams.threadId).toBe("thread-private");
|
||||
expect(feedbackParams.includeLogs).toBe(true);
|
||||
});
|
||||
|
||||
it("keeps diagnostics confirmation eviction scoped to account identity", async () => {
|
||||
@@ -1405,10 +1423,12 @@ describe("codex command", () => {
|
||||
`${sessionFile}.codex-app-server.json`,
|
||||
JSON.stringify({ schemaVersion: 1, threadId: "thread-789", cwd: "/repo" }),
|
||||
);
|
||||
const safeCodexControlRequest = vi.fn(async () => ({
|
||||
ok: true as const,
|
||||
value: { threadId: "thread-789" },
|
||||
}));
|
||||
const safeCodexControlRequest = vi.fn(
|
||||
async (_pluginConfig: unknown, _method: string, _requestParams: unknown) => ({
|
||||
ok: true as const,
|
||||
value: { threadId: "thread-789" },
|
||||
}),
|
||||
);
|
||||
const note = "x".repeat(2050);
|
||||
const deps = createDeps({ safeCodexControlRequest });
|
||||
|
||||
@@ -1418,13 +1438,10 @@ describe("codex command", () => {
|
||||
const token = readDiagnosticsConfirmationToken(request);
|
||||
await handleCodexCommand(createContext(`diagnostics confirm ${token}`, sessionFile), { deps });
|
||||
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledWith(
|
||||
undefined,
|
||||
CODEX_CONTROL_METHODS.feedback,
|
||||
expect.objectContaining({
|
||||
reason: "x".repeat(2048),
|
||||
}),
|
||||
);
|
||||
expect(safeCodexControlRequest.mock.calls[0]?.[0]).toBeUndefined();
|
||||
expect(safeCodexControlRequest.mock.calls[0]?.[1]).toBe(CODEX_CONTROL_METHODS.feedback);
|
||||
const feedbackParams = requireRequestParams(safeCodexControlRequest.mock.calls[0]);
|
||||
expect(feedbackParams.reason).toBe("x".repeat(2048));
|
||||
});
|
||||
|
||||
it("escapes diagnostics notes before showing approval text", async () => {
|
||||
@@ -1544,17 +1561,14 @@ describe("codex command", () => {
|
||||
{ deps },
|
||||
);
|
||||
const firstToken = readDiagnosticsConfirmationToken(firstRequest);
|
||||
await expect(
|
||||
handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${firstToken}`, sessionFile, {
|
||||
accountId: "account-1",
|
||||
channelId: "channel-1",
|
||||
}),
|
||||
{ deps },
|
||||
),
|
||||
).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const firstConfirmResult = await handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${firstToken}`, sessionFile, {
|
||||
accountId: "account-1",
|
||||
channelId: "channel-1",
|
||||
}),
|
||||
{ deps },
|
||||
);
|
||||
expectResultTextContains(firstConfirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
|
||||
await fs.writeFile(
|
||||
`${sessionFile}.codex-app-server.json`,
|
||||
@@ -1568,17 +1582,14 @@ describe("codex command", () => {
|
||||
{ deps },
|
||||
);
|
||||
const secondToken = readDiagnosticsConfirmationToken(secondRequest);
|
||||
await expect(
|
||||
handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${secondToken}`, sessionFile, {
|
||||
accountId: "account-2",
|
||||
channelId: "channel-2",
|
||||
}),
|
||||
{ deps },
|
||||
),
|
||||
).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const secondConfirmResult = await handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${secondToken}`, sessionFile, {
|
||||
accountId: "account-2",
|
||||
channelId: "channel-2",
|
||||
}),
|
||||
{ deps },
|
||||
);
|
||||
expectResultTextContains(secondConfirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
@@ -1605,14 +1616,11 @@ describe("codex command", () => {
|
||||
{ deps },
|
||||
);
|
||||
const firstToken = readDiagnosticsConfirmationToken(firstRequest);
|
||||
await expect(
|
||||
handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${firstToken}`, sessionFile, firstScope),
|
||||
{ deps },
|
||||
),
|
||||
).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const firstConfirmResult = await handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${firstToken}`, sessionFile, firstScope),
|
||||
{ deps },
|
||||
);
|
||||
expectResultTextContains(firstConfirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
|
||||
await fs.writeFile(
|
||||
`${sessionFile}.codex-app-server.json`,
|
||||
@@ -1627,14 +1635,11 @@ describe("codex command", () => {
|
||||
{ deps },
|
||||
);
|
||||
const secondToken = readDiagnosticsConfirmationToken(secondRequest);
|
||||
await expect(
|
||||
handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${secondToken}`, sessionFile, secondScope),
|
||||
{ deps },
|
||||
),
|
||||
).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const secondConfirmResult = await handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${secondToken}`, sessionFile, secondScope),
|
||||
{ deps },
|
||||
);
|
||||
expectResultTextContains(secondConfirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
@@ -1661,14 +1666,11 @@ describe("codex command", () => {
|
||||
{ deps },
|
||||
);
|
||||
const firstToken = readDiagnosticsConfirmationToken(firstRequest);
|
||||
await expect(
|
||||
handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${firstToken}`, sessionFile, firstScope),
|
||||
{ deps },
|
||||
),
|
||||
).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const firstConfirmResult = await handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${firstToken}`, sessionFile, firstScope),
|
||||
{ deps },
|
||||
);
|
||||
expectResultTextContains(firstConfirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
|
||||
await fs.writeFile(
|
||||
`${sessionFile}.codex-app-server.json`,
|
||||
@@ -1683,14 +1685,11 @@ describe("codex command", () => {
|
||||
{ deps },
|
||||
);
|
||||
const secondToken = readDiagnosticsConfirmationToken(secondRequest);
|
||||
await expect(
|
||||
handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${secondToken}`, sessionFile, secondScope),
|
||||
{ deps },
|
||||
),
|
||||
).resolves.toMatchObject({
|
||||
text: expect.stringContaining("Codex diagnostics sent to OpenAI servers:"),
|
||||
});
|
||||
const secondConfirmResult = await handleCodexCommand(
|
||||
createContext(`diagnostics confirm ${secondToken}`, sessionFile, secondScope),
|
||||
{ deps },
|
||||
);
|
||||
expectResultTextContains(secondConfirmResult, "Codex diagnostics sent to OpenAI servers:");
|
||||
|
||||
expect(safeCodexControlRequest).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
@@ -1937,7 +1936,7 @@ describe("codex command", () => {
|
||||
sessionFile,
|
||||
workspaceDir: "/repo",
|
||||
}));
|
||||
const requestConversationBinding = vi.fn(async () => ({
|
||||
const requestConversationBinding = vi.fn(async (_request?: { summary?: string }) => ({
|
||||
status: "bound" as const,
|
||||
binding: {
|
||||
bindingId: "binding-1",
|
||||
@@ -1999,7 +1998,7 @@ describe("codex command", () => {
|
||||
sessionFile,
|
||||
workspaceDir: "/repo with space",
|
||||
}));
|
||||
const requestConversationBinding = vi.fn(async () => ({
|
||||
const requestConversationBinding = vi.fn(async (_request?: { summary?: string }) => ({
|
||||
status: "bound" as const,
|
||||
binding: {
|
||||
bindingId: "binding-1",
|
||||
@@ -2048,7 +2047,7 @@ describe("codex command", () => {
|
||||
sessionFile,
|
||||
workspaceDir: unsafeWorkspace,
|
||||
}));
|
||||
const requestConversationBinding = vi.fn(async () => ({
|
||||
const requestConversationBinding = vi.fn(async (_request?: { summary?: string }) => ({
|
||||
status: "bound" as const,
|
||||
binding: {
|
||||
bindingId: "binding-1",
|
||||
@@ -2077,11 +2076,9 @@ describe("codex command", () => {
|
||||
expect(result.text).toContain("/repo \uff3btrusted\uff3d\uff08https://evil\uff09");
|
||||
expect(result.text).not.toContain("<@U123>");
|
||||
expect(result.text).not.toContain("[trusted](https://evil)");
|
||||
expect(requestConversationBinding).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
summary:
|
||||
"Codex app-server thread thread-123 <\uff20U123> in /repo \uff3btrusted\uff3d\uff08https://evil\uff09",
|
||||
}),
|
||||
const bindingRequest = requestConversationBinding.mock.calls[0]?.[0];
|
||||
expect(bindingRequest?.summary).toBe(
|
||||
"Codex app-server thread thread-123 <\uff20U123> in /repo \uff3btrusted\uff3d\uff08https://evil\uff09",
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user