mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-19 05:57:28 +00:00
refactor(tests): share harnesses for cli and monitor fixtures
This commit is contained in:
@@ -27,6 +27,25 @@ vi.mock("qrcode-terminal", () => ({
|
|||||||
|
|
||||||
const { registerQrCli } = await import("./qr-cli.js");
|
const { registerQrCli } = await import("./qr-cli.js");
|
||||||
|
|
||||||
|
function createRemoteQrConfig(params?: { withTailscale?: boolean }) {
|
||||||
|
return {
|
||||||
|
gateway: {
|
||||||
|
...(params?.withTailscale ? { tailscale: { mode: "serve" } } : {}),
|
||||||
|
remote: { url: "wss://remote.example.com:444", token: "remote-tok" },
|
||||||
|
auth: { mode: "token", token: "local-tok" },
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
entries: {
|
||||||
|
"device-pair": {
|
||||||
|
config: {
|
||||||
|
publicUrl: "wss://wrong.example.com:443",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
describe("registerQrCli", () => {
|
describe("registerQrCli", () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.clearAllMocks();
|
vi.clearAllMocks();
|
||||||
@@ -124,21 +143,7 @@ describe("registerQrCli", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("uses gateway.remote.url when --remote is set (ignores device-pair publicUrl)", async () => {
|
it("uses gateway.remote.url when --remote is set (ignores device-pair publicUrl)", async () => {
|
||||||
loadConfig.mockReturnValue({
|
loadConfig.mockReturnValue(createRemoteQrConfig());
|
||||||
gateway: {
|
|
||||||
remote: { url: "wss://remote.example.com:444", token: "remote-tok" },
|
|
||||||
auth: { mode: "token", token: "local-tok" },
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
entries: {
|
|
||||||
"device-pair": {
|
|
||||||
config: {
|
|
||||||
publicUrl: "wss://wrong.example.com:443",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const program = new Command();
|
const program = new Command();
|
||||||
registerQrCli(program);
|
registerQrCli(program);
|
||||||
@@ -152,21 +157,7 @@ describe("registerQrCli", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("reports gateway.remote.url as source in --remote json output", async () => {
|
it("reports gateway.remote.url as source in --remote json output", async () => {
|
||||||
loadConfig.mockReturnValue({
|
loadConfig.mockReturnValue(createRemoteQrConfig());
|
||||||
gateway: {
|
|
||||||
remote: { url: "wss://remote.example.com:444", token: "remote-tok" },
|
|
||||||
auth: { mode: "token", token: "local-tok" },
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
entries: {
|
|
||||||
"device-pair": {
|
|
||||||
config: {
|
|
||||||
publicUrl: "wss://wrong.example.com:443",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const program = new Command();
|
const program = new Command();
|
||||||
registerQrCli(program);
|
registerQrCli(program);
|
||||||
@@ -202,22 +193,7 @@ describe("registerQrCli", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("prefers gateway.remote.url over tailscale when --remote is set", async () => {
|
it("prefers gateway.remote.url over tailscale when --remote is set", async () => {
|
||||||
loadConfig.mockReturnValue({
|
loadConfig.mockReturnValue(createRemoteQrConfig({ withTailscale: true }));
|
||||||
gateway: {
|
|
||||||
tailscale: { mode: "serve" },
|
|
||||||
remote: { url: "wss://remote.example.com:444", token: "remote-tok" },
|
|
||||||
auth: { mode: "token", token: "local-tok" },
|
|
||||||
},
|
|
||||||
plugins: {
|
|
||||||
entries: {
|
|
||||||
"device-pair": {
|
|
||||||
config: {
|
|
||||||
publicUrl: "wss://wrong.example.com:443",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
runCommandWithTimeout.mockResolvedValue({
|
runCommandWithTimeout.mockResolvedValue({
|
||||||
code: 0,
|
code: 0,
|
||||||
stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}',
|
stdout: '{"Self":{"DNSName":"ts-host.tailnet.ts.net."}}',
|
||||||
|
|||||||
@@ -38,6 +38,22 @@ const makeEntries = (
|
|||||||
return out;
|
return out;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function createAutoThreadMentionContext() {
|
||||||
|
const guildInfo: DiscordGuildEntryResolved = {
|
||||||
|
requireMention: true,
|
||||||
|
channels: {
|
||||||
|
general: { allow: true, autoThread: true },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const channelConfig = resolveDiscordChannelConfig({
|
||||||
|
guildInfo,
|
||||||
|
channelId: "1",
|
||||||
|
channelName: "General",
|
||||||
|
channelSlug: "general",
|
||||||
|
});
|
||||||
|
return { guildInfo, channelConfig };
|
||||||
|
}
|
||||||
|
|
||||||
describe("registerDiscordListener", () => {
|
describe("registerDiscordListener", () => {
|
||||||
class FakeListener {}
|
class FakeListener {}
|
||||||
|
|
||||||
@@ -402,18 +418,7 @@ describe("discord mention gating", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("does not require mention inside autoThread threads", () => {
|
it("does not require mention inside autoThread threads", () => {
|
||||||
const guildInfo: DiscordGuildEntryResolved = {
|
const { guildInfo, channelConfig } = createAutoThreadMentionContext();
|
||||||
requireMention: true,
|
|
||||||
channels: {
|
|
||||||
general: { allow: true, autoThread: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const channelConfig = resolveDiscordChannelConfig({
|
|
||||||
guildInfo,
|
|
||||||
channelId: "1",
|
|
||||||
channelName: "General",
|
|
||||||
channelSlug: "general",
|
|
||||||
});
|
|
||||||
expect(
|
expect(
|
||||||
resolveDiscordShouldRequireMention({
|
resolveDiscordShouldRequireMention({
|
||||||
isGuildMessage: true,
|
isGuildMessage: true,
|
||||||
@@ -427,18 +432,7 @@ describe("discord mention gating", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("requires mention inside user-created threads with autoThread enabled", () => {
|
it("requires mention inside user-created threads with autoThread enabled", () => {
|
||||||
const guildInfo: DiscordGuildEntryResolved = {
|
const { guildInfo, channelConfig } = createAutoThreadMentionContext();
|
||||||
requireMention: true,
|
|
||||||
channels: {
|
|
||||||
general: { allow: true, autoThread: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const channelConfig = resolveDiscordChannelConfig({
|
|
||||||
guildInfo,
|
|
||||||
channelId: "1",
|
|
||||||
channelName: "General",
|
|
||||||
channelSlug: "general",
|
|
||||||
});
|
|
||||||
expect(
|
expect(
|
||||||
resolveDiscordShouldRequireMention({
|
resolveDiscordShouldRequireMention({
|
||||||
isGuildMessage: true,
|
isGuildMessage: true,
|
||||||
@@ -452,18 +446,7 @@ describe("discord mention gating", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("requires mention when thread owner is unknown", () => {
|
it("requires mention when thread owner is unknown", () => {
|
||||||
const guildInfo: DiscordGuildEntryResolved = {
|
const { guildInfo, channelConfig } = createAutoThreadMentionContext();
|
||||||
requireMention: true,
|
|
||||||
channels: {
|
|
||||||
general: { allow: true, autoThread: true },
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const channelConfig = resolveDiscordChannelConfig({
|
|
||||||
guildInfo,
|
|
||||||
channelId: "1",
|
|
||||||
channelName: "General",
|
|
||||||
channelSlug: "general",
|
|
||||||
});
|
|
||||||
expect(
|
expect(
|
||||||
resolveDiscordShouldRequireMention({
|
resolveDiscordShouldRequireMention({
|
||||||
isGuildMessage: true,
|
isGuildMessage: true,
|
||||||
|
|||||||
@@ -1,6 +1,31 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { describe, expect, it, vi } from "vitest";
|
||||||
import { resolveFetch, wrapFetchWithAbortSignal } from "./fetch.js";
|
import { resolveFetch, wrapFetchWithAbortSignal } from "./fetch.js";
|
||||||
|
|
||||||
|
function createForeignSignalHarness() {
|
||||||
|
let abortHandler: (() => void) | null = null;
|
||||||
|
const removeEventListener = vi.fn((event: string, handler: () => void) => {
|
||||||
|
if (event === "abort" && abortHandler === handler) {
|
||||||
|
abortHandler = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const fakeSignal = {
|
||||||
|
aborted: false,
|
||||||
|
addEventListener: (event: string, handler: () => void) => {
|
||||||
|
if (event === "abort") {
|
||||||
|
abortHandler = handler;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeEventListener,
|
||||||
|
} as AbortSignal;
|
||||||
|
|
||||||
|
return {
|
||||||
|
fakeSignal,
|
||||||
|
removeEventListener,
|
||||||
|
triggerAbort: () => abortHandler?.(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
describe("wrapFetchWithAbortSignal", () => {
|
describe("wrapFetchWithAbortSignal", () => {
|
||||||
it("adds duplex for requests with a body", async () => {
|
it("adds duplex for requests with a body", async () => {
|
||||||
let seenInit: RequestInit | undefined;
|
let seenInit: RequestInit | undefined;
|
||||||
@@ -25,27 +50,14 @@ describe("wrapFetchWithAbortSignal", () => {
|
|||||||
|
|
||||||
const wrapped = wrapFetchWithAbortSignal(fetchImpl);
|
const wrapped = wrapFetchWithAbortSignal(fetchImpl);
|
||||||
|
|
||||||
let abortHandler: (() => void) | null = null;
|
const { fakeSignal, triggerAbort } = createForeignSignalHarness();
|
||||||
const fakeSignal = {
|
|
||||||
aborted: false,
|
|
||||||
addEventListener: (event: string, handler: () => void) => {
|
|
||||||
if (event === "abort") {
|
|
||||||
abortHandler = handler;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeEventListener: (event: string, handler: () => void) => {
|
|
||||||
if (event === "abort" && abortHandler === handler) {
|
|
||||||
abortHandler = null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
} as AbortSignal;
|
|
||||||
|
|
||||||
const promise = wrapped("https://example.com", { signal: fakeSignal });
|
const promise = wrapped("https://example.com", { signal: fakeSignal });
|
||||||
expect(fetchImpl).toHaveBeenCalledOnce();
|
expect(fetchImpl).toHaveBeenCalledOnce();
|
||||||
expect(seenSignal).toBeInstanceOf(AbortSignal);
|
expect(seenSignal).toBeInstanceOf(AbortSignal);
|
||||||
expect(seenSignal).not.toBe(fakeSignal);
|
expect(seenSignal).not.toBe(fakeSignal);
|
||||||
|
|
||||||
abortHandler?.();
|
triggerAbort();
|
||||||
expect(seenSignal?.aborted).toBe(true);
|
expect(seenSignal?.aborted).toBe(true);
|
||||||
|
|
||||||
await promise;
|
await promise;
|
||||||
@@ -64,22 +76,7 @@ describe("wrapFetchWithAbortSignal", () => {
|
|||||||
);
|
);
|
||||||
const wrapped = wrapFetchWithAbortSignal(fetchImpl);
|
const wrapped = wrapFetchWithAbortSignal(fetchImpl);
|
||||||
|
|
||||||
let abortHandler: (() => void) | null = null;
|
const { fakeSignal, removeEventListener } = createForeignSignalHarness();
|
||||||
const removeEventListener = vi.fn((event: string, handler: () => void) => {
|
|
||||||
if (event === "abort" && abortHandler === handler) {
|
|
||||||
abortHandler = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const fakeSignal = {
|
|
||||||
aborted: false,
|
|
||||||
addEventListener: (event: string, handler: () => void) => {
|
|
||||||
if (event === "abort") {
|
|
||||||
abortHandler = handler;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeEventListener,
|
|
||||||
} as AbortSignal;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await expect(wrapped("https://example.com", { signal: fakeSignal })).rejects.toBe(fetchError);
|
await expect(wrapped("https://example.com", { signal: fakeSignal })).rejects.toBe(fetchError);
|
||||||
@@ -100,22 +97,7 @@ describe("wrapFetchWithAbortSignal", () => {
|
|||||||
});
|
});
|
||||||
const wrapped = wrapFetchWithAbortSignal(fetchImpl);
|
const wrapped = wrapFetchWithAbortSignal(fetchImpl);
|
||||||
|
|
||||||
let abortHandler: (() => void) | null = null;
|
const { fakeSignal, removeEventListener } = createForeignSignalHarness();
|
||||||
const removeEventListener = vi.fn((event: string, handler: () => void) => {
|
|
||||||
if (event === "abort" && abortHandler === handler) {
|
|
||||||
abortHandler = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const fakeSignal = {
|
|
||||||
aborted: false,
|
|
||||||
addEventListener: (event: string, handler: () => void) => {
|
|
||||||
if (event === "abort") {
|
|
||||||
abortHandler = handler;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
removeEventListener,
|
|
||||||
} as AbortSignal;
|
|
||||||
|
|
||||||
expect(() => wrapped("https://example.com", { signal: fakeSignal })).toThrow(syncError);
|
expect(() => wrapped("https://example.com", { signal: fakeSignal })).toThrow(syncError);
|
||||||
expect(removeEventListener).toHaveBeenCalledOnce();
|
expect(removeEventListener).toHaveBeenCalledOnce();
|
||||||
|
|||||||
@@ -5,22 +5,26 @@ import {
|
|||||||
shouldEnableWindowsGitBashPasteFallback,
|
shouldEnableWindowsGitBashPasteFallback,
|
||||||
} from "./tui.js";
|
} from "./tui.js";
|
||||||
|
|
||||||
|
function createSubmitHarness() {
|
||||||
|
const editor = {
|
||||||
|
setText: vi.fn(),
|
||||||
|
addToHistory: vi.fn(),
|
||||||
|
};
|
||||||
|
const handleCommand = vi.fn();
|
||||||
|
const sendMessage = vi.fn();
|
||||||
|
const handleBangLine = vi.fn();
|
||||||
|
const onSubmit = createEditorSubmitHandler({
|
||||||
|
editor,
|
||||||
|
handleCommand,
|
||||||
|
sendMessage,
|
||||||
|
handleBangLine,
|
||||||
|
});
|
||||||
|
return { editor, handleCommand, sendMessage, handleBangLine, onSubmit };
|
||||||
|
}
|
||||||
|
|
||||||
describe("createEditorSubmitHandler", () => {
|
describe("createEditorSubmitHandler", () => {
|
||||||
it("routes lines starting with ! to handleBangLine", () => {
|
it("routes lines starting with ! to handleBangLine", () => {
|
||||||
const editor = {
|
const { handleCommand, sendMessage, handleBangLine, onSubmit } = createSubmitHarness();
|
||||||
setText: vi.fn(),
|
|
||||||
addToHistory: vi.fn(),
|
|
||||||
};
|
|
||||||
const handleCommand = vi.fn();
|
|
||||||
const sendMessage = vi.fn();
|
|
||||||
const handleBangLine = vi.fn();
|
|
||||||
|
|
||||||
const onSubmit = createEditorSubmitHandler({
|
|
||||||
editor,
|
|
||||||
handleCommand,
|
|
||||||
sendMessage,
|
|
||||||
handleBangLine,
|
|
||||||
});
|
|
||||||
|
|
||||||
onSubmit("!ls");
|
onSubmit("!ls");
|
||||||
|
|
||||||
@@ -31,20 +35,7 @@ describe("createEditorSubmitHandler", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("treats a lone ! as a normal message", () => {
|
it("treats a lone ! as a normal message", () => {
|
||||||
const editor = {
|
const { sendMessage, handleBangLine, onSubmit } = createSubmitHarness();
|
||||||
setText: vi.fn(),
|
|
||||||
addToHistory: vi.fn(),
|
|
||||||
};
|
|
||||||
const handleCommand = vi.fn();
|
|
||||||
const sendMessage = vi.fn();
|
|
||||||
const handleBangLine = vi.fn();
|
|
||||||
|
|
||||||
const onSubmit = createEditorSubmitHandler({
|
|
||||||
editor,
|
|
||||||
handleCommand,
|
|
||||||
sendMessage,
|
|
||||||
handleBangLine,
|
|
||||||
});
|
|
||||||
|
|
||||||
onSubmit("!");
|
onSubmit("!");
|
||||||
|
|
||||||
@@ -54,20 +45,7 @@ describe("createEditorSubmitHandler", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("does not treat leading whitespace before ! as a bang command", () => {
|
it("does not treat leading whitespace before ! as a bang command", () => {
|
||||||
const editor = {
|
const { editor, sendMessage, handleBangLine, onSubmit } = createSubmitHarness();
|
||||||
setText: vi.fn(),
|
|
||||||
addToHistory: vi.fn(),
|
|
||||||
};
|
|
||||||
const handleCommand = vi.fn();
|
|
||||||
const sendMessage = vi.fn();
|
|
||||||
const handleBangLine = vi.fn();
|
|
||||||
|
|
||||||
const onSubmit = createEditorSubmitHandler({
|
|
||||||
editor,
|
|
||||||
handleCommand,
|
|
||||||
sendMessage,
|
|
||||||
handleBangLine,
|
|
||||||
});
|
|
||||||
|
|
||||||
onSubmit(" !ls");
|
onSubmit(" !ls");
|
||||||
|
|
||||||
@@ -77,20 +55,7 @@ describe("createEditorSubmitHandler", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("trims normal messages before sending and adding to history", () => {
|
it("trims normal messages before sending and adding to history", () => {
|
||||||
const editor = {
|
const { editor, sendMessage, onSubmit } = createSubmitHarness();
|
||||||
setText: vi.fn(),
|
|
||||||
addToHistory: vi.fn(),
|
|
||||||
};
|
|
||||||
const handleCommand = vi.fn();
|
|
||||||
const sendMessage = vi.fn();
|
|
||||||
const handleBangLine = vi.fn();
|
|
||||||
|
|
||||||
const onSubmit = createEditorSubmitHandler({
|
|
||||||
editor,
|
|
||||||
handleCommand,
|
|
||||||
sendMessage,
|
|
||||||
handleBangLine,
|
|
||||||
});
|
|
||||||
|
|
||||||
onSubmit(" hello ");
|
onSubmit(" hello ");
|
||||||
|
|
||||||
@@ -99,20 +64,7 @@ describe("createEditorSubmitHandler", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("preserves internal newlines for multiline messages", () => {
|
it("preserves internal newlines for multiline messages", () => {
|
||||||
const editor = {
|
const { editor, handleCommand, sendMessage, handleBangLine, onSubmit } = createSubmitHarness();
|
||||||
setText: vi.fn(),
|
|
||||||
addToHistory: vi.fn(),
|
|
||||||
};
|
|
||||||
const handleCommand = vi.fn();
|
|
||||||
const sendMessage = vi.fn();
|
|
||||||
const handleBangLine = vi.fn();
|
|
||||||
|
|
||||||
const onSubmit = createEditorSubmitHandler({
|
|
||||||
editor,
|
|
||||||
handleCommand,
|
|
||||||
sendMessage,
|
|
||||||
handleBangLine,
|
|
||||||
});
|
|
||||||
|
|
||||||
onSubmit("Line 1\nLine 2\nLine 3");
|
onSubmit("Line 1\nLine 2\nLine 3");
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,27 @@ const DEFAULT_MESSAGES_CFG = {
|
|||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
function createAllowListConfig(allowFrom: string[]) {
|
||||||
|
return {
|
||||||
|
channels: {
|
||||||
|
whatsapp: {
|
||||||
|
allowFrom,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
messages: DEFAULT_MESSAGES_CFG,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openInboxMonitor(onMessage = vi.fn()) {
|
||||||
|
const listener = await monitorWebInbox({
|
||||||
|
verbose: false,
|
||||||
|
accountId: DEFAULT_ACCOUNT_ID,
|
||||||
|
authDir: getAuthDir(),
|
||||||
|
onMessage,
|
||||||
|
});
|
||||||
|
return { onMessage, listener, sock: getSock() };
|
||||||
|
}
|
||||||
|
|
||||||
async function expectOutboundDmSkipsPairing(params: {
|
async function expectOutboundDmSkipsPairing(params: {
|
||||||
selfChatMode: boolean;
|
selfChatMode: boolean;
|
||||||
messageId: string;
|
messageId: string;
|
||||||
@@ -73,27 +94,9 @@ describe("web monitor inbox", () => {
|
|||||||
installWebMonitorInboxUnitTestHooks();
|
installWebMonitorInboxUnitTestHooks();
|
||||||
|
|
||||||
it("allows messages from senders in allowFrom list", async () => {
|
it("allows messages from senders in allowFrom list", async () => {
|
||||||
mockLoadConfig.mockReturnValue({
|
mockLoadConfig.mockReturnValue(createAllowListConfig(["+111", "+999"]));
|
||||||
channels: {
|
|
||||||
whatsapp: {
|
|
||||||
// Allow +999
|
|
||||||
allowFrom: ["+111", "+999"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
messages: {
|
|
||||||
messagePrefix: undefined,
|
|
||||||
responsePrefix: undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onMessage = vi.fn();
|
const { onMessage, listener, sock } = await openInboxMonitor();
|
||||||
const listener = await monitorWebInbox({
|
|
||||||
verbose: false,
|
|
||||||
accountId: DEFAULT_ACCOUNT_ID,
|
|
||||||
authDir: getAuthDir(),
|
|
||||||
onMessage,
|
|
||||||
});
|
|
||||||
const sock = getSock();
|
|
||||||
|
|
||||||
const upsert = {
|
const upsert = {
|
||||||
type: "notify",
|
type: "notify",
|
||||||
@@ -124,27 +127,9 @@ describe("web monitor inbox", () => {
|
|||||||
it("allows same-phone messages even if not in allowFrom", async () => {
|
it("allows same-phone messages even if not in allowFrom", async () => {
|
||||||
// Same-phone mode: when from === selfJid, should always be allowed
|
// Same-phone mode: when from === selfJid, should always be allowed
|
||||||
// This allows users to message themselves even with restrictive allowFrom
|
// This allows users to message themselves even with restrictive allowFrom
|
||||||
mockLoadConfig.mockReturnValue({
|
mockLoadConfig.mockReturnValue(createAllowListConfig(["+111"]));
|
||||||
channels: {
|
|
||||||
whatsapp: {
|
|
||||||
// Only allow +111, but self is +123
|
|
||||||
allowFrom: ["+111"],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
messages: {
|
|
||||||
messagePrefix: undefined,
|
|
||||||
responsePrefix: undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const onMessage = vi.fn();
|
const { onMessage, listener, sock } = await openInboxMonitor();
|
||||||
const listener = await monitorWebInbox({
|
|
||||||
verbose: false,
|
|
||||||
accountId: DEFAULT_ACCOUNT_ID,
|
|
||||||
authDir: getAuthDir(),
|
|
||||||
onMessage,
|
|
||||||
});
|
|
||||||
const sock = getSock();
|
|
||||||
|
|
||||||
// Message from self (sock.user.id is "123@s.whatsapp.net" in mock)
|
// Message from self (sock.user.id is "123@s.whatsapp.net" in mock)
|
||||||
const upsert = {
|
const upsert = {
|
||||||
@@ -176,14 +161,7 @@ describe("web monitor inbox", () => {
|
|||||||
.mockResolvedValueOnce({ code: "PAIRCODE", created: true })
|
.mockResolvedValueOnce({ code: "PAIRCODE", created: true })
|
||||||
.mockResolvedValueOnce({ code: "PAIRCODE", created: false });
|
.mockResolvedValueOnce({ code: "PAIRCODE", created: false });
|
||||||
|
|
||||||
const onMessage = vi.fn();
|
const { onMessage, listener, sock } = await openInboxMonitor();
|
||||||
const listener = await monitorWebInbox({
|
|
||||||
verbose: false,
|
|
||||||
accountId: DEFAULT_ACCOUNT_ID,
|
|
||||||
authDir: getAuthDir(),
|
|
||||||
onMessage,
|
|
||||||
});
|
|
||||||
const sock = getSock();
|
|
||||||
|
|
||||||
// Message from someone else should be blocked
|
// Message from someone else should be blocked
|
||||||
const upsertBlocked = {
|
const upsertBlocked = {
|
||||||
@@ -280,14 +258,7 @@ describe("web monitor inbox", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("handles append messages by marking them read but skipping auto-reply", async () => {
|
it("handles append messages by marking them read but skipping auto-reply", async () => {
|
||||||
const onMessage = vi.fn();
|
const { onMessage, listener, sock } = await openInboxMonitor();
|
||||||
const listener = await monitorWebInbox({
|
|
||||||
verbose: false,
|
|
||||||
accountId: DEFAULT_ACCOUNT_ID,
|
|
||||||
authDir: getAuthDir(),
|
|
||||||
onMessage,
|
|
||||||
});
|
|
||||||
const sock = getSock();
|
|
||||||
|
|
||||||
const upsert = {
|
const upsert = {
|
||||||
type: "append",
|
type: "append",
|
||||||
|
|||||||
Reference in New Issue
Block a user