Skip to content

Commit df4563f

Browse files
gantoineclaude
andcommitted
test(discord-presence): assert no Discord connection while disabled
Lock in that a DiscordIpcClient is only ever constructed/connected when the toggle is enabled: not on boot when disabled, and not when activity or privacy updates arrive while disabled. Includes an enabled-path sanity check so the assertions are meaningful. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 3bb964c commit df4563f

1 file changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import { beforeEach, describe, expect, it, vi } from "vitest";
2+
import type { PresenceIntent } from "./schemas";
3+
4+
// Mock the scoped logger (the real one pulls in electron-log).
5+
vi.mock("../../utils/logger", () => ({
6+
logger: {
7+
scope: () => ({
8+
info: vi.fn(),
9+
warn: vi.fn(),
10+
error: vi.fn(),
11+
debug: vi.fn(),
12+
}),
13+
},
14+
}));
15+
16+
// Controllable settings instead of the electron-store singleton.
17+
const settings = vi.hoisted(() => ({
18+
values: {} as Record<string, boolean>,
19+
}));
20+
vi.mock("../settingsStore", () => ({
21+
settingsStore: {
22+
get: (key: string, def: boolean) => settings.values[key] ?? def,
23+
set: (key: string, value: boolean) => {
24+
settings.values[key] = value;
25+
},
26+
},
27+
}));
28+
29+
// Stub the IPC client so we can assert whether a connection was ever opened —
30+
// and so node:net never runs in the test environment. A regular function (not
31+
// an arrow) is used so the mock is constructable via `new`.
32+
vi.mock("./discord-ipc", () => ({
33+
DiscordIpcClient: vi.fn(function (this: Record<string, unknown>) {
34+
this.on = vi.fn();
35+
this.connect = vi.fn();
36+
this.destroy = vi.fn();
37+
this.setActivity = vi.fn();
38+
}),
39+
}));
40+
41+
// A real client id so the "not configured" guard is never the reason a
42+
// connection is skipped — we want to prove the *enabled* gate does the work.
43+
vi.mock("./constants", async (importOriginal) => {
44+
const actual = await importOriginal<typeof import("./constants")>();
45+
return { ...actual, getDiscordClientId: () => "test-client-id" };
46+
});
47+
48+
import { DiscordIpcClient } from "./discord-ipc";
49+
import { DiscordPresenceService } from "./service";
50+
51+
const SAMPLE_INTENT: PresenceIntent = {
52+
hasActiveTask: true,
53+
taskTitle: "Repository overview",
54+
repoName: "posthog/posthog",
55+
agentRunning: true,
56+
};
57+
58+
// The `this` captured for each `new DiscordIpcClient()` call.
59+
const clientInstance = (index: number) =>
60+
vi.mocked(DiscordIpcClient).mock.instances[index] as unknown as {
61+
connect: ReturnType<typeof vi.fn>;
62+
destroy: ReturnType<typeof vi.fn>;
63+
};
64+
65+
describe("DiscordPresenceService connection gating", () => {
66+
beforeEach(() => {
67+
vi.clearAllMocks();
68+
settings.values = {
69+
discordPresenceEnabled: false,
70+
discordPresenceShowTaskTitle: false,
71+
discordPresenceShowRepoName: false,
72+
};
73+
});
74+
75+
it("does not connect to Discord on construction when disabled", () => {
76+
const service = new DiscordPresenceService();
77+
expect(DiscordIpcClient).not.toHaveBeenCalled();
78+
expect(service.getState().connected).toBe(false);
79+
});
80+
81+
it("does not connect when activity or privacy updates arrive while disabled", () => {
82+
const service = new DiscordPresenceService();
83+
service.setActivity(SAMPLE_INTENT);
84+
service.setShowTaskTitle(true);
85+
service.setShowRepoName(true);
86+
expect(DiscordIpcClient).not.toHaveBeenCalled();
87+
});
88+
89+
it("connects only once enabled, and tears down when turned back off", () => {
90+
const service = new DiscordPresenceService();
91+
expect(DiscordIpcClient).not.toHaveBeenCalled();
92+
93+
service.setEnabled(true);
94+
expect(DiscordIpcClient).toHaveBeenCalledTimes(1);
95+
expect(clientInstance(0).connect).toHaveBeenCalledTimes(1);
96+
97+
service.setEnabled(false);
98+
expect(clientInstance(0).destroy).toHaveBeenCalledTimes(1);
99+
100+
// Activity pushed after disabling must not spin up a new connection.
101+
service.setActivity(SAMPLE_INTENT);
102+
expect(DiscordIpcClient).toHaveBeenCalledTimes(1);
103+
});
104+
105+
it("connects on construction when already enabled (guard sanity check)", () => {
106+
settings.values.discordPresenceEnabled = true;
107+
new DiscordPresenceService();
108+
expect(DiscordIpcClient).toHaveBeenCalledTimes(1);
109+
expect(clientInstance(0).connect).toHaveBeenCalledTimes(1);
110+
});
111+
});

0 commit comments

Comments
 (0)