@@ -72,6 +72,13 @@ describe("shouldDriveOpenTasks", () => {
7272 deferredDryEdge : true ,
7373 } ) ,
7474 ) . toBe ( true ) ;
75+ expect (
76+ shouldDriveOpenTasks ( {
77+ hasOpenTasks : true ,
78+ parentProcessing : false ,
79+ deferredDryEdge : true ,
80+ } ) ,
81+ ) . toBe ( true ) ;
7582 expect (
7683 shouldDriveOpenTasks ( {
7784 previousRunning : 0 ,
@@ -158,7 +165,7 @@ describe("collectUncollectedTerminals", () => {
158165 } ) ,
159166 ) . toBe ( true ) ;
160167
161- const reports = collectUncollectedTerminals ( mailbox , sessions . list ( ) ) ;
168+ const reports = collectUncollectedTerminals ( mailbox , sessions . list ( ) , true ) ;
162169 expect ( reports . map ( ( r ) => r . agent_id ) . sort ( ) ) . toEqual ( [ "done" , "fail" ] ) ;
163170 expect ( reports . find ( ( r ) => r . agent_id === "done" ) ) . toEqual ( {
164171 agent_id : "done" ,
@@ -194,9 +201,11 @@ describe("collectUncollectedTerminals", () => {
194201 return taken ;
195202 } ,
196203 } ;
197- const reports = collectUncollectedTerminals ( mailbox , [
198- { id : "ghost" , description : "from store" , report : "store report" } ,
199- ] ) ;
204+ const reports = collectUncollectedTerminals (
205+ mailbox ,
206+ [ { id : "ghost" , description : "from store" , report : "store report" } ] ,
207+ true ,
208+ ) ;
200209 expect ( reports ) . toEqual ( [
201210 {
202211 agent_id : "ghost" ,
@@ -217,10 +226,30 @@ describe("collectUncollectedTerminals", () => {
217226 peek : ( id ) => records . get ( id ) ,
218227 take : ( id ) => records . get ( id ) ,
219228 } ;
220- const reports = collectUncollectedTerminals ( mailbox , [ ] ) ;
229+ const reports = collectUncollectedTerminals ( mailbox , [ ] , true ) ;
221230 expect ( reports [ 0 ] ?. report ?. length ) . toBe ( FLEET_DRY_REPORT_CHARS ) ;
222231 expect ( reports [ 0 ] ?. report ?. endsWith ( "…" ) ) . toBe ( true ) ;
223232 } ) ;
233+
234+ test ( "consume false peeks without take" , ( ) => {
235+ const records = new Map < string , FleetDryMailboxRecord > ( [
236+ [ "w1" , { status : "done" , report : "ok" } ] ,
237+ ] ) ;
238+ const mailbox : FleetDryMailbox = {
239+ ids : ( ) => [ ...records . keys ( ) ] ,
240+ peek : ( id ) => records . get ( id ) ,
241+ take : ( id ) => {
242+ const existing = records . get ( id ) ;
243+ if ( existing === undefined ) return undefined ;
244+ const taken = { ...existing , collected : true } ;
245+ records . set ( id , taken ) ;
246+ return taken ;
247+ } ,
248+ } ;
249+ const reports = collectUncollectedTerminals ( mailbox , [ ] , false ) ;
250+ expect ( reports ) . toEqual ( [ { agent_id : "w1" , status : "done" , report : "ok" } ] ) ;
251+ expect ( records . get ( "w1" ) ?. collected ) . not . toBe ( true ) ;
252+ } ) ;
224253} ) ;
225254
226255describe ( "driveOpenTasksAfterFleetDry" , ( ) => {
@@ -368,4 +397,109 @@ describe("driveOpenTasksAfterFleetDry", () => {
368397 expect ( driven ) . toBe ( false ) ;
369398 expect ( records . get ( "w1" ) ?. collected ) . not . toBe ( true ) ;
370399 } ) ;
400+
401+ test ( "TUI sendWithAttemptIdentity rejection leaves mailbox uncollected" , async ( ) => {
402+ const records = new Map < string , FleetDryMailboxRecord > ( [
403+ [ "w1" , { status : "done" , report : "ok" } ] ,
404+ ] ) ;
405+ const mailbox : FleetDryMailbox = {
406+ ids : ( ) => [ ...records . keys ( ) ] ,
407+ peek : ( id ) => records . get ( id ) ,
408+ take : ( id ) => {
409+ const existing = records . get ( id ) ;
410+ if ( existing === undefined ) return undefined ;
411+ const taken = { ...existing , collected : true } ;
412+ records . set ( id , taken ) ;
413+ return taken ;
414+ } ,
415+ } ;
416+ const sendWithAttemptIdentity = async ( ) : Promise < boolean > => {
417+ await Promise . resolve ( ) ;
418+ throw new Error ( "agentProxy.send failed" ) ;
419+ } ;
420+ const driven = driveOpenTasksAfterFleetDry ( {
421+ deferredDryEdge : true ,
422+ openTasks : [ openTask ] ,
423+ parentProcessing : false ,
424+ mailbox,
425+ lanes : [ ] ,
426+ beginSystemContinuation : ( ) => undefined ,
427+ send : ( ) => sendWithAttemptIdentity ( ) ,
428+ } ) ;
429+ expect ( driven ) . toBe ( true ) ;
430+ expect ( records . get ( "w1" ) ?. collected ) . not . toBe ( true ) ;
431+ await Promise . resolve ( ) ;
432+ await Promise . resolve ( ) ;
433+ expect ( records . get ( "w1" ) ?. collected ) . not . toBe ( true ) ;
434+ } ) ;
435+
436+ test ( "TUI sendWithAttemptIdentity false after handleSendFailure leaves mailbox uncollected" , async ( ) => {
437+ const records = new Map < string , FleetDryMailboxRecord > ( [
438+ [ "w1" , { status : "done" , report : "ok" } ] ,
439+ ] ) ;
440+ const mailbox : FleetDryMailbox = {
441+ ids : ( ) => [ ...records . keys ( ) ] ,
442+ peek : ( id ) => records . get ( id ) ,
443+ take : ( id ) => {
444+ const existing = records . get ( id ) ;
445+ if ( existing === undefined ) return undefined ;
446+ const taken = { ...existing , collected : true } ;
447+ records . set ( id , taken ) ;
448+ return taken ;
449+ } ,
450+ } ;
451+ const sendWithAttemptIdentity = async ( ) : Promise < boolean > => {
452+ await Promise . resolve ( ) ;
453+ return false ;
454+ } ;
455+ const driven = driveOpenTasksAfterFleetDry ( {
456+ deferredDryEdge : true ,
457+ openTasks : [ openTask ] ,
458+ parentProcessing : false ,
459+ mailbox,
460+ lanes : [ ] ,
461+ beginSystemContinuation : ( ) => undefined ,
462+ send : ( ) => sendWithAttemptIdentity ( ) ,
463+ } ) ;
464+ expect ( driven ) . toBe ( true ) ;
465+ await Promise . resolve ( ) ;
466+ await Promise . resolve ( ) ;
467+ expect ( records . get ( "w1" ) ?. collected ) . not . toBe ( true ) ;
468+ } ) ;
469+
470+ test ( "TUI sendWithAttemptIdentity true takes mailbox after send resolves" , async ( ) => {
471+ const records = new Map < string , FleetDryMailboxRecord > ( [
472+ [ "w1" , { status : "done" , report : "ok" } ] ,
473+ ] ) ;
474+ const mailbox : FleetDryMailbox = {
475+ ids : ( ) => [ ...records . keys ( ) ] ,
476+ peek : ( id ) => records . get ( id ) ,
477+ take : ( id ) => {
478+ const existing = records . get ( id ) ;
479+ if ( existing === undefined ) return undefined ;
480+ const taken = { ...existing , collected : true } ;
481+ records . set ( id , taken ) ;
482+ return taken ;
483+ } ,
484+ } ;
485+ let resolveSend : ( ( ok : boolean ) => void ) | undefined ;
486+ const sendWithAttemptIdentity = ( ) : Promise < boolean > =>
487+ new Promise ( ( resolve ) => {
488+ resolveSend = resolve ;
489+ } ) ;
490+ const driven = driveOpenTasksAfterFleetDry ( {
491+ deferredDryEdge : true ,
492+ openTasks : [ openTask ] ,
493+ parentProcessing : false ,
494+ mailbox,
495+ lanes : [ ] ,
496+ beginSystemContinuation : ( ) => undefined ,
497+ send : ( ) => sendWithAttemptIdentity ( ) ,
498+ } ) ;
499+ expect ( driven ) . toBe ( true ) ;
500+ expect ( records . get ( "w1" ) ?. collected ) . not . toBe ( true ) ;
501+ resolveSend ?.( true ) ;
502+ await Promise . resolve ( ) ;
503+ expect ( records . get ( "w1" ) ?. collected ) . toBe ( true ) ;
504+ } ) ;
371505} ) ;
0 commit comments