File size: 5,078 Bytes
d197cf3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | // Gmail hook tests cover Gmail hook configuration and setup helpers.
import { describe, expect, it } from "vitest";
import { type OpenClawConfig, DEFAULT_GATEWAY_PORT } from "../config/config.js";
import {
buildDefaultHookUrl,
buildGogWatchServeArgs,
buildGogWatchServeLogArgs,
buildTopicPath,
parseTopicPath,
resolveGmailHookRuntimeConfig,
} from "./gmail.js";
const baseConfig = {
hooks: {
token: "hook-token",
gmail: {
account: "openclaw@gmail.com",
topic: "projects/demo/topics/gog-gmail-watch",
pushToken: "push-token",
},
},
} satisfies OpenClawConfig;
describe("gmail hook config", () => {
function resolveWithGmailOverrides(
overrides: Partial<NonNullable<OpenClawConfig["hooks"]>["gmail"]>,
) {
return resolveGmailHookRuntimeConfig(
{
hooks: {
token: "hook-token",
gmail: {
account: "openclaw@gmail.com",
topic: "projects/demo/topics/gog-gmail-watch",
pushToken: "push-token",
...overrides,
},
},
},
{},
);
}
function expectResolvedPaths(
result: ReturnType<typeof resolveGmailHookRuntimeConfig>,
expected: { servePath: string; publicPath: string; target?: string },
) {
expect(result.ok).toBe(true);
if (!result.ok) {
return;
}
expect(result.value.serve.path).toBe(expected.servePath);
expect(result.value.tailscale.path).toBe(expected.publicPath);
if (expected.target !== undefined) {
expect(result.value.tailscale.target).toBe(expected.target);
}
}
it("builds default hook url", () => {
expect(buildDefaultHookUrl("/hooks", DEFAULT_GATEWAY_PORT)).toBe(
`http://127.0.0.1:${DEFAULT_GATEWAY_PORT}/hooks/gmail`,
);
});
it("parses topic path", () => {
const topic = buildTopicPath("proj", "topic");
expect(parseTopicPath(topic)).toEqual({
projectId: "proj",
topicName: "topic",
});
});
it("resolves runtime config with defaults", () => {
const result = resolveGmailHookRuntimeConfig(baseConfig, {});
expect(result.ok).toBe(true);
if (result.ok) {
expect(result.value.account).toBe("openclaw@gmail.com");
expect(result.value.label).toBe("INBOX");
expect(result.value.includeBody).toBe(true);
expect(result.value.serve.port).toBe(8788);
expect(result.value.hookUrl).toBe(`http://127.0.0.1:${DEFAULT_GATEWAY_PORT}/hooks/gmail`);
}
});
it("builds watch serve log args without secrets", () => {
const result = resolveGmailHookRuntimeConfig(baseConfig, {});
expect(result.ok).toBe(true);
if (!result.ok) {
return;
}
const serveArgs = buildGogWatchServeArgs(result.value);
expect(serveArgs).toContain("--exclude-labels");
expect(serveArgs[serveArgs.indexOf("--exclude-labels") + 1]).toBe("SPAM,TRASH,DRAFT,SENT");
const args = buildGogWatchServeLogArgs(result.value);
expect(args).not.toContain("push-token");
expect(args).not.toContain("hook-token");
expect(args).not.toContain("--token");
expect(args).not.toContain("--hook-token");
// --token, --hook-url, and --hook-token are stripped from the log args.
expect(args).toEqual([
"gmail",
"watch",
"serve",
"--account",
"openclaw@gmail.com",
"--bind",
"127.0.0.1",
"--port",
"8788",
"--path",
"/gmail-pubsub",
"--include-body",
"--exclude-labels",
"SPAM,TRASH,DRAFT,SENT",
"--max-bytes",
"20000",
]);
});
it("fails without hook token", () => {
const result = resolveGmailHookRuntimeConfig(
{
hooks: {
gmail: {
account: "openclaw@gmail.com",
topic: "projects/demo/topics/gog-gmail-watch",
pushToken: "push-token",
},
},
},
{},
);
expect(result.ok).toBe(false);
});
it("defaults serve path to / when tailscale is enabled", () => {
const result = resolveWithGmailOverrides({ tailscale: { mode: "funnel" } });
expectResolvedPaths(result, { servePath: "/", publicPath: "/gmail-pubsub" });
});
it("keeps the default public path when serve path is explicit", () => {
const result = resolveWithGmailOverrides({
serve: { path: "/gmail-pubsub" },
tailscale: { mode: "funnel" },
});
expectResolvedPaths(result, { servePath: "/", publicPath: "/gmail-pubsub" });
});
it("keeps custom public path when serve path is set", () => {
const result = resolveWithGmailOverrides({
serve: { path: "/custom" },
tailscale: { mode: "funnel" },
});
expectResolvedPaths(result, { servePath: "/", publicPath: "/custom" });
});
it("keeps serve path when tailscale target is set", () => {
const target = "http://127.0.0.1:8788/custom";
const result = resolveWithGmailOverrides({
serve: { path: "/custom" },
tailscale: { mode: "funnel", target },
});
expectResolvedPaths(result, { servePath: "/custom", publicPath: "/custom", target });
});
});
|