@@ -687,3 +687,107 @@ describe('IsolationResolver', () => {
687687 ) . toThrow ( 'staleThresholdDays must be positive, got -1' ) ;
688688 } ) ;
689689} ) ;
690+ test ( 'existing env — emits warning when base branch mismatches' , async ( ) => {
691+ const env = makeEnvRow ( ) ;
692+ isAncestorOfSpy . mockResolvedValue ( false ) ;
693+ const resolver = createResolver ( {
694+ store : makeMockStore ( { getById : async ( ) => env } ) ,
695+ } ) ;
696+
697+ const result = await resolver . resolve ( {
698+ existingEnvId : 'env-1' ,
699+ codebase : defaultCodebase ,
700+ hints : { baseBranch : 'dev' } ,
701+ platformType : 'web' ,
702+ } ) ;
703+
704+ expect ( result . status ) . toBe ( 'resolved' ) ;
705+ if ( result . status === 'resolved' ) {
706+ expect ( result . warnings ) . toBeDefined ( ) ;
707+ expect ( result . warnings ?. [ 0 ] ) . toContain ( "not based on 'dev'" ) ;
708+ }
709+ } ) ;
710+
711+ test ( 'existing env — no warning when base branch matches' , async ( ) => {
712+ const env = makeEnvRow ( ) ;
713+ isAncestorOfSpy . mockResolvedValue ( true ) ;
714+ const resolver = createResolver ( {
715+ store : makeMockStore ( { getById : async ( ) => env } ) ,
716+ } ) ;
717+
718+ const result = await resolver . resolve ( {
719+ existingEnvId : 'env-1' ,
720+ codebase : defaultCodebase ,
721+ hints : { baseBranch : 'dev' } ,
722+ platformType : 'web' ,
723+ } ) ;
724+
725+ expect ( result . status ) . toBe ( 'resolved' ) ;
726+ if ( result . status === 'resolved' ) {
727+ expect ( result . warnings ) . toBeUndefined ( ) ;
728+ }
729+ } ) ;
730+
731+ test ( 'workflow reuse — emits warning when base branch mismatches' , async ( ) => {
732+ const env = makeEnvRow ( ) ;
733+ isAncestorOfSpy . mockResolvedValue ( false ) ;
734+ const resolver = createResolver ( {
735+ store : makeMockStore ( {
736+ findActiveByWorkflow : async ( _cid , wt , wid ) =>
737+ wt === 'issue' && wid === '42' ? env : null ,
738+ } ) ,
739+ } ) ;
740+
741+ const result = await resolver . resolve ( {
742+ existingEnvId : null ,
743+ codebase : defaultCodebase ,
744+ hints : { workflowType : 'issue' , workflowId : '42' , baseBranch : 'dev' } ,
745+ platformType : 'web' ,
746+ } ) ;
747+
748+ expect ( result . status ) . toBe ( 'resolved' ) ;
749+ if ( result . status === 'resolved' ) {
750+ expect ( result . warnings ) . toBeDefined ( ) ;
751+ expect ( result . warnings ?. [ 0 ] ) . toContain ( "not based on 'dev'" ) ;
752+ }
753+ } ) ;
754+
755+ test ( 'existing env — no base branch check when baseBranch not in hints' , async ( ) => {
756+ const env = makeEnvRow ( ) ;
757+ const resolver = createResolver ( {
758+ store : makeMockStore ( { getById : async ( ) => env } ) ,
759+ } ) ;
760+
761+ await resolver . resolve ( {
762+ existingEnvId : 'env-1' ,
763+ codebase : defaultCodebase ,
764+ platformType : 'web' ,
765+ } ) ;
766+
767+ expect ( isAncestorOfSpy ) . not . toHaveBeenCalled ( ) ;
768+ } ) ;
769+
770+ // --- Constructor validation tests ---
771+
772+ test ( 'throws on zero staleThresholdDays' , ( ) => {
773+ expect (
774+ ( ) =>
775+ new IsolationResolver ( {
776+ store : makeMockStore ( ) ,
777+ provider : makeMockProvider ( ) ,
778+ staleThresholdDays : 0 ,
779+ } )
780+ ) . toThrow ( 'staleThresholdDays must be positive, got 0' ) ;
781+ } ) ;
782+
783+ test ( 'throws on negative staleThresholdDays' , ( ) => {
784+ expect (
785+ ( ) =>
786+ new IsolationResolver ( {
787+ store : makeMockStore ( ) ,
788+ provider : makeMockProvider ( ) ,
789+ staleThresholdDays : - 1 ,
790+ } )
791+ ) . toThrow ( 'staleThresholdDays must be positive, got -1' ) ;
792+ } ) ;
793+ } ) ;
0 commit comments