@@ -784,4 +784,85 @@ describe('Schedule4 context, load + write error, edit, delete and status paths',
784784
785785 expect ( await screen . findByRole ( 'table' , { name : / T o w i n g T o t a l / i } ) ) . toBeInTheDocument ( )
786786 } )
787+
788+ test ( 'stale PUT is ignored when context changes before it settles (Story 29.6)' , async ( ) => {
789+ let putGate : ( v : unknown ) => void = ( ) => { }
790+ const putPromise = new Promise ( ( resolve ) => {
791+ putGate = resolve
792+ } )
793+ let releasePut = ( ) => { }
794+ const releasePromise = new Promise < void > ( ( resolve ) => {
795+ releasePut = resolve
796+ } )
797+
798+ let putCalled = false
799+ server . use (
800+ http . get ( URL , ( { request } ) =>
801+ new window . URL ( request . url ) . searchParams . get ( 'millId' ) === '999'
802+ ? HttpResponse . json (
803+ doc ( {
804+ millId : 999 ,
805+ year : 2020 ,
806+ editable : false ,
807+ locations : [ { id : 999 , revisionCount : 1 , name : 'Context 999/2020 loaded' , comments : null , categories : [ ] , subPageRows : [ ] } ] ,
808+ } ) ,
809+ )
810+ : HttpResponse . json ( doc ( ) ) ,
811+ ) ,
812+ http . put ( LOCATIONS_URL , async ( ) => {
813+ putCalled = true
814+ putGate ( null )
815+ await releasePromise
816+ return HttpResponse . json ( {
817+ ...doc ( ) ,
818+ message : { key : 'dataSavedSuccesfullyInfoMsg' , text : 'Data saved successfully' } ,
819+ } )
820+ } ) ,
821+ )
822+
823+ const rootRoute = createRootRoute ( )
824+ const scheduleRoute = createRoute ( {
825+ getParentRoute : ( ) => rootRoute ,
826+ path : '/schedule-4' ,
827+ validateSearch : realScheduleRoute . options . validateSearch ,
828+ component : ( ) => (
829+ < MillYearProvider initial = { { millId : 514 , year : 2021 } } >
830+ < StaleRaceHarness />
831+ </ MillYearProvider >
832+ ) ,
833+ } )
834+ const router = createRouter ( {
835+ routeTree : rootRoute . addChildren ( [ scheduleRoute ] ) ,
836+ history : createMemoryHistory ( { initialEntries : [ '/schedule-4' ] } ) ,
837+ } )
838+ render ( < RouterProvider router = { router } /> )
839+ const user = userEvent . setup ( )
840+
841+ await screen . findByText ( 'Harbour Dump' )
842+ await user . click ( screen . getByRole ( 'button' , { name : / a d d n e w l o c a t i o n / i } ) )
843+ await user . type ( screen . getByLabelText ( 'Location Name' ) , 'New Dump' )
844+ await user . click ( screen . getByRole ( 'button' , { name : / ^ s a v e $ / i } ) )
845+ await user . click ( screen . getByRole ( 'button' , { name : / c h a n g e / i } ) )
846+
847+ expect ( await screen . findByText ( 'Context 999/2020 loaded' ) ) . toBeInTheDocument ( )
848+
849+ releasePut ( )
850+ await waitFor ( ( ) => {
851+ expect ( screen . queryByText ( 'Data saved successfully' ) ) . not . toBeInTheDocument ( )
852+ } )
853+ } )
787854} )
855+
856+ import useMillYear from '@/context/millYear/useMillYear'
857+
858+ const StaleRaceHarness = ( ) => {
859+ const { setContext } = useMillYear ( )
860+ return (
861+ < >
862+ < button type = "button" onClick = { ( ) => setContext ( 999 , 2020 ) } >
863+ change
864+ </ button >
865+ < Schedule4 />
866+ </ >
867+ )
868+ }
0 commit comments