mirror of
https://github.com/aljazceru/opencode.git
synced 2026-01-28 12:15:02 +01:00
fix tests
This commit is contained in:
@@ -75,12 +75,23 @@ export namespace Permission {
|
|||||||
async (state) => {
|
async (state) => {
|
||||||
for (const pending of Object.values(state.pending)) {
|
for (const pending of Object.values(state.pending)) {
|
||||||
for (const item of Object.values(pending)) {
|
for (const item of Object.values(pending)) {
|
||||||
item.reject(new RejectedError(item.info.sessionID, item.info.id, item.info.callID, item.info.metadata))
|
item.reject(
|
||||||
|
new RejectedError(
|
||||||
|
item.info.sessionID,
|
||||||
|
item.info.id,
|
||||||
|
item.info.callID,
|
||||||
|
item.info.metadata,
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export function pending() {
|
||||||
|
return state().pending
|
||||||
|
}
|
||||||
|
|
||||||
export async function ask(input: {
|
export async function ask(input: {
|
||||||
type: Info["type"]
|
type: Info["type"]
|
||||||
title: Info["title"]
|
title: Info["title"]
|
||||||
@@ -139,7 +150,11 @@ export namespace Permission {
|
|||||||
export const Response = z.enum(["once", "always", "reject"])
|
export const Response = z.enum(["once", "always", "reject"])
|
||||||
export type Response = z.infer<typeof Response>
|
export type Response = z.infer<typeof Response>
|
||||||
|
|
||||||
export function respond(input: { sessionID: Info["sessionID"]; permissionID: Info["id"]; response: Response }) {
|
export function respond(input: {
|
||||||
|
sessionID: Info["sessionID"]
|
||||||
|
permissionID: Info["id"]
|
||||||
|
response: Response
|
||||||
|
}) {
|
||||||
log.info("response", input)
|
log.info("response", input)
|
||||||
const { pending, approved } = state()
|
const { pending, approved } = state()
|
||||||
const match = pending[input.sessionID]?.[input.permissionID]
|
const match = pending[input.sessionID]?.[input.permissionID]
|
||||||
@@ -151,7 +166,14 @@ export namespace Permission {
|
|||||||
response: input.response,
|
response: input.response,
|
||||||
})
|
})
|
||||||
if (input.response === "reject") {
|
if (input.response === "reject") {
|
||||||
match.reject(new RejectedError(input.sessionID, input.permissionID, match.info.callID, match.info.metadata))
|
match.reject(
|
||||||
|
new RejectedError(
|
||||||
|
input.sessionID,
|
||||||
|
input.permissionID,
|
||||||
|
match.info.callID,
|
||||||
|
match.info.metadata,
|
||||||
|
),
|
||||||
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
match.resolve()
|
match.resolve()
|
||||||
@@ -166,7 +188,11 @@ export namespace Permission {
|
|||||||
for (const item of Object.values(items)) {
|
for (const item of Object.values(items)) {
|
||||||
const itemKeys = toKeys(item.info.pattern, item.info.type)
|
const itemKeys = toKeys(item.info.pattern, item.info.type)
|
||||||
if (covered(itemKeys, approved[input.sessionID])) {
|
if (covered(itemKeys, approved[input.sessionID])) {
|
||||||
respond({ sessionID: item.info.sessionID, permissionID: item.info.id, response: input.response })
|
respond({
|
||||||
|
sessionID: item.info.sessionID,
|
||||||
|
permissionID: item.info.id,
|
||||||
|
response: input.response,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -179,7 +205,9 @@ export namespace Permission {
|
|||||||
public readonly toolCallID?: string,
|
public readonly toolCallID?: string,
|
||||||
public readonly metadata?: Record<string, any>,
|
public readonly metadata?: Record<string, any>,
|
||||||
) {
|
) {
|
||||||
super(`The user rejected permission to use this specific tool call. You may try again with different parameters.`)
|
super(
|
||||||
|
`The user rejected permission to use this specific tool call. You may try again with different parameters.`,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import path from "path"
|
|||||||
import { PatchTool } from "../../src/tool/patch"
|
import { PatchTool } from "../../src/tool/patch"
|
||||||
import { Instance } from "../../src/project/instance"
|
import { Instance } from "../../src/project/instance"
|
||||||
import { tmpdir } from "../fixture/fixture"
|
import { tmpdir } from "../fixture/fixture"
|
||||||
|
import { Permission } from "../../src/permission"
|
||||||
import * as fs from "fs/promises"
|
import * as fs from "fs/promises"
|
||||||
|
|
||||||
const ctx = {
|
const ctx = {
|
||||||
@@ -21,9 +22,7 @@ describe("tool.patch", () => {
|
|||||||
await Instance.provide({
|
await Instance.provide({
|
||||||
directory: "/tmp",
|
directory: "/tmp",
|
||||||
fn: async () => {
|
fn: async () => {
|
||||||
await expect(patchTool.execute({ patchText: "" }, ctx)).rejects.toThrow(
|
expect(patchTool.execute({ patchText: "" }, ctx)).rejects.toThrow("patchText is required")
|
||||||
"patchText is required",
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -32,7 +31,7 @@ describe("tool.patch", () => {
|
|||||||
await Instance.provide({
|
await Instance.provide({
|
||||||
directory: "/tmp",
|
directory: "/tmp",
|
||||||
fn: async () => {
|
fn: async () => {
|
||||||
await expect(patchTool.execute({ patchText: "invalid patch" }, ctx)).rejects.toThrow(
|
expect(patchTool.execute({ patchText: "invalid patch" }, ctx)).rejects.toThrow(
|
||||||
"Failed to parse patch",
|
"Failed to parse patch",
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@@ -46,13 +45,29 @@ describe("tool.patch", () => {
|
|||||||
const emptyPatch = `*** Begin Patch
|
const emptyPatch = `*** Begin Patch
|
||||||
*** End Patch`
|
*** End Patch`
|
||||||
|
|
||||||
await expect(patchTool.execute({ patchText: emptyPatch }, ctx)).rejects.toThrow(
|
expect(patchTool.execute({ patchText: emptyPatch }, ctx)).rejects.toThrow(
|
||||||
"No file changes found in patch",
|
"No file changes found in patch",
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test("should ask permission for files outside working directory", async () => {
|
||||||
|
await Instance.provide({
|
||||||
|
directory: "/tmp",
|
||||||
|
fn: async () => {
|
||||||
|
const maliciousPatch = `*** Begin Patch
|
||||||
|
*** Add File: /etc/passwd
|
||||||
|
+malicious content
|
||||||
|
*** End Patch`
|
||||||
|
patchTool.execute({ patchText: maliciousPatch }, ctx)
|
||||||
|
// TODO: this sucks
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||||
|
expect(Permission.pending()[ctx.sessionID]).toBeDefined()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test("should handle simple add file operation", async () => {
|
test("should handle simple add file operation", async () => {
|
||||||
await using fixture = await tmpdir()
|
await using fixture = await tmpdir()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user