test: share delivery target session helpers

This commit is contained in:
Peter Steinberger 2026-03-13 21:27:52 +00:00
parent d7f9035e80
commit 0574ac23d0
1 changed files with 34 additions and 25 deletions

View File

@ -64,6 +64,23 @@ function setMainSessionEntry(entry?: SessionStore[string]) {
vi.mocked(loadSessionStore).mockReturnValue(store);
}
function setLastSessionEntry(params: {
sessionId: string;
lastChannel: string;
lastTo: string;
lastThreadId?: string;
lastAccountId?: string;
}) {
setMainSessionEntry({
sessionId: params.sessionId,
updatedAt: 1000,
lastChannel: params.lastChannel,
lastTo: params.lastTo,
...(params.lastThreadId ? { lastThreadId: params.lastThreadId } : {}),
...(params.lastAccountId ? { lastAccountId: params.lastAccountId } : {}),
});
}
function setWhatsAppAllowFrom(allowFrom: string[]) {
vi.mocked(resolveWhatsAppAccount).mockReturnValue({
allowFrom,
@ -86,11 +103,17 @@ async function resolveForAgent(params: {
});
}
async function resolveLastTarget(cfg: OpenClawConfig) {
return resolveForAgent({
cfg,
target: { channel: "last", to: undefined },
});
}
describe("resolveDeliveryTarget", () => {
it("reroutes implicit whatsapp delivery to authorized allowFrom recipient", async () => {
setMainSessionEntry({
setLastSessionEntry({
sessionId: "sess-w1",
updatedAt: 1000,
lastChannel: "whatsapp",
lastTo: "+15550000099",
});
@ -98,16 +121,15 @@ describe("resolveDeliveryTarget", () => {
setStoredWhatsAppAllowFrom(["+15550000001"]);
const cfg = makeCfg({ bindings: [] });
const result = await resolveDeliveryTarget(cfg, AGENT_ID, { channel: "last", to: undefined });
const result = await resolveLastTarget(cfg);
expect(result.channel).toBe("whatsapp");
expect(result.to).toBe("+15550000001");
});
it("keeps explicit whatsapp target unchanged", async () => {
setMainSessionEntry({
setLastSessionEntry({
sessionId: "sess-w2",
updatedAt: 1000,
lastChannel: "whatsapp",
lastTo: "+15550000099",
});
@ -220,9 +242,8 @@ describe("resolveDeliveryTarget", () => {
});
it("drops session threadId when destination does not match the previous recipient", async () => {
setMainSessionEntry({
setLastSessionEntry({
sessionId: "sess-2",
updatedAt: 1000,
lastChannel: "telegram",
lastTo: "999999",
lastThreadId: "thread-1",
@ -233,9 +254,8 @@ describe("resolveDeliveryTarget", () => {
});
it("keeps session threadId when destination matches the previous recipient", async () => {
setMainSessionEntry({
setLastSessionEntry({
sessionId: "sess-3",
updatedAt: 1000,
lastChannel: "telegram",
lastTo: "123456",
lastThreadId: "thread-2",
@ -248,10 +268,7 @@ describe("resolveDeliveryTarget", () => {
it("uses single configured channel when neither explicit nor session channel exists", async () => {
setMainSessionEntry(undefined);
const result = await resolveForAgent({
cfg: makeCfg({ bindings: [] }),
target: { channel: "last", to: undefined },
});
const result = await resolveLastTarget(makeCfg({ bindings: [] }));
expect(result.channel).toBe("telegram");
expect(result.ok).toBe(false);
if (result.ok) {
@ -268,10 +285,7 @@ describe("resolveDeliveryTarget", () => {
new Error("Channel is required when multiple channels are configured: telegram, slack"),
);
const result = await resolveForAgent({
cfg: makeCfg({ bindings: [] }),
target: { channel: "last", to: undefined },
});
const result = await resolveLastTarget(makeCfg({ bindings: [] }));
expect(result.channel).toBeUndefined();
expect(result.to).toBeUndefined();
expect(result.ok).toBe(false);
@ -308,17 +322,13 @@ describe("resolveDeliveryTarget", () => {
});
it("uses main session channel when channel=last and session route exists", async () => {
setMainSessionEntry({
setLastSessionEntry({
sessionId: "sess-4",
updatedAt: 1000,
lastChannel: "telegram",
lastTo: "987654",
});
const result = await resolveForAgent({
cfg: makeCfg({ bindings: [] }),
target: { channel: "last", to: undefined },
});
const result = await resolveLastTarget(makeCfg({ bindings: [] }));
expect(result.channel).toBe("telegram");
expect(result.to).toBe("987654");
@ -326,9 +336,8 @@ describe("resolveDeliveryTarget", () => {
});
it("explicit delivery.accountId overrides session-derived accountId", async () => {
setMainSessionEntry({
setLastSessionEntry({
sessionId: "sess-5",
updatedAt: 1000,
lastChannel: "telegram",
lastTo: "chat-999",
lastAccountId: "default",