|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
|
import { GET as getRpaStatus } from "@/app/api/rpa/status/route";
|
|
|
import { POST as pauseWorkerRoute } from "@/app/api/rpa/worker/pause/route";
|
|
|
|
|
|
vi.mock("@/modules/cache/circuit-breaker", () => ({
|
|
|
isCircuitOpen: vi.fn().mockResolvedValue(false),
|
|
|
}));
|
|
|
|
|
|
vi.mock("@/workers/rpa/queue", () => ({
|
|
|
getQueueDepth: vi.fn().mockResolvedValue(3),
|
|
|
}));
|
|
|
|
|
|
vi.mock("@/workers/rpa/worker-state", () => ({
|
|
|
listWorkerHeartbeats: vi.fn().mockResolvedValue([
|
|
|
{ workerId: "worker-1", lastSeenMs: Date.now() },
|
|
|
]),
|
|
|
getWorkerPauseRemaining: vi.fn().mockResolvedValue(0),
|
|
|
pauseWorker: vi.fn().mockResolvedValue(undefined),
|
|
|
isWorkerPaused: vi.fn().mockResolvedValue(false),
|
|
|
}));
|
|
|
|
|
|
vi.mock("@/lib/prisma", () => ({
|
|
|
prisma: {
|
|
|
quoteRecord: {
|
|
|
count: vi.fn().mockResolvedValue(10),
|
|
|
},
|
|
|
},
|
|
|
}));
|
|
|
|
|
|
import { pauseWorker } from "@/workers/rpa/worker-state";
|
|
|
|
|
|
const ADMIN_HEADERS = {
|
|
|
"x-auth-type": "admin",
|
|
|
"x-user-id": "U_admin_demo",
|
|
|
"x-user-role": "admin",
|
|
|
};
|
|
|
|
|
|
const SERVICE_HEADERS = {
|
|
|
"x-auth-type": "service",
|
|
|
"x-customer-id": "CUST_001",
|
|
|
"x-permissions": "",
|
|
|
};
|
|
|
|
|
|
beforeEach(() => {
|
|
|
vi.clearAllMocks();
|
|
|
});
|
|
|
|
|
|
describe("RPA 管理 API 集成(task-116)", () => {
|
|
|
it("GET /api/rpa/status → 200 + workers", async () => {
|
|
|
const response = await getRpaStatus(
|
|
|
new Request("http://localhost/api/rpa/status", {
|
|
|
headers: ADMIN_HEADERS,
|
|
|
}),
|
|
|
);
|
|
|
const json = await response.json();
|
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
expect(json.code).toBe(0);
|
|
|
expect(json.data.workers).toHaveLength(1);
|
|
|
expect(json.data.queue_depth).toBe(3);
|
|
|
});
|
|
|
|
|
|
it("POST pause → Worker 暂停", async () => {
|
|
|
const response = await pauseWorkerRoute(
|
|
|
new Request("http://localhost/api/rpa/worker/pause", {
|
|
|
method: "POST",
|
|
|
headers: {
|
|
|
...ADMIN_HEADERS,
|
|
|
"Content-Type": "application/json",
|
|
|
},
|
|
|
body: JSON.stringify({
|
|
|
worker_id: "worker-1",
|
|
|
duration_minutes: 5,
|
|
|
}),
|
|
|
}),
|
|
|
);
|
|
|
const json = await response.json();
|
|
|
|
|
|
expect(response.status).toBe(200);
|
|
|
expect(json.code).toBe(0);
|
|
|
expect(pauseWorker).toHaveBeenCalledWith("worker-1", 5);
|
|
|
});
|
|
|
|
|
|
it("非 admin → 403", async () => {
|
|
|
const response = await getRpaStatus(
|
|
|
new Request("http://localhost/api/rpa/status", {
|
|
|
headers: SERVICE_HEADERS,
|
|
|
}),
|
|
|
);
|
|
|
expect(response.status).toBe(403);
|
|
|
});
|
|
|
});
|