@@ -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