@@ -3,7 +3,7 @@ import { afterEach, describe, expect, it, vi } from "vitest";
33
44import { fetchLedgers , LEDGERS_API_PATH , type LedgersResult , type LedgersSummary } from "./lib/ledgers" ;
55import { type GovernorPauseState , type GovernorPauseStateResult } from "./lib/governor" ;
6- import { LedgersPage , LedgersView } from "./routes/ledgers" ;
6+ import { GovernorControlSection , LedgersPage , LedgersView } from "./routes/ledgers" ;
77import { handleLedgersRequest , type LedgersApiDeps } from "../vite-ledgers-api" ;
88
99// Test-local fixture factories (were lib exports reachable only from tests; moved here per #6187).
@@ -529,3 +529,39 @@ describe("handleLedgersRequest (#4855)", () => {
529529 expect ( handled ) . toEqual ( { status : 500 , body : JSON . stringify ( { error : "sqlite locked" } ) } ) ;
530530 } ) ;
531531} ) ;
532+
533+ describe ( "GovernorControlSection pause-reason reset (#7079)" , ( ) => {
534+ const notPaused : GovernorPauseStateResult = { ok : true , pauseState : { paused : false , reason : null , pausedAt : null } } ;
535+ const pausedResult : GovernorPauseStateResult = {
536+ ok : true ,
537+ pauseState : { paused : true , reason : "investigating flaky test" , pausedAt : "2026-07-18T00:00:00.000Z" } ,
538+ } ;
539+ const control = ( result : GovernorPauseStateResult , onPause = vi . fn ( ) ) => (
540+ < GovernorControlSection result = { result } pending = { false } onPause = { onPause } onResume = { vi . fn ( ) } />
541+ ) ;
542+
543+ it ( "clears the reason after a successful pause, so a later resume→pause starts from a blank input" , ( ) => {
544+ const onPause = vi . fn ( ) ;
545+ const { rerender } = render ( control ( notPaused , onPause ) ) ;
546+ fireEvent . change ( screen . getByLabelText ( "Pause reason" ) , { target : { value : "investigating flaky test" } } ) ;
547+ fireEvent . click ( screen . getByRole ( "button" , { name : "Pause governor" } ) ) ;
548+ expect ( onPause ) . toHaveBeenCalledWith ( "investigating flaky test" ) ;
549+
550+ // The poll reflects the successful pause (paused: true), then the operator resumes back to the pause form.
551+ rerender ( control ( pausedResult , onPause ) ) ;
552+ rerender ( control ( notPaused , onPause ) ) ;
553+ expect ( ( screen . getByLabelText ( "Pause reason" ) as HTMLInputElement ) . value ) . toBe ( "" ) ;
554+ } ) ;
555+
556+ it ( "preserves the typed reason after a FAILED pause, so it can be retried without retyping" , ( ) => {
557+ const onPause = vi . fn ( ) ;
558+ const { rerender } = render ( control ( notPaused , onPause ) ) ;
559+ fireEvent . change ( screen . getByLabelText ( "Pause reason" ) , { target : { value : "investigating flaky test" } } ) ;
560+ fireEvent . click ( screen . getByRole ( "button" , { name : "Pause governor" } ) ) ;
561+
562+ // The pause fails (ok: false): the reset must NOT fire. Re-render back to the form (a retry) and the reason stays.
563+ rerender ( control ( { ok : false , error : "governor state write failed" } , onPause ) ) ;
564+ rerender ( control ( notPaused , onPause ) ) ;
565+ expect ( ( screen . getByLabelText ( "Pause reason" ) as HTMLInputElement ) . value ) . toBe ( "investigating flaky test" ) ;
566+ } ) ;
567+ } ) ;
0 commit comments