Files
boss/tests/master-agent-task-control-state-route.test.ts

101 lines
3.5 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import os from "node:os";
import path from "node:path";
import { mkdtemp, rm } from "node:fs/promises";
import { NextRequest } from "next/server";
let runtimeRoot = "";
let data: typeof import("../src/lib/boss-data.ts");
let getControlState: (typeof import("../src/app/api/v1/master-agent/tasks/[taskId]/control-state/route.ts"))["GET"];
async function setup() {
if (runtimeRoot) return;
runtimeRoot = await mkdtemp(path.join(os.tmpdir(), "boss-master-task-control-state-"));
process.env.BOSS_RUNTIME_ROOT = runtimeRoot;
process.env.BOSS_STATE_FILE = path.join(runtimeRoot, "boss-state.json");
const [dataModule, routeModule] = await Promise.all([
import("../src/lib/boss-data.ts"),
import("../src/app/api/v1/master-agent/tasks/[taskId]/control-state/route.ts"),
]);
data = dataModule;
getControlState = routeModule.GET;
}
test.beforeEach(async () => {
await setup();
await rm(runtimeRoot, { recursive: true, force: true });
});
test.after(async () => {
if (runtimeRoot) await rm(runtimeRoot, { recursive: true, force: true });
});
test("GET task control-state lets the owning device see cancellation without exposing prompt text", async () => {
const task = await data.queueMasterAgentTask({
taskId: "control-state-task",
projectId: "master-agent",
taskType: "conversation_reply",
requestMessageId: "msg-control-state",
requestText: "private user request should not leak",
executionPrompt: "private execution prompt should not leak",
requestedBy: "krisolo",
requestedByAccount: "krisolo",
deviceId: "mac-studio",
targetCodexThreadRef: "thread-control-state",
});
await data.claimNextMasterAgentTask("mac-studio");
await data.cancelMasterAgentTask({
taskId: task.taskId,
actorAccount: "krisolo",
reason: "用户在 APP 取消了当前任务",
});
const response = await getControlState(
new NextRequest(`http://127.0.0.1:3000/api/v1/master-agent/tasks/${task.taskId}/control-state`, {
method: "GET",
headers: {
"x-boss-device-token": "boss-mac-studio-token",
},
}),
{ params: Promise.resolve({ taskId: task.taskId }) },
);
const payload = await response.json();
assert.equal(response.status, 200);
assert.equal(payload.ok, true);
assert.equal(payload.taskId, "control-state-task");
assert.equal(payload.status, "canceled");
assert.equal(payload.canceled, true);
assert.equal(payload.cancelReason, "用户在 APP 取消了当前任务");
assert.equal(JSON.stringify(payload).includes("private user request"), false);
assert.equal(JSON.stringify(payload).includes("private execution prompt"), false);
});
test("GET task control-state rejects a different device token", async () => {
const task = await data.queueMasterAgentTask({
taskId: "control-state-forbidden-task",
projectId: "master-agent",
taskType: "conversation_reply",
requestMessageId: "msg-control-state-forbidden",
requestText: "继续",
executionPrompt: "继续",
requestedBy: "krisolo",
requestedByAccount: "krisolo",
deviceId: "mac-studio",
});
const response = await getControlState(
new NextRequest(`http://127.0.0.1:3000/api/v1/master-agent/tasks/${task.taskId}/control-state`, {
method: "GET",
headers: {
"x-boss-device-token": "wrong-token",
},
}),
{ params: Promise.resolve({ taskId: task.taskId }) },
);
assert.equal(response.status, 403);
});