@@ -24,13 +24,102 @@ import { FirebaseApp, initializeApp } from '@firebase/app';
24
24
25
25
import { Firestore , initializeFirestore , setLogLevel } from '../../../src' ;
26
26
import { PrivateSettings } from '../../../src/lite-api/settings' ;
27
+ import { logDebug } from '../../../src/util/log' ;
27
28
28
29
// TODO(dimond): Right now we create a new app and Firestore instance for
29
30
// every test and never clean them up. We may need to revisit.
30
31
let appCount = 0 ;
31
32
33
+ const originalFetch = globalThis . fetch ;
34
+
35
+ /**
36
+ * A class that acts as a spy for a ReadableStream.
37
+ * It logs the content of the input stream as it's read and then pipes it through.
38
+ */
39
+ class ReadableStreamSpy < Uint8Array > {
40
+ private inputReadableStream : ReadableStream < Uint8Array > ;
41
+ private spyTransformStream : TransformStream < Uint8Array , Uint8Array > ;
42
+ private spiedReadableStream : ReadableStream < Uint8Array > ;
43
+
44
+ private readonly decoder = new TextDecoder ( ) ;
45
+
46
+ /**
47
+ * Creates an instance of ReadableStreamSpy.
48
+ * @param inputReadableStream The ReadableStream to spy on.
49
+ */
50
+ constructor ( inputReadableStream : ReadableStream < Uint8Array > ) {
51
+ if ( ! ( inputReadableStream instanceof ReadableStream ) ) {
52
+ throw new Error ( 'Input must be a ReadableStream.' ) ;
53
+ }
54
+
55
+ this . inputReadableStream = inputReadableStream ;
56
+
57
+ // Create a TransformStream that logs data
58
+ this . spyTransformStream = new TransformStream < Uint8Array , Uint8Array > ( {
59
+ transform : (
60
+ chunk : Uint8Array ,
61
+ controller : TransformStreamDefaultController < Uint8Array >
62
+ ) => {
63
+ // @ts -ignore
64
+ logDebug ( this . decoder . decode ( chunk ) ) ;
65
+
66
+ controller . enqueue ( chunk ) ; // Pass the chunk along
67
+ } ,
68
+ flush : ( controller : TransformStreamDefaultController < Uint8Array > ) => {
69
+ // Any cleanup or final actions if needed
70
+ }
71
+ } ) ;
72
+
73
+ // Pipe the input stream through the spy transform stream
74
+ this . spiedReadableStream = this . inputReadableStream . pipeThrough (
75
+ this . spyTransformStream
76
+ ) ;
77
+ }
78
+
79
+ /**
80
+ * Gets the spied-on ReadableStream.
81
+ * You should read from this stream to observe the logged chunks.
82
+ * @returns The ReadableStream with spy functionality.
83
+ */
84
+ get readableStream ( ) : ReadableStream < Uint8Array > {
85
+ return this . spiedReadableStream ;
86
+ }
87
+ }
88
+
89
+ globalThis . fetch = async function ( requestOrUrl , options ) {
90
+ // @ts -ignore
91
+ const url =
92
+ typeof requestOrUrl === 'string' ? requestOrUrl : requestOrUrl . url ;
93
+
94
+ logDebug ( `FETCH FOR ${ url } ` ) ;
95
+
96
+ if (
97
+ url . startsWith (
98
+ 'https://firestore.googleapis.com/google.firestore.v1.Firestore/Listen/channel'
99
+ )
100
+ ) {
101
+ const response = await originalFetch ( requestOrUrl , options ) ;
102
+
103
+ if ( response . body ) {
104
+ const spy = new ReadableStreamSpy ( response . body ) ;
105
+
106
+ return Promise . resolve (
107
+ new Response ( spy . readableStream , {
108
+ headers : response . headers ,
109
+ status : response . status ,
110
+ statusText : response . statusText
111
+ } )
112
+ ) ;
113
+ }
114
+
115
+ return Promise . resolve ( response ) ;
116
+ }
117
+
118
+ return originalFetch ( requestOrUrl , options ) ;
119
+ } ;
120
+
32
121
// enable contextual debug logging
33
- setLogLevel ( 'error' , 100 ) ;
122
+ setLogLevel ( 'error' , 200 ) ;
34
123
35
124
export function newTestApp ( projectId : string , appName ?: string ) : FirebaseApp {
36
125
if ( appName === undefined ) {
0 commit comments