@@ -272,20 +272,39 @@ describe("thread-ownership plugin", () => {
272272 expect ( infoMessage ) . toContain ( "cancelled send" ) ;
273273 } ) ;
274274
275- it ( "cancels when the 409 conflict body is truncated or malformed" , async ( ) => {
276- // Simulates an over-cap or malformed 409 body: readResponseTextLimited
277- // stops at the cap, JSON.parse fails on the truncated text, but the 409
278- // status itself means another agent owns this thread — still cancel.
275+ it ( "cancels when the forwarder conflict JSON is malformed" , async ( ) => {
276+ vi . mocked ( globalThis . fetch ) . mockResolvedValue ( new Response ( "{" , { status : 409 } ) ) ;
277+
278+ const result = await sendSlackThreadMessage ( ) ;
279+
280+ expect ( result ) . toEqual ( { cancel : true } ) ;
281+ const warningMessage = requireFirstLogMessage (
282+ api . logger . warn ,
283+ "ownership conflict warning log" ,
284+ ) ;
285+ expect ( warningMessage ) . toContain ( "conflict body unreadable" ) ;
286+ expect ( warningMessage ) . toContain ( "malformed JSON response" ) ;
287+ const infoMessage = requireFirstLogMessage ( api . logger . info , "ownership cancel info log" ) ;
288+ expect ( infoMessage ) . toContain ( "cancelled send" ) ;
289+ expect ( infoMessage ) . toContain ( "owned by unknown" ) ;
290+ } ) ;
291+
292+ it ( "cancels when the forwarder conflict JSON exceeds the bounded read limit" , async ( ) => {
279293 vi . mocked ( globalThis . fetch ) . mockResolvedValue (
280- new Response ( '{ " owner" : "other-agent" ,' , { status : 409 } ) ,
294+ new Response ( JSON . stringify ( { owner : "x" . repeat ( 70 * 1024 ) } ) , { status : 409 } ) ,
281295 ) ;
282296
283297 const result = await sendSlackThreadMessage ( ) ;
284298
285299 expect ( result ) . toEqual ( { cancel : true } ) ;
300+ const warningMessage = requireFirstLogMessage (
301+ api . logger . warn ,
302+ "ownership conflict warning log" ,
303+ ) ;
304+ expect ( warningMessage ) . toContain ( "conflict body unreadable" ) ;
305+ expect ( warningMessage ) . toContain ( "JSON response exceeds 65536 bytes" ) ;
286306 const infoMessage = requireFirstLogMessage ( api . logger . info , "ownership cancel info log" ) ;
287307 expect ( infoMessage ) . toContain ( "cancelled send" ) ;
288- // The owner field was unparseable, so the log falls back to "unknown".
289308 expect ( infoMessage ) . toContain ( "owned by unknown" ) ;
290309 } ) ;
291310
0 commit comments