diff --git a/extensions/qa-lab/src/discord-crabline-roundtrip.e2e.test.ts b/extensions/qa-lab/src/discord-crabline-roundtrip.e2e.test.ts index 670db08c3c54..849f00b4b12e 100644 --- a/extensions/qa-lab/src/discord-crabline-roundtrip.e2e.test.ts +++ b/extensions/qa-lab/src/discord-crabline-roundtrip.e2e.test.ts @@ -1,6 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; import { resolveOpenClawCrablineChannelDriverSelection } from "@openclaw/crabline"; +import { readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime"; import { describe, expect, it } from "vitest"; import { CRABLINE_DISCORD_PROVIDER_ENDPOINT_ARTIFACT } from "./crabline-discord-provider-endpoint-artifact.js"; import { runQaSuite } from "./suite-launch.runtime.js"; @@ -23,10 +24,6 @@ function readObject(value: unknown): Record | undefined { : undefined; } -function readString(value: unknown): string { - return typeof value === "string" ? value : ""; -} - async function readRecorderEvents(recorderPath: string): Promise { const raw = await fs.readFile(recorderPath, "utf8"); if (raw.includes("discord.com") || raw.includes("discordapp.com")) { @@ -101,26 +98,26 @@ describe("Discord Crabline real-plugin roundtrip", () => { event.accepted === true, ); const inboundBody = readObject(inbound?.body); - const inboundChannelId = readString(inboundBody?.channelId); - const parentChannelId = readString(inboundBody?.parentChannelId); + const inboundChannelId = readStringValue(inboundBody?.channelId) ?? ""; + const parentChannelId = readStringValue(inboundBody?.parentChannelId) ?? ""; expect(inboundChannelId).toMatch(/^\d{17,20}$/u); expect(parentChannelId).toMatch(/^\d{17,20}$/u); expect(inboundChannelId).not.toBe(parentChannelId); - expect(readString(inboundBody?.content)).toMatch(/<@\d{17,20}>/u); + expect(readStringValue(inboundBody?.content) ?? "").toMatch(/<@\d{17,20}>/u); const outbound = events.find( (event) => event.type === "api" && event.method === "POST" && event.path === `/api/v10/channels/${inboundChannelId}/messages` && - readString(readObject(event.body)?.content).includes(EXPECTED_MARKER) && + (readStringValue(readObject(event.body)?.content) ?? "").includes(EXPECTED_MARKER) && event.accepted === true, ); const outboundBody = readObject(outbound?.body); const messageReference = readObject(outboundBody?.message_reference); expect(outbound).toBeDefined(); - expect(readString(outboundBody?.content)).toContain(EXPECTED_MARKER); - expect(readString(outboundBody?.content)).not.toMatch(/<@\d{17,20}>/u); + expect(readStringValue(outboundBody?.content) ?? "").toContain(EXPECTED_MARKER); + expect(readStringValue(outboundBody?.content) ?? "").not.toMatch(/<@\d{17,20}>/u); expect(messageReference).toMatchObject({ message_id: expect.stringMatching(/^\d{17,20}$/u), });