@@ -37,7 +37,11 @@ import {
37
37
AppCheckInternalComponentName
38
38
} from '@firebase/app-check-interop-types' ;
39
39
import { makeFakeApp , createTestService } from '../test/utils' ;
40
- import { FunctionsService , httpsCallable } from './service' ;
40
+ import {
41
+ FunctionsService ,
42
+ httpsCallable ,
43
+ httpsCallableFromURL
44
+ } from './service' ;
41
45
import { FUNCTIONS_TYPE } from './constants' ;
42
46
import { FunctionsError } from './error' ;
43
47
@@ -523,9 +527,136 @@ describe('Firebase Functions > Stream', () => {
523
527
const [ _ , options ] = mockFetch . firstCall . args ;
524
528
expect ( options . headers [ 'Authorization' ] ) . to . equal ( 'Bearer auth-token' ) ;
525
529
expect ( options . headers [ 'Content-Type' ] ) . to . equal ( 'application/json' ) ;
530
+ expect ( options . credentials ) . to . equal ( undefined ) ;
526
531
expect ( options . headers [ 'Accept' ] ) . to . equal ( 'text/event-stream' ) ;
527
532
} ) ;
528
533
534
+ it ( 'calls cloud workstations with credentials' , async ( ) => {
535
+ const authMock : FirebaseAuthInternal = {
536
+ getToken : async ( ) => ( { accessToken : 'auth-token' } )
537
+ } as unknown as FirebaseAuthInternal ;
538
+ const authProvider = new Provider < FirebaseAuthInternalName > (
539
+ 'auth-internal' ,
540
+ new ComponentContainer ( 'test' )
541
+ ) ;
542
+ authProvider . setComponent (
543
+ new Component ( 'auth-internal' , ( ) => authMock , ComponentType . PRIVATE )
544
+ ) ;
545
+ const appCheckMock : FirebaseAppCheckInternal = {
546
+ getToken : async ( ) => ( { token : 'app-check-token' } )
547
+ } as unknown as FirebaseAppCheckInternal ;
548
+ const appCheckProvider = new Provider < AppCheckInternalComponentName > (
549
+ 'app-check-internal' ,
550
+ new ComponentContainer ( 'test' )
551
+ ) ;
552
+ appCheckProvider . setComponent (
553
+ new Component (
554
+ 'app-check-internal' ,
555
+ ( ) => appCheckMock ,
556
+ ComponentType . PRIVATE
557
+ )
558
+ ) ;
559
+
560
+ const functions = createTestService (
561
+ app ,
562
+ region ,
563
+ authProvider ,
564
+ undefined ,
565
+ appCheckProvider
566
+ ) ;
567
+ functions . emulatorOrigin = 'test.cloudworkstations.dev' ;
568
+ const mockFetch = sinon . stub ( functions , 'fetchImpl' as any ) ;
569
+
570
+ const mockResponse = new ReadableStream ( {
571
+ start ( controller ) {
572
+ controller . enqueue (
573
+ new TextEncoder ( ) . encode ( 'data: {"result":"Success"}\n' )
574
+ ) ;
575
+ controller . close ( ) ;
576
+ }
577
+ } ) ;
578
+
579
+ mockFetch . resolves ( {
580
+ body : mockResponse ,
581
+ headers : new Headers ( { 'Content-Type' : 'text/event-stream' } ) ,
582
+ status : 200 ,
583
+ statusText : 'OK'
584
+ } as Response ) ;
585
+
586
+ const func = httpsCallable < Record < string , any > , string , string > (
587
+ functions ,
588
+ 'stream'
589
+ ) ;
590
+ await func . stream ( { } ) ;
591
+
592
+ expect ( mockFetch . calledOnce ) . to . be . true ;
593
+ const [ _ , options ] = mockFetch . firstCall . args ;
594
+ expect ( options . credentials ) . to . equal ( 'include' ) ;
595
+ } ) ;
596
+
597
+ it ( 'calls streamFromURL cloud workstations with credentials' , async ( ) => {
598
+ const authMock : FirebaseAuthInternal = {
599
+ getToken : async ( ) => ( { accessToken : 'auth-token' } )
600
+ } as unknown as FirebaseAuthInternal ;
601
+ const authProvider = new Provider < FirebaseAuthInternalName > (
602
+ 'auth-internal' ,
603
+ new ComponentContainer ( 'test' )
604
+ ) ;
605
+ authProvider . setComponent (
606
+ new Component ( 'auth-internal' , ( ) => authMock , ComponentType . PRIVATE )
607
+ ) ;
608
+ const appCheckMock : FirebaseAppCheckInternal = {
609
+ getToken : async ( ) => ( { token : 'app-check-token' } )
610
+ } as unknown as FirebaseAppCheckInternal ;
611
+ const appCheckProvider = new Provider < AppCheckInternalComponentName > (
612
+ 'app-check-internal' ,
613
+ new ComponentContainer ( 'test' )
614
+ ) ;
615
+ appCheckProvider . setComponent (
616
+ new Component (
617
+ 'app-check-internal' ,
618
+ ( ) => appCheckMock ,
619
+ ComponentType . PRIVATE
620
+ )
621
+ ) ;
622
+
623
+ const functions = createTestService (
624
+ app ,
625
+ region ,
626
+ authProvider ,
627
+ undefined ,
628
+ appCheckProvider
629
+ ) ;
630
+ functions . emulatorOrigin = 'test.cloudworkstations.dev' ;
631
+ const mockFetch = sinon . stub ( functions , 'fetchImpl' as any ) ;
632
+
633
+ const mockResponse = new ReadableStream ( {
634
+ start ( controller ) {
635
+ controller . enqueue (
636
+ new TextEncoder ( ) . encode ( 'data: {"result":"Success"}\n' )
637
+ ) ;
638
+ controller . close ( ) ;
639
+ }
640
+ } ) ;
641
+
642
+ mockFetch . resolves ( {
643
+ body : mockResponse ,
644
+ headers : new Headers ( { 'Content-Type' : 'text/event-stream' } ) ,
645
+ status : 200 ,
646
+ statusText : 'OK'
647
+ } as Response ) ;
648
+
649
+ const func = httpsCallableFromURL < Record < string , any > , string , string > (
650
+ functions ,
651
+ 'stream'
652
+ ) ;
653
+ await func . stream ( { } ) ;
654
+
655
+ expect ( mockFetch . calledOnce ) . to . be . true ;
656
+ const [ _ , options ] = mockFetch . firstCall . args ;
657
+ expect ( options . credentials ) . to . equal ( 'include' ) ;
658
+ } ) ;
659
+
529
660
it ( 'aborts during initial fetch' , async ( ) => {
530
661
const controller = new AbortController ( ) ;
531
662
0 commit comments