mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-20 14:30:57 +00:00
fix(zalouser): decouple tests from zca-js runtime
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
import { vi } from "vitest";
|
||||
import { createDefaultResolvedZalouserAccount } from "./test-helpers.js";
|
||||
|
||||
vi.mock("./accounts.js", async (importOriginal) => {
|
||||
const actual = (await importOriginal()) as Record<string, unknown>;
|
||||
vi.mock("./accounts.js", () => {
|
||||
return {
|
||||
...actual,
|
||||
listZalouserAccountIds: () => ["default"],
|
||||
resolveDefaultZalouserAccountId: () => "default",
|
||||
resolveZalouserAccountSync: () => createDefaultResolvedZalouserAccount(),
|
||||
resolveZalouserAccount: async () => createDefaultResolvedZalouserAccount(),
|
||||
listEnabledZalouserAccounts: async () => [createDefaultResolvedZalouserAccount()],
|
||||
getZcaUserInfo: async () => null,
|
||||
checkZcaAuthenticated: async () => false,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -1,18 +1,9 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import "./accounts.test-mocks.js";
|
||||
import { createZalouserRuntimeEnv } from "./test-helpers.js";
|
||||
|
||||
const listZaloGroupMembersMock = vi.hoisted(() => vi.fn(async () => []));
|
||||
|
||||
vi.mock("./zalo-js.js", async (importOriginal) => {
|
||||
const actual = (await importOriginal()) as Record<string, unknown>;
|
||||
return {
|
||||
...actual,
|
||||
listZaloGroupMembers: listZaloGroupMembersMock,
|
||||
};
|
||||
});
|
||||
|
||||
import "./zalo-js.test-mocks.js";
|
||||
import { zalouserPlugin } from "./channel.js";
|
||||
import { createZalouserRuntimeEnv } from "./test-helpers.js";
|
||||
import { listZaloGroupMembersMock } from "./zalo-js.test-mocks.js";
|
||||
|
||||
const runtimeStub = createZalouserRuntimeEnv();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { primeChannelOutboundSendMock } from "../../../src/channels/plugins/contracts/suites.js";
|
||||
import "./accounts.test-mocks.js";
|
||||
import "./zalo-js.test-mocks.js";
|
||||
import type { ReplyPayload } from "../runtime-api.js";
|
||||
import { zalouserPlugin } from "./channel.js";
|
||||
import { setZalouserRuntime } from "./runtime.js";
|
||||
|
||||
@@ -4,6 +4,7 @@ import path from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/channels/plugins/setup-wizard.js";
|
||||
import { withEnvAsync } from "../../../test/helpers/extensions/env.js";
|
||||
import "./zalo-js.test-mocks.js";
|
||||
import { zalouserSetupPlugin } from "./channel.setup.js";
|
||||
|
||||
const zalouserSetupAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import "./zalo-js.test-mocks.js";
|
||||
import { zalouserPlugin } from "./channel.js";
|
||||
import { setZalouserRuntime } from "./runtime.js";
|
||||
import { sendMessageZalouser, sendReactionZalouser } from "./send.js";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig, PluginRuntime, RuntimeEnv } from "../runtime-api.js";
|
||||
import "./monitor.send-mocks.js";
|
||||
import "./zalo-js.test-mocks.js";
|
||||
import { __testing } from "./monitor.js";
|
||||
import { sendMessageZalouserMock } from "./monitor.send-mocks.js";
|
||||
import { setZalouserRuntime } from "./runtime.js";
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import type { OpenClawConfig, PluginRuntime, RuntimeEnv } from "../runtime-api.js";
|
||||
import "./monitor.send-mocks.js";
|
||||
import "./zalo-js.test-mocks.js";
|
||||
import { resolveZalouserAccountSync } from "./accounts.js";
|
||||
import { __testing } from "./monitor.js";
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Reactions } from "./zca-client.js";
|
||||
import { Reactions } from "./zca-constants.js";
|
||||
|
||||
const REACTION_ALIAS_MAP = new Map<string, string>([
|
||||
["like", Reactions.LIKE],
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
sendZaloTextMessage,
|
||||
sendZaloTypingEvent,
|
||||
} from "./zalo-js.js";
|
||||
import { TextStyle } from "./zca-client.js";
|
||||
import { TextStyle } from "./zca-constants.js";
|
||||
|
||||
vi.mock("./zalo-js.js", () => ({
|
||||
sendZaloTextMessage: vi.fn(),
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
sendZaloTextMessage,
|
||||
sendZaloTypingEvent,
|
||||
} from "./zalo-js.js";
|
||||
import { TextStyle } from "./zca-client.js";
|
||||
import { TextStyle } from "./zca-constants.js";
|
||||
|
||||
export type ZalouserSendOptions = ZaloSendOptions;
|
||||
export type ZalouserSendResult = ZaloSendResult;
|
||||
|
||||
@@ -3,30 +3,7 @@ import { buildChannelSetupWizardAdapterFromSetupWizard } from "../../../src/chan
|
||||
import { createRuntimeEnv } from "../../../test/helpers/extensions/runtime-env.js";
|
||||
import { createTestWizardPrompter } from "../../../test/helpers/extensions/setup-wizard.js";
|
||||
import type { OpenClawConfig } from "../runtime-api.js";
|
||||
|
||||
vi.mock("./zalo-js.js", async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import("./zalo-js.js")>();
|
||||
return {
|
||||
...actual,
|
||||
checkZaloAuthenticated: vi.fn(async () => false),
|
||||
logoutZaloProfile: vi.fn(async () => {}),
|
||||
startZaloQrLogin: vi.fn(async () => ({
|
||||
message: "qr pending",
|
||||
qrDataUrl: undefined,
|
||||
})),
|
||||
waitForZaloQrLogin: vi.fn(async () => ({
|
||||
connected: false,
|
||||
message: "login pending",
|
||||
})),
|
||||
resolveZaloAllowFromEntries: vi.fn(async ({ entries }: { entries: string[] }) =>
|
||||
entries.map((entry) => ({ input: entry, resolved: true, id: entry, note: undefined })),
|
||||
),
|
||||
resolveZaloGroupsByEntries: vi.fn(async ({ entries }: { entries: string[] }) =>
|
||||
entries.map((entry) => ({ input: entry, resolved: true, id: entry, note: undefined })),
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
import "./zalo-js.test-mocks.js";
|
||||
import { zalouserPlugin } from "./channel.js";
|
||||
|
||||
const zalouserConfigureAdapter = buildChannelSetupWizardAdapterFromSetupWizard({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { parseZalouserTextStyles } from "./text-styles.js";
|
||||
import { TextStyle } from "./zca-client.js";
|
||||
import { TextStyle } from "./zca-constants.js";
|
||||
|
||||
describe("parseZalouserTextStyles", () => {
|
||||
it("renders inline markdown emphasis as Zalo style ranges", () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TextStyle, type Style } from "./zca-client.js";
|
||||
import { TextStyle, type Style } from "./zca-constants.js";
|
||||
|
||||
type InlineStyle = (typeof TextStyle)[keyof typeof TextStyle];
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Style } from "./zca-client.js";
|
||||
import type { Style } from "./zca-constants.js";
|
||||
|
||||
export type ZcaFriend = {
|
||||
userId: string;
|
||||
|
||||
60
extensions/zalouser/src/zalo-js.test-mocks.ts
Normal file
60
extensions/zalouser/src/zalo-js.test-mocks.ts
Normal file
@@ -0,0 +1,60 @@
|
||||
import { vi } from "vitest";
|
||||
|
||||
const zaloJsMocks = vi.hoisted(() => ({
|
||||
checkZaloAuthenticatedMock: vi.fn(async () => false),
|
||||
getZaloUserInfoMock: vi.fn(async () => null),
|
||||
listZaloFriendsMock: vi.fn(async () => []),
|
||||
listZaloFriendsMatchingMock: vi.fn(async () => []),
|
||||
listZaloGroupMembersMock: vi.fn(async () => []),
|
||||
listZaloGroupsMock: vi.fn(async () => []),
|
||||
listZaloGroupsMatchingMock: vi.fn(async () => []),
|
||||
logoutZaloProfileMock: vi.fn(async () => {}),
|
||||
resolveZaloAllowFromEntriesMock: vi.fn(async ({ entries }: { entries: string[] }) =>
|
||||
entries.map((entry) => ({ input: entry, resolved: true, id: entry, note: undefined })),
|
||||
),
|
||||
resolveZaloGroupContextMock: vi.fn(async () => null),
|
||||
resolveZaloGroupsByEntriesMock: vi.fn(async ({ entries }: { entries: string[] }) =>
|
||||
entries.map((entry) => ({ input: entry, resolved: true, id: entry, note: undefined })),
|
||||
),
|
||||
startZaloListenerMock: vi.fn(async () => ({ stop: vi.fn() })),
|
||||
startZaloQrLoginMock: vi.fn(async () => ({
|
||||
message: "qr pending",
|
||||
qrDataUrl: undefined,
|
||||
})),
|
||||
waitForZaloQrLoginMock: vi.fn(async () => ({
|
||||
connected: false,
|
||||
message: "login pending",
|
||||
})),
|
||||
}));
|
||||
|
||||
export const checkZaloAuthenticatedMock = zaloJsMocks.checkZaloAuthenticatedMock;
|
||||
export const getZaloUserInfoMock = zaloJsMocks.getZaloUserInfoMock;
|
||||
export const listZaloFriendsMock = zaloJsMocks.listZaloFriendsMock;
|
||||
export const listZaloFriendsMatchingMock = zaloJsMocks.listZaloFriendsMatchingMock;
|
||||
export const listZaloGroupMembersMock = zaloJsMocks.listZaloGroupMembersMock;
|
||||
export const listZaloGroupsMock = zaloJsMocks.listZaloGroupsMock;
|
||||
export const listZaloGroupsMatchingMock = zaloJsMocks.listZaloGroupsMatchingMock;
|
||||
export const logoutZaloProfileMock = zaloJsMocks.logoutZaloProfileMock;
|
||||
export const resolveZaloAllowFromEntriesMock = zaloJsMocks.resolveZaloAllowFromEntriesMock;
|
||||
export const resolveZaloGroupContextMock = zaloJsMocks.resolveZaloGroupContextMock;
|
||||
export const resolveZaloGroupsByEntriesMock = zaloJsMocks.resolveZaloGroupsByEntriesMock;
|
||||
export const startZaloListenerMock = zaloJsMocks.startZaloListenerMock;
|
||||
export const startZaloQrLoginMock = zaloJsMocks.startZaloQrLoginMock;
|
||||
export const waitForZaloQrLoginMock = zaloJsMocks.waitForZaloQrLoginMock;
|
||||
|
||||
vi.mock("./zalo-js.js", () => ({
|
||||
checkZaloAuthenticated: checkZaloAuthenticatedMock,
|
||||
getZaloUserInfo: getZaloUserInfoMock,
|
||||
listZaloFriends: listZaloFriendsMock,
|
||||
listZaloFriendsMatching: listZaloFriendsMatchingMock,
|
||||
listZaloGroupMembers: listZaloGroupMembersMock,
|
||||
listZaloGroups: listZaloGroupsMock,
|
||||
listZaloGroupsMatching: listZaloGroupsMatchingMock,
|
||||
logoutZaloProfile: logoutZaloProfileMock,
|
||||
resolveZaloAllowFromEntries: resolveZaloAllowFromEntriesMock,
|
||||
resolveZaloGroupContext: resolveZaloGroupContextMock,
|
||||
resolveZaloGroupsByEntries: resolveZaloGroupsByEntriesMock,
|
||||
startZaloListener: startZaloListenerMock,
|
||||
startZaloQrLogin: startZaloQrLoginMock,
|
||||
waitForZaloQrLogin: waitForZaloQrLoginMock,
|
||||
}));
|
||||
@@ -19,17 +19,16 @@ import type {
|
||||
ZcaUserInfo,
|
||||
} from "./types.js";
|
||||
import {
|
||||
LoginQRCallbackEventType,
|
||||
TextStyle,
|
||||
ThreadType,
|
||||
Zalo,
|
||||
type API,
|
||||
type Credentials,
|
||||
type GroupInfo,
|
||||
type LoginQRCallbackEvent,
|
||||
type Message,
|
||||
type User,
|
||||
Zalo,
|
||||
} from "./zca-client.js";
|
||||
import { LoginQRCallbackEventType, ThreadType } from "./zca-constants.js";
|
||||
|
||||
const API_LOGIN_TIMEOUT_MS = 20_000;
|
||||
const QR_LOGIN_TTL_MS = 3 * 60_000;
|
||||
|
||||
@@ -1,67 +1,17 @@
|
||||
import * as zcaJsRuntime from "zca-js";
|
||||
import {
|
||||
LoginQRCallbackEventType,
|
||||
Reactions,
|
||||
TextStyle,
|
||||
ThreadType,
|
||||
type Style,
|
||||
} from "./zca-constants.js";
|
||||
|
||||
const zcaJs = zcaJsRuntime as unknown as {
|
||||
ThreadType: unknown;
|
||||
LoginQRCallbackEventType: unknown;
|
||||
Reactions: unknown;
|
||||
Zalo: unknown;
|
||||
};
|
||||
|
||||
export const ThreadType = zcaJs.ThreadType as {
|
||||
User: 0;
|
||||
Group: 1;
|
||||
};
|
||||
|
||||
export const LoginQRCallbackEventType = zcaJs.LoginQRCallbackEventType as {
|
||||
QRCodeGenerated: 0;
|
||||
QRCodeExpired: 1;
|
||||
QRCodeScanned: 2;
|
||||
QRCodeDeclined: 3;
|
||||
GotLoginInfo: 4;
|
||||
};
|
||||
|
||||
export const Reactions = zcaJs.Reactions as Record<string, string> & {
|
||||
HEART: string;
|
||||
LIKE: string;
|
||||
HAHA: string;
|
||||
WOW: string;
|
||||
CRY: string;
|
||||
ANGRY: string;
|
||||
NONE: string;
|
||||
};
|
||||
|
||||
// Mirror zca-js sendMessage style constants locally because the package root
|
||||
// typing surface does not consistently expose TextStyle/Style to tsgo.
|
||||
export const TextStyle = {
|
||||
Bold: "b",
|
||||
Italic: "i",
|
||||
Underline: "u",
|
||||
StrikeThrough: "s",
|
||||
Red: "c_db342e",
|
||||
Orange: "c_f27806",
|
||||
Yellow: "c_f7b503",
|
||||
Green: "c_15a85f",
|
||||
Small: "f_13",
|
||||
Big: "f_18",
|
||||
UnorderedList: "lst_1",
|
||||
OrderedList: "lst_2",
|
||||
Indent: "ind_$",
|
||||
} as const;
|
||||
|
||||
type TextStyleValue = (typeof TextStyle)[keyof typeof TextStyle];
|
||||
|
||||
export type Style =
|
||||
| {
|
||||
start: number;
|
||||
len: number;
|
||||
st: Exclude<TextStyleValue, typeof TextStyle.Indent>;
|
||||
}
|
||||
| {
|
||||
start: number;
|
||||
len: number;
|
||||
st: typeof TextStyle.Indent;
|
||||
indentSize?: number;
|
||||
};
|
||||
export { LoginQRCallbackEventType, Reactions, TextStyle, ThreadType };
|
||||
export type { Style };
|
||||
|
||||
export type Credentials = {
|
||||
imei: string;
|
||||
|
||||
55
extensions/zalouser/src/zca-constants.ts
Normal file
55
extensions/zalouser/src/zca-constants.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
export const ThreadType = {
|
||||
User: 0,
|
||||
Group: 1,
|
||||
} as const;
|
||||
|
||||
export const LoginQRCallbackEventType = {
|
||||
QRCodeGenerated: 0,
|
||||
QRCodeExpired: 1,
|
||||
QRCodeScanned: 2,
|
||||
QRCodeDeclined: 3,
|
||||
GotLoginInfo: 4,
|
||||
} as const;
|
||||
|
||||
export const Reactions = {
|
||||
HEART: "/-heart",
|
||||
LIKE: "/-strong",
|
||||
HAHA: ":>",
|
||||
WOW: ":o",
|
||||
CRY: ":-((",
|
||||
ANGRY: ":-h",
|
||||
NONE: "",
|
||||
} as const;
|
||||
|
||||
// Mirror zca-js sendMessage style constants locally because the package root
|
||||
// typing surface does not consistently expose TextStyle/Style to tsgo.
|
||||
export const TextStyle = {
|
||||
Bold: "b",
|
||||
Italic: "i",
|
||||
Underline: "u",
|
||||
StrikeThrough: "s",
|
||||
Red: "c_db342e",
|
||||
Orange: "c_f27806",
|
||||
Yellow: "c_f7b503",
|
||||
Green: "c_15a85f",
|
||||
Small: "f_13",
|
||||
Big: "f_18",
|
||||
UnorderedList: "lst_1",
|
||||
OrderedList: "lst_2",
|
||||
Indent: "ind_$",
|
||||
} as const;
|
||||
|
||||
type TextStyleValue = (typeof TextStyle)[keyof typeof TextStyle];
|
||||
|
||||
export type Style =
|
||||
| {
|
||||
start: number;
|
||||
len: number;
|
||||
st: Exclude<TextStyleValue, typeof TextStyle.Indent>;
|
||||
}
|
||||
| {
|
||||
start: number;
|
||||
len: number;
|
||||
st: typeof TextStyle.Indent;
|
||||
indentSize?: number;
|
||||
};
|
||||
Reference in New Issue
Block a user