test: reuse LINE webhook runtime fixture (#146710)

This commit is contained in:
Peter Steinberger 2026-09-13 10:07:06 -07:00 • committed by GitHub
parent 710fed6cd0
commit 1d879559c3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,10 +1,10 @@
// Line tests cover webhook node plugin behavior.
import crypto from "node:crypto";
import type { IncomingMessage, ServerResponse } from "node:http";
import type { NextFunction, Request, Response } from "express";
import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env";
import { createMockIncomingRequest } from "openclaw/plugin-sdk/test-env";
import { afterAll, describe, expect, it, vi } from "vitest";
import { createRuntimeSpies } from "../../test-support/runtime-spies.js";
const runDetachedWebhookWorkSpy = vi.hoisted(() => vi.fn());
vi.mock("openclaw/plugin-sdk/webhook-request-guards", async () => {
@ -71,20 +71,6 @@ function firstParsedPayload(
return firstMockCall(mock, label)[0] as ParsedLineWebhookPayload;
}
type RuntimeEnvMock = RuntimeEnv & {
error: ReturnType<typeof vi.fn<(...args: unknown[]) => void>>;
exit: ReturnType<typeof vi.fn<(code: number) => void>>;
log: ReturnType<typeof vi.fn<(...args: unknown[]) => void>>;
};
function createRuntimeMock(): RuntimeEnvMock {
return {
error: vi.fn<(...args: unknown[]) => void>(),
exit: vi.fn<(code: number) => void>(),
log: vi.fn<(...args: unknown[]) => void>(),
};
}
function createMiddlewareRes() {
const status = vi.fn<Response["status"]>();
const json = vi.fn<Response["json"]>();
@ -106,7 +92,7 @@ function createMiddlewareRequest(
function createPostWebhookTestHarness(rawBody: string, secret = "secret") {
const bot = { handleWebhook: vi.fn(async () => "durable" as const) };
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const handler = createLineNodeWebhookHandler({
channelSecret: secret,
bot,
@ -200,7 +186,7 @@ async function invokeNodePostContract(params: {
}
return "durable" as const;
});
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const handler = createLineNodeWebhookHandler({
channelSecret: SECRET,
bot: { handleWebhook: dispatched },
@ -229,7 +215,7 @@ async function invokeMiddlewarePostContract(params: {
rawBody: string;
signed: boolean;
}) {
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const onEvents = vi.fn(async () => {
if (params.failWith) {
// oxlint-disable-next-line typescript/only-throw-error -- Webhook boundaries must report non-Error throws from downstream dispatchers.
@ -371,7 +357,7 @@ describe("LINE webhook shared POST contract", () => {
describe("createLineNodeWebhookHandler", () => {
it("returns 200 for GET", async () => {
const bot = { handleWebhook: vi.fn(async () => "durable" as const) };
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const handler = createLineNodeWebhookHandler({
channelSecret: "secret",
bot,
@ -388,7 +374,7 @@ describe("createLineNodeWebhookHandler", () => {
it("returns 204 for HEAD", async () => {
const bot = { handleWebhook: vi.fn(async () => "durable" as const) };
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const handler = createLineNodeWebhookHandler({
channelSecret: "secret",
bot,
@ -416,7 +402,7 @@ describe("createLineNodeWebhookHandler", () => {
it("rejects unsigned POST requests before reading the body", async () => {
const bot = { handleWebhook: vi.fn(async () => "durable" as const) };
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const readBody = vi.fn(async () => JSON.stringify({ events: [{ type: "message" }] }));
const handler = createLineNodeWebhookHandler({
channelSecret: "secret",
@ -436,7 +422,7 @@ describe("createLineNodeWebhookHandler", () => {
it("uses strict pre-auth limits for signed POST requests", async () => {
const rawBody = JSON.stringify({ events: [{ type: "message" }] });
const bot = { handleWebhook: vi.fn(async () => "durable" as const) };
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const readBody = vi.fn(async (_req: IncomingMessage, maxBytes: number, timeoutMs?: number) => {
expect(maxBytes).toBe(64 * 1024);
expect(timeoutMs).toBe(5_000);
@ -498,7 +484,7 @@ describe("createLineNodeWebhookHandler", () => {
),
};
const onRequestAuthenticated = vi.fn();
const runtime = createRuntimeMock();
const runtime = createRuntimeSpies();
const handler = createLineNodeWebhookHandler({
channelSecret: SECRET,
bot,