@dereekb/firebase-server 13.0.0 → 13.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/test/index.esm.js CHANGED
@@ -1,5 +1,3 @@
1
- import 'core-js/modules/es.json.parse.js';
2
- import 'core-js/modules/es.json.stringify.js';
3
1
  import { randomEmailFactory, randomPhoneNumberFactory, mapGetter, incrementingNumberFactory, asGetter, getValueFromGetter, cachedGetter, asArray, mapObjectMap } from '@dereekb/util';
4
2
  import { AbstractChildTestContextFixture, useTestContextFixture, testContextBuilder, AbstractTestContextFixture, useTestFunctionFixture, useTestFunctionMapFixture, ExpectedErrorOfSpecificTypeError } from '@dereekb/util/test';
5
3
  import { decode } from 'jsonwebtoken';
@@ -10,143 +8,133 @@ import { makeTestingFirestoreDrivers, TestFirestoreContextFixture, TestFirestore
10
8
  import { googleCloudFirestoreDrivers, googleCloudFirebaseStorageDrivers, googleCloudStorageFromFirebaseAdminStorage, DefaultFirebaseServerEnvService, FirebaseServerEnvService, firebaseServerAppTokenProvider, firebaseServerStorageDefaultBucketIdTokenProvider } from '@dereekb/firebase-server';
11
9
  import { Firestore } from '@google-cloud/firestore';
12
10
  import { Storage } from '@google-cloud/storage';
13
- import 'core-js/modules/es.iterator.constructor.js';
14
- import 'core-js/modules/es.iterator.for-each.js';
15
11
  import { Test } from '@nestjs/testing';
16
12
  import { serverEnvTokenProvider, ServerEnvironmentService } from '@dereekb/nestjs';
17
13
  import { HttpsError } from 'firebase-functions/v1/https';
18
14
  import { BaseError } from 'make-error';
19
15
 
20
16
  class AuthorizedUserTestContextFixture extends AbstractChildTestContextFixture {
21
- // MARK: AuthorizedUserTestContext (Forwarded)
22
- get uid() {
23
- return this.instance.uid;
24
- }
25
- loadUserRecord() {
26
- return this.instance.loadUserRecord();
27
- }
28
- loadUserEmailAndPhone() {
29
- return this.instance.loadUserEmailAndPhone();
30
- }
31
- loadIdToken() {
32
- return this.instance.loadIdToken();
33
- }
34
- loadDecodedIdToken() {
35
- return this.instance.loadDecodedIdToken();
36
- }
37
- makeContextOptions() {
38
- return this.instance.makeContextOptions();
39
- }
40
- callWrappedFunction(fn, params, skipJsonConversion) {
41
- return this.instance.callWrappedFunction(fn, params, skipJsonConversion);
42
- }
43
- callCloudFunction(fn, params, skipJsonConversion = false) {
44
- return this.instance.callCloudFunction(fn, params, skipJsonConversion);
45
- }
17
+ // MARK: AuthorizedUserTestContext (Forwarded)
18
+ get uid() {
19
+ return this.instance.uid;
20
+ }
21
+ loadUserRecord() {
22
+ return this.instance.loadUserRecord();
23
+ }
24
+ loadUserEmailAndPhone() {
25
+ return this.instance.loadUserEmailAndPhone();
26
+ }
27
+ loadIdToken() {
28
+ return this.instance.loadIdToken();
29
+ }
30
+ loadDecodedIdToken() {
31
+ return this.instance.loadDecodedIdToken();
32
+ }
33
+ makeContextOptions() {
34
+ return this.instance.makeContextOptions();
35
+ }
36
+ callWrappedFunction(fn, params, skipJsonConversion) {
37
+ return this.instance.callWrappedFunction(fn, params, skipJsonConversion);
38
+ }
39
+ callCloudFunction(fn, params, skipJsonConversion = false) {
40
+ return this.instance.callCloudFunction(fn, params, skipJsonConversion);
41
+ }
46
42
  }
47
43
  function convertParamsToParsedJsonObjectAndBack(object) {
48
- const paramsAsJson = JSON.parse(JSON.stringify(object));
49
- return paramsAsJson;
44
+ const paramsAsJson = JSON.parse(JSON.stringify(object));
45
+ return paramsAsJson;
50
46
  }
51
47
  class AuthorizedUserTestContextInstance {
52
- constructor(uid, testContext) {
53
- this.uid = void 0;
54
- this.testContext = void 0;
55
- this.uid = uid;
56
- this.testContext = testContext;
57
- }
58
- loadUserRecord() {
59
- return this.testContext.auth.getUser(this.uid);
60
- }
61
- async loadUserEmailAndPhone() {
62
- const record = await this.loadUserRecord();
63
- return {
64
- email: record.email,
65
- phone: record.phoneNumber
66
- };
67
- }
68
- loadIdToken() {
69
- return this.loadUserRecord().then(record => createEncodedTestFirestoreTokenForUserRecord(this.testContext.auth, record));
70
- }
71
- loadDecodedIdToken() {
72
- return this.loadIdToken().then(decodeEncodedCreateCustomTokenResult);
73
- }
74
- makeContextOptions() {
75
- return this.loadUserRecord().then(record => createTestFunctionContextOptions(this.testContext.auth, record));
76
- }
77
- /**
78
- * Calls a wrapped function with the input params and the context from makeContextOptions().
79
- *
80
- * @param fn
81
- * @param params
82
- * @param skipJsonConversion
83
- */
84
- callWrappedFunction(fn, params, skipJsonConversion) {
85
- // Parse to JSON then back to simulate sending JSON to the server, and the server parsing it as a POJO.
86
- const parsedParams = params == null || skipJsonConversion ? params : convertParamsToParsedJsonObjectAndBack(params);
87
- return this.makeContextOptions().then(options => fn(parsedParams, options));
88
- }
89
- callCloudFunction(fn, params, skipJsonConversion = false) {
90
- if (params != null && params.scheduleTime) {
91
- // Workaround for https://github.com/firebase/firebase-functions-test/issues/210
92
- const scheduleTime = params.scheduleTime;
93
- delete params.scheduleTime;
94
- params.timestamp = scheduleTime;
95
- }
96
- return this.callWrappedFunction(fn, params, skipJsonConversion);
97
- }
98
- /**
99
- * Calls a wrapped gen 2 auth blocking function with the input params and context options from makeContextOptions().
100
- *
101
- * @param fn
102
- * @param userRecord
103
- * @param eventType
104
- * @param eventOverride
105
- * @param skipJsonConversion
106
- * @returns
107
- */
108
- callAuthBlockingFunction(fn, userRecord, eventType, eventOverride, skipJsonConversion = false) {
109
- const timestamp = new Date().toISOString();
110
- const event = {
111
- ipAddress: '127.0.0.1',
112
- userAgent: 'testing',
113
- eventId: '0',
114
- params: {},
115
- resource: {
116
- service: 'dbx-test',
117
- name: 'fake-resource'
118
- },
119
- timestamp,
120
- ...eventOverride,
121
- data: userRecord,
122
- eventType
123
- };
124
- return this.callCloudFunction(fn, event, skipJsonConversion);
125
- }
126
- /**
127
- * @deprecated gen 1
128
- *
129
- * @param fn
130
- * @param params
131
- * @param contextOptions
132
- * @param skipJsonConversion
133
- * @returns
134
- */
135
- callEventCloudFunction(fn, params, contextOptions, skipJsonConversion = false) {
136
- const parsedParams = params == null || skipJsonConversion ? params : convertParamsToParsedJsonObjectAndBack(params);
137
- return this.makeContextOptions().then(options => fn(parsedParams, contextOptions ? {
138
- ...contextOptions,
139
- ...options
140
- } : options));
141
- }
48
+ uid;
49
+ testContext;
50
+ constructor(uid, testContext) {
51
+ this.uid = uid;
52
+ this.testContext = testContext;
53
+ }
54
+ loadUserRecord() {
55
+ return this.testContext.auth.getUser(this.uid);
56
+ }
57
+ async loadUserEmailAndPhone() {
58
+ const record = await this.loadUserRecord();
59
+ return {
60
+ email: record.email,
61
+ phone: record.phoneNumber
62
+ };
63
+ }
64
+ loadIdToken() {
65
+ return this.loadUserRecord().then((record) => createEncodedTestFirestoreTokenForUserRecord(this.testContext.auth, record));
66
+ }
67
+ loadDecodedIdToken() {
68
+ return this.loadIdToken().then(decodeEncodedCreateCustomTokenResult);
69
+ }
70
+ makeContextOptions() {
71
+ return this.loadUserRecord().then((record) => createTestFunctionContextOptions(this.testContext.auth, record));
72
+ }
73
+ /**
74
+ * Calls a wrapped function with the input params and the context from makeContextOptions().
75
+ *
76
+ * @param fn
77
+ * @param params
78
+ * @param skipJsonConversion
79
+ */
80
+ callWrappedFunction(fn, params, skipJsonConversion) {
81
+ // Parse to JSON then back to simulate sending JSON to the server, and the server parsing it as a POJO.
82
+ const parsedParams = params == null || skipJsonConversion ? params : convertParamsToParsedJsonObjectAndBack(params);
83
+ return this.makeContextOptions().then((options) => fn(parsedParams, options));
84
+ }
85
+ callCloudFunction(fn, params, skipJsonConversion = false) {
86
+ if (params != null && params.scheduleTime) {
87
+ // Workaround for https://github.com/firebase/firebase-functions-test/issues/210
88
+ const scheduleTime = params.scheduleTime;
89
+ delete params.scheduleTime;
90
+ params.timestamp = scheduleTime;
91
+ }
92
+ return this.callWrappedFunction(fn, params, skipJsonConversion);
93
+ }
94
+ /**
95
+ * Calls a wrapped gen 2 auth blocking function with the input params and context options from makeContextOptions().
96
+ *
97
+ * @param fn
98
+ * @param userRecord
99
+ * @param eventType
100
+ * @param eventOverride
101
+ * @param skipJsonConversion
102
+ * @returns
103
+ */
104
+ callAuthBlockingFunction(fn, userRecord, eventType, eventOverride, skipJsonConversion = false) {
105
+ const timestamp = new Date().toISOString();
106
+ const event = {
107
+ ipAddress: '127.0.0.1',
108
+ userAgent: 'testing',
109
+ eventId: '0',
110
+ params: {},
111
+ resource: { service: 'dbx-test', name: 'fake-resource' },
112
+ timestamp,
113
+ ...eventOverride,
114
+ data: userRecord,
115
+ eventType
116
+ };
117
+ return this.callCloudFunction(fn, event, skipJsonConversion);
118
+ }
119
+ /**
120
+ * @deprecated gen 1
121
+ *
122
+ * @param fn
123
+ * @param params
124
+ * @param contextOptions
125
+ * @param skipJsonConversion
126
+ * @returns
127
+ */
128
+ callEventCloudFunction(fn, params, contextOptions, skipJsonConversion = false) {
129
+ const parsedParams = params == null || skipJsonConversion ? params : convertParamsToParsedJsonObjectAndBack(params);
130
+ return this.makeContextOptions().then((options) => fn(parsedParams, contextOptions ? { ...contextOptions, ...options } : options));
131
+ }
142
132
  }
143
133
  /**
144
134
  * Convenience function for using authorizedUserContextFactory directly and passing buildTests.
145
135
  */
146
136
  function authorizedUserContext(config, buildTests) {
147
- authorizedUserContextFactory(config)({
148
- f: config.f
149
- }, buildTests);
137
+ authorizedUserContextFactory(config)({ f: config.f }, buildTests);
150
138
  }
151
139
  const AUTHORIZED_USER_RANDOM_EMAIL_FACTORY = randomEmailFactory();
152
140
  const AUTHORIZED_USER_RANDOM_PHONE_NUMBER_FACTORY = randomPhoneNumberFactory();
@@ -154,86 +142,66 @@ const AUTHORIZED_USER_RANDOM_PHONE_NUMBER_FACTORY = randomPhoneNumberFactory();
154
142
  * Creates a new Jest Context that has a random user for authorization for use in firebase server tests.
155
143
  */
156
144
  function authorizedUserContextFactory(config) {
157
- const {
158
- uid: uidGetter,
159
- makeInstance = (uid, testInstance) => new AuthorizedUserTestContextInstance(uid, testInstance),
160
- makeFixture = f => new AuthorizedUserTestContextFixture(f),
161
- makeUserDetails = () => ({}),
162
- initUser
163
- } = config;
164
- const makeUid = uidGetter ? asGetter(uidGetter) : testUidFactory;
165
- return (params, buildTests) => {
166
- const {
167
- f,
168
- user: inputUserGetterOrValue,
169
- addContactInfo: inputAddContactInfoGetterOrValue,
170
- template: inputTemplateGetterOrValue
171
- } = params;
172
- const inputAddContactInfoGetter = asGetter(inputAddContactInfoGetterOrValue);
173
- const inputUserGetter = asGetter(inputUserGetterOrValue);
174
- const templateGetter = asGetter(inputTemplateGetterOrValue);
175
- return useTestContextFixture({
176
- fixture: makeFixture(f),
177
- buildTests,
178
- initInstance: async () => {
179
- const inputAddContactInfo = await inputAddContactInfoGetter();
180
- const inputUser = await inputUserGetter();
181
- const inputTemplate = await templateGetter();
182
- const uid = inputUser?.uid || makeUid();
183
- const {
184
- details,
185
- claims,
186
- addContactInfo: userDetailsAddContactInfo
187
- } = {
188
- ...makeUserDetails(uid, params),
189
- ...inputTemplate
190
- };
191
- const {
192
- phoneNumber: detailsPhoneNumber,
193
- email: detailsEmail
194
- } = details ?? {}; // keep details if provided
195
- const addContactInfo = inputAddContactInfo || userDetailsAddContactInfo;
196
- const auth = f.instance.auth;
197
- let email;
198
- let phoneNumber;
199
- if (addContactInfo) {
200
- email = detailsEmail ?? AUTHORIZED_USER_RANDOM_EMAIL_FACTORY();
201
- phoneNumber = detailsPhoneNumber ?? AUTHORIZED_USER_RANDOM_PHONE_NUMBER_FACTORY();
202
- } else {
203
- email = detailsEmail;
204
- phoneNumber = detailsPhoneNumber ?? undefined;
205
- }
206
- const userRecord = await auth.createUser({
207
- uid,
208
- displayName: 'Test Person',
209
- ...details,
210
- email,
211
- phoneNumber,
212
- ...inputUser
145
+ const { uid: uidGetter, makeInstance = (uid, testInstance) => new AuthorizedUserTestContextInstance(uid, testInstance), makeFixture = (f) => new AuthorizedUserTestContextFixture(f), makeUserDetails = () => ({}), initUser } = config;
146
+ const makeUid = uidGetter ? asGetter(uidGetter) : testUidFactory;
147
+ return (params, buildTests) => {
148
+ const { f, user: inputUserGetterOrValue, addContactInfo: inputAddContactInfoGetterOrValue, template: inputTemplateGetterOrValue } = params;
149
+ const inputAddContactInfoGetter = asGetter(inputAddContactInfoGetterOrValue);
150
+ const inputUserGetter = asGetter(inputUserGetterOrValue);
151
+ const templateGetter = asGetter(inputTemplateGetterOrValue);
152
+ return useTestContextFixture({
153
+ fixture: makeFixture(f),
154
+ buildTests,
155
+ initInstance: async () => {
156
+ const inputAddContactInfo = await inputAddContactInfoGetter();
157
+ const inputUser = await inputUserGetter();
158
+ const inputTemplate = await templateGetter();
159
+ const uid = inputUser?.uid || makeUid();
160
+ const { details, claims, addContactInfo: userDetailsAddContactInfo } = { ...makeUserDetails(uid, params), ...inputTemplate };
161
+ const { phoneNumber: detailsPhoneNumber, email: detailsEmail } = details ?? {}; // keep details if provided
162
+ const addContactInfo = inputAddContactInfo || userDetailsAddContactInfo;
163
+ const auth = f.instance.auth;
164
+ let email;
165
+ let phoneNumber;
166
+ if (addContactInfo) {
167
+ email = detailsEmail ?? AUTHORIZED_USER_RANDOM_EMAIL_FACTORY();
168
+ phoneNumber = detailsPhoneNumber ?? AUTHORIZED_USER_RANDOM_PHONE_NUMBER_FACTORY();
169
+ }
170
+ else {
171
+ email = detailsEmail;
172
+ phoneNumber = detailsPhoneNumber ?? undefined;
173
+ }
174
+ const userRecord = await auth.createUser({
175
+ uid,
176
+ displayName: 'Test Person',
177
+ ...details,
178
+ email,
179
+ phoneNumber,
180
+ ...inputUser
181
+ });
182
+ if (claims) {
183
+ await auth.setCustomUserClaims(uid, claims);
184
+ }
185
+ const instance = await makeInstance(uid, f.instance, params, userRecord);
186
+ if (initUser) {
187
+ await initUser(instance, params);
188
+ }
189
+ return instance;
190
+ },
191
+ destroyInstance: async (instance) => {
192
+ const app = instance.testContext.app;
193
+ const uid = instance.uid;
194
+ await app.auth().deleteUser(uid);
195
+ }
213
196
  });
214
- if (claims) {
215
- await auth.setCustomUserClaims(uid, claims);
216
- }
217
- const instance = await makeInstance(uid, f.instance, params, userRecord);
218
- if (initUser) {
219
- await initUser(instance, params);
220
- }
221
- return instance;
222
- },
223
- destroyInstance: async instance => {
224
- const app = instance.testContext.app;
225
- const uid = instance.uid;
226
- await app.auth().deleteUser(uid);
227
- }
228
- });
229
- };
197
+ };
230
198
  }
231
199
  /**
232
200
  * Incrementing number factory for generating test UID values.
233
201
  *
234
202
  * Has the format 'test-uid-<number>'
235
203
  */
236
- const testUidFactory = mapGetter(incrementingNumberFactory(), i => `${new Date().getTime()}0${i}`);
204
+ const testUidFactory = mapGetter(incrementingNumberFactory(), (i) => `${new Date().getTime()}0${i}`);
237
205
  /**
238
206
  * Creates a CallableContextOptions with auth attached corresponding to the input UserRecord.
239
207
  *
@@ -242,11 +210,11 @@ const testUidFactory = mapGetter(incrementingNumberFactory(), i => `${new Date()
242
210
  * @returns
243
211
  */
244
212
  async function createTestFunctionContextOptions(auth, userRecord) {
245
- const authData = await createTestFunctionContextAuthData(auth, userRecord);
246
- const contextOptions = {
247
- auth: authData
248
- };
249
- return contextOptions;
213
+ const authData = await createTestFunctionContextAuthData(auth, userRecord);
214
+ const contextOptions = {
215
+ auth: authData
216
+ };
217
+ return contextOptions;
250
218
  }
251
219
  /**
252
220
  * Creates AuthData from the input auth and user record.
@@ -256,13 +224,13 @@ async function createTestFunctionContextOptions(auth, userRecord) {
256
224
  * @returns
257
225
  */
258
226
  async function createTestFunctionContextAuthData(auth, userRecord) {
259
- const token = await createTestFirestoreTokenForUserRecord(auth, userRecord);
260
- const authData = {
261
- uid: token.uid,
262
- token,
263
- rawToken: ''
264
- };
265
- return authData;
227
+ const token = await createTestFirestoreTokenForUserRecord(auth, userRecord);
228
+ const authData = {
229
+ uid: token.uid,
230
+ token,
231
+ rawToken: ''
232
+ };
233
+ return authData;
266
234
  }
267
235
  /**
268
236
  * Creates and decodes a firestore token used for testing.
@@ -272,7 +240,7 @@ async function createTestFunctionContextAuthData(auth, userRecord) {
272
240
  * @returns
273
241
  */
274
242
  function createTestFirestoreTokenForUserRecord(auth, userRecord) {
275
- return createEncodedTestFirestoreTokenForUserRecord(auth, userRecord).then(decodeEncodedCreateCustomTokenResult);
243
+ return createEncodedTestFirestoreTokenForUserRecord(auth, userRecord).then(decodeEncodedCreateCustomTokenResult);
276
244
  }
277
245
  /**
278
246
  * Creates an encoded firestore token used for testing.
@@ -282,167 +250,158 @@ function createTestFirestoreTokenForUserRecord(auth, userRecord) {
282
250
  * @returns
283
251
  */
284
252
  function createEncodedTestFirestoreTokenForUserRecord(auth, userRecord) {
285
- // TODO: Consider replacing createCustomToken, as the custom claims are put into an object called claims in the JWT, instead of spread over. The decodeEncodedCreateCustomTokenResult() function handles this issue, but it may not be expected.
286
- return auth.createCustomToken(userRecord.uid, testFirestoreClaimsFromUserRecord(userRecord));
253
+ // TODO: Consider replacing createCustomToken, as the custom claims are put into an object called claims in the JWT, instead of spread over. The decodeEncodedCreateCustomTokenResult() function handles this issue, but it may not be expected.
254
+ return auth.createCustomToken(userRecord.uid, testFirestoreClaimsFromUserRecord(userRecord));
287
255
  }
288
256
  function decodeEncodedCreateCustomTokenResult(token) {
289
- const decoded = decode(token);
290
- const decodedToken = {
291
- ...decoded,
292
- ...decoded.claims,
293
- auth_time: decoded.iat,
294
- firebase: decoded.claims?.firebase ?? {}
295
- };
296
- delete decodedToken.claims; // remove the "claims" item if it exists.
297
- return decodedToken;
257
+ const decoded = decode(token);
258
+ const decodedToken = {
259
+ ...decoded,
260
+ ...decoded.claims,
261
+ auth_time: decoded.iat,
262
+ firebase: decoded.claims?.firebase ?? {}
263
+ };
264
+ delete decodedToken.claims; // remove the "claims" item if it exists.
265
+ return decodedToken;
298
266
  }
299
267
  function testFirestoreClaimsFromUserRecord(userRecord) {
300
- // Copy claims to be similar to DecodedIdToken pieces.
301
- const baseClaims = {
302
- picture: userRecord.photoURL,
303
- email: userRecord.email,
304
- email_verified: userRecord.emailVerified ?? false,
305
- firebase: {
306
- sign_in_provider: '@dereekb/firebase-server/test',
307
- identities: []
308
- }
309
- };
310
- const customClaims = userRecord.customClaims;
311
- const claims = {
312
- ...customClaims,
313
- ...baseClaims
314
- };
315
- return claims;
268
+ // Copy claims to be similar to DecodedIdToken pieces.
269
+ const baseClaims = {
270
+ picture: userRecord.photoURL,
271
+ email: userRecord.email,
272
+ email_verified: userRecord.emailVerified ?? false,
273
+ firebase: {
274
+ sign_in_provider: '@dereekb/firebase-server/test',
275
+ identities: []
276
+ }
277
+ };
278
+ const customClaims = userRecord.customClaims;
279
+ const claims = {
280
+ ...customClaims,
281
+ ...baseClaims
282
+ };
283
+ return claims;
316
284
  }
317
285
 
318
286
  class ModelTestContextFixture extends AbstractChildTestContextFixture {
319
- // MARK: ModelTestContext (Forwarded)
320
- get documentId() {
321
- return this.instance.documentId;
322
- }
323
- get documentKey() {
324
- return this.instance.documentKey;
325
- }
326
- get documentFlatKey() {
327
- return this.instance.documentFlatKey;
328
- }
329
- get documentTwoWayFlatKey() {
330
- return this.instance.documentTwoWayFlatKey;
331
- }
332
- get documentRef() {
333
- return this.instance.documentRef;
334
- }
335
- get document() {
336
- return this.instance.document;
337
- }
287
+ // MARK: ModelTestContext (Forwarded)
288
+ get documentId() {
289
+ return this.instance.documentId;
290
+ }
291
+ get documentKey() {
292
+ return this.instance.documentKey;
293
+ }
294
+ get documentFlatKey() {
295
+ return this.instance.documentFlatKey;
296
+ }
297
+ get documentTwoWayFlatKey() {
298
+ return this.instance.documentTwoWayFlatKey;
299
+ }
300
+ get documentRef() {
301
+ return this.instance.documentRef;
302
+ }
303
+ get document() {
304
+ return this.instance.document;
305
+ }
338
306
  }
339
307
  class ModelTestContextInstance {
340
- constructor(collection, ref, testContext) {
341
- this.collection = void 0;
342
- this.ref = void 0;
343
- this.testContext = void 0;
344
- this.collection = collection;
345
- this.ref = ref;
346
- this.testContext = testContext;
347
- }
348
- get documentId() {
349
- return this.ref.id;
350
- }
351
- get documentKey() {
352
- return this.ref.path;
353
- }
354
- get documentFlatKey() {
355
- return flatFirestoreModelKey(this.documentKey);
356
- }
357
- get documentTwoWayFlatKey() {
358
- return twoWayFlatFirestoreModelKey(this.documentKey);
359
- }
360
- get documentRef() {
361
- return this.ref;
362
- }
363
- get document() {
364
- return this.collection.documentAccessor().loadDocument(this.ref);
365
- }
308
+ collection;
309
+ ref;
310
+ testContext;
311
+ constructor(collection, ref, testContext) {
312
+ this.collection = collection;
313
+ this.ref = ref;
314
+ this.testContext = testContext;
315
+ }
316
+ get documentId() {
317
+ return this.ref.id;
318
+ }
319
+ get documentKey() {
320
+ return this.ref.path;
321
+ }
322
+ get documentFlatKey() {
323
+ return flatFirestoreModelKey(this.documentKey);
324
+ }
325
+ get documentTwoWayFlatKey() {
326
+ return twoWayFlatFirestoreModelKey(this.documentKey);
327
+ }
328
+ get documentRef() {
329
+ return this.ref;
330
+ }
331
+ get document() {
332
+ return this.collection.documentAccessor().loadDocument(this.ref);
333
+ }
366
334
  }
367
335
  /**
368
336
  * Creates a new Test Context that has a random user for authorization for use in firebase server tests.
369
337
  */
370
338
  function modelTestContextFactory(config) {
371
- const {
372
- getCollection,
373
- collectionForDocument,
374
- makeRef = collection => {
375
- const accessor = collection.documentAccessor();
376
- if (accessor.newDocument == null) {
377
- throw new Error('collection passed to makeRef() was not a full FirestoreCollection. Either supply a custom makeRef() function or a FirestoreCollection that has newDocument() available on the documentAccessor.');
378
- }
379
- return accessor.newDocument().documentRef;
380
- },
381
- makeInstance = (collection, ref, testInstance) => new ModelTestContextInstance(collection, ref, testInstance),
382
- makeFixture = f => new ModelTestContextFixture(f),
383
- initDocument,
384
- destroyInstance
385
- } = config;
386
- return (params, buildTests) => {
387
- const {
388
- f
389
- } = params;
390
- return useTestContextFixture({
391
- fixture: makeFixture(f),
392
- buildTests,
393
- initInstance: async () => {
394
- const parentInstance = f.instance;
395
- let ref;
396
- let collection;
397
- let init;
398
- if (params.doc) {
399
- const doc = await getValueFromGetter(params.doc);
400
- if (!collectionForDocument) {
401
- throw new Error('collectionForDocument() is required when using ModelTestContextDocumentRefParams values as input.');
402
- }
403
- collection = collectionForDocument(parentInstance, doc);
404
- const expectedCollectionName = collection.documentAccessor().modelIdentity.collectionName;
405
- if (expectedCollectionName !== doc.modelIdentity.collectionName) {
406
- throw new Error(`Input doc is in a different collection (${doc.modelIdentity.collectionName}) than expected (${expectedCollectionName}).`);
407
- }
408
- ref = doc.documentRef;
409
- init = false;
410
- } else {
411
- collection = getCollection(parentInstance, params);
412
- ref = await makeRef(collection, params, parentInstance);
413
- init = true;
414
- }
415
- const instance = await makeInstance(collection, ref, parentInstance);
416
- if (init && initDocument) {
417
- await initDocument(instance, params);
339
+ const { getCollection, collectionForDocument, makeRef = (collection) => {
340
+ const accessor = collection.documentAccessor();
341
+ if (accessor.newDocument == null) {
342
+ throw new Error('collection passed to makeRef() was not a full FirestoreCollection. Either supply a custom makeRef() function or a FirestoreCollection that has newDocument() available on the documentAccessor.');
418
343
  }
419
- return instance;
420
- },
421
- destroyInstance
422
- });
423
- };
344
+ return accessor.newDocument().documentRef;
345
+ }, makeInstance = (collection, ref, testInstance) => new ModelTestContextInstance(collection, ref, testInstance), makeFixture = (f) => new ModelTestContextFixture(f), initDocument, destroyInstance } = config;
346
+ return (params, buildTests) => {
347
+ const { f } = params;
348
+ return useTestContextFixture({
349
+ fixture: makeFixture(f),
350
+ buildTests,
351
+ initInstance: async () => {
352
+ const parentInstance = f.instance;
353
+ let ref;
354
+ let collection;
355
+ let init;
356
+ if (params.doc) {
357
+ const doc = await getValueFromGetter(params.doc);
358
+ if (!collectionForDocument) {
359
+ throw new Error('collectionForDocument() is required when using ModelTestContextDocumentRefParams values as input.');
360
+ }
361
+ collection = collectionForDocument(parentInstance, doc);
362
+ const expectedCollectionName = collection.documentAccessor().modelIdentity.collectionName;
363
+ if (expectedCollectionName !== doc.modelIdentity.collectionName) {
364
+ throw new Error(`Input doc is in a different collection (${doc.modelIdentity.collectionName}) than expected (${expectedCollectionName}).`);
365
+ }
366
+ ref = doc.documentRef;
367
+ init = false;
368
+ }
369
+ else {
370
+ collection = getCollection(parentInstance, params);
371
+ ref = await makeRef(collection, params, parentInstance);
372
+ init = true;
373
+ }
374
+ const instance = await makeInstance(collection, ref, parentInstance);
375
+ if (init && initDocument) {
376
+ await initDocument(instance, params);
377
+ }
378
+ return instance;
379
+ },
380
+ destroyInstance
381
+ });
382
+ };
424
383
  }
425
384
 
426
385
  let adminEnvironmentInitialized = false;
427
386
  function isAdminEnvironmentInitialized() {
428
- return adminEnvironmentInitialized;
387
+ return adminEnvironmentInitialized;
429
388
  }
430
389
  function generateNewProjectId() {
431
- const projectId = 'firebase-test-' + new Date().getTime();
432
- return projectId;
390
+ const projectId = 'firebase-test-' + new Date().getTime();
391
+ return projectId;
433
392
  }
434
393
  function rollNewGCloudProjectEnvironmentVariable() {
435
- const projectId = generateNewProjectId();
436
- process.env.GCLOUD_TEST_PROJECT = projectId;
437
- process.env.GCLOUD_PROJECT = projectId;
438
- applyFirebaseGCloudTestProjectIdToFirebaseConfigEnv();
439
- return projectId;
394
+ const projectId = generateNewProjectId();
395
+ process.env.GCLOUD_TEST_PROJECT = projectId;
396
+ process.env.GCLOUD_PROJECT = projectId;
397
+ applyFirebaseGCloudTestProjectIdToFirebaseConfigEnv();
398
+ return projectId;
440
399
  }
441
400
  function getGCloudProjectId() {
442
- return process.env.GCLOUD_PROJECT;
401
+ return process.env.GCLOUD_PROJECT;
443
402
  }
444
403
  function getGCloudTestProjectId() {
445
- return process.env.GCLOUD_TEST_PROJECT;
404
+ return process.env.GCLOUD_TEST_PROJECT;
446
405
  }
447
406
  /**
448
407
  * Applies the current GCLOUD_PROJECT to FIREBASE_CONFIG.
@@ -451,53 +410,55 @@ function getGCloudTestProjectId() {
451
410
  * so that each component can also
452
411
  */
453
412
  function applyFirebaseGCloudTestProjectIdToFirebaseConfigEnv() {
454
- // firebase-functions-test overwrites this each time.
455
- // https://github.com/firebase/firebase-functions-test/blob/acb068f4c086f3355b2960b9e9e5895716c7f8cc/src/lifecycle.ts#L37
456
- const testProjectId = getGCloudTestProjectId();
457
- // console.log('Test project: ', testProjectId);
458
- if (!testProjectId) {
459
- throw new Error('No test project id was available in the environment. Did you call initFirebaseAdminTestEnvironment() first?');
460
- }
461
- const config = JSON.parse(process.env.FIREBASE_CONFIG ?? '{}');
462
- config.projectId = testProjectId;
463
- process.env.FIREBASE_CONFIG = JSON.stringify(config);
464
- process.env.GCLOUD_PROJECT = testProjectId; // re-apply to GCLOUD_PROJECT too
465
- return testProjectId;
413
+ // firebase-functions-test overwrites this each time.
414
+ // https://github.com/firebase/firebase-functions-test/blob/acb068f4c086f3355b2960b9e9e5895716c7f8cc/src/lifecycle.ts#L37
415
+ const testProjectId = getGCloudTestProjectId();
416
+ // console.log('Test project: ', testProjectId);
417
+ if (!testProjectId) {
418
+ throw new Error('No test project id was available in the environment. Did you call initFirebaseAdminTestEnvironment() first?');
419
+ }
420
+ const config = JSON.parse(process.env.FIREBASE_CONFIG ?? '{}');
421
+ config.projectId = testProjectId;
422
+ process.env.FIREBASE_CONFIG = JSON.stringify(config);
423
+ process.env.GCLOUD_PROJECT = testProjectId; // re-apply to GCLOUD_PROJECT too
424
+ return testProjectId;
466
425
  }
467
426
  /**
468
427
  * Should be called before calling/using adminFirebaseTestBuilder(). This should only be called once.
469
428
  */
470
429
  function initFirebaseAdminTestEnvironment(config) {
471
- function crashForEmulator(emulator) {
472
- throw new Error(`Emulator for ${emulator} was not set null or to a host. Crashing to prevent contamination.`);
473
- }
474
- function configureEmulator(emulator, envKey) {
475
- const emulatorConfig = config.emulators[emulator];
476
- if (emulatorConfig) {
477
- process.env[envKey] = emulatorConfig;
478
- } else if (config.emulators.firestore !== null) {
479
- crashForEmulator(emulator);
480
- }
481
- }
482
- rollNewGCloudProjectEnvironmentVariable();
483
- configureEmulator('auth', 'FIREBASE_AUTH_EMULATOR_HOST');
484
- configureEmulator('firestore', 'FIRESTORE_EMULATOR_HOST');
485
- configureEmulator('storage', 'FIREBASE_STORAGE_EMULATOR_HOST');
486
- applyFirebaseGCloudTestProjectIdToFirebaseConfigEnv();
487
- adminEnvironmentInitialized = true;
430
+ function crashForEmulator(emulator) {
431
+ throw new Error(`Emulator for ${emulator} was not set null or to a host. Crashing to prevent contamination.`);
432
+ }
433
+ function configureEmulator(emulator, envKey) {
434
+ const emulatorConfig = config.emulators[emulator];
435
+ if (emulatorConfig) {
436
+ process.env[envKey] = emulatorConfig;
437
+ }
438
+ else if (config.emulators.firestore !== null) {
439
+ crashForEmulator(emulator);
440
+ }
441
+ }
442
+ rollNewGCloudProjectEnvironmentVariable();
443
+ configureEmulator('auth', 'FIREBASE_AUTH_EMULATOR_HOST');
444
+ configureEmulator('firestore', 'FIRESTORE_EMULATOR_HOST');
445
+ configureEmulator('storage', 'FIREBASE_STORAGE_EMULATOR_HOST');
446
+ applyFirebaseGCloudTestProjectIdToFirebaseConfigEnv();
447
+ adminEnvironmentInitialized = true;
488
448
  }
489
449
 
490
450
  function makeGoogleFirestoreContext(drivers, firestore) {
491
- const context = firestoreContextFactory(drivers)(firestore);
492
- context.drivers = drivers;
493
- return context;
451
+ const context = firestoreContextFactory(drivers)(firestore);
452
+ context.drivers = drivers;
453
+ return context;
494
454
  }
495
455
  class GoogleCloudTestFirestoreInstance extends TestFirestoreInstance {
496
- constructor(drivers, firestore) {
497
- super(makeGoogleFirestoreContext(drivers, firestore));
498
- }
456
+ constructor(drivers, firestore) {
457
+ super(makeGoogleFirestoreContext(drivers, firestore));
458
+ }
459
+ }
460
+ class GoogleCloudTestFirestoreContextFixture extends TestFirestoreContextFixture {
499
461
  }
500
- class GoogleCloudTestFirestoreContextFixture extends TestFirestoreContextFixture {}
501
462
  let COUNTER$1 = 0;
502
463
  /**
503
464
  * A TestContextBuilderFunction for building firestore test context factories using @google-cloud/firestore. This means SERVER TESTING ONLY. For client testing, look at @dereekb/firestore.
@@ -507,44 +468,43 @@ let COUNTER$1 = 0;
507
468
  * If you need all of Firebase (firebase-admin library), look at adminFirebaseAdminTestBuilder() instead.
508
469
  */
509
470
  const googleCloudTestFirestoreBuilder = testContextBuilder({
510
- buildConfig: input => {
511
- const config = {
512
- host: input?.host ?? 'localhost',
513
- port: input?.port ?? 0
514
- };
515
- return config;
516
- },
517
- buildFixture: () => new GoogleCloudTestFirestoreContextFixture(),
518
- setupInstance: async config => {
519
- const random = Math.floor(Math.random() * 10000);
520
- const drivers = makeTestingFirestoreDrivers(googleCloudFirestoreDrivers());
521
- const projectId = `test-${COUNTER$1++}-${Date.now()}-${random}`.substring(0, 30);
522
- const firestore = new Firestore({
523
- projectId,
524
- host: config.host,
525
- port: config.port,
526
- maxIdleChannels: 0
527
- });
528
- return new GoogleCloudTestFirestoreInstance(drivers, firestore);
529
- },
530
- teardownInstance: async (instance, config) => {
531
- await instance.firestore.terminate();
532
- }
471
+ buildConfig: (input) => {
472
+ const config = {
473
+ host: input?.host ?? 'localhost',
474
+ port: input?.port ?? 0
475
+ };
476
+ return config;
477
+ },
478
+ buildFixture: () => new GoogleCloudTestFirestoreContextFixture(),
479
+ setupInstance: async (config) => {
480
+ const random = Math.floor(Math.random() * 10000);
481
+ const drivers = makeTestingFirestoreDrivers(googleCloudFirestoreDrivers());
482
+ const projectId = `test-${COUNTER$1++}-${Date.now()}-${random}`.substring(0, 30);
483
+ const firestore = new Firestore({
484
+ projectId,
485
+ host: config.host,
486
+ port: config.port,
487
+ maxIdleChannels: 0
488
+ });
489
+ return new GoogleCloudTestFirestoreInstance(drivers, firestore);
490
+ },
491
+ teardownInstance: async (instance, config) => {
492
+ await instance.firestore.terminate();
493
+ }
533
494
  });
534
495
 
535
496
  function makeGoogleFirebaseStorageContext(drivers, firebaseStorage, defaultBucketId) {
536
- const context = firebaseStorageContextFactory(drivers)(firebaseStorage, {
537
- defaultBucketId
538
- });
539
- context.drivers = drivers;
540
- return context;
497
+ const context = firebaseStorageContextFactory(drivers)(firebaseStorage, { defaultBucketId });
498
+ context.drivers = drivers;
499
+ return context;
541
500
  }
542
501
  class GoogleCloudTestFirebaseStorageInstance extends TestFirebaseStorageInstance {
543
- constructor(drivers, firebaseStorage, defaultBucketId) {
544
- super(makeGoogleFirebaseStorageContext(drivers, firebaseStorage, defaultBucketId));
545
- }
502
+ constructor(drivers, firebaseStorage, defaultBucketId) {
503
+ super(makeGoogleFirebaseStorageContext(drivers, firebaseStorage, defaultBucketId));
504
+ }
505
+ }
506
+ class GoogleCloudTestFirebaseStorageContextFixture extends TestFirebaseStorageContextFixture {
546
507
  }
547
- class GoogleCloudTestFirebaseStorageContextFixture extends TestFirebaseStorageContextFixture {}
548
508
  let COUNTER = 0;
549
509
  /**
550
510
  * A TestContextBuilderFunction for building firebase storage test context factories using @google-cloud/storage. This means SERVER TESTING ONLY. For client testing, look at @dereekb/firestore.
@@ -554,136 +514,136 @@ let COUNTER = 0;
554
514
  * If you need all of Firebase (firebase-admin library), look at adminFirebaseAdminTestBuilder() instead.
555
515
  */
556
516
  const googleCloudTestFirebaseStorageBuilder = testContextBuilder({
557
- buildConfig: input => {
558
- const config = {
559
- host: input?.host ?? 'localhost',
560
- port: input?.port ?? 0
561
- };
562
- if (!config.port) {
563
- throw new Error('Port for host is required.');
564
- }
565
- return config;
566
- },
567
- buildFixture: () => new GoogleCloudTestFirebaseStorageContextFixture(),
568
- setupInstance: async config => {
569
- const drivers = makeTestingFirebaseStorageDrivers(googleCloudFirebaseStorageDrivers());
570
- const projectId = `firebase-storage-server-test-${new Date().getTime()}-${COUNTER++}`;
571
- const firebaseStorage = new Storage({
572
- projectId,
573
- // ensure http:// is provided so the library doesn't default to/try https://
574
- apiEndpoint: `http://${config.host}:${config.port}`
575
- });
576
- const defaultBucketId = projectId;
577
- return new GoogleCloudTestFirebaseStorageInstance(drivers, firebaseStorage, defaultBucketId);
578
- },
579
- teardownInstance: async (instance, config) => {
580
- // nothing to teardown
581
- }
517
+ buildConfig: (input) => {
518
+ const config = {
519
+ host: input?.host ?? 'localhost',
520
+ port: input?.port ?? 0
521
+ };
522
+ if (!config.port) {
523
+ throw new Error('Port for host is required.');
524
+ }
525
+ return config;
526
+ },
527
+ buildFixture: () => new GoogleCloudTestFirebaseStorageContextFixture(),
528
+ setupInstance: async (config) => {
529
+ const drivers = makeTestingFirebaseStorageDrivers(googleCloudFirebaseStorageDrivers());
530
+ const projectId = `firebase-storage-server-test-${new Date().getTime()}-${COUNTER++}`;
531
+ const firebaseStorage = new Storage({
532
+ projectId,
533
+ // ensure http:// is provided so the library doesn't default to/try https://
534
+ apiEndpoint: `http://${config.host}:${config.port}`
535
+ });
536
+ const defaultBucketId = projectId;
537
+ return new GoogleCloudTestFirebaseStorageInstance(drivers, firebaseStorage, defaultBucketId);
538
+ },
539
+ teardownInstance: async (instance, config) => {
540
+ // nothing to teardown
541
+ }
582
542
  });
583
543
 
584
544
  class FirebaseAdminTestContextFixture extends AbstractTestContextFixture {
585
- // MARK: FirebaseAdminTestContext (Forwarded)
586
- get app() {
587
- return this.instance.app;
588
- }
589
- get auth() {
590
- return this.instance.auth;
591
- }
592
- get firestore() {
593
- return this.instance.firestore;
594
- }
595
- get firestoreInstance() {
596
- return this.instance.firestoreInstance;
597
- }
598
- get firestoreContext() {
599
- return this.instance.firestoreContext;
600
- }
601
- get storage() {
602
- return this.instance.storage;
603
- }
604
- get storageInstance() {
605
- return this.instance.storageInstance;
606
- }
607
- get storageContext() {
608
- return this.instance.storageContext;
609
- }
610
- get fnWrapper() {
611
- return this.instance.fnWrapper;
612
- }
545
+ // MARK: FirebaseAdminTestContext (Forwarded)
546
+ get app() {
547
+ return this.instance.app;
548
+ }
549
+ get auth() {
550
+ return this.instance.auth;
551
+ }
552
+ get firestore() {
553
+ return this.instance.firestore;
554
+ }
555
+ get firestoreInstance() {
556
+ return this.instance.firestoreInstance;
557
+ }
558
+ get firestoreContext() {
559
+ return this.instance.firestoreContext;
560
+ }
561
+ get storage() {
562
+ return this.instance.storage;
563
+ }
564
+ get storageInstance() {
565
+ return this.instance.storageInstance;
566
+ }
567
+ get storageContext() {
568
+ return this.instance.storageContext;
569
+ }
570
+ get fnWrapper() {
571
+ return this.instance.fnWrapper;
572
+ }
613
573
  }
614
574
  // MARK: FirebaseAdminTestBuilder
615
575
  class FirebaseAdminTestContextInstance {
616
- constructor(app) {
617
- this.app = void 0;
618
- this.getTestFirestoreInstance = cachedGetter(() => {
619
- const drivers = makeTestingFirestoreDrivers(googleCloudFirestoreDrivers());
620
- return new GoogleCloudTestFirestoreInstance(drivers, this.firestore);
576
+ app;
577
+ getTestFirestoreInstance = cachedGetter(() => {
578
+ const drivers = makeTestingFirestoreDrivers(googleCloudFirestoreDrivers());
579
+ return new GoogleCloudTestFirestoreInstance(drivers, this.firestore);
621
580
  });
622
- this.getTestFirebaseStorageInstance = cachedGetter(() => {
623
- const drivers = makeTestingFirebaseStorageDrivers(googleCloudFirebaseStorageDrivers());
624
- const defaultBucketId = this.app.options.storageBucket;
625
- return new GoogleCloudTestFirebaseStorageInstance(drivers, this.storage, defaultBucketId);
581
+ getTestFirebaseStorageInstance = cachedGetter(() => {
582
+ const drivers = makeTestingFirebaseStorageDrivers(googleCloudFirebaseStorageDrivers());
583
+ const defaultBucketId = this.app.options.storageBucket;
584
+ return new GoogleCloudTestFirebaseStorageInstance(drivers, this.storage, defaultBucketId);
626
585
  });
627
- this.app = app;
628
- }
629
- get auth() {
630
- return this.app.auth();
631
- }
632
- get firestore() {
633
- return this.app.firestore();
634
- }
635
- get firestoreInstance() {
636
- return this.getTestFirestoreInstance();
637
- }
638
- get firestoreContext() {
639
- return this.firestoreInstance.firestoreContext;
640
- }
641
- get storage() {
642
- return googleCloudStorageFromFirebaseAdminStorage(this.app.storage());
643
- }
644
- get storageInstance() {
645
- return this.getTestFirebaseStorageInstance();
646
- }
647
- get storageContext() {
648
- return this.storageInstance.storageContext;
649
- }
650
- get fnWrapper() {
651
- throw new Error('wrapCloudFunction is unsupported by this type.');
652
- }
586
+ constructor(app) {
587
+ this.app = app;
588
+ }
589
+ get auth() {
590
+ return this.app.auth();
591
+ }
592
+ get firestore() {
593
+ return this.app.firestore();
594
+ }
595
+ get firestoreInstance() {
596
+ return this.getTestFirestoreInstance();
597
+ }
598
+ get firestoreContext() {
599
+ return this.firestoreInstance.firestoreContext;
600
+ }
601
+ get storage() {
602
+ return googleCloudStorageFromFirebaseAdminStorage(this.app.storage());
603
+ }
604
+ get storageInstance() {
605
+ return this.getTestFirebaseStorageInstance();
606
+ }
607
+ get storageContext() {
608
+ return this.storageInstance.storageContext;
609
+ }
610
+ get fnWrapper() {
611
+ throw new Error('wrapCloudFunction is unsupported by this type.');
612
+ }
653
613
  }
654
614
  class AbstractFirebaseAdminTestContextInstanceChild {
655
- constructor(parent) {
656
- this.parent = void 0;
657
- this.parent = parent;
658
- }
659
- // MARK: FirebaseAdminTestContext (Forwarded)
660
- get app() {
661
- return this.parent.app;
662
- }
663
- get auth() {
664
- return this.parent.auth;
665
- }
666
- get firestore() {
667
- return this.parent.firestore;
668
- }
669
- get firestoreInstance() {
670
- return this.parent.firestoreInstance;
671
- }
672
- get firestoreContext() {
673
- return this.parent.firestoreContext;
674
- }
675
- get storage() {
676
- return this.parent.storage;
677
- }
678
- get storageInstance() {
679
- return this.parent.storageInstance;
680
- }
681
- get storageContext() {
682
- return this.parent.storageContext;
683
- }
684
- get fnWrapper() {
685
- return this.parent.fnWrapper;
686
- }
615
+ parent;
616
+ constructor(parent) {
617
+ this.parent = parent;
618
+ }
619
+ // MARK: FirebaseAdminTestContext (Forwarded)
620
+ get app() {
621
+ return this.parent.app;
622
+ }
623
+ get auth() {
624
+ return this.parent.auth;
625
+ }
626
+ get firestore() {
627
+ return this.parent.firestore;
628
+ }
629
+ get firestoreInstance() {
630
+ return this.parent.firestoreInstance;
631
+ }
632
+ get firestoreContext() {
633
+ return this.parent.firestoreContext;
634
+ }
635
+ get storage() {
636
+ return this.parent.storage;
637
+ }
638
+ get storageInstance() {
639
+ return this.parent.storageInstance;
640
+ }
641
+ get storageContext() {
642
+ return this.parent.storageContext;
643
+ }
644
+ get fnWrapper() {
645
+ return this.parent.fnWrapper;
646
+ }
687
647
  }
688
648
  /**
689
649
  * A TestContextBuilderFunction for building firebase test context factories using firebase-admin.
@@ -691,28 +651,25 @@ class AbstractFirebaseAdminTestContextInstanceChild {
691
651
  * This can be used to easily build a testing context that sets up RulesTestEnvironment for tests that sets itself up and tears itself down.
692
652
  */
693
653
  const firebaseAdminTestBuilder = testContextBuilder({
694
- buildConfig: input => {
695
- const config = {
696
- ...input
697
- };
698
- return config;
699
- },
700
- buildFixture: () => new FirebaseAdminTestContextFixture(),
701
- setupInstance: async config => {
702
- if (!isAdminEnvironmentInitialized()) {
703
- throw new Error('Call initFirebaseAdminTestEnvironment() from @dereekb/firebase-server was not called before using adminFirebaseTestBuilder().');
654
+ buildConfig: (input) => {
655
+ const config = {
656
+ ...input
657
+ };
658
+ return config;
659
+ },
660
+ buildFixture: () => new FirebaseAdminTestContextFixture(),
661
+ setupInstance: async (config) => {
662
+ if (!isAdminEnvironmentInitialized()) {
663
+ throw new Error('Call initFirebaseAdminTestEnvironment() from @dereekb/firebase-server was not called before using adminFirebaseTestBuilder().');
664
+ }
665
+ const projectId = generateNewProjectId();
666
+ const storageBucket = 'b-' + projectId;
667
+ const app = admin.initializeApp({ projectId, storageBucket });
668
+ return new FirebaseAdminTestContextInstance(app);
669
+ },
670
+ teardownInstance: async (instance, config) => {
671
+ await instance.app.delete(); // clean up the instance
704
672
  }
705
- const projectId = generateNewProjectId();
706
- const storageBucket = 'b-' + projectId;
707
- const app = admin.initializeApp({
708
- projectId,
709
- storageBucket
710
- });
711
- return new FirebaseAdminTestContextInstance(app);
712
- },
713
- teardownInstance: async (instance, config) => {
714
- await instance.app.delete(); // clean up the instance
715
- }
716
673
  });
717
674
  const firebaseAdminTestContextFactory = firebaseAdminTestBuilder({});
718
675
  // MARK: Firestore Context
@@ -725,66 +682,66 @@ const firebaseAdminTestContextFactory = firebaseAdminTestBuilder({});
725
682
  * @returns
726
683
  */
727
684
  function firebaseAdminFirestoreContextFixture(factory) {
728
- return buildTests => {
729
- factory(f => firebaseAdminFirestoreContextWithFixture(f, buildTests));
730
- };
685
+ return (buildTests) => {
686
+ factory((f) => firebaseAdminFirestoreContextWithFixture(f, buildTests));
687
+ };
731
688
  }
732
689
  function firebaseAdminFirestoreContextWithFixture(f, buildTests) {
733
- useTestContextFixture({
734
- fixture: new TestFirestoreContextFixture(),
735
- /**
736
- * Build tests by passing the fixture to the testing functions.
737
- *
738
- * This will inject all tests and sub testing lifecycle items.
739
- */
740
- buildTests,
741
- initInstance: () => f.instance.getTestFirestoreInstance()
742
- });
690
+ useTestContextFixture({
691
+ fixture: new TestFirestoreContextFixture(),
692
+ /**
693
+ * Build tests by passing the fixture to the testing functions.
694
+ *
695
+ * This will inject all tests and sub testing lifecycle items.
696
+ */
697
+ buildTests,
698
+ initInstance: () => f.instance.getTestFirestoreInstance()
699
+ });
743
700
  }
744
701
 
745
702
  function firebaseAdminCloudFunctionWrapper(instance) {
746
- const wrapV1CloudFunction = x => {
747
- return instance.wrap(x);
748
- };
749
- const wrapV2CallableRequest = x => {
750
- const wrappedCloudFunction = instance.wrap(x);
751
- // context is marked optional here to better match the gen 1 callable function signature
752
- return async (data, context) => {
753
- const request = {
754
- ...context,
755
- data,
756
- // NOTE: These will typically not be used/available as they are express.js properties that are not available or useful to the handlers
757
- rawRequest: context?.rawRequest ?? {},
758
- acceptsStreaming: false
759
- };
760
- const result = await wrappedCloudFunction(request);
761
- return result;
703
+ const wrapV1CloudFunction = (x) => {
704
+ return instance.wrap(x);
705
+ };
706
+ const wrapV2CallableRequest = (x) => {
707
+ const wrappedCloudFunction = instance.wrap(x);
708
+ // context is marked optional here to better match the gen 1 callable function signature
709
+ return async (data, context) => {
710
+ const request = {
711
+ ...context,
712
+ data,
713
+ // NOTE: These will typically not be used/available as they are express.js properties that are not available or useful to the handlers
714
+ rawRequest: context?.rawRequest ?? {},
715
+ acceptsStreaming: false
716
+ };
717
+ const result = (await wrappedCloudFunction(request));
718
+ return result;
719
+ };
720
+ };
721
+ const wrapV2CloudFunction = (x) => {
722
+ return instance.wrap(x);
723
+ };
724
+ const wrapBlockingFunction = ((blockingFunction) => {
725
+ return instance.wrap(blockingFunction);
726
+ });
727
+ const wrapCloudFunction = (x) => {
728
+ return instance.wrap(x);
729
+ };
730
+ const wrapper = {
731
+ wrapV1CloudFunction,
732
+ wrapV2CloudFunction,
733
+ wrapV2CallableRequest,
734
+ wrapCallableRequest: wrapV2CallableRequest,
735
+ wrapBlockingFunction,
736
+ wrapCloudFunction
762
737
  };
763
- };
764
- const wrapV2CloudFunction = x => {
765
- return instance.wrap(x);
766
- };
767
- const wrapBlockingFunction = blockingFunction => {
768
- return instance.wrap(blockingFunction);
769
- };
770
- const wrapCloudFunction = x => {
771
- return instance.wrap(x);
772
- };
773
- const wrapper = {
774
- wrapV1CloudFunction,
775
- wrapV2CloudFunction,
776
- wrapV2CallableRequest,
777
- wrapCallableRequest: wrapV2CallableRequest,
778
- wrapBlockingFunction,
779
- wrapCloudFunction
780
- };
781
- return wrapper;
738
+ return wrapper;
782
739
  }
783
740
  function wrapCloudFunctionV1ForTests(wrapper, getter) {
784
- return () => wrapper.wrapV1CloudFunction(getter());
741
+ return () => wrapper.wrapV1CloudFunction(getter());
785
742
  }
786
743
  function wrapCallableRequestForTests(wrapper, getter) {
787
- return () => wrapper.wrapCallableRequest(getter());
744
+ return () => wrapper.wrapCallableRequest(getter());
788
745
  }
789
746
 
790
747
  // MARK: FirebaseAdminFunctionTestBuilder
@@ -794,68 +751,69 @@ let functionsInitialized = false;
794
751
  */
795
752
  let firebaseFunctionsTestInstance;
796
753
  function setupFirebaseAdminFunctionTestSingleton(reroll = false) {
797
- if (!isAdminEnvironmentInitialized()) {
798
- throw new Error('initFirebaseAdminTestEnvironment() was not called.');
799
- }
800
- if (firebaseFunctionsTestInstance) {
801
- firebaseFunctionsTestInstance.cleanup(); // destroy the old instance if it is up.
802
- }
803
- firebaseFunctionsTestInstance = functions();
804
- if (reroll) {
805
- rollNewGCloudProjectEnvironmentVariable();
806
- } else {
807
- applyFirebaseGCloudTestProjectIdToFirebaseConfigEnv();
808
- }
809
- functionsInitialized = true;
810
- return firebaseFunctionsTestInstance;
754
+ if (!isAdminEnvironmentInitialized()) {
755
+ throw new Error('initFirebaseAdminTestEnvironment() was not called.');
756
+ }
757
+ if (firebaseFunctionsTestInstance) {
758
+ firebaseFunctionsTestInstance.cleanup(); // destroy the old instance if it is up.
759
+ }
760
+ firebaseFunctionsTestInstance = functions();
761
+ if (reroll) {
762
+ rollNewGCloudProjectEnvironmentVariable();
763
+ }
764
+ else {
765
+ applyFirebaseGCloudTestProjectIdToFirebaseConfigEnv();
766
+ }
767
+ functionsInitialized = true;
768
+ return firebaseFunctionsTestInstance;
811
769
  }
812
770
  function rerollFirebaseAdminFunctionTestSingleton() {
813
- return setupFirebaseAdminFunctionTestSingleton(true);
771
+ return setupFirebaseAdminFunctionTestSingleton(true);
814
772
  }
815
773
  class FirebaseAdminFunctionTestContextFixture extends AbstractTestContextFixture {
816
- // MARK: FirebaseAdminTestContext (Forwarded)
817
- get app() {
818
- return this.instance.app;
819
- }
820
- get auth() {
821
- return this.instance.auth;
822
- }
823
- get firestore() {
824
- return this.instance.firestore;
825
- }
826
- get firestoreInstance() {
827
- return this.instance.firestoreInstance;
828
- }
829
- get firestoreContext() {
830
- return this.instance.firestoreContext;
831
- }
832
- get storage() {
833
- return this.instance.storage;
834
- }
835
- get storageInstance() {
836
- return this.instance.storageInstance;
837
- }
838
- get storageContext() {
839
- return this.instance.storageContext;
840
- }
841
- get fnWrapper() {
842
- return this.instance.fnWrapper;
843
- }
774
+ // MARK: FirebaseAdminTestContext (Forwarded)
775
+ get app() {
776
+ return this.instance.app;
777
+ }
778
+ get auth() {
779
+ return this.instance.auth;
780
+ }
781
+ get firestore() {
782
+ return this.instance.firestore;
783
+ }
784
+ get firestoreInstance() {
785
+ return this.instance.firestoreInstance;
786
+ }
787
+ get firestoreContext() {
788
+ return this.instance.firestoreContext;
789
+ }
790
+ get storage() {
791
+ return this.instance.storage;
792
+ }
793
+ get storageInstance() {
794
+ return this.instance.storageInstance;
795
+ }
796
+ get storageContext() {
797
+ return this.instance.storageContext;
798
+ }
799
+ get fnWrapper() {
800
+ return this.instance.fnWrapper;
801
+ }
844
802
  }
845
803
  class FirebaseAdminFunctionTestContextInstance extends FirebaseAdminTestContextInstance {
846
- constructor(instance, app) {
847
- super(app);
848
- this.instance = void 0;
849
- this._fnWrapper = cachedGetter(() => firebaseAdminCloudFunctionWrapper(this.instance));
850
- this.instance = instance;
851
- }
852
- get fnWrapper() {
853
- return this._fnWrapper();
854
- }
804
+ instance;
805
+ _fnWrapper = cachedGetter(() => firebaseAdminCloudFunctionWrapper(this.instance));
806
+ constructor(instance, app) {
807
+ super(app);
808
+ this.instance = instance;
809
+ }
810
+ get fnWrapper() {
811
+ return this._fnWrapper();
812
+ }
855
813
  }
856
814
  let DEFAULT_FIREBASE_ADMIN_FUNCTION_TEST_USE_FUNCTION_SINGLETON_CONTEXT = false;
857
815
  function setDefaultFirebaseAdminFunctionTestUseFunctionSingleton(use) {
858
- DEFAULT_FIREBASE_ADMIN_FUNCTION_TEST_USE_FUNCTION_SINGLETON_CONTEXT = use;
816
+ DEFAULT_FIREBASE_ADMIN_FUNCTION_TEST_USE_FUNCTION_SINGLETON_CONTEXT = use;
859
817
  }
860
818
  /**
861
819
  * A TestContextBuilderFunction for building firebase test context factories using firebase-admin.
@@ -863,320 +821,296 @@ function setDefaultFirebaseAdminFunctionTestUseFunctionSingleton(use) {
863
821
  * This can be used to easily build a testing context that sets up RulesTestEnvironment for tests that sets itself up and tears itself down.
864
822
  */
865
823
  const firebaseAdminFunctionTestBuilder = testContextBuilder({
866
- buildConfig: input => {
867
- const config = {
868
- ...input,
869
- useFunctionSingletonContext: input?.useFunctionSingletonContext ?? DEFAULT_FIREBASE_ADMIN_FUNCTION_TEST_USE_FUNCTION_SINGLETON_CONTEXT
870
- };
871
- return config;
872
- },
873
- buildFixture: () => new FirebaseAdminFunctionTestContextFixture(),
874
- setupInstance: async config => {
875
- if (!isAdminEnvironmentInitialized()) {
876
- throw new Error('initFirebaseAdminTestEnvironment() (in @dereekb/firebase-server package) was not called before using adminFirebaseTestBuilder().');
877
- }
878
- if (config.useFunctionSingletonContext) {
879
- if (!functionsInitialized) {
880
- throw new Error('Call setupFirebaseAdminFunctionTestSingleton() (in @dereekb/firebase-server package) if using functions in a singleton context (useFunctionSingletonContext = true/undefined).');
881
- }
882
- } else if (config.useFunctionSingletonContext === false) {
883
- firebaseFunctionsTestInstance = rerollFirebaseAdminFunctionTestSingleton();
884
- }
885
- const projectId = getGCloudTestProjectId();
886
- const storageBucket = 'b-' + projectId;
887
- const app = admin.initializeApp({
888
- projectId,
889
- storageBucket
890
- });
891
- return new FirebaseAdminFunctionTestContextInstance(firebaseFunctionsTestInstance, app);
892
- },
893
- teardownInstance: async (instance, config) => {
894
- if (config.useFunctionSingletonContext === false) {
895
- try {
896
- await instance.app.delete(); // will be called in cleanup
897
- firebaseFunctionsTestInstance.cleanup();
898
- } catch (e) {
899
- // do nothing
900
- }
901
- firebaseFunctionsTestInstance = undefined;
902
- }
903
- }
824
+ buildConfig: (input) => {
825
+ const config = {
826
+ ...input,
827
+ useFunctionSingletonContext: input?.useFunctionSingletonContext ?? DEFAULT_FIREBASE_ADMIN_FUNCTION_TEST_USE_FUNCTION_SINGLETON_CONTEXT
828
+ };
829
+ return config;
830
+ },
831
+ buildFixture: () => new FirebaseAdminFunctionTestContextFixture(),
832
+ setupInstance: async (config) => {
833
+ if (!isAdminEnvironmentInitialized()) {
834
+ throw new Error('initFirebaseAdminTestEnvironment() (in @dereekb/firebase-server package) was not called before using adminFirebaseTestBuilder().');
835
+ }
836
+ if (config.useFunctionSingletonContext) {
837
+ if (!functionsInitialized) {
838
+ throw new Error('Call setupFirebaseAdminFunctionTestSingleton() (in @dereekb/firebase-server package) if using functions in a singleton context (useFunctionSingletonContext = true/undefined).');
839
+ }
840
+ }
841
+ else if (config.useFunctionSingletonContext === false) {
842
+ firebaseFunctionsTestInstance = rerollFirebaseAdminFunctionTestSingleton();
843
+ }
844
+ const projectId = getGCloudTestProjectId();
845
+ const storageBucket = 'b-' + projectId;
846
+ const app = admin.initializeApp({ projectId, storageBucket });
847
+ return new FirebaseAdminFunctionTestContextInstance(firebaseFunctionsTestInstance, app);
848
+ },
849
+ teardownInstance: async (instance, config) => {
850
+ if (config.useFunctionSingletonContext === false) {
851
+ try {
852
+ await instance.app.delete(); // will be called in cleanup
853
+ firebaseFunctionsTestInstance.cleanup();
854
+ }
855
+ catch (e) {
856
+ // do nothing
857
+ }
858
+ firebaseFunctionsTestInstance = undefined;
859
+ }
860
+ }
904
861
  });
905
862
  const firebaseAdminFunctionTestContextFactory = firebaseAdminFunctionTestBuilder({});
906
863
 
907
864
  class FirebaseAdminNestTestContextFixture extends AbstractChildTestContextFixture {
908
- // MARK: Forwarded
909
- get nest() {
910
- return this.instance.nest;
911
- }
912
- get nestAppPromiseGetter() {
913
- return this.instance.nestAppPromiseGetter;
914
- }
915
- get(typeOrToken, options) {
916
- return this.instance.get(typeOrToken, options);
917
- }
865
+ // MARK: Forwarded
866
+ get nest() {
867
+ return this.instance.nest;
868
+ }
869
+ get nestAppPromiseGetter() {
870
+ return this.instance.nestAppPromiseGetter;
871
+ }
872
+ get(typeOrToken, options) {
873
+ return this.instance.get(typeOrToken, options);
874
+ }
918
875
  }
919
876
  class FirebaseAdminNestTestContextInstance extends AbstractFirebaseAdminTestContextInstanceChild {
920
- constructor(parent, nest) {
921
- super(parent);
922
- this.nest = void 0;
923
- this.nestAppPromiseGetter = () => Promise.resolve(this.nest);
924
- this.nest = nest;
925
- }
926
- get(typeOrToken, options) {
927
- return options ? this.nest.get(typeOrToken, options) : this.nest.get(typeOrToken);
928
- }
877
+ nest;
878
+ nestAppPromiseGetter = () => Promise.resolve(this.nest);
879
+ constructor(parent, nest) {
880
+ super(parent);
881
+ this.nest = nest;
882
+ }
883
+ get(typeOrToken, options) {
884
+ return options ? this.nest.get(typeOrToken, options) : this.nest.get(typeOrToken);
885
+ }
929
886
  }
930
887
  function firebaseAdminNestContextFixture(config, factory) {
931
- return buildTests => {
932
- factory(f => firebaseAdminNestContextWithFixture(config, f, buildTests));
933
- };
888
+ return (buildTests) => {
889
+ factory((f) => firebaseAdminNestContextWithFixture(config, f, buildTests));
890
+ };
891
+ }
892
+ class FirebaseAdminNestRootModule {
934
893
  }
935
- class FirebaseAdminNestRootModule {}
936
894
  function firebaseAdminNestContextWithFixture(config, f, buildTests) {
937
- const {
938
- nestModules,
939
- makeProviders = () => [],
940
- forceStorageBucket = false,
941
- defaultStorageBucket: inputDefaultStorageBucket,
942
- envConfig,
943
- injectFirebaseServerAppTokenProvider,
944
- injectServerEnvServiceProvider,
945
- makeFixture = parent => new FirebaseAdminNestTestContextFixture(parent),
946
- makeInstance = (instance, nest) => new FirebaseAdminNestTestContextInstance(instance, nest),
947
- initInstance
948
- } = config;
949
- useTestContextFixture({
950
- fixture: makeFixture(f),
951
- /**
952
- * Build tests by passing the fixture to the testing functions.
953
- *
954
- * This will inject all tests and sub Jest lifecycle items.
955
- */
956
- buildTests,
957
- initInstance: async () => {
958
- const imports = asArray(nestModules);
959
- const providers = makeProviders(f.instance) ?? [];
960
- const defaultStorageBucket = inputDefaultStorageBucket ?? f.instance.app.options.storageBucket;
961
- // Inject the serverEnvTokenProvider and optionally the FirebaseServerEnvService
962
- if (injectServerEnvServiceProvider !== false || envConfig != null) {
963
- providers.push(serverEnvTokenProvider(envConfig || {
964
- production: false
965
- }));
966
- if (injectServerEnvServiceProvider !== false) {
967
- providers.push({
968
- provide: FirebaseServerEnvService,
969
- useClass: DefaultFirebaseServerEnvService
970
- }, {
971
- provide: ServerEnvironmentService,
972
- useExisting: FirebaseServerEnvService
973
- });
895
+ const { nestModules, makeProviders = () => [], forceStorageBucket = false, defaultStorageBucket: inputDefaultStorageBucket, envConfig, injectFirebaseServerAppTokenProvider, injectServerEnvServiceProvider, makeFixture = (parent) => new FirebaseAdminNestTestContextFixture(parent), makeInstance = (instance, nest) => new FirebaseAdminNestTestContextInstance(instance, nest), initInstance } = config;
896
+ useTestContextFixture({
897
+ fixture: makeFixture(f),
898
+ /**
899
+ * Build tests by passing the fixture to the testing functions.
900
+ *
901
+ * This will inject all tests and sub Jest lifecycle items.
902
+ */
903
+ buildTests,
904
+ initInstance: async () => {
905
+ const imports = asArray(nestModules);
906
+ const providers = makeProviders(f.instance) ?? [];
907
+ const defaultStorageBucket = inputDefaultStorageBucket ?? f.instance.app.options.storageBucket;
908
+ // Inject the serverEnvTokenProvider and optionally the FirebaseServerEnvService
909
+ if (injectServerEnvServiceProvider !== false || envConfig != null) {
910
+ providers.push(serverEnvTokenProvider(envConfig || { production: false }));
911
+ if (injectServerEnvServiceProvider !== false) {
912
+ providers.push({
913
+ provide: FirebaseServerEnvService,
914
+ useClass: DefaultFirebaseServerEnvService
915
+ }, {
916
+ provide: ServerEnvironmentService,
917
+ useExisting: FirebaseServerEnvService
918
+ });
919
+ }
920
+ }
921
+ // Inject the firebaseServerAppTokenProvider
922
+ if (injectFirebaseServerAppTokenProvider) {
923
+ providers.push(firebaseServerAppTokenProvider(asGetter(f.instance.app)));
924
+ }
925
+ if (defaultStorageBucket) {
926
+ providers.push(firebaseServerStorageDefaultBucketIdTokenProvider({
927
+ defaultBucketId: defaultStorageBucket,
928
+ forceBucket: forceStorageBucket
929
+ }));
930
+ }
931
+ const rootModule = {
932
+ module: FirebaseAdminNestRootModule,
933
+ providers,
934
+ exports: providers,
935
+ global: true
936
+ };
937
+ const builder = Test.createTestingModule({
938
+ imports: [rootModule, ...imports]
939
+ });
940
+ const nest = await builder.compile();
941
+ const instance = makeInstance(f.instance, nest);
942
+ if (initInstance) {
943
+ await initInstance(instance);
944
+ }
945
+ return instance;
946
+ },
947
+ destroyInstance: async (instance) => {
948
+ await instance.nest.close();
974
949
  }
975
- }
976
- // Inject the firebaseServerAppTokenProvider
977
- if (injectFirebaseServerAppTokenProvider) {
978
- providers.push(firebaseServerAppTokenProvider(asGetter(f.instance.app)));
979
- }
980
- if (defaultStorageBucket) {
981
- providers.push(firebaseServerStorageDefaultBucketIdTokenProvider({
982
- defaultBucketId: defaultStorageBucket,
983
- forceBucket: forceStorageBucket
984
- }));
985
- }
986
- const rootModule = {
987
- module: FirebaseAdminNestRootModule,
988
- providers,
989
- exports: providers,
990
- global: true
991
- };
992
- const builder = Test.createTestingModule({
993
- imports: [rootModule, ...imports]
994
- });
995
- const nest = await builder.compile();
996
- const instance = makeInstance(f.instance, nest);
997
- if (initInstance) {
998
- await initInstance(instance);
999
- }
1000
- return instance;
1001
- },
1002
- destroyInstance: async instance => {
1003
- await instance.nest.close();
1004
- }
1005
- });
950
+ });
1006
951
  }
1007
952
  function firebaseAdminNestContextFactory(config) {
1008
- return firebaseAdminNestContextFixture(config, firebaseAdminTestContextFactory);
953
+ return firebaseAdminNestContextFixture(config, firebaseAdminTestContextFactory);
1009
954
  }
1010
955
 
1011
956
  function wrapCloudFunctionForNestTestsGetter(wrapper, fn) {
1012
- return wrapCloudFunctionV1ForTests(wrapper.fnWrapper, () => fn(wrapper.nestAppPromiseGetter));
957
+ return wrapCloudFunctionV1ForTests(wrapper.fnWrapper, () => fn(wrapper.nestAppPromiseGetter));
1013
958
  }
1014
959
  function wrapCallableRequestForNestTestsGetter(wrapper, fn) {
1015
- return wrapCallableRequestForTests(wrapper.fnWrapper, () => fn(wrapper.nestAppPromiseGetter));
960
+ return wrapCallableRequestForTests(wrapper.fnWrapper, () => fn(wrapper.nestAppPromiseGetter));
1016
961
  }
1017
962
  class FirebaseAdminFunctionNestTestContextFixture extends FirebaseAdminNestTestContextFixture {
1018
- // MARK: FirebaseAdminTestContext (Forwarded)
1019
- wrapCloudFunctionForNestTests(fn) {
1020
- return this.wrapCloudFunctionForNestTestsGetter(fn)();
1021
- }
1022
- wrapCloudFunctionForNestTestsGetter(fn) {
1023
- return wrapCloudFunctionForNestTestsGetter(this, fn);
1024
- }
1025
- wrapCallableRequestForNestTests(fn) {
1026
- return this.wrapCallableRequestForNestTestsGetter(fn)();
1027
- }
1028
- wrapCallableRequestForNestTestsGetter(fn) {
1029
- return wrapCallableRequestForNestTestsGetter(this, fn);
1030
- }
1031
- // MARK: FirebaseAdminCloudFunctionWrapperSource
1032
- get fnWrapper() {
1033
- return this.parent.instance.fnWrapper;
1034
- }
963
+ // MARK: FirebaseAdminTestContext (Forwarded)
964
+ wrapCloudFunctionForNestTests(fn) {
965
+ return this.wrapCloudFunctionForNestTestsGetter(fn)();
966
+ }
967
+ wrapCloudFunctionForNestTestsGetter(fn) {
968
+ return wrapCloudFunctionForNestTestsGetter(this, fn);
969
+ }
970
+ wrapCallableRequestForNestTests(fn) {
971
+ return this.wrapCallableRequestForNestTestsGetter(fn)();
972
+ }
973
+ wrapCallableRequestForNestTestsGetter(fn) {
974
+ return wrapCallableRequestForNestTestsGetter(this, fn);
975
+ }
976
+ // MARK: FirebaseAdminCloudFunctionWrapperSource
977
+ get fnWrapper() {
978
+ return this.parent.instance.fnWrapper;
979
+ }
1035
980
  }
1036
981
  class FirebaseAdminFunctionNestTestContextInstance extends FirebaseAdminNestTestContextInstance {
1037
- // MARK: FirebaseAdminTestContext (Forwarded)
1038
- get fnWrapper() {
1039
- return this.parent.fnWrapper;
1040
- }
982
+ // MARK: FirebaseAdminTestContext (Forwarded)
983
+ get fnWrapper() {
984
+ return this.parent.fnWrapper;
985
+ }
1041
986
  }
1042
987
  function firebaseAdminFunctionNestContextFixture(config, factory) {
1043
- return buildTests => {
1044
- factory(f => firebaseAdminFunctionNestContextWithFixture(config, f, buildTests));
1045
- };
988
+ return (buildTests) => {
989
+ factory((f) => firebaseAdminFunctionNestContextWithFixture(config, f, buildTests));
990
+ };
991
+ }
992
+ class FirebaseAdminFunctionNestRootModule {
1046
993
  }
1047
- class FirebaseAdminFunctionNestRootModule {}
1048
994
  function firebaseAdminFunctionNestContextWithFixture(config, f, buildTests) {
1049
- const mergedConfig = {
1050
- makeFixture: parent => new FirebaseAdminFunctionNestTestContextFixture(parent),
1051
- makeInstance: (instance, nest) => new FirebaseAdminFunctionNestTestContextInstance(instance, nest),
1052
- ...config
1053
- };
1054
- return firebaseAdminNestContextWithFixture(mergedConfig, f, buildTests);
995
+ const mergedConfig = {
996
+ makeFixture: (parent) => new FirebaseAdminFunctionNestTestContextFixture(parent),
997
+ makeInstance: (instance, nest) => new FirebaseAdminFunctionNestTestContextInstance(instance, nest),
998
+ ...config
999
+ };
1000
+ return firebaseAdminNestContextWithFixture(mergedConfig, f, buildTests);
1055
1001
  }
1056
1002
  function firebaseAdminFunctionNestContextFactory(config) {
1057
- return firebaseAdminFunctionNestContextFixture(config, firebaseAdminFunctionTestContextFactory);
1003
+ return firebaseAdminFunctionNestContextFixture(config, firebaseAdminFunctionTestContextFactory);
1058
1004
  }
1059
1005
 
1060
1006
  const CallableRequestTestMultipleFixtureSuffix = 'WrappedFn';
1061
1007
  function isCallableRequestTestSingleConfig(config) {
1062
- const isSingle = Boolean(config.fn);
1063
- return isSingle;
1008
+ const isSingle = Boolean(config.fn);
1009
+ return isSingle;
1064
1010
  }
1065
1011
  function callableRequestTest(config, buildTests) {
1066
- if (isCallableRequestTestSingleConfig(config)) {
1067
- const {
1068
- f,
1069
- fn
1070
- } = config;
1071
- useTestFunctionFixture({
1072
- fn: () => {
1073
- const x = wrapCallableRequestForNestTestsGetter(f, fn)();
1074
- return x;
1075
- }
1076
- }, buildTests);
1077
- } else {
1078
- const {
1079
- f,
1080
- fns: inputFns
1081
- } = config;
1082
- const mappedFns = mapObjectMap(inputFns, fn => () => wrapCallableRequestForNestTestsGetter(f, fn)());
1083
- const fns = {};
1084
- Object.keys(mappedFns).forEach(key => {
1085
- fns[`${key}${CallableRequestTestMultipleFixtureSuffix}`] = mappedFns[key];
1086
- });
1087
- useTestFunctionMapFixture({
1088
- fns
1089
- }, buildTests);
1090
- }
1012
+ if (isCallableRequestTestSingleConfig(config)) {
1013
+ const { f, fn } = config;
1014
+ useTestFunctionFixture({
1015
+ fn: () => {
1016
+ const x = wrapCallableRequestForNestTestsGetter(f, fn)();
1017
+ return x;
1018
+ }
1019
+ }, buildTests);
1020
+ }
1021
+ else {
1022
+ const { f, fns: inputFns } = config;
1023
+ const mappedFns = mapObjectMap(inputFns, (fn) => () => wrapCallableRequestForNestTestsGetter(f, fn)());
1024
+ const fns = {};
1025
+ Object.keys(mappedFns).forEach((key) => {
1026
+ fns[`${key}${CallableRequestTestMultipleFixtureSuffix}`] = mappedFns[key];
1027
+ });
1028
+ useTestFunctionMapFixture({
1029
+ fns
1030
+ }, buildTests);
1031
+ }
1091
1032
  }
1092
1033
  function describeCallableRequestTest(label, config, buildTests) {
1093
- describe(label, () => {
1094
- callableRequestTest(config, buildTests);
1095
- });
1034
+ describe(label, () => {
1035
+ callableRequestTest(config, buildTests);
1036
+ });
1096
1037
  }
1097
1038
 
1098
1039
  function isCloudFunctionTestSingleConfig(config) {
1099
- const isSingle = Boolean(config.fn);
1100
- return isSingle;
1040
+ const isSingle = Boolean(config.fn);
1041
+ return isSingle;
1101
1042
  }
1102
1043
  function cloudFunctionTest(config, buildTests) {
1103
- if (isCloudFunctionTestSingleConfig(config)) {
1104
- const {
1105
- f,
1106
- fn
1107
- } = config;
1108
- useTestFunctionFixture({
1109
- fn: () => {
1110
- const x = wrapCloudFunctionForNestTestsGetter(f, fn)();
1111
- return x;
1112
- }
1113
- }, buildTests);
1114
- } else {
1115
- const {
1116
- f,
1117
- fns: inputFns
1118
- } = config;
1119
- const mappedFns = mapObjectMap(inputFns, fn => () => wrapCloudFunctionForNestTestsGetter(f, fn)());
1120
- const fns = {};
1121
- Object.keys(mappedFns).forEach(key => {
1122
- fns[`${key}CloudFn`] = mappedFns[key];
1123
- });
1124
- useTestFunctionMapFixture({
1125
- fns
1126
- }, buildTests);
1127
- }
1044
+ if (isCloudFunctionTestSingleConfig(config)) {
1045
+ const { f, fn } = config;
1046
+ useTestFunctionFixture({
1047
+ fn: () => {
1048
+ const x = wrapCloudFunctionForNestTestsGetter(f, fn)();
1049
+ return x;
1050
+ }
1051
+ }, buildTests);
1052
+ }
1053
+ else {
1054
+ const { f, fns: inputFns } = config;
1055
+ const mappedFns = mapObjectMap(inputFns, (fn) => () => wrapCloudFunctionForNestTestsGetter(f, fn)());
1056
+ const fns = {};
1057
+ Object.keys(mappedFns).forEach((key) => {
1058
+ fns[`${key}CloudFn`] = mappedFns[key];
1059
+ });
1060
+ useTestFunctionMapFixture({
1061
+ fns
1062
+ }, buildTests);
1063
+ }
1128
1064
  }
1129
1065
  function describeCloudFunctionTest(label, config, buildTests) {
1130
- describe(label, () => {
1131
- cloudFunctionTest(config, buildTests);
1132
- });
1066
+ describe(label, () => {
1067
+ cloudFunctionTest(config, buildTests);
1068
+ });
1133
1069
  }
1134
1070
 
1135
1071
  function initFirebaseServerAdminTestEnvironment() {
1136
- initFirebaseAdminTestEnvironment({
1137
- emulators: {
1138
- auth: '0.0.0.0:9903',
1139
- firestore: '0.0.0.0:9904',
1140
- storage: '0.0.0.0:9906'
1141
- }
1142
- });
1072
+ initFirebaseAdminTestEnvironment({
1073
+ emulators: {
1074
+ auth: '0.0.0.0:9903',
1075
+ firestore: '0.0.0.0:9904',
1076
+ storage: '0.0.0.0:9906'
1077
+ }
1078
+ });
1143
1079
  }
1144
1080
  function describeFirestoreTest(s) {
1145
- let collection;
1146
- beforeEach(() => {
1147
- collection = mockItemFirestoreCollection(s.firestoreContext);
1148
- });
1149
- describe('firestore', () => {
1150
- it('should interact with the firestore.', async () => {
1151
- const document = collection.documentAccessor().newDocument();
1152
- const setData = {
1153
- value: 'a',
1154
- test: true
1155
- };
1156
- await document.accessor.set(setData);
1157
- const exists = await document.accessor.exists();
1158
- expect(exists).toBe(true);
1159
- const snapshot = await document.accessor.get();
1160
- const data = snapshot.data();
1161
- expect(data).toBeDefined();
1081
+ let collection;
1082
+ beforeEach(() => {
1083
+ collection = mockItemFirestoreCollection(s.firestoreContext);
1084
+ });
1085
+ describe('firestore', () => {
1086
+ it('should interact with the firestore.', async () => {
1087
+ const document = collection.documentAccessor().newDocument();
1088
+ const setData = {
1089
+ value: 'a',
1090
+ test: true
1091
+ };
1092
+ await document.accessor.set(setData);
1093
+ const exists = await document.accessor.exists();
1094
+ expect(exists).toBe(true);
1095
+ const snapshot = await document.accessor.get();
1096
+ const data = snapshot.data();
1097
+ expect(data).toBeDefined();
1098
+ });
1162
1099
  });
1163
- });
1164
1100
  }
1165
1101
 
1166
1102
  /**
1167
1103
  * Error thrown when the error type was different than the expected type.
1168
1104
  */
1169
1105
  class ExpectedHttpErrorWithSpecificServerErrorCode extends BaseError {
1170
- constructor(httpError, expectedErrorCode) {
1171
- const {
1172
- code
1173
- } = httpError.details;
1174
- super(`Expected HttpError with an error code of "${expectedErrorCode}", but recieved "${code}" instead.`);
1175
- this.httpError = void 0;
1176
- this.expectedErrorCode = void 0;
1177
- this.httpError = httpError;
1178
- this.expectedErrorCode = expectedErrorCode;
1179
- }
1106
+ httpError;
1107
+ expectedErrorCode;
1108
+ constructor(httpError, expectedErrorCode) {
1109
+ const { code } = httpError.details;
1110
+ super(`Expected HttpError with an error code of "${expectedErrorCode}", but recieved "${code}" instead.`);
1111
+ this.httpError = httpError;
1112
+ this.expectedErrorCode = expectedErrorCode;
1113
+ }
1180
1114
  }
1181
1115
  /**
1182
1116
  * Creates a ExpectFailAssertionFunction that asserts the encountered error is of the expected type using the instanceof keyword.
@@ -1188,25 +1122,25 @@ class ExpectedHttpErrorWithSpecificServerErrorCode extends BaseError {
1188
1122
  * @returns
1189
1123
  */
1190
1124
  function expectFailAssertHttpErrorServerErrorCode(expectedCode) {
1191
- return error => {
1192
- if (error instanceof HttpsError) {
1193
- const {
1194
- code
1195
- } = error.details;
1196
- if (code !== expectedCode) {
1197
- throw new ExpectedHttpErrorWithSpecificServerErrorCode(error, expectedCode);
1198
- }
1199
- } else {
1200
- throw new ExpectedErrorOfSpecificTypeError(error, HttpsError);
1201
- }
1202
- return true;
1203
- };
1125
+ return (error) => {
1126
+ if (error instanceof HttpsError) {
1127
+ const { code } = error.details;
1128
+ if (code !== expectedCode) {
1129
+ throw new ExpectedHttpErrorWithSpecificServerErrorCode(error, expectedCode);
1130
+ }
1131
+ }
1132
+ else {
1133
+ throw new ExpectedErrorOfSpecificTypeError(error, HttpsError);
1134
+ }
1135
+ return true;
1136
+ };
1204
1137
  }
1205
1138
  // MARK: Compat
1206
1139
  /**
1207
1140
  * @deprecated Use ExpectedHttpErrorWithSpecificServerErrorCode from shared instead. This is kept for backwards compatibility.
1208
1141
  */
1209
- class JestExpectedHttpErrorWithSpecificServerErrorCode extends ExpectedHttpErrorWithSpecificServerErrorCode {}
1142
+ class JestExpectedHttpErrorWithSpecificServerErrorCode extends ExpectedHttpErrorWithSpecificServerErrorCode {
1143
+ }
1210
1144
  /**
1211
1145
  * @deprecated Use expectFailAssertHttpErrorServerErrorCode from shared instead. This is kept for backwards compatibility.
1212
1146
  */
@@ -1218,8 +1152,8 @@ const jestExpectFailAssertHttpErrorServerErrorCode = expectFailAssertHttpErrorSe
1218
1152
  * Host of localhost, port 9904
1219
1153
  */
1220
1154
  const adminFirestoreFactory = googleCloudTestFirestoreBuilder({
1221
- host: 'localhost',
1222
- port: 9904
1155
+ host: 'localhost',
1156
+ port: 9904
1223
1157
  });
1224
1158
  /**
1225
1159
  * Convenience mock instance for tests within an authorized context.
@@ -1234,8 +1168,8 @@ const dbxComponentsAdminTestWithMockItemCollection = testWithMockItemCollectionF
1234
1168
  * Host of localhost, port 9906
1235
1169
  */
1236
1170
  const adminFirebaseStorageFactory = googleCloudTestFirebaseStorageBuilder({
1237
- host: '0.0.0.0',
1238
- port: 9906
1171
+ host: '0.0.0.0',
1172
+ port: 9906
1239
1173
  });
1240
1174
  /**
1241
1175
  * Convenience mock instance for tests within an authorized context.