From c2995bc4701e4c3edcb13c7f4bf962f66dc6b352 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 7 Apr 2026 15:40:10 +0100 Subject: [PATCH] test: speed up zalouser directory tests --- .../zalouser/src/channel.directory.test.ts | 79 +++++++++++++------ extensions/zalouser/src/channel.ts | 16 +--- extensions/zalouser/src/directory.ts | 54 +++++++++++++ 3 files changed, 113 insertions(+), 36 deletions(-) create mode 100644 extensions/zalouser/src/directory.ts diff --git a/extensions/zalouser/src/channel.directory.test.ts b/extensions/zalouser/src/channel.directory.test.ts index c0f11a218c7..77d99d0f15f 100644 --- a/extensions/zalouser/src/channel.directory.test.ts +++ b/extensions/zalouser/src/channel.directory.test.ts @@ -1,6 +1,6 @@ -import { describe, expect, it } from "vitest"; +import { beforeEach, describe, expect, it } from "vitest"; import "./accounts.test-mocks.js"; -import { zalouserPlugin } from "./channel.js"; +import { listZalouserDirectoryGroupMembers } from "./directory.js"; import { createZalouserRuntimeEnv } from "./test-helpers.js"; import "./zalo-js.test-mocks.js"; import { listZaloGroupMembersMock } from "./zalo-js.test-mocks.js"; @@ -8,36 +8,67 @@ import { listZaloGroupMembersMock } from "./zalo-js.test-mocks.js"; const runtimeStub = createZalouserRuntimeEnv(); describe("zalouser directory group members", () => { - it("accepts prefixed group ids from directory groups list output", async () => { - await zalouserPlugin.directory!.listGroupMembers!({ - cfg: {}, - accountId: "default", - groupId: "group:1471383327500481391", - runtime: runtimeStub, - }); + beforeEach(() => { + listZaloGroupMembersMock.mockClear(); + }); - expect(listZaloGroupMembersMock).toHaveBeenCalledWith("default", "1471383327500481391"); + it("accepts prefixed group ids from directory groups list output", async () => { + await listZalouserDirectoryGroupMembers( + { + cfg: {}, + accountId: "default", + groupId: "group:1471383327500481391", + }, + { + listZaloGroupMembers: async (profile, groupId) => + await listZaloGroupMembersMock(profile, groupId, runtimeStub), + }, + ); + + expect(listZaloGroupMembersMock).toHaveBeenLastCalledWith( + "default", + "1471383327500481391", + runtimeStub, + ); }); it("keeps backward compatibility for raw group ids", async () => { - await zalouserPlugin.directory!.listGroupMembers!({ - cfg: {}, - accountId: "default", - groupId: "1471383327500481391", - runtime: runtimeStub, - }); + await listZalouserDirectoryGroupMembers( + { + cfg: {}, + accountId: "default", + groupId: "1471383327500481391", + }, + { + listZaloGroupMembers: async (profile, groupId) => + await listZaloGroupMembersMock(profile, groupId, runtimeStub), + }, + ); - expect(listZaloGroupMembersMock).toHaveBeenCalledWith("default", "1471383327500481391"); + expect(listZaloGroupMembersMock).toHaveBeenLastCalledWith( + "default", + "1471383327500481391", + runtimeStub, + ); }); it("accepts provider-native g- group ids without stripping the prefix", async () => { - await zalouserPlugin.directory!.listGroupMembers!({ - cfg: {}, - accountId: "default", - groupId: "g-1471383327500481391", - runtime: runtimeStub, - }); + await listZalouserDirectoryGroupMembers( + { + cfg: {}, + accountId: "default", + groupId: "g-1471383327500481391", + }, + { + listZaloGroupMembers: async (profile, groupId) => + await listZaloGroupMembersMock(profile, groupId, runtimeStub), + }, + ); - expect(listZaloGroupMembersMock).toHaveBeenCalledWith("default", "g-1471383327500481391"); + expect(listZaloGroupMembersMock).toHaveBeenLastCalledWith( + "default", + "g-1471383327500481391", + runtimeStub, + ); }); }); diff --git a/extensions/zalouser/src/channel.ts b/extensions/zalouser/src/channel.ts index 51ca12355e1..3876cc7a11b 100644 --- a/extensions/zalouser/src/channel.ts +++ b/extensions/zalouser/src/channel.ts @@ -37,6 +37,7 @@ import { normalizeAccountId, sendPayloadWithChunkedTextAndMedia, } from "./channel-api.js"; +import { listZalouserDirectoryGroupMembers } from "./directory.js"; import { buildZalouserGroupCandidates, findZalouserGroupEntry } from "./group-policy.js"; import { resolveZalouserReactionMessageIds } from "./message-sid.js"; import type { ZalouserProbeResult } from "./probe.js"; @@ -44,7 +45,6 @@ import { writeQrDataUrlToTempFile } from "./qr-temp-file.js"; import { getZalouserRuntime } from "./runtime.js"; import { normalizeZalouserTarget, - parseZalouserDirectoryGroupId, parseZalouserOutboundTarget, resolveZalouserOutboundSessionRoute, } from "./session-route.js"; @@ -319,18 +319,10 @@ export const zalouserPlugin: ChannelPlugin { const { listZaloGroupMembers } = await loadZalouserChannelRuntime(); - const account = resolveZalouserAccountSync({ cfg: cfg, accountId }); - const normalizedGroupId = parseZalouserDirectoryGroupId(groupId); - const members = await listZaloGroupMembers(account.profile, normalizedGroupId); - const rows = members.map((member) => - mapUser({ - id: member.userId, - name: member.displayName, - avatarUrl: member.avatar ?? null, - raw: member, - }), + return await listZalouserDirectoryGroupMembers( + { cfg, accountId, groupId, limit }, + { listZaloGroupMembers }, ); - return typeof limit === "number" && limit > 0 ? rows.slice(0, limit) : rows; }, }, resolver: { diff --git a/extensions/zalouser/src/directory.ts b/extensions/zalouser/src/directory.ts new file mode 100644 index 00000000000..bfbb4ee10d9 --- /dev/null +++ b/extensions/zalouser/src/directory.ts @@ -0,0 +1,54 @@ +import { resolveZalouserAccountSync } from "./accounts.js"; +import type { ChannelDirectoryEntry, OpenClawConfig } from "./channel-api.js"; +import { parseZalouserDirectoryGroupId } from "./session-route.js"; + +type ZalouserDirectoryDeps = { + listZaloGroupMembers: ( + profile: string, + groupId: string, + ) => Promise< + Array<{ + userId: string; + displayName?: string | null; + avatar?: string | null; + }> + >; +}; + +function mapUser(params: { + id: string; + name?: string | null; + avatarUrl?: string | null; + raw?: unknown; +}): ChannelDirectoryEntry { + return { + kind: "user", + id: params.id, + name: params.name ?? undefined, + avatarUrl: params.avatarUrl ?? undefined, + raw: params.raw, + }; +} + +export async function listZalouserDirectoryGroupMembers( + params: { + cfg: OpenClawConfig; + accountId?: string; + groupId: string; + limit?: number; + }, + deps: ZalouserDirectoryDeps, +) { + const account = resolveZalouserAccountSync({ cfg: params.cfg, accountId: params.accountId }); + const normalizedGroupId = parseZalouserDirectoryGroupId(params.groupId); + const members = await deps.listZaloGroupMembers(account.profile, normalizedGroupId); + const rows = members.map((member) => + mapUser({ + id: member.userId, + name: member.displayName, + avatarUrl: member.avatar ?? null, + raw: member, + }), + ); + return typeof params.limit === "number" && params.limit > 0 ? rows.slice(0, params.limit) : rows; +}