test: speed up googlechat setup tests

This commit is contained in:
Peter Steinberger
2026-04-07 14:14:56 +01:00
parent df993291b6
commit 3f8d7bb1fe
3 changed files with 91 additions and 52 deletions

View File

@@ -27,7 +27,6 @@ import { googleChatApprovalAuth } from "./approval-auth.js";
import {
buildChannelConfigSchema,
chunkTextForOutbound,
createAccountStatusSink,
DEFAULT_ACCOUNT_ID,
fetchRemoteMedia,
GoogleChatConfigSchema,
@@ -42,13 +41,13 @@ import {
resolveDefaultGoogleChatAccountId,
resolveGoogleChatAccount,
resolveGoogleChatOutboundSpace,
runPassiveAccountLifecycle,
type ChannelMessageActionAdapter,
type ChannelStatusIssue,
type OpenClawConfig,
type ResolvedGoogleChatAccount,
} from "./channel.deps.runtime.js";
import { collectGoogleChatMutableAllowlistWarnings } from "./doctor.js";
import { startGoogleChatGatewayAccount } from "./gateway.js";
import { resolveGoogleChatGroupRequireMention } from "./group-policy.js";
import { collectRuntimeConfigAssignments, secretTargetRegistryEntries } from "./secret-contract.js";
import { googlechatSetupAdapter } from "./setup-core.js";
@@ -293,45 +292,7 @@ export const googlechatPlugin = createChatChannelPlugin({
}),
}),
gateway: {
startAccount: async (ctx) => {
const account = ctx.account;
const statusSink = createAccountStatusSink({
accountId: account.accountId,
setStatus: ctx.setStatus,
});
ctx.log?.info(`[${account.accountId}] starting Google Chat webhook`);
const { resolveGoogleChatWebhookPath, startGoogleChatMonitor } =
await loadGoogleChatChannelRuntime();
statusSink({
running: true,
lastStartAt: Date.now(),
webhookPath: resolveGoogleChatWebhookPath({ account }),
audienceType: account.config.audienceType,
audience: account.config.audience,
});
await runPassiveAccountLifecycle({
abortSignal: ctx.abortSignal,
start: async () =>
await startGoogleChatMonitor({
account,
config: ctx.cfg,
runtime: ctx.runtime,
abortSignal: ctx.abortSignal,
webhookPath: account.config.webhookPath,
webhookUrl: account.config.webhookUrl,
statusSink,
}),
stop: async (unregister) => {
unregister?.();
},
onStop: async () => {
statusSink({
running: false,
lastStopAt: Date.now(),
});
},
});
},
startAccount: startGoogleChatGatewayAccount,
},
},
pairing: {

View File

@@ -0,0 +1,61 @@
import { createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
import {
createAccountStatusSink,
runPassiveAccountLifecycle,
type OpenClawConfig,
type ResolvedGoogleChatAccount,
} from "./channel.deps.runtime.js";
const loadGoogleChatChannelRuntime = createLazyRuntimeNamedExport(
() => import("./channel.runtime.js"),
"googleChatChannelRuntime",
);
export async function startGoogleChatGatewayAccount(ctx: {
account: ResolvedGoogleChatAccount;
cfg: OpenClawConfig;
runtime: unknown;
abortSignal: AbortSignal;
setStatus: (patch: Record<string, unknown>) => void;
log?: {
info?: (message: string) => void;
};
}): Promise<void> {
const account = ctx.account;
const statusSink = createAccountStatusSink({
accountId: account.accountId,
setStatus: ctx.setStatus,
});
ctx.log?.info?.(`[${account.accountId}] starting Google Chat webhook`);
const { resolveGoogleChatWebhookPath, startGoogleChatMonitor } =
await loadGoogleChatChannelRuntime();
statusSink({
running: true,
lastStartAt: Date.now(),
webhookPath: resolveGoogleChatWebhookPath({ account }),
audienceType: account.config.audienceType,
audience: account.config.audience,
});
await runPassiveAccountLifecycle({
abortSignal: ctx.abortSignal,
start: async () =>
await startGoogleChatMonitor({
account,
config: ctx.cfg,
runtime: ctx.runtime,
abortSignal: ctx.abortSignal,
webhookPath: account.config.webhookPath,
webhookUrl: account.config.webhookUrl,
statusSink,
}),
stop: async (unregister) => {
unregister?.();
},
onStop: async () => {
statusSink({
running: false,
lastStopAt: Date.now(),
});
},
});
}

View File

@@ -15,8 +15,13 @@ import {
} from "../../../test/helpers/plugins/start-account-lifecycle.js";
import type { OpenClawConfig } from "../runtime-api.js";
import { resolveGoogleChatAccount, type ResolvedGoogleChatAccount } from "./accounts.js";
import { googlechatPlugin } from "./channel.js";
import {
listGoogleChatAccountIds,
resolveDefaultGoogleChatAccountId,
} from "./channel.deps.runtime.js";
import { startGoogleChatGatewayAccount } from "./gateway.js";
import { googlechatSetupAdapter } from "./setup-core.js";
import { googlechatSetupWizard } from "./setup-surface.js";
const hoisted = vi.hoisted(() => ({
startGoogleChatMonitor: vi.fn(),
@@ -30,8 +35,20 @@ vi.mock("./monitor.js", async () => {
};
});
const googlechatConfigure = createPluginSetupWizardConfigure(googlechatPlugin);
const googlechatStatus = createPluginSetupWizardStatus(googlechatPlugin);
const googlechatSetupPlugin = {
id: "googlechat",
meta: {
label: "Google Chat",
},
config: {
defaultAccountId: resolveDefaultGoogleChatAccountId,
listAccountIds: listGoogleChatAccountIds,
},
setupWizard: googlechatSetupWizard,
} as never;
const googlechatConfigure = createPluginSetupWizardConfigure(googlechatSetupPlugin);
const googlechatStatus = createPluginSetupWizardStatus(googlechatSetupPlugin);
function buildAccount(): ResolvedGoogleChatAccount {
return {
@@ -165,7 +182,7 @@ describe("googlechat setup", () => {
it("reads the named-account DM policy instead of the channel root", () => {
expect(
googlechatPlugin.setupWizard?.dmPolicy?.getCurrent(
googlechatSetupWizard.dmPolicy?.getCurrent(
{
channels: {
googlechat: {
@@ -234,7 +251,7 @@ describe("googlechat setup", () => {
});
it("reports account-scoped config keys for named accounts", () => {
expect(googlechatPlugin.setupWizard?.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({
expect(googlechatSetupWizard.dmPolicy?.resolveConfigKeys?.({}, "alerts")).toEqual({
policyKey: "channels.googlechat.accounts.alerts.dm.policy",
allowFromKey: "channels.googlechat.accounts.alerts.dm.allowFrom",
});
@@ -260,13 +277,13 @@ describe("googlechat setup", () => {
},
} as OpenClawConfig;
expect(googlechatPlugin.setupWizard?.dmPolicy?.getCurrent(cfg)).toBe("allowlist");
expect(googlechatPlugin.setupWizard?.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({
expect(googlechatSetupWizard.dmPolicy?.getCurrent(cfg)).toBe("allowlist");
expect(googlechatSetupWizard.dmPolicy?.resolveConfigKeys?.(cfg)).toEqual({
policyKey: "channels.googlechat.accounts.alerts.dm.policy",
allowFromKey: "channels.googlechat.accounts.alerts.dm.allowFrom",
});
const next = googlechatPlugin.setupWizard?.dmPolicy?.setPolicy(cfg, "open");
const next = googlechatSetupWizard.dmPolicy?.setPolicy(cfg, "open");
expect(next?.channels?.googlechat?.dm?.policy).toBe("disabled");
expect(next?.channels?.googlechat?.accounts?.alerts?.dm?.policy).toBe("open");
});
@@ -277,7 +294,7 @@ describe("googlechat setup", () => {
text: vi.fn(async () => "users/123456789"),
};
const next = await googlechatPlugin.setupWizard?.dmPolicy?.promptAllowFrom?.({
const next = await googlechatSetupWizard.dmPolicy?.promptAllowFrom?.({
cfg: {
channels: {
googlechat: {
@@ -306,7 +323,7 @@ describe("googlechat setup", () => {
});
it('writes open DM policy to the named account and preserves inherited allowFrom with "*"', () => {
const next = googlechatPlugin.setupWizard?.dmPolicy?.setPolicy(
const next = googlechatSetupWizard.dmPolicy?.setPolicy(
{
channels: {
googlechat: {
@@ -335,7 +352,7 @@ describe("googlechat setup", () => {
hoisted.startGoogleChatMonitor.mockResolvedValue(unregister);
const { abort, patches, task, isSettled } = startAccountAndTrackLifecycle({
startAccount: googlechatPlugin.gateway!.startAccount!,
startAccount: startGoogleChatGatewayAccount,
account: buildAccount(),
});
await expectPendingUntilAbort({