@@ -431,18 +431,48 @@ test("auto-stop already-off skip is retained in the JSON report", async () => {
431431 expect ( JSON . parse ( result . stdout ) ) . toEqual ( { processed : [ ] , skipped : [ "qwen-test" ] } ) ;
432432 expect ( calls . some ( ( call ) => call . api . includes ( "batchDeactivate" ) ) ) . toBe ( false ) ;
433433} ) ;
434- test ( "auto-stop failure retains raw result and a structured warning under quiet " , async ( ) => {
434+ test ( "auto-stop enable failure retains raw result, warning, and non-zero exit " , async ( ) => {
435435 batchResult = { failureModels : [ { failureModelId : "qwen-test" , errorCode : "Rejected" } ] } ;
436436 const result = await invoke ( cases [ 1 ] ! , { format : "json" , quiet : true } ) ;
437- expect ( result . exitCode ) . toBe ( 0 ) ;
437+ expect ( result . exitCode ) . toBe ( ExitCode . GENERAL ) ;
438438 expect ( JSON . parse ( result . stdout ) ) . toEqual ( [ batchResult ] ) ;
439439 expect ( result . strayOut ) . toBe ( "" ) ;
440440 expect ( result . strayErr ) . toBe ( "" ) ;
441- expect ( JSON . parse ( result . stderr ) . warning ) . toMatchObject ( {
441+ const stderrLines = result . stderr . trim ( ) . split ( "\n" ) ;
442+ expect ( JSON . parse ( stderrLines [ 0 ] ! ) . warning ) . toMatchObject ( {
442443 code : "FREETIER_OPERATION_FAILED" ,
443444 details : { model : "qwen-test" , error_code : "Rejected" } ,
444445 } ) ;
446+ expect ( JSON . parse ( stderrLines [ 1 ] ! ) . error . message ) . toContain (
447+ "Failed to enable auto-stop for 1 model(s): qwen-test" ,
448+ ) ;
445449} ) ;
450+
451+ test . each ( [ "text" , "json" ] as const ) (
452+ "auto-stop --off failure omits Disabled success copy and exits non-zero in %s" ,
453+ async ( format ) => {
454+ batchResult = { failureModels : [ { failureModelId : "qwen-test" , errorCode : "Rejected" } ] } ;
455+ const result = await invoke (
456+ { ...cases [ 1 ] ! , flags : { model : "qwen-test" , off : true } } ,
457+ { format, quiet : true } ,
458+ ) ;
459+ expect ( result . exitCode ) . toBe ( ExitCode . GENERAL ) ;
460+ expect ( result . strayOut + result . strayErr ) . toBe ( "" ) ;
461+ expect ( result . stdout ) . not . toContain ( "Disabled auto-stop" ) ;
462+ expect ( result . stderr ) . toContain ( "Failed to disable auto-stop for" ) ;
463+ expect ( result . stderr ) . toContain ( "qwen-test" ) ;
464+ expect ( result . stderr ) . toContain ( "Failed to disable auto-stop for 1 model(s): qwen-test" ) ;
465+ if ( format === "json" ) {
466+ expect ( JSON . parse ( result . stdout ) ) . toEqual ( {
467+ processed : [ { model : "qwen-test" , result : batchResult } ] ,
468+ skipped : [ ] ,
469+ } ) ;
470+ expect ( result . stderr ) . toContain ( "FREETIER_OPERATION_FAILED" ) ;
471+ } else {
472+ expect ( result . stdout ) . toBe ( "" ) ;
473+ }
474+ } ,
475+ ) ;
446476test ( "OpenAPI parameters and one-time key disclosure stay unchanged" , async ( ) => {
447477 const scenario = cases . find ( ( item ) => item . name === "token-plan create-key" ) ! ;
448478 const result = await invoke ( scenario , { format : "json" , quiet : true } ) ;
@@ -551,24 +581,24 @@ test.each(["text", "json"] as const)(
551581 } ,
552582) ;
553583test . each ( [ "text" , "json" ] as const ) (
554- "timeout warnings retain the original exit and result policy in %s" ,
584+ "timeout warnings keep the result then exit TIMEOUT in %s" ,
555585 async ( format ) => {
556586 batchResult = { taskId : "task-test" } ;
557587 vi . useFakeTimers ( { toFake : [ "setTimeout" ] } ) ;
558588 try {
559589 const pending = invoke ( cases [ 1 ] ! , { format, quiet : true } ) ;
560590 await vi . runAllTimersAsync ( ) ;
561591 const result = await pending ;
562- expect ( result . exitCode ) . toBe ( 0 ) ;
592+ expect ( result . exitCode ) . toBe ( ExitCode . TIMEOUT ) ;
563593 expect ( result . strayOut + result . strayErr ) . toBe ( "" ) ;
564594 expect ( calls ) . toHaveLength ( 20 ) ;
565595 expect ( calls [ 1 ] ! . data ) . toEqual ( { BatchActivateFreeTierOnlyRequest : { taskId : "task-test" } } ) ;
596+ expect ( result . stderr ) . toContain (
597+ "Timed out waiting to confirm enable auto-stop for 1 model(s): qwen-test" ,
598+ ) ;
566599 if ( format === "json" ) {
567600 expect ( JSON . parse ( result . stdout ) ) . toEqual ( [ null ] ) ;
568- expect ( JSON . parse ( result . stderr ) . warning ) . toMatchObject ( {
569- code : "FREETIER_OPERATION_TIMEOUT" ,
570- details : { model : "qwen-test" } ,
571- } ) ;
601+ expect ( result . stderr ) . toContain ( "FREETIER_OPERATION_TIMEOUT" ) ;
572602 } else {
573603 expect ( result . stdout ) . toBe ( "" ) ;
574604 expect ( result . stderr ) . toContain ( 'Operation timed out for "qwen-test".' ) ;
@@ -578,3 +608,37 @@ test.each(["text", "json"] as const)(
578608 }
579609 } ,
580610) ;
611+
612+ test . each ( [ "text" , "json" ] as const ) (
613+ "auto-stop --off timeout omits Disabled success copy and exits TIMEOUT in %s" ,
614+ async ( format ) => {
615+ batchResult = { taskId : "task-test" } ;
616+ vi . useFakeTimers ( { toFake : [ "setTimeout" ] } ) ;
617+ try {
618+ const pending = invoke (
619+ { ...cases [ 1 ] ! , flags : { model : "qwen-test" , off : true } } ,
620+ { format, quiet : true } ,
621+ ) ;
622+ await vi . runAllTimersAsync ( ) ;
623+ const result = await pending ;
624+ expect ( result . exitCode ) . toBe ( ExitCode . TIMEOUT ) ;
625+ expect ( result . stdout ) . not . toContain ( "Disabled auto-stop" ) ;
626+ expect ( result . stderr ) . toContain ( "Operation timed out for" ) ;
627+ expect ( result . stderr ) . toContain ( "qwen-test" ) ;
628+ expect ( result . stderr ) . toContain (
629+ "Timed out waiting to confirm disable auto-stop for 1 model(s): qwen-test" ,
630+ ) ;
631+ if ( format === "json" ) {
632+ expect ( JSON . parse ( result . stdout ) ) . toEqual ( {
633+ processed : [ { model : "qwen-test" , result : null } ] ,
634+ skipped : [ ] ,
635+ } ) ;
636+ expect ( result . stderr ) . toContain ( "FREETIER_OPERATION_TIMEOUT" ) ;
637+ } else {
638+ expect ( result . stdout ) . toBe ( "" ) ;
639+ }
640+ } finally {
641+ vi . useRealTimers ( ) ;
642+ }
643+ } ,
644+ ) ;
0 commit comments