@@ -84,8 +84,10 @@ class TestStreamTransport extends AbstractDataConnectStreamTransport {
8484 }
8585
8686 authProvider = {
87- getAuth : ( ) => ( { getUid : ( ) => this . _authToken } )
88- } as AuthTokenProvider ;
87+ getAuth : ( ) => ( { getUid : ( ) => this . _authToken } ) ,
88+ getToken : ( forceToken ?: boolean ) =>
89+ Promise . resolve ( { accessToken : this . _authToken || 'token' } )
90+ } as unknown as AuthTokenProvider ;
8991
9092 /** Manually set app check token for testing purposes. */
9193 setAppCheckToken ( token : string | null ) : void {
@@ -116,6 +118,11 @@ interface TransportWithInternals {
116118 triggerOnConnectionReady ( ) : void ;
117119 closeConnection ( ) : Promise < void > ;
118120 cancelClose ( ) : void ;
121+ sendRequestMessage < Variables > (
122+ requestBody : DataConnectStreamRequest < Variables >
123+ ) : Promise < void > ;
124+ getWithAuth ( forceToken ?: boolean ) : Promise < string | null > ;
125+ hasWaitedForInitialAuth : boolean ;
119126 prepareMessage <
120127 Variables ,
121128 StreamBody extends DataConnectStreamRequest < Variables >
@@ -209,12 +216,40 @@ describe('AbstractDataConnectStreamTransport', () => {
209216 transport . setAuthToken ( initialAuthToken ) ;
210217 transport . setAppCheckToken ( initialAppCheckToken ) ;
211218 transport . appId = initialAppId ;
219+ transport . hasWaitedForInitialAuth = true ;
212220 } ) ;
213221
214222 afterEach ( ( ) => {
215223 sinon . restore ( ) ;
216224 } ) ;
217225
226+ describe ( 'sendRequestMessage' , ( ) => {
227+ it ( 'should wait until auth token and app check token have been initialized before sending the message' , async ( ) => {
228+ transport . hasWaitedForInitialAuth = false ;
229+
230+ let resolveAuth ! : ( ) => void ;
231+ const authPromise = new Promise < string | null > ( resolve => {
232+ resolveAuth = ( ) => resolve ( 'token' ) ;
233+ } ) ;
234+
235+ const getWithAuthStub = sinon
236+ . stub ( transport , 'getWithAuth' )
237+ . returns ( authPromise ) ;
238+ const sendMessageSpy = sinon . spy ( transport , 'sendMessage' ) ;
239+
240+ const promise = transport . sendRequestMessage ( unpreparedMessage ) ;
241+
242+ expect ( getWithAuthStub ) . to . have . been . calledOnce ;
243+ expect ( sendMessageSpy ) . to . not . have . been . called ;
244+
245+ resolveAuth ( ) ;
246+ await promise ;
247+
248+ expect ( sendMessageSpy ) . to . have . been . calledOnce ;
249+ expect ( sendMessageSpy ) . to . have . been . calledAfter ( getWithAuthStub ) ;
250+ } ) ;
251+ } ) ;
252+
218253 describe ( 'prepareMessage' , ( ) => {
219254 it ( 'should not change data fields' , ( ) => {
220255 const preparedMessage = transport . prepareMessage (
@@ -235,30 +270,34 @@ describe('AbstractDataConnectStreamTransport', () => {
235270 unpreparedMessage
236271 ) as DataConnectStreamRequest < unknown > ;
237272 expect ( preparedMessage . headers ) . to . exist ;
238- expect ( preparedMessage . headers ?. authToken ) . to . equal ( initialAuthToken ) ;
273+ expect ( preparedMessage . headers ?. [ 'X-Firebase-Auth-Token' ] ) . to . equal (
274+ initialAuthToken
275+ ) ;
239276 } ) ;
240277
241278 it ( 'should NOT add the same auth token to subsequent messages' , ( ) => {
242279 transport . prepareMessage ( unpreparedMessage ) ;
243280 const secondPreparedMessage = transport . prepareMessage (
244281 unpreparedMessage
245282 ) as DataConnectStreamRequest < unknown > ;
246- expect ( secondPreparedMessage . headers ?. authToken ) . to . be . undefined ;
283+ expect ( secondPreparedMessage . headers ?. [ 'X-Firebase-Auth-Token' ] ) . to . be
284+ . undefined ;
247285 } ) ;
248286
249287 it ( 'should include auth token when it changes' , ( ) => {
250288 transport . prepareMessage ( unpreparedMessage ) ;
251289 const secondPreparedMessage = transport . prepareMessage (
252290 unpreparedMessage
253291 ) as DataConnectStreamRequest < unknown > ;
254- expect ( secondPreparedMessage . headers ?. authToken ) . to . be . undefined ;
292+ expect ( secondPreparedMessage . headers ?. [ 'X-Firebase-Auth-Token' ] ) . to . be
293+ . undefined ;
255294 transport . setAuthToken ( newAuthToken ) ;
256295 const thirdPreparedMessage = transport . prepareMessage (
257296 unpreparedMessage
258297 ) as DataConnectStreamRequest < unknown > ;
259- expect ( thirdPreparedMessage . headers ?. authToken ) . to . equal (
260- newAuthToken
261- ) ;
298+ expect (
299+ thirdPreparedMessage . headers ?. [ 'X-Firebase-Auth-Token' ]
300+ ) . to . equal ( newAuthToken ) ;
262301 } ) ;
263302 } ) ;
264303
@@ -268,30 +307,33 @@ describe('AbstractDataConnectStreamTransport', () => {
268307 unpreparedMessage
269308 ) as DataConnectStreamRequest < unknown > ;
270309 expect ( firstPreparedMessage . headers ) . to . exist ;
271- expect ( firstPreparedMessage . headers ?. appCheckToken ) . to . equal (
272- initialAppCheckToken
273- ) ;
310+ expect (
311+ firstPreparedMessage . headers ?. [ 'X-Firebase-App-Check' ]
312+ ) . to . equal ( initialAppCheckToken ) ;
274313 } ) ;
275314
276315 it ( 'should NOT add the same app check token to subsequent messages' , ( ) => {
277316 transport . prepareMessage ( unpreparedMessage ) ;
278317 const secondPreparedMessage = transport . prepareMessage (
279318 unpreparedMessage
280319 ) as DataConnectStreamRequest < unknown > ;
281- expect ( secondPreparedMessage . headers ?. appCheckToken ) . to . be . undefined ;
320+ expect ( secondPreparedMessage . headers ?. [ 'X-Firebase-App-Check' ] ) . to . be
321+ . undefined ;
282322 } ) ;
283323
284324 it ( 'should NOT include app check token when it changes' , ( ) => {
285325 transport . prepareMessage ( unpreparedMessage ) ;
286326 const secondPreparedMessage = transport . prepareMessage (
287327 unpreparedMessage
288328 ) as DataConnectStreamRequest < unknown > ;
289- expect ( secondPreparedMessage . headers ?. appCheckToken ) . to . be . undefined ;
329+ expect ( secondPreparedMessage . headers ?. [ 'X-Firebase-App-Check' ] ) . to . be
330+ . undefined ;
290331 transport . setAppCheckToken ( newAppCheckToken ) ;
291332 const thirdPreparedMessage = transport . prepareMessage (
292333 unpreparedMessage
293334 ) as DataConnectStreamRequest < unknown > ;
294- expect ( thirdPreparedMessage . headers ?. appCheckToken ) . to . be . undefined ;
335+ expect ( thirdPreparedMessage . headers ?. [ 'X-Firebase-App-Check' ] ) . to . be
336+ . undefined ;
295337 } ) ;
296338 } ) ;
297339
@@ -374,8 +416,8 @@ describe('AbstractDataConnectStreamTransport', () => {
374416 unpreparedMessage
375417 ) as DataConnectStreamRequest < unknown > ;
376418 expect ( secondMessage . name ) . to . be . undefined ;
377- expect ( secondMessage . headers ?. appCheckToken ) . to . be . undefined ;
378- expect ( secondMessage . headers ?. authToken ) . to . be . undefined ;
419+ expect ( secondMessage . headers ?. [ 'X-Firebase-App-Check' ] ) . to . be . undefined ;
420+ expect ( secondMessage . headers ?. [ 'X-Firebase-Auth-Token' ] ) . to . be . undefined ;
379421
380422 // Trigger the physical connection reset
381423 transport . triggerOnConnectionReady ( ) ;
@@ -385,10 +427,12 @@ describe('AbstractDataConnectStreamTransport', () => {
385427 unpreparedMessage
386428 ) as DataConnectStreamRequest < unknown > ;
387429 expect ( thirdMessage . name ) . to . equal ( expectedName ) ;
388- expect ( thirdMessage . headers ?. appCheckToken ) . to . equal (
430+ expect ( thirdMessage . headers ?. [ 'X-Firebase-App-Check' ] ) . to . equal (
389431 initialAppCheckToken
390432 ) ;
391- expect ( thirdMessage . headers ?. authToken ) . to . equal ( initialAuthToken ) ;
433+ expect ( thirdMessage . headers ?. [ 'X-Firebase-Auth-Token' ] ) . to . equal (
434+ initialAuthToken
435+ ) ;
392436 } ) ;
393437 } ) ;
394438
@@ -592,21 +636,23 @@ describe('AbstractDataConnectStreamTransport', () => {
592636 onDisconnect : sinon . spy ( ) ,
593637 onError : sinon . spy ( )
594638 } ;
639+
640+ const sendMessageStub = sinon . stub ( transport , 'sendMessage' ) ;
641+ sendMessageStub . onFirstCall ( ) . resolves ( ) ;
642+ sendMessageStub . onSecondCall ( ) . rejects ( expectedError ) ;
643+
595644 transport . invokeSubscribe ( observer , queryName1 , variables1 ) ;
596645
597646 const expectedKey = transport . getMapKey ( queryName1 , variables1 ) ;
598647 const subscribeRequest =
599648 transport . activeSubscribeRequests . get ( expectedKey ) ;
600649 const subscribeRequestId = subscribeRequest ?. requestId ! ;
601650
602- const sendMessageStub = sinon
603- . stub ( transport , 'sendMessage' )
604- . rejects ( expectedError ) ;
605651 transport . invokeUnsubscribe ( queryName1 , variables1 ) ;
606652 // invokeUnsubscribe's sendMessage is fire and forget
607653 await sleep ( 500 ) ;
608654
609- expect ( sendMessageStub ) . to . have . been . calledOnce ;
655+ expect ( sendMessageStub ) . to . have . been . calledTwice ;
610656 expect ( logErrorStub ) . to . have . been . calledOnce ;
611657 expect ( logErrorStub ) . to . have . been . calledWithMatch (
612658 'Stream Transport failed to send unsubscribe message'
@@ -1025,10 +1071,10 @@ describe('AbstractDataConnectStreamTransport', () => {
10251071 await transport . invokeSubscribe ( observer , queryName1 , variables1 ) ;
10261072 await transport . invokeUnsubscribe ( queryName1 , variables1 ) ;
10271073
1028- clock . tick ( 1000 * 59 ) ;
1074+ await clock . tickAsync ( 1000 * 59 ) ;
10291075 expect ( closeSpy ) . to . not . have . been . called ;
10301076
1031- clock . tick ( 1000 * 2 ) ;
1077+ await clock . tickAsync ( 1000 * 2 ) ;
10321078 expect ( closeSpy ) . to . have . been . calledOnce ;
10331079 } ) ;
10341080
@@ -1044,12 +1090,12 @@ describe('AbstractDataConnectStreamTransport', () => {
10441090 await transport . invokeSubscribe ( observer , queryName1 , variables1 ) ;
10451091 await transport . invokeUnsubscribe ( queryName1 , variables1 ) ;
10461092
1047- clock . tick ( 1000 * 30 ) ;
1093+ await clock . tickAsync ( 1000 * 30 ) ;
10481094 expect ( closeSpy ) . to . not . have . been . called ;
10491095
10501096 await transport . invokeSubscribe ( observer , queryName2 , variables2 ) ;
10511097
1052- clock . tick ( 1000 * 65 ) ;
1098+ await clock . tickAsync ( 1000 * 65 ) ;
10531099 expect ( closeSpy ) . to . not . have . been . called ;
10541100 } ) ;
10551101
@@ -1066,16 +1112,16 @@ describe('AbstractDataConnectStreamTransport', () => {
10661112 await transport . invokeSubscribe ( observer , queryName1 , variables1 ) ;
10671113 await transport . invokeUnsubscribe ( queryName1 , variables1 ) ;
10681114
1069- clock . tick ( 1000 * 30 ) ;
1115+ await clock . tickAsync ( 1000 * 30 ) ;
10701116 expect ( closeSpy ) . to . not . have . been . called ;
10711117
10721118 sendMessageStub . rejects ( ) ;
10731119 await transport . invokeSubscribe ( observer , queryName2 , variables2 ) ;
10741120
1075- clock . tick ( 1000 * 30 ) ;
1121+ await clock . tickAsync ( 1000 * 30 ) ;
10761122 expect ( closeSpy ) . to . not . have . been . called ;
10771123
1078- clock . tick ( 1000 * 35 ) ;
1124+ await clock . tickAsync ( 1000 * 35 ) ;
10791125 expect ( closeSpy ) . to . have . been . calledOnce ;
10801126 } ) ;
10811127
@@ -1093,7 +1139,7 @@ describe('AbstractDataConnectStreamTransport', () => {
10931139
10941140 void transport . invokeQuery ( queryName2 , variables2 ) ;
10951141
1096- clock . tick ( 1000 * 65 ) ;
1142+ await clock . tickAsync ( 1000 * 65 ) ;
10971143 expect ( closeSpy ) . to . not . have . been . called ;
10981144 } ) ;
10991145
@@ -1111,7 +1157,7 @@ describe('AbstractDataConnectStreamTransport', () => {
11111157
11121158 const queryPromise = transport . invokeQuery ( queryName2 , variables2 ) ;
11131159
1114- clock . tick ( 1000 * 65 ) ;
1160+ await clock . tickAsync ( 1000 * 65 ) ;
11151161 expect ( closeSpy ) . to . not . have . been . called ;
11161162
11171163 const expectedKey = transport . getMapKey ( queryName2 , variables2 ) ;
0 commit comments