@@ -40,7 +40,7 @@ function fixture() {
4040 [ 'store' , 'pane-binding' , 'split-pane-retention' , 'split-group-helpers' , 'split-view-worker-scroll' , 'split-view-workers' ] . forEach ( function ( name ) {
4141 vm . runInContext ( fs . readFileSync ( 'lib/public/modules/' + name + '.js' , 'utf8' ) . replace ( / ^ i m p o r t .* ; \n / gm, '' ) . replace ( / ^ e x p o r t \{ [ ^ } ] + \} ; ? $ / gm, '' ) . replace ( / ^ e x p o r t / gm, '' ) , context ) ;
4242 } ) ;
43- context . createStore ( { connected : true , authIdentityLoaded : true , currentSlug : 'p' , activeProjectSlug : 'p' , sessionListProjectSlug : 'p' , myUserId : 'owner' , currentProjectOwnerId : 'owner' ,
43+ context . createStore ( { connected : true , authIdentityLoaded : true , currentSlug : 'p' , activeSessionId : 1 , activeProjectSlug : 'p' , sessionListProjectSlug : 'p' , myUserId : 'owner' , currentProjectOwnerId : 'owner' ,
4444 projectSplitViewSocketGeneration : 1 , paneBindingSessions : sessions , projectSplitViewActiveId : 'view' , projectSplitViews : [ { id : 'view' , sessions : [ driver ] } ] ,
4545 splitGroups : [ { id : 'pair' , members : [ 1 , 2 ] , pair : { version : 2 , driverId : 1 , workerIds : [ 2 ] } } , { id : 'cached-pair' , members : [ 4 , 5 ] , pair : { version : 2 , driverId : 4 , workerIds : [ 5 ] } } ] } ) ;
4646 function makePane ( session ) {
@@ -141,3 +141,79 @@ test('revoking and restoring pair metadata preserves active Driver identity whil
141141 if ( boundary === 'owner' ) assert . equal ( f . pane . isConnected , false ) ;
142142 } ) ;
143143} ) ;
144+
145+ test ( 'creation opens the first exact Worker once, selects its pill and preserves Driver focus' , function ( ) {
146+ var f = fixture ( ) , api = f . context , group = api . store . get ( 'splitGroups' ) [ 0 ] ;
147+ var composer = f . document . createElement ( 'textarea' ) ; f . document . body . appendChild ( composer ) ; composer . focus ( ) ;
148+ api . showCreatedWorkerViewer ( group ) ;
149+ assert . equal ( api . store . get ( 'splitViewWorkerConversation' ) . workerOriginId , 'worker-2' ) ;
150+ assert . equal ( f . document . activeElement , composer ) ;
151+ assert . equal ( f . pane . querySelectorAll ( '.split-view-worker-chip' ) [ 0 ] . attrs [ 'aria-expanded' ] , 'true' ) ;
152+ assert . equal ( f . sends ( ) , 1 ) ;
153+ api . close ( false ) ;
154+ assert . equal ( f . pane . querySelectorAll ( '.split-view-worker-chip' ) [ 0 ] . attrs [ 'aria-expanded' ] , 'false' ) ;
155+ api . showCreatedWorkerViewer ( group ) ; api . renderPaneWorkers ( f . pane , f . sessions [ 0 ] ) ;
156+ assert . equal ( api . store . get ( 'splitViewWorkerConversation' ) , null , 'duplicate creation and rerender cannot reopen dismissal' ) ;
157+ api . showCreatedWorkerViewer ( { members : [ 1 , 2 , 3 ] , pair : { version : 2 , driverId : 1 , workerIds : [ 2 , 3 ] } } ) ;
158+ assert . equal ( api . store . get ( 'splitViewWorkerConversation' ) , null , 'additional Workers remain as pills' ) ;
159+ f . click ( 0 ) ;
160+ assert . equal ( api . store . get ( 'splitViewWorkerConversation' ) . workerOriginId , 'worker-2' , 'explicit click still opens the viewer' ) ;
161+ } ) ;
162+ test ( 'creation waits for bound pane readiness and never opens for old history' , function ( ) {
163+ var f = fixture ( ) , api = f . context , frame = f . pane . querySelector ( '.split-pane-frame' ) , identity = frame . clayPane . identity ;
164+ frame . clayPane . identity = function ( ) { return Object . assign ( { } , identity ( ) , { ready : false } ) ; } ;
165+ api . showCreatedWorkerViewer ( api . store . get ( 'splitGroups' ) [ 0 ] ) ;
166+ assert . ok ( api . store . get ( 'createdWorkerViewer' ) ) ; assert . equal ( f . sends ( ) , 0 ) ;
167+ frame . clayPane . identity = identity ; api . renderPaneWorkers ( f . pane , f . sessions [ 0 ] ) ;
168+ assert . equal ( api . store . get ( 'createdWorkerViewer' ) , null ) ;
169+ assert . equal ( api . store . get ( 'splitViewWorkerConversation' ) . workerOriginId , 'worker-2' ) ;
170+ var replay = fixture ( ) ; replay . context . store . set ( { replayingHistory : true } ) ;
171+ replay . context . showCreatedWorkerViewer ( replay . context . store . get ( 'splitGroups' ) [ 0 ] ) ;
172+ assert . equal ( replay . sends ( ) , 0 ) ; assert . equal ( replay . context . store . get ( 'createdWorkerViewer' ) , undefined ) ;
173+ } ) ;
174+ [ 'myUserId' , 'currentSlug' , 'projectSplitViewSocketGeneration' , 'activeSessionId' , 'connected' ] . forEach ( function ( field ) {
175+ test ( 'pending introduction cancels when ' + field + ' changes before readiness' , function ( ) {
176+ var f = fixture ( ) , api = f . context , frame = f . pane . querySelector ( '.split-pane-frame' ) , identity = frame . clayPane . identity ;
177+ frame . clayPane . identity = function ( ) { return Object . assign ( { } , identity ( ) , { ready : false } ) ; } ;
178+ api . showCreatedWorkerViewer ( api . store . get ( 'splitGroups' ) [ 0 ] ) ;
179+ var change = { } ; change [ field ] = field === 'connected' ? false : 'changed' ; api . store . set ( change ) ;
180+ assert . equal ( api . store . get ( 'createdWorkerViewer' ) , null ) ; assert . equal ( f . sends ( ) , 0 ) ;
181+ } ) ;
182+ } ) ;
183+ [ function ( f ) { f . sessions [ 1 ] . sessionOriginId = 'replaced' ; } ,
184+ function ( f ) { f . sessions [ 1 ] . workerGeneration ++ ; } ,
185+ function ( f ) { f . sessions [ 1 ] . ownerId = 'foreign' ; } ,
186+ function ( f ) { f . context . store . set ( { splitGroups : [ ] } ) ; } ] . forEach ( function ( change , index ) {
187+ test ( 'pending introduction rejects replaced or revoked Worker ' + index , function ( ) {
188+ var f = fixture ( ) , api = f . context , frame = f . pane . querySelector ( '.split-pane-frame' ) , identity = frame . clayPane . identity ;
189+ frame . clayPane . identity = function ( ) { return Object . assign ( { } , identity ( ) , { ready : false } ) ; } ;
190+ api . showCreatedWorkerViewer ( api . store . get ( 'splitGroups' ) [ 0 ] ) ; change ( f ) ;
191+ frame . clayPane . identity = identity ; api . renderPaneWorkers ( f . pane , f . sessions [ 0 ] ) ;
192+ assert . equal ( f . sends ( ) , 0 ) ; assert . equal ( ! ! api . store . get ( 'splitViewWorkerConversation' ) , false ) ;
193+ } ) ;
194+ } ) ;
195+
196+ test ( 'an existing viewer is never replaced and pane/DM/hidden contexts never introduce Workers' , function ( ) {
197+ var f = fixture ( ) , api = f . context ; f . click ( 1 ) ;
198+ api . showCreatedWorkerViewer ( api . store . get ( 'splitGroups' ) [ 0 ] ) ;
199+ assert . equal ( api . store . get ( 'splitViewWorkerConversation' ) . workerOriginId , 'worker-3' ) ;
200+ [ 'paneMode' , 'dmMode' , 'hidden' ] . forEach ( function ( field ) {
201+ var blocked = fixture ( ) ;
202+ if ( field === 'hidden' ) blocked . document . hidden = true ;
203+ else { var change = { } ; change [ field ] = true ; blocked . context . store . set ( change ) ; }
204+ blocked . context . showCreatedWorkerViewer ( blocked . context . store . get ( 'splitGroups' ) [ 0 ] ) ;
205+ assert . equal ( blocked . sends ( ) , 0 ) ;
206+ } ) ;
207+ } ) ;
208+ test ( 'exact creation origin waits for late Worker metadata and keeps only the first pending introduction' , function ( ) {
209+ var f = fixture ( ) , api = f . context , worker = f . sessions . splice ( 1 , 1 ) [ 0 ] ;
210+ var group = Object . assign ( { } , api . store . get ( 'splitGroups' ) [ 0 ] , { pairAnchors : { version : 2 , driver : { origin : 'driver' } , workers : [ { origin : worker . sessionOriginId } ] } } ) ;
211+ api . showCreatedWorkerViewer ( group ) ;
212+ assert . equal ( api . store . get ( 'createdWorkerViewer' ) . workerOrigin , worker . sessionOriginId ) ;
213+ assert . equal ( f . sends ( ) , 0 ) ;
214+ api . showCreatedWorkerViewer ( { members : [ 1 , 2 , 3 ] , pair : { version : 2 , driverId : 1 , workerIds : [ 2 , 3 ] } } ) ;
215+ assert . equal ( api . store . get ( 'createdWorkerViewer' ) . workerId , 2 ) ;
216+ f . sessions . splice ( 1 , 0 , worker ) ; api . renderPaneWorkers ( f . pane , f . sessions [ 0 ] ) ;
217+ assert . equal ( api . store . get ( 'splitViewWorkerConversation' ) . workerOriginId , worker . sessionOriginId ) ;
218+ assert . equal ( f . sends ( ) , 1 ) ;
219+ } ) ;
0 commit comments