import { beforeEach, describe, expect, it, vi } from "vitest" ;
const requestJsonlSocketMock = vi.hoisted(() => vi.fn());
vi.mock("./jsonl-socket.js" , () => ({
requestJsonlSocket: (...args: unknown[]) => requestJsonlSocketMock(...args),
}));
import { requestExecHostViaSocket } from "./exec-host.js" ;
describe("requestExecHostViaSocket" , () => {
beforeEach(() => {
requestJsonlSocketMock.mockReset();
});
it("returns null when socket credentials are missing" , async () => {
await expect(
requestExecHostViaSocket({
socketPath: "" ,
token: "secret" ,
request: { command: ["echo" , "hi" ] },
}),
).resolves.toBeNull();
await expect(
requestExecHostViaSocket({
socketPath: "/tmp/socket" ,
token: "" ,
request: { command: ["echo" , "hi" ] },
}),
).resolves.toBeNull();
expect(requestJsonlSocketMock).not.toHaveBeenCalled();
});
it("builds an exec payload and forwards the default timeout" , async () => {
requestJsonlSocketMock.mockResolvedValueOnce({ ok: true , payload: { success: true } });
await expect(
requestExecHostViaSocket({
socketPath: "/tmp/socket" ,
token: "secret" ,
request: {
command: ["echo" , "hi" ],
cwd: "/tmp" ,
},
}),
).resolves.toEqual({ ok: true , payload: { success: true } });
const call = requestJsonlSocketMock.mock.calls[0 ]?.[0 ] as
| {
socketPath: string;
requestLine: string;
timeoutMs: number;
accept: (msg: unknown) => unknown;
}
| undefined;
if (!call) {
throw new Error("expected requestJsonlSocket call" );
}
expect(call.socketPath).toBe("/tmp/socket" );
expect(call.timeoutMs).toBe(20 _000 );
const payload = JSON.parse(call.requestLine) as {
type: string;
id: string;
nonce: string;
ts: number;
hmac: string;
requestJson: string;
};
expect(payload.type).toBe("exec" );
expect(payload.id).toMatch(/^[0 -9 a-f]{8 }-[0 -9 a-f]{4 }-[0 -9 a-f]{4 }-[0 -9 a-f]{4 }-[0 -9 a-f]{12 }$/i);
expect(payload.nonce).toMatch(/^[0 -9 a-f]{32 }$/);
expect(typeof payload.ts).toBe("number" );
expect(payload.hmac).toMatch(/^[0 -9 a-f]{64 }$/);
expect(JSON.parse(payload.requestJson)).toEqual({
command: ["echo" , "hi" ],
cwd: "/tmp" ,
});
});
it("accepts only exec response messages and maps malformed matches to null" , async () => {
requestJsonlSocketMock.mockImplementationOnce(async ({ accept }) => {
expect(accept({ type: "ignore" })).toBeUndefined();
expect(accept({ type: "exec-res" , ok: true , payload: { success: true } })).toEqual({
ok: true ,
payload: { success: true },
});
expect(accept({ type: "exec-res" , ok: false , error: { code: "DENIED" } })).toEqual({
ok: false ,
error: { code: "DENIED" },
});
expect(accept({ type: "exec-res" , ok: true })).toBeNull();
return null ;
});
await expect(
requestExecHostViaSocket({
socketPath: "/tmp/socket" ,
token: "secret" ,
timeoutMs: 123 ,
request: { command: ["echo" , "hi" ] },
}),
).resolves.toBeNull();
expect(
(requestJsonlSocketMock.mock.calls[0 ]?.[0 ] as { timeoutMs?: number } | undefined)?.timeoutMs,
).toBe(123 );
});
});
Messung V0.5 in Prozent C=100 H=96 G=97
¤ Dauer der Verarbeitung: 0.2 Sekunden
¤
*© Formatika GbR, Deutschland