@@ -279,3 +279,38 @@ describe('PCTransportManager.negotiate', () => {
279279 await expect ( p ) . resolves . toBeUndefined ( ) ;
280280 } ) ;
281281} ) ;
282+
283+ describe ( 'PCTransportManager.triggerIceRestart' , ( ) => {
284+ let originalRTCPeerConnection : unknown ;
285+
286+ beforeEach ( ( ) => {
287+ originalRTCPeerConnection = ( globalThis as unknown as { RTCPeerConnection ?: unknown } )
288+ . RTCPeerConnection ;
289+ ( globalThis as unknown as { RTCPeerConnection : unknown } ) . RTCPeerConnection = StubPC ;
290+ } ) ;
291+
292+ afterEach ( ( ) => {
293+ ( globalThis as unknown as { RTCPeerConnection : unknown } ) . RTCPeerConnection =
294+ originalRTCPeerConnection ;
295+ } ) ;
296+
297+ /**
298+ * The subscriber must keep applying remote candidates across a reconnect.
299+ *
300+ * Putting it into `restartingIce` would queue them until a new remote description arrives —
301+ * but the server only re-offers the subscriber when the reconnect moved us to another node,
302+ * so on an ordinary signal-only resume nothing would ever flush that queue, and the
303+ * transport would stop adopting new network paths for the rest of the session. The server
304+ * also never sends candidates ahead of the offer that introduces them, so queueing buys
305+ * nothing in exchange.
306+ */
307+ it ( 'does not stop the subscriber applying remote candidates' , async ( ) => {
308+ const manager = new PCTransportManager ( 'subscriber-primary' , { } ) ;
309+ const publisher = new FakePublisher ( ) ;
310+ ( manager as unknown as { publisher : FakePublisher } ) . publisher = publisher ;
311+
312+ await manager . triggerIceRestart ( ) ;
313+
314+ expect ( manager . subscriber ?. restartingIce ) . toBe ( false ) ;
315+ } ) ;
316+ } ) ;
0 commit comments