mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-29 02:41:07 +00:00
test: collapse telegram transport and status suites
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { createRequire } from "node:module";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { fetchTelegramChatId } from "./api-fetch.js";
|
||||
|
||||
const require = createRequire(import.meta.url);
|
||||
@@ -10,6 +10,31 @@ const { kHttpsProxyAgent, kNoProxyAgent } = require("undici/lib/core/symbols.js"
|
||||
kHttpsProxyAgent: symbol;
|
||||
kNoProxyAgent: symbol;
|
||||
};
|
||||
const proxyMocks = vi.hoisted(() => {
|
||||
const undiciFetch = vi.fn();
|
||||
const proxyAgentSpy = vi.fn();
|
||||
const setGlobalDispatcher = vi.fn();
|
||||
class ProxyAgent {
|
||||
static lastCreated: ProxyAgent | undefined;
|
||||
proxyUrl: string;
|
||||
constructor(proxyUrl: string) {
|
||||
this.proxyUrl = proxyUrl;
|
||||
ProxyAgent.lastCreated = this;
|
||||
proxyAgentSpy(proxyUrl);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ProxyAgent,
|
||||
undiciFetch,
|
||||
proxyAgentSpy,
|
||||
setGlobalDispatcher,
|
||||
getLastAgent: () => ProxyAgent.lastCreated,
|
||||
};
|
||||
});
|
||||
|
||||
let getProxyUrlFromFetch: typeof import("./proxy.js").getProxyUrlFromFetch;
|
||||
let makeProxyFetch: typeof import("./proxy.js").makeProxyFetch;
|
||||
|
||||
function getOwnSymbolValue(
|
||||
target: Record<PropertyKey, unknown>,
|
||||
@@ -136,3 +161,40 @@ describe("undici env proxy semantics", () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("makeProxyFetch", () => {
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
proxyMocks.undiciFetch.mockReset();
|
||||
proxyMocks.proxyAgentSpy.mockClear();
|
||||
proxyMocks.setGlobalDispatcher.mockClear();
|
||||
vi.doMock("undici", () => ({
|
||||
ProxyAgent: proxyMocks.ProxyAgent,
|
||||
fetch: proxyMocks.undiciFetch,
|
||||
setGlobalDispatcher: proxyMocks.setGlobalDispatcher,
|
||||
}));
|
||||
({ getProxyUrlFromFetch, makeProxyFetch } = await import("./proxy.js"));
|
||||
});
|
||||
|
||||
it("uses undici fetch with ProxyAgent dispatcher", async () => {
|
||||
const proxyUrl = "http://proxy.test:8080";
|
||||
proxyMocks.undiciFetch.mockResolvedValue({ ok: true });
|
||||
|
||||
const proxyFetch = makeProxyFetch(proxyUrl);
|
||||
await proxyFetch("https://api.telegram.org/bot123/getMe");
|
||||
|
||||
expect(proxyMocks.proxyAgentSpy).toHaveBeenCalledWith(proxyUrl);
|
||||
expect(proxyMocks.undiciFetch).toHaveBeenCalledWith(
|
||||
"https://api.telegram.org/bot123/getMe",
|
||||
expect.objectContaining({ dispatcher: proxyMocks.getLastAgent() }),
|
||||
);
|
||||
expect(proxyMocks.setGlobalDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("attaches proxy metadata for resolver transport handling", () => {
|
||||
const proxyUrl = "http://proxy.test:8080";
|
||||
const proxyFetch = makeProxyFetch(proxyUrl);
|
||||
|
||||
expect(getProxyUrlFromFetch(proxyFetch)).toBe(proxyUrl);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const mocks = vi.hoisted(() => {
|
||||
const undiciFetch = vi.fn();
|
||||
const proxyAgentSpy = vi.fn();
|
||||
const setGlobalDispatcher = vi.fn();
|
||||
class ProxyAgent {
|
||||
static lastCreated: ProxyAgent | undefined;
|
||||
proxyUrl: string;
|
||||
constructor(proxyUrl: string) {
|
||||
this.proxyUrl = proxyUrl;
|
||||
ProxyAgent.lastCreated = this;
|
||||
proxyAgentSpy(proxyUrl);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
ProxyAgent,
|
||||
undiciFetch,
|
||||
proxyAgentSpy,
|
||||
setGlobalDispatcher,
|
||||
getLastAgent: () => ProxyAgent.lastCreated,
|
||||
};
|
||||
});
|
||||
|
||||
let getProxyUrlFromFetch: typeof import("./proxy.js").getProxyUrlFromFetch;
|
||||
let makeProxyFetch: typeof import("./proxy.js").makeProxyFetch;
|
||||
|
||||
describe("makeProxyFetch", () => {
|
||||
beforeEach(async () => {
|
||||
vi.resetModules();
|
||||
mocks.undiciFetch.mockReset();
|
||||
mocks.proxyAgentSpy.mockClear();
|
||||
mocks.setGlobalDispatcher.mockClear();
|
||||
vi.doMock("undici", () => ({
|
||||
ProxyAgent: mocks.ProxyAgent,
|
||||
fetch: mocks.undiciFetch,
|
||||
setGlobalDispatcher: mocks.setGlobalDispatcher,
|
||||
}));
|
||||
({ getProxyUrlFromFetch, makeProxyFetch } = await import("./proxy.js"));
|
||||
});
|
||||
|
||||
it("uses undici fetch with ProxyAgent dispatcher", async () => {
|
||||
const proxyUrl = "http://proxy.test:8080";
|
||||
mocks.undiciFetch.mockResolvedValue({ ok: true });
|
||||
|
||||
const proxyFetch = makeProxyFetch(proxyUrl);
|
||||
await proxyFetch("https://api.telegram.org/bot123/getMe");
|
||||
|
||||
expect(mocks.proxyAgentSpy).toHaveBeenCalledWith(proxyUrl);
|
||||
expect(mocks.undiciFetch).toHaveBeenCalledWith(
|
||||
"https://api.telegram.org/bot123/getMe",
|
||||
expect.objectContaining({ dispatcher: mocks.getLastAgent() }),
|
||||
);
|
||||
expect(mocks.setGlobalDispatcher).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("attaches proxy metadata for resolver transport handling", () => {
|
||||
const proxyUrl = "http://proxy.test:8080";
|
||||
const proxyFetch = makeProxyFetch(proxyUrl);
|
||||
|
||||
expect(getProxyUrlFromFetch(proxyFetch)).toBe(proxyUrl);
|
||||
});
|
||||
});
|
||||
@@ -1,77 +0,0 @@
|
||||
import type { ChannelAccountSnapshot } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { collectTelegramStatusIssues } from "./status-issues.js";
|
||||
|
||||
describe("collectTelegramStatusIssues", () => {
|
||||
it("reports privacy-mode and wildcard unmentioned-group configuration risks", () => {
|
||||
const issues = collectTelegramStatusIssues([
|
||||
{
|
||||
accountId: "main",
|
||||
enabled: true,
|
||||
configured: true,
|
||||
allowUnmentionedGroups: true,
|
||||
audit: {
|
||||
hasWildcardUnmentionedGroups: true,
|
||||
unresolvedGroups: 2,
|
||||
},
|
||||
} as ChannelAccountSnapshot,
|
||||
]);
|
||||
|
||||
expect(issues).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
channel: "telegram",
|
||||
accountId: "main",
|
||||
kind: "config",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
expect(issues.some((issue) => issue.message.includes("privacy mode"))).toBe(true);
|
||||
expect(issues.some((issue) => issue.message.includes('uses "*"'))).toBe(true);
|
||||
expect(issues.some((issue) => issue.message.includes("unresolvedGroups=2"))).toBe(true);
|
||||
});
|
||||
|
||||
it("reports unreachable groups with match metadata", () => {
|
||||
const issues = collectTelegramStatusIssues([
|
||||
{
|
||||
accountId: "main",
|
||||
enabled: true,
|
||||
configured: true,
|
||||
audit: {
|
||||
groups: [
|
||||
{
|
||||
chatId: "-100123",
|
||||
ok: false,
|
||||
status: "left",
|
||||
error: "403",
|
||||
matchKey: "alerts",
|
||||
matchSource: "channels.telegram.groups",
|
||||
},
|
||||
],
|
||||
},
|
||||
} as ChannelAccountSnapshot,
|
||||
]);
|
||||
|
||||
expect(issues).toHaveLength(1);
|
||||
expect(issues[0]).toMatchObject({
|
||||
channel: "telegram",
|
||||
accountId: "main",
|
||||
kind: "runtime",
|
||||
});
|
||||
expect(issues[0]?.message).toContain("Group -100123 not reachable");
|
||||
expect(issues[0]?.message).toContain("alerts");
|
||||
expect(issues[0]?.message).toContain("channels.telegram.groups");
|
||||
});
|
||||
|
||||
it("ignores accounts that are not both enabled and configured", () => {
|
||||
expect(
|
||||
collectTelegramStatusIssues([
|
||||
{
|
||||
accountId: "main",
|
||||
enabled: false,
|
||||
configured: true,
|
||||
} as ChannelAccountSnapshot,
|
||||
]),
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { ChannelAccountSnapshot } from "openclaw/plugin-sdk/channel-contract";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { DEFAULT_EMOJIS } from "../../../src/channels/status-reactions.js";
|
||||
import { collectTelegramStatusIssues } from "./status-issues.js";
|
||||
import {
|
||||
buildTelegramStatusReactionVariants,
|
||||
extractTelegramAllowedEmojiReactions,
|
||||
@@ -9,6 +11,80 @@ import {
|
||||
resolveTelegramStatusReactionEmojis,
|
||||
} from "./status-reaction-variants.js";
|
||||
|
||||
describe("collectTelegramStatusIssues", () => {
|
||||
it("reports privacy-mode and wildcard unmentioned-group configuration risks", () => {
|
||||
const issues = collectTelegramStatusIssues([
|
||||
{
|
||||
accountId: "main",
|
||||
enabled: true,
|
||||
configured: true,
|
||||
allowUnmentionedGroups: true,
|
||||
audit: {
|
||||
hasWildcardUnmentionedGroups: true,
|
||||
unresolvedGroups: 2,
|
||||
},
|
||||
} as ChannelAccountSnapshot,
|
||||
]);
|
||||
|
||||
expect(issues).toEqual(
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({
|
||||
channel: "telegram",
|
||||
accountId: "main",
|
||||
kind: "config",
|
||||
}),
|
||||
]),
|
||||
);
|
||||
expect(issues.some((issue) => issue.message.includes("privacy mode"))).toBe(true);
|
||||
expect(issues.some((issue) => issue.message.includes('uses "*"'))).toBe(true);
|
||||
expect(issues.some((issue) => issue.message.includes("unresolvedGroups=2"))).toBe(true);
|
||||
});
|
||||
|
||||
it("reports unreachable groups with match metadata", () => {
|
||||
const issues = collectTelegramStatusIssues([
|
||||
{
|
||||
accountId: "main",
|
||||
enabled: true,
|
||||
configured: true,
|
||||
audit: {
|
||||
groups: [
|
||||
{
|
||||
chatId: "-100123",
|
||||
ok: false,
|
||||
status: "left",
|
||||
error: "403",
|
||||
matchKey: "alerts",
|
||||
matchSource: "channels.telegram.groups",
|
||||
},
|
||||
],
|
||||
},
|
||||
} as ChannelAccountSnapshot,
|
||||
]);
|
||||
|
||||
expect(issues).toHaveLength(1);
|
||||
expect(issues[0]).toMatchObject({
|
||||
channel: "telegram",
|
||||
accountId: "main",
|
||||
kind: "runtime",
|
||||
});
|
||||
expect(issues[0]?.message).toContain("Group -100123 not reachable");
|
||||
expect(issues[0]?.message).toContain("alerts");
|
||||
expect(issues[0]?.message).toContain("channels.telegram.groups");
|
||||
});
|
||||
|
||||
it("ignores accounts that are not both enabled and configured", () => {
|
||||
expect(
|
||||
collectTelegramStatusIssues([
|
||||
{
|
||||
accountId: "main",
|
||||
enabled: false,
|
||||
configured: true,
|
||||
} as ChannelAccountSnapshot,
|
||||
]),
|
||||
).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveTelegramStatusReactionEmojis", () => {
|
||||
it("falls back to Telegram-safe defaults for empty overrides", () => {
|
||||
const result = resolveTelegramStatusReactionEmojis({
|
||||
Reference in New Issue
Block a user