@@ -123,7 +123,7 @@ void clearedViewerOwnershipMakesAnUnchangedRegionStaleForReconnect() {
123123 }
124124
125125 @ Test
126- void unchangedGeometryReusesClientProxyWithoutMorePackets () {
126+ void unchangedGeometryReusesClientProxyWithoutMorePacketsOrViewerLookups () {
127127 TableSessionContext session = mock (TableSessionContext .class );
128128 SparrowRayInteractionProxyCoordinator .Backend backend = mock (
129129 SparrowRayInteractionProxyCoordinator .Backend .class
@@ -153,6 +153,56 @@ void unchangedGeometryReusesClientProxyWithoutMorePackets() {
153153 verify (backend , times (1 )).create (eq (viewer ), any ());
154154 verify (backend , times (1 )).spawn (viewer , List .of (proxy ));
155155 verify (backend , never ()).destroy (viewer , List .of (proxy ));
156+ verify (session , times (1 )).onlinePlayer (VIEWER_ID );
157+ assertEquals (1 , coordinator .entityCount ());
158+ }
159+
160+ @ Test
161+ void offlineCachedViewerUsesFreshSessionPlayer () {
162+ TableSessionContext session = mock (TableSessionContext .class );
163+ SparrowRayInteractionProxyCoordinator .Backend backend = mock (
164+ SparrowRayInteractionProxyCoordinator .Backend .class
165+ );
166+ SparrowRayInteractionProxyCoordinator .ClientProxy firstProxy = mock (
167+ SparrowRayInteractionProxyCoordinator .ClientProxy .class
168+ );
169+ SparrowRayInteractionProxyCoordinator .ClientProxy reconnectedProxy = mock (
170+ SparrowRayInteractionProxyCoordinator .ClientProxy .class
171+ );
172+ Player firstViewer = mock (Player .class );
173+ Player reconnectedViewer = mock (Player .class );
174+ when (session .id ()).thenReturn ("table-a" );
175+ when (session .onlinePlayer (VIEWER_ID )).thenReturn (firstViewer ).thenReturn (reconnectedViewer );
176+ when (firstViewer .isOnline ()).thenReturn (true );
177+ when (reconnectedViewer .isOnline ()).thenReturn (true );
178+ when (backend .available ()).thenReturn (true );
179+ when (backend .create (eq (firstViewer ), any ())).thenReturn (List .of (firstProxy ));
180+ when (backend .create (eq (reconnectedViewer ), any ())).thenReturn (List .of (reconnectedProxy ));
181+ when (firstProxy .entityId ()).thenReturn (1205 );
182+ when (reconnectedProxy .entityId ()).thenReturn (1206 );
183+ doAnswer (invocation -> {
184+ invocation .<Runnable >getArgument (1 ).run ();
185+ return null ;
186+ }).when (session ).runForViewer (any (Player .class ), any (Runnable .class ));
187+ SparrowRayInteractionProxyCoordinator coordinator = new SparrowRayInteractionProxyCoordinator (
188+ session ,
189+ backend
190+ );
191+ Map <UUID , List <DisplayInteractionRayRegistry .RayInteraction >> interactions = Map .of (
192+ VIEWER_ID ,
193+ List .of (interaction ())
194+ );
195+
196+ coordinator .replace ("actions" , interactions );
197+ when (firstViewer .isOnline ()).thenReturn (false );
198+ coordinator .replace ("actions" , interactions );
199+
200+ verify (backend ).spawn (firstViewer , List .of (firstProxy ));
201+ verify (backend ).spawn (reconnectedViewer , List .of (reconnectedProxy ));
202+ verify (backend , never ()).destroy (firstViewer , List .of (firstProxy ));
203+ verify (session , times (2 )).onlinePlayer (VIEWER_ID );
204+ assertNull (ClientInteractionProxyRegistry .tableIdFor (1205 , VIEWER_ID ));
205+ assertEquals ("table-a" , ClientInteractionProxyRegistry .tableIdFor (1206 , VIEWER_ID ));
156206 assertEquals (1 , coordinator .entityCount ());
157207 }
158208
0 commit comments