Skip to content

Commit d2ca638

Browse files
gantoineclaude
andcommitted
test(discord-presence): parameterise buildActivity and assert truncation content
Collapse the per-scenario it blocks into a single it.each table, and make the truncation case verify the prefix and trailing ellipsis are preserved rather than only bounding the length. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 8dbc6ae commit d2ca638

1 file changed

Lines changed: 109 additions & 59 deletions

File tree

apps/code/src/main/services/discord-presence/presence-format.test.ts

Lines changed: 109 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -17,68 +17,118 @@ const activeIntent: PresenceIntent = {
1717
agentRunning: true,
1818
};
1919

20-
describe("buildActivity", () => {
21-
it("hides the task title and repo name by default (privacy-first)", () => {
22-
const activity = buildActivity(activeIntent, baseOptions);
23-
expect(activity.details).toBe("Working on a task");
24-
expect(activity.state).toBe("agent running");
25-
});
26-
27-
it("includes the task title only when opted in", () => {
28-
const activity = buildActivity(activeIntent, {
29-
...baseOptions,
30-
showTaskTitle: true,
31-
});
32-
expect(activity.details).toBe('Working on "Add Discord presence"');
33-
});
34-
35-
it("includes the repo name only when opted in", () => {
36-
const activity = buildActivity(activeIntent, {
37-
...baseOptions,
38-
showRepoName: true,
39-
});
40-
expect(activity.state).toBe("posthog/code · agent running");
41-
});
20+
const idleNoTask: PresenceIntent = {
21+
hasActiveTask: false,
22+
taskTitle: null,
23+
repoName: null,
24+
agentRunning: false,
25+
};
4226

43-
it("reflects review status with the idle badge when the agent is idle on a task", () => {
44-
const activity = buildActivity(
45-
{ ...activeIntent, agentRunning: false },
46-
{ ...baseOptions, showRepoName: true },
47-
);
48-
expect(activity.state).toBe("posthog/code · reviewing");
49-
expect(activity.assets?.small_image).toBe("posthog_idle");
50-
expect(activity.assets?.small_text).toBe("Reviewing");
51-
});
27+
interface Case {
28+
name: string;
29+
intent: PresenceIntent;
30+
options: typeof baseOptions;
31+
expected: {
32+
details?: string;
33+
state?: string;
34+
smallImage?: string;
35+
smallText?: string;
36+
timestampStart?: number;
37+
detailsMaxLength?: number;
38+
detailsStartsWith?: string;
39+
detailsEndsWith?: string;
40+
};
41+
}
5242

53-
it("falls back to an idle/browsing presence with the idle badge when no task is focused", () => {
54-
const activity = buildActivity(
55-
{
56-
hasActiveTask: false,
57-
taskTitle: null,
58-
repoName: null,
59-
agentRunning: false,
60-
},
61-
{ ...baseOptions, showTaskTitle: true, showRepoName: true },
62-
);
63-
expect(activity.details).toBe("Idle");
64-
expect(activity.state).toBe("browsing");
65-
expect(activity.assets?.small_image).toBe("posthog_idle");
66-
expect(activity.assets?.small_text).toBe("Idle");
67-
});
43+
const cases: Case[] = [
44+
{
45+
name: "hides task title and repo name by default (privacy-first)",
46+
intent: activeIntent,
47+
options: baseOptions,
48+
expected: { details: "Working on a task", state: "agent running" },
49+
},
50+
{
51+
name: "includes the task title only when opted in",
52+
intent: activeIntent,
53+
options: { ...baseOptions, showTaskTitle: true },
54+
expected: { details: 'Working on "Add Discord presence"' },
55+
},
56+
{
57+
name: "includes the repo name only when opted in",
58+
intent: activeIntent,
59+
options: { ...baseOptions, showRepoName: true },
60+
expected: { state: "posthog/code · agent running" },
61+
},
62+
{
63+
name: "shows the idle badge and review status when idle on a task",
64+
intent: { ...activeIntent, agentRunning: false },
65+
options: { ...baseOptions, showRepoName: true },
66+
expected: {
67+
state: "posthog/code · reviewing",
68+
smallImage: "posthog_idle",
69+
smallText: "Reviewing",
70+
},
71+
},
72+
{
73+
name: "falls back to idle/browsing with the idle badge when no task is focused",
74+
intent: idleNoTask,
75+
options: { ...baseOptions, showTaskTitle: true, showRepoName: true },
76+
expected: {
77+
details: "Idle",
78+
state: "browsing",
79+
smallImage: "posthog_idle",
80+
smallText: "Idle",
81+
},
82+
},
83+
{
84+
name: "surfaces the running indicator asset and start timestamp while working",
85+
intent: activeIntent,
86+
options: baseOptions,
87+
expected: { smallImage: "agent_running", timestampStart: STARTED_AT },
88+
},
89+
{
90+
name: "truncates over-long titles to Discord's field limit, keeping prefix and ellipsis",
91+
intent: { ...activeIntent, taskTitle: "x".repeat(200) },
92+
options: { ...baseOptions, showTaskTitle: true },
93+
expected: {
94+
detailsMaxLength: 128,
95+
detailsStartsWith: 'Working on "',
96+
detailsEndsWith: "…",
97+
},
98+
},
99+
];
68100

69-
it("surfaces the running indicator asset while the agent works", () => {
70-
const activity = buildActivity(activeIntent, baseOptions);
71-
expect(activity.assets?.small_image).toBe("agent_running");
72-
expect(activity.timestamps?.start).toBe(STARTED_AT);
73-
});
101+
describe("buildActivity", () => {
102+
it.each(cases)("$name", ({ intent, options, expected }) => {
103+
const activity = buildActivity(intent, options);
74104

75-
it("truncates over-long titles to Discord's field limit", () => {
76-
const longTitle = "x".repeat(200);
77-
const activity = buildActivity(
78-
{ ...activeIntent, taskTitle: longTitle },
79-
{ ...baseOptions, showTaskTitle: true },
80-
);
81-
expect(activity.details).toBeDefined();
82-
expect((activity.details as string).length).toBeLessThanOrEqual(128);
105+
if (expected.details !== undefined) {
106+
expect(activity.details).toBe(expected.details);
107+
}
108+
if (expected.state !== undefined) {
109+
expect(activity.state).toBe(expected.state);
110+
}
111+
if (expected.smallImage !== undefined) {
112+
expect(activity.assets?.small_image).toBe(expected.smallImage);
113+
}
114+
if (expected.smallText !== undefined) {
115+
expect(activity.assets?.small_text).toBe(expected.smallText);
116+
}
117+
if (expected.timestampStart !== undefined) {
118+
expect(activity.timestamps?.start).toBe(expected.timestampStart);
119+
}
120+
if (expected.detailsMaxLength !== undefined) {
121+
expect(activity.details?.length).toBeLessThanOrEqual(
122+
expected.detailsMaxLength,
123+
);
124+
}
125+
if (expected.detailsStartsWith !== undefined) {
126+
expect(activity.details?.startsWith(expected.detailsStartsWith)).toBe(
127+
true,
128+
);
129+
}
130+
if (expected.detailsEndsWith !== undefined) {
131+
expect(activity.details?.endsWith(expected.detailsEndsWith)).toBe(true);
132+
}
83133
});
84134
});

0 commit comments

Comments
 (0)