@firebase/rules-unit-testing 1.3.15-canary.cdada6c68 → 1.3.16-2022028193537
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/CHANGELOG.md +7 -0
- package/dist/index.cjs.js +409 -573
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -4
- package/dist/src/api/index.d.ts +131 -0
- package/dist/test/{dummy.test.d.ts → database.test.d.ts} +1 -1
- package/package.json +18 -10
- package/dist/src/impl/discovery.d.ts +0 -47
- package/dist/src/impl/rules.d.ts +0 -29
- package/dist/src/impl/test_environment.d.ts +0 -43
- package/dist/src/impl/url.d.ts +0 -32
- package/dist/src/initialize.d.ts +0 -39
- package/dist/src/public_types/index.d.ts +0 -225
- package/dist/src/util.d.ts +0 -75
- package/dist/test/impl/discovery.test.d.ts +0 -17
- package/dist/test/impl/rules.test.d.ts +0 -17
- package/dist/test/setup.d.ts +0 -19
- package/dist/test/test_utils.d.ts +0 -18
- package/dist/test/util.test.d.ts +0 -17
package/dist/index.cjs.js
CHANGED
|
@@ -2,16 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
require('firebase/firestore
|
|
8
|
-
require('firebase/
|
|
9
|
-
require('
|
|
5
|
+
var firebase = require('firebase');
|
|
6
|
+
require('firebase/database');
|
|
7
|
+
require('firebase/firestore');
|
|
8
|
+
require('firebase/storage');
|
|
9
|
+
var request = require('request');
|
|
10
|
+
var logger = require('@firebase/logger');
|
|
11
|
+
var component = require('@firebase/component');
|
|
12
|
+
var util = require('@firebase/util');
|
|
10
13
|
|
|
11
14
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
function _interopNamespace(e) {
|
|
17
|
+
if (e && e.__esModule) return e;
|
|
18
|
+
var n = Object.create(null);
|
|
19
|
+
if (e) {
|
|
20
|
+
Object.keys(e).forEach(function (k) {
|
|
21
|
+
if (k !== 'default') {
|
|
22
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
23
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () {
|
|
26
|
+
return e[k];
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
n['default'] = e;
|
|
33
|
+
return Object.freeze(n);
|
|
34
|
+
}
|
|
35
|
+
|
|
14
36
|
var firebase__default = /*#__PURE__*/_interopDefaultLegacy(firebase);
|
|
37
|
+
var request__namespace = /*#__PURE__*/_interopNamespace(request);
|
|
15
38
|
|
|
16
39
|
/*! *****************************************************************************
|
|
17
40
|
Copyright (c) Microsoft Corporation.
|
|
@@ -79,7 +102,7 @@ function __generator(thisArg, body) {
|
|
|
79
102
|
|
|
80
103
|
/**
|
|
81
104
|
* @license
|
|
82
|
-
* Copyright
|
|
105
|
+
* Copyright 2018 Google LLC
|
|
83
106
|
*
|
|
84
107
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
85
108
|
* you may not use this file except in compliance with the License.
|
|
@@ -93,643 +116,461 @@ function __generator(thisArg, body) {
|
|
|
93
116
|
* See the License for the specific language governing permissions and
|
|
94
117
|
* limitations under the License.
|
|
95
118
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
119
|
+
var firestore = firebase__default['default'].firestore, database = firebase__default['default'].database; firebase__default['default'].storage;
|
|
120
|
+
/** If this environment variable is set, use it for the database emulator's address. */
|
|
121
|
+
var DATABASE_ADDRESS_ENV = 'FIREBASE_DATABASE_EMULATOR_HOST';
|
|
122
|
+
/** The default address for the local database emulator. */
|
|
123
|
+
var DATABASE_ADDRESS_DEFAULT = 'localhost:9000';
|
|
124
|
+
/** If this environment variable is set, use it for the Firestore emulator. */
|
|
125
|
+
var FIRESTORE_ADDRESS_ENV = 'FIRESTORE_EMULATOR_HOST';
|
|
126
|
+
/** The default address for the local Firestore emulator. */
|
|
127
|
+
var FIRESTORE_ADDRESS_DEFAULT = 'localhost:8080';
|
|
128
|
+
/** If this environment variable is set, use it for the Storage emulator. */
|
|
129
|
+
var FIREBASE_STORAGE_ADDRESS_ENV = 'FIREBASE_STORAGE_EMULATOR_HOST';
|
|
130
|
+
var CLOUD_STORAGE_ADDRESS_ENV = 'STORAGE_EMULATOR_HOST';
|
|
131
|
+
/** The default address for the local Firestore emulator. */
|
|
132
|
+
var STORAGE_ADDRESS_DEFAULT = 'localhost:9199';
|
|
133
|
+
/** Environment variable to locate the Emulator Hub */
|
|
134
|
+
var HUB_HOST_ENV = 'FIREBASE_EMULATOR_HUB';
|
|
135
|
+
/** The default address for the Emulator Hub */
|
|
136
|
+
var HUB_HOST_DEFAULT = 'localhost:4400';
|
|
137
|
+
/** The actual address for the database emulator */
|
|
138
|
+
var _databaseHost = undefined;
|
|
139
|
+
/** The actual address for the Firestore emulator */
|
|
140
|
+
var _firestoreHost = undefined;
|
|
141
|
+
/** The actual address for the Storage emulator */
|
|
142
|
+
var _storageHost = undefined;
|
|
143
|
+
/** The actual address for the Emulator Hub */
|
|
144
|
+
var _hubHost = undefined;
|
|
145
|
+
function trimmedBase64Encode(val) {
|
|
146
|
+
// Use base64url encoding and remove padding in the end (dot characters).
|
|
147
|
+
return util.base64Encode(val).replace(/\./g, "");
|
|
148
|
+
}
|
|
149
|
+
function createUnsecuredJwt(token, projectId) {
|
|
150
|
+
// Unsecured JWTs use "none" as the algorithm.
|
|
151
|
+
var header = {
|
|
152
|
+
alg: 'none',
|
|
153
|
+
kid: 'fakekid',
|
|
154
|
+
type: 'JWT'
|
|
155
|
+
};
|
|
156
|
+
var project = projectId || 'fake-project';
|
|
157
|
+
var iat = token.iat || 0;
|
|
158
|
+
var uid = token.sub || token.uid || token.user_id;
|
|
159
|
+
if (!uid) {
|
|
160
|
+
throw new Error("Auth must contain 'sub', 'uid', or 'user_id' field!");
|
|
109
161
|
}
|
|
110
|
-
|
|
111
|
-
|
|
162
|
+
var payload = __assign({
|
|
163
|
+
// Set all required fields to decent defaults
|
|
164
|
+
iss: "https://securetoken.google.com/" + project, aud: project, iat: iat, exp: iat + 3600, auth_time: iat, sub: uid, user_id: uid, firebase: {
|
|
165
|
+
sign_in_provider: 'custom',
|
|
166
|
+
identities: {}
|
|
167
|
+
} }, token);
|
|
168
|
+
// Remove the uid option since it's not actually part of the token spec.
|
|
169
|
+
if (payload.uid) {
|
|
170
|
+
delete payload.uid;
|
|
112
171
|
}
|
|
113
|
-
|
|
172
|
+
// Unsecured JWTs use the empty string as a signature.
|
|
173
|
+
var signature = '';
|
|
174
|
+
return [
|
|
175
|
+
trimmedBase64Encode(JSON.stringify(header)),
|
|
176
|
+
trimmedBase64Encode(JSON.stringify(payload)),
|
|
177
|
+
signature
|
|
178
|
+
].join('.');
|
|
114
179
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
*/
|
|
119
|
-
function
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
180
|
+
function apps() {
|
|
181
|
+
return firebase__default['default'].apps;
|
|
182
|
+
}
|
|
183
|
+
/** Construct an App authenticated with options.auth. */
|
|
184
|
+
function initializeTestApp(options) {
|
|
185
|
+
var jwt = options.auth
|
|
186
|
+
? createUnsecuredJwt(options.auth, options.projectId)
|
|
187
|
+
: undefined;
|
|
188
|
+
return initializeApp(jwt, options.databaseName, options.projectId, options.storageBucket);
|
|
189
|
+
}
|
|
190
|
+
/** Construct an App authenticated as an admin user. */
|
|
191
|
+
function initializeAdminApp(options) {
|
|
192
|
+
var admin = require('firebase-admin');
|
|
193
|
+
var app = admin.initializeApp(getAppOptions(options.databaseName, options.projectId, options.storageBucket), getRandomAppName());
|
|
194
|
+
if (options.projectId) {
|
|
195
|
+
app.firestore().settings({
|
|
196
|
+
host: getFirestoreHost(),
|
|
197
|
+
ssl: false
|
|
198
|
+
});
|
|
128
199
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return url;
|
|
132
|
-
}
|
|
133
|
-
|
|
200
|
+
return app;
|
|
201
|
+
}
|
|
134
202
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
139
|
-
* you may not use this file except in compliance with the License.
|
|
140
|
-
* You may obtain a copy of the License at
|
|
141
|
-
*
|
|
142
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
203
|
+
* Set the host and port configuration for applicable emulators. This will override any values
|
|
204
|
+
* found in environment variables. Must be called before initializeAdminApp or initializeTestApp.
|
|
143
205
|
*
|
|
144
|
-
*
|
|
145
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
146
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
147
|
-
* See the License for the specific language governing permissions and
|
|
148
|
-
* limitations under the License.
|
|
206
|
+
* @param options options object.
|
|
149
207
|
*/
|
|
208
|
+
function useEmulators(options) {
|
|
209
|
+
if (!(options.database || options.firestore || options.storage || options.hub)) {
|
|
210
|
+
throw new Error("Argument to useEmulators must contain at least one of 'database', 'firestore', 'storage', or 'hub'.");
|
|
211
|
+
}
|
|
212
|
+
if (options.database) {
|
|
213
|
+
_databaseHost = getAddress(options.database.host, options.database.port);
|
|
214
|
+
}
|
|
215
|
+
if (options.firestore) {
|
|
216
|
+
_firestoreHost = getAddress(options.firestore.host, options.firestore.port);
|
|
217
|
+
}
|
|
218
|
+
if (options.storage) {
|
|
219
|
+
_storageHost = getAddress(options.storage.host, options.storage.port);
|
|
220
|
+
}
|
|
221
|
+
if (options.hub) {
|
|
222
|
+
_hubHost = getAddress(options.hub.host, options.hub.port);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
150
225
|
/**
|
|
151
|
-
* Use the Firebase Emulator hub to discover other running emulators.
|
|
226
|
+
* Use the Firebase Emulator hub to discover other running emulators. Call useEmulators() with
|
|
227
|
+
* the result to configure the library to use the discovered emulators.
|
|
152
228
|
*
|
|
153
|
-
* @param
|
|
154
|
-
* @
|
|
229
|
+
* @param hubHost the host where the Emulator Hub is running (ex: 'localhost')
|
|
230
|
+
* @param hubPort the port where the Emulator Hub is running (ex: 4400)
|
|
155
231
|
*/
|
|
156
|
-
function discoverEmulators(
|
|
157
|
-
if (fetch === void 0) { fetch = fetch__default['default']; }
|
|
232
|
+
function discoverEmulators(hubHost, hubPort) {
|
|
158
233
|
return __awaiter(this, void 0, void 0, function () {
|
|
159
|
-
var res,
|
|
234
|
+
var hubAddress, res, options, data;
|
|
160
235
|
return __generator(this, function (_a) {
|
|
161
236
|
switch (_a.label) {
|
|
162
|
-
case 0:
|
|
237
|
+
case 0:
|
|
238
|
+
if ((hubHost && !hubPort) || (!hubHost && hubPort)) {
|
|
239
|
+
throw new Error("Invalid configuration hubHost=" + hubHost + " and hubPort=" + hubPort + ". If either parameter is supplied, both must be defined.");
|
|
240
|
+
}
|
|
241
|
+
hubAddress = hubHost && hubPort ? getAddress(hubHost, hubPort) : getHubHost();
|
|
242
|
+
return [4 /*yield*/, requestPromise(request__namespace.get, {
|
|
243
|
+
method: 'GET',
|
|
244
|
+
uri: "http://" + hubAddress + "/emulators"
|
|
245
|
+
})];
|
|
163
246
|
case 1:
|
|
164
247
|
res = _a.sent();
|
|
165
|
-
if (
|
|
166
|
-
throw new Error("HTTP Error " + res.
|
|
248
|
+
if (res.statusCode !== 200) {
|
|
249
|
+
throw new Error("HTTP Error " + res.statusCode + " when attempting to reach Emulator Hub at " + hubAddress + ", are you sure it is running?");
|
|
167
250
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
case 2:
|
|
171
|
-
data = _a.sent();
|
|
251
|
+
options = {};
|
|
252
|
+
data = JSON.parse(res.body);
|
|
172
253
|
if (data.database) {
|
|
173
|
-
|
|
254
|
+
options.database = {
|
|
174
255
|
host: data.database.host,
|
|
175
256
|
port: data.database.port
|
|
176
257
|
};
|
|
177
258
|
}
|
|
178
259
|
if (data.firestore) {
|
|
179
|
-
|
|
260
|
+
options.firestore = {
|
|
180
261
|
host: data.firestore.host,
|
|
181
262
|
port: data.firestore.port
|
|
182
263
|
};
|
|
183
264
|
}
|
|
184
265
|
if (data.storage) {
|
|
185
|
-
|
|
266
|
+
options.storage = {
|
|
186
267
|
host: data.storage.host,
|
|
187
268
|
port: data.storage.port
|
|
188
269
|
};
|
|
189
270
|
}
|
|
190
271
|
if (data.hub) {
|
|
191
|
-
|
|
272
|
+
options.hub = {
|
|
192
273
|
host: data.hub.host,
|
|
193
274
|
port: data.hub.port
|
|
194
275
|
};
|
|
195
276
|
}
|
|
196
|
-
return [2 /*return*/,
|
|
277
|
+
return [2 /*return*/, options];
|
|
197
278
|
}
|
|
198
279
|
});
|
|
199
280
|
});
|
|
200
281
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
function getEmulatorHostAndPort(emulator, conf, discovered) {
|
|
205
|
-
var _a, _b;
|
|
206
|
-
if (conf && ('host' in conf || 'port' in conf)) {
|
|
207
|
-
var host = conf.host, port = conf.port;
|
|
208
|
-
if (host || port) {
|
|
209
|
-
if (!host || !port) {
|
|
210
|
-
throw new Error("Invalid configuration " + emulator + ".host=" + host + " and " + emulator + ".port=" + port + ". " +
|
|
211
|
-
'If either parameter is supplied, both must be defined.');
|
|
212
|
-
}
|
|
213
|
-
if (discovered && !discovered[emulator]) {
|
|
214
|
-
console.warn("Warning: config for the " + emulator + " emulator is specified, but the Emulator hub " +
|
|
215
|
-
'reports it as not running. This may lead to errors such as connection refused.');
|
|
216
|
-
}
|
|
217
|
-
return {
|
|
218
|
-
host: fixHostname(conf.host, (_a = discovered === null || discovered === void 0 ? void 0 : discovered.hub) === null || _a === void 0 ? void 0 : _a.host),
|
|
219
|
-
port: conf.port
|
|
220
|
-
};
|
|
221
|
-
}
|
|
282
|
+
function getAddress(host, port) {
|
|
283
|
+
if (host.includes('::')) {
|
|
284
|
+
return "[" + host + "]:" + port;
|
|
222
285
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (fallback) {
|
|
226
|
-
if (discovered && !discovered[emulator]) {
|
|
227
|
-
console.warn("Warning: the environment variable " + envVar + " is set, but the Emulator hub reports the " +
|
|
228
|
-
(emulator + " emulator as not running. This may lead to errors such as connection refused."));
|
|
229
|
-
}
|
|
230
|
-
return {
|
|
231
|
-
host: fixHostname(fallback.host, (_b = discovered === null || discovered === void 0 ? void 0 : discovered.hub) === null || _b === void 0 ? void 0 : _b.host),
|
|
232
|
-
port: fallback.port
|
|
233
|
-
};
|
|
286
|
+
else {
|
|
287
|
+
return host + ":" + port;
|
|
234
288
|
}
|
|
235
289
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
if (!hostAndPort) {
|
|
246
|
-
return undefined;
|
|
247
|
-
}
|
|
248
|
-
var parsed;
|
|
249
|
-
try {
|
|
250
|
-
parsed = new URL("http://" + hostAndPort);
|
|
251
|
-
}
|
|
252
|
-
catch (_a) {
|
|
253
|
-
throw new Error("Invalid format in environment variable " + envVar + "=" + hostAndPort + " (expected host:port)");
|
|
254
|
-
}
|
|
255
|
-
var host = parsed.hostname;
|
|
256
|
-
var port = Number(parsed.port || '80');
|
|
257
|
-
if (!Number.isInteger(port)) {
|
|
258
|
-
throw new Error("Invalid port in environment variable " + envVar + "=" + hostAndPort);
|
|
259
|
-
}
|
|
260
|
-
return { host: host, port: port };
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
/**
|
|
264
|
-
* @license
|
|
265
|
-
* Copyright 2021 Google LLC
|
|
266
|
-
*
|
|
267
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
268
|
-
* you may not use this file except in compliance with the License.
|
|
269
|
-
* You may obtain a copy of the License at
|
|
270
|
-
*
|
|
271
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
272
|
-
*
|
|
273
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
274
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
275
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
276
|
-
* See the License for the specific language governing permissions and
|
|
277
|
-
* limitations under the License.
|
|
278
|
-
*/
|
|
279
|
-
/**
|
|
280
|
-
* An implementation of {@code RulesTestEnvironment}. This is private to hide the constructor,
|
|
281
|
-
* which should never be directly called by the developer.
|
|
282
|
-
* @private
|
|
283
|
-
*/
|
|
284
|
-
var RulesTestEnvironmentImpl = /** @class */ (function () {
|
|
285
|
-
function RulesTestEnvironmentImpl(projectId, emulators) {
|
|
286
|
-
this.projectId = projectId;
|
|
287
|
-
this.emulators = emulators;
|
|
288
|
-
this.contexts = new Set();
|
|
289
|
-
this.destroyed = false;
|
|
290
|
-
}
|
|
291
|
-
RulesTestEnvironmentImpl.prototype.authenticatedContext = function (user_id, tokenOptions) {
|
|
292
|
-
this.checkNotDestroyed();
|
|
293
|
-
return this.createContext(__assign(__assign({}, tokenOptions), { sub: user_id, user_id: user_id }));
|
|
294
|
-
};
|
|
295
|
-
RulesTestEnvironmentImpl.prototype.unauthenticatedContext = function () {
|
|
296
|
-
this.checkNotDestroyed();
|
|
297
|
-
return this.createContext(/* authToken = */ undefined);
|
|
298
|
-
};
|
|
299
|
-
RulesTestEnvironmentImpl.prototype.withSecurityRulesDisabled = function (callback) {
|
|
300
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
301
|
-
var context;
|
|
302
|
-
return __generator(this, function (_a) {
|
|
303
|
-
switch (_a.label) {
|
|
304
|
-
case 0:
|
|
305
|
-
this.checkNotDestroyed();
|
|
306
|
-
context = this.createContext('owner');
|
|
307
|
-
_a.label = 1;
|
|
308
|
-
case 1:
|
|
309
|
-
_a.trys.push([1, , 3, 4]);
|
|
310
|
-
return [4 /*yield*/, callback(context)];
|
|
311
|
-
case 2:
|
|
312
|
-
_a.sent();
|
|
313
|
-
return [3 /*break*/, 4];
|
|
314
|
-
case 3:
|
|
315
|
-
// We eagarly clean up this context to actively prevent misuse outside of the callback, e.g.
|
|
316
|
-
// storing the context in a variable.
|
|
317
|
-
context.cleanup();
|
|
318
|
-
this.contexts.delete(context);
|
|
319
|
-
return [7 /*endfinally*/];
|
|
320
|
-
case 4: return [2 /*return*/];
|
|
321
|
-
}
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
};
|
|
325
|
-
RulesTestEnvironmentImpl.prototype.createContext = function (authToken) {
|
|
326
|
-
var context = new RulesTestContextImpl(this.projectId, this.emulators, authToken);
|
|
327
|
-
this.contexts.add(context);
|
|
328
|
-
return context;
|
|
329
|
-
};
|
|
330
|
-
RulesTestEnvironmentImpl.prototype.clearDatabase = function () {
|
|
331
|
-
this.checkNotDestroyed();
|
|
332
|
-
return this.withSecurityRulesDisabled(function (context) {
|
|
333
|
-
return context.database().ref('/').set(null);
|
|
334
|
-
});
|
|
335
|
-
};
|
|
336
|
-
RulesTestEnvironmentImpl.prototype.clearFirestore = function () {
|
|
337
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
338
|
-
var resp, _a;
|
|
339
|
-
return __generator(this, function (_b) {
|
|
340
|
-
switch (_b.label) {
|
|
341
|
-
case 0:
|
|
342
|
-
this.checkNotDestroyed();
|
|
343
|
-
assertEmulatorRunning(this.emulators, 'firestore');
|
|
344
|
-
return [4 /*yield*/, fetch__default['default'](makeUrl(this.emulators.firestore, "/emulator/v1/projects/" + this.projectId + "/databases/(default)/documents"), {
|
|
345
|
-
method: 'DELETE'
|
|
346
|
-
})];
|
|
347
|
-
case 1:
|
|
348
|
-
resp = _b.sent();
|
|
349
|
-
if (!!resp.ok) return [3 /*break*/, 3];
|
|
350
|
-
_a = Error.bind;
|
|
351
|
-
return [4 /*yield*/, resp.text()];
|
|
352
|
-
case 2: throw new (_a.apply(Error, [void 0, _b.sent()]))();
|
|
353
|
-
case 3: return [2 /*return*/];
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
};
|
|
358
|
-
RulesTestEnvironmentImpl.prototype.clearStorage = function () {
|
|
359
|
-
var _this = this;
|
|
360
|
-
this.checkNotDestroyed();
|
|
361
|
-
return this.withSecurityRulesDisabled(function (context) { return __awaiter(_this, void 0, void 0, function () {
|
|
362
|
-
var items;
|
|
363
|
-
return __generator(this, function (_a) {
|
|
364
|
-
switch (_a.label) {
|
|
365
|
-
case 0: return [4 /*yield*/, context.storage().ref().listAll()];
|
|
366
|
-
case 1:
|
|
367
|
-
items = (_a.sent()).items;
|
|
368
|
-
return [4 /*yield*/, Promise.all(items.map(function (item) {
|
|
369
|
-
return item.delete();
|
|
370
|
-
}))];
|
|
371
|
-
case 2:
|
|
372
|
-
_a.sent();
|
|
373
|
-
return [2 /*return*/];
|
|
374
|
-
}
|
|
375
|
-
});
|
|
376
|
-
}); });
|
|
377
|
-
};
|
|
378
|
-
RulesTestEnvironmentImpl.prototype.cleanup = function () {
|
|
379
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
380
|
-
return __generator(this, function (_a) {
|
|
381
|
-
this.destroyed = true;
|
|
382
|
-
this.contexts.forEach(function (context) {
|
|
383
|
-
context.envDestroyed = true;
|
|
384
|
-
context.cleanup();
|
|
385
|
-
});
|
|
386
|
-
this.contexts.clear();
|
|
387
|
-
return [2 /*return*/];
|
|
388
|
-
});
|
|
389
|
-
});
|
|
390
|
-
};
|
|
391
|
-
RulesTestEnvironmentImpl.prototype.checkNotDestroyed = function () {
|
|
392
|
-
if (this.destroyed) {
|
|
393
|
-
throw new Error('This RulesTestEnvironment has already been cleaned up. ' +
|
|
394
|
-
'(This may indicate a leak or missing `await` in your test cases. If you do intend to ' +
|
|
395
|
-
'perform more tests, please call cleanup() later or create another RulesTestEnvironment.)');
|
|
290
|
+
function getDatabaseHost() {
|
|
291
|
+
if (!_databaseHost) {
|
|
292
|
+
var fromEnv = process.env[DATABASE_ADDRESS_ENV];
|
|
293
|
+
if (fromEnv) {
|
|
294
|
+
_databaseHost = fromEnv;
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
console.warn("Warning: " + DATABASE_ADDRESS_ENV + " not set, using default value " + DATABASE_ADDRESS_DEFAULT);
|
|
298
|
+
_databaseHost = DATABASE_ADDRESS_DEFAULT;
|
|
396
299
|
}
|
|
397
|
-
};
|
|
398
|
-
return RulesTestEnvironmentImpl;
|
|
399
|
-
}());
|
|
400
|
-
/**
|
|
401
|
-
* An implementation of {@code RulesTestContext}. This is private to hide the constructor,
|
|
402
|
-
* which should never be directly called by the developer.
|
|
403
|
-
* @private
|
|
404
|
-
*/
|
|
405
|
-
var RulesTestContextImpl = /** @class */ (function () {
|
|
406
|
-
function RulesTestContextImpl(projectId, emulators, authToken) {
|
|
407
|
-
this.projectId = projectId;
|
|
408
|
-
this.emulators = emulators;
|
|
409
|
-
this.authToken = authToken;
|
|
410
|
-
this.destroyed = false;
|
|
411
|
-
this.envDestroyed = false;
|
|
412
300
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
assertEmulatorRunning(this.emulators, 'firestore');
|
|
421
|
-
var firestore = this.getApp().firestore();
|
|
422
|
-
if (settings) {
|
|
423
|
-
firestore.settings(settings);
|
|
301
|
+
return _databaseHost;
|
|
302
|
+
}
|
|
303
|
+
function getFirestoreHost() {
|
|
304
|
+
if (!_firestoreHost) {
|
|
305
|
+
var fromEnv = process.env[FIRESTORE_ADDRESS_ENV];
|
|
306
|
+
if (fromEnv) {
|
|
307
|
+
_firestoreHost = fromEnv;
|
|
424
308
|
}
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
RulesTestContextImpl.prototype.database = function (databaseURL) {
|
|
429
|
-
assertEmulatorRunning(this.emulators, 'database');
|
|
430
|
-
var database = this.getApp().database(databaseURL);
|
|
431
|
-
database.useEmulator(this.emulators.database.host, this.emulators.database.port, { mockUserToken: this.authToken });
|
|
432
|
-
return database;
|
|
433
|
-
};
|
|
434
|
-
RulesTestContextImpl.prototype.storage = function (bucketUrl) {
|
|
435
|
-
if (bucketUrl === void 0) { bucketUrl = "gs://" + this.projectId; }
|
|
436
|
-
assertEmulatorRunning(this.emulators, 'storage');
|
|
437
|
-
var storage = this.getApp().storage(bucketUrl);
|
|
438
|
-
storage.useEmulator(this.emulators.storage.host, this.emulators.storage.port, { mockUserToken: this.authToken });
|
|
439
|
-
return storage;
|
|
440
|
-
};
|
|
441
|
-
RulesTestContextImpl.prototype.getApp = function () {
|
|
442
|
-
if (this.envDestroyed) {
|
|
443
|
-
throw new Error('This RulesTestContext is no longer valid because its RulesTestEnvironment has been ' +
|
|
444
|
-
'cleaned up. (This may indicate a leak or missing `await` in your test cases.)');
|
|
309
|
+
else {
|
|
310
|
+
console.warn("Warning: " + FIRESTORE_ADDRESS_ENV + " not set, using default value " + FIRESTORE_ADDRESS_DEFAULT);
|
|
311
|
+
_firestoreHost = FIRESTORE_ADDRESS_DEFAULT;
|
|
445
312
|
}
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
313
|
+
}
|
|
314
|
+
return _firestoreHost;
|
|
315
|
+
}
|
|
316
|
+
function getStorageHost() {
|
|
317
|
+
if (!_storageHost) {
|
|
318
|
+
var fromEnv = process.env[FIREBASE_STORAGE_ADDRESS_ENV] ||
|
|
319
|
+
process.env[CLOUD_STORAGE_ADDRESS_ENV];
|
|
320
|
+
if (fromEnv) {
|
|
321
|
+
// The STORAGE_EMULATOR_HOST env var is an older Cloud Standard which includes http:// while
|
|
322
|
+
// the FIREBASE_STORAGE_EMULATOR_HOST is a newer variable supported beginning in the Admin
|
|
323
|
+
// SDK v9.7.0 which does not have the protocol.
|
|
324
|
+
_storageHost = fromEnv.replace('http://', '');
|
|
450
325
|
}
|
|
451
|
-
|
|
452
|
-
|
|
326
|
+
else {
|
|
327
|
+
console.warn("Warning: " + FIREBASE_STORAGE_ADDRESS_ENV + " not set, using default value " + STORAGE_ADDRESS_DEFAULT);
|
|
328
|
+
_storageHost = STORAGE_ADDRESS_DEFAULT;
|
|
453
329
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
if (
|
|
461
|
-
|
|
462
|
-
'connecting anyway, please specify its host and port in initializeTestEnvironment({...}).');
|
|
330
|
+
}
|
|
331
|
+
return _storageHost;
|
|
332
|
+
}
|
|
333
|
+
function getHubHost() {
|
|
334
|
+
if (!_hubHost) {
|
|
335
|
+
var fromEnv = process.env[HUB_HOST_ENV];
|
|
336
|
+
if (fromEnv) {
|
|
337
|
+
_hubHost = fromEnv;
|
|
463
338
|
}
|
|
464
339
|
else {
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
("discovery, or specify manually via initializeTestEnvironment({" + emulator + ": {host, port}})."));
|
|
340
|
+
console.warn("Warning: " + HUB_HOST_ENV + " not set, using default value " + HUB_HOST_DEFAULT);
|
|
341
|
+
_hubHost = HUB_HOST_DEFAULT;
|
|
468
342
|
}
|
|
469
343
|
}
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
344
|
+
return _hubHost;
|
|
345
|
+
}
|
|
346
|
+
function parseHost(host) {
|
|
347
|
+
var withProtocol = host.startsWith('http') ? host : "http://" + host;
|
|
348
|
+
var u = new URL(withProtocol);
|
|
349
|
+
return {
|
|
350
|
+
hostname: u.hostname,
|
|
351
|
+
port: Number.parseInt(u.port, 10)
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function getRandomAppName() {
|
|
355
|
+
return 'app-' + new Date().getTime() + '-' + Math.random();
|
|
356
|
+
}
|
|
357
|
+
function getDatabaseUrl(databaseName) {
|
|
358
|
+
return "http://" + getDatabaseHost() + "?ns=" + databaseName;
|
|
359
|
+
}
|
|
360
|
+
function getAppOptions(databaseName, projectId, storageBucket) {
|
|
361
|
+
var appOptions = {};
|
|
362
|
+
if (databaseName) {
|
|
363
|
+
appOptions['databaseURL'] = getDatabaseUrl(databaseName);
|
|
364
|
+
}
|
|
365
|
+
if (projectId) {
|
|
366
|
+
appOptions['projectId'] = projectId;
|
|
367
|
+
}
|
|
368
|
+
if (storageBucket) {
|
|
369
|
+
appOptions['storageBucket'] = storageBucket;
|
|
370
|
+
}
|
|
371
|
+
return appOptions;
|
|
372
|
+
}
|
|
373
|
+
function initializeApp(accessToken, databaseName, projectId, storageBucket) {
|
|
374
|
+
var _this = this;
|
|
375
|
+
var appOptions = getAppOptions(databaseName, projectId, storageBucket);
|
|
376
|
+
var app = firebase__default['default'].initializeApp(appOptions, getRandomAppName());
|
|
377
|
+
if (accessToken) {
|
|
378
|
+
var mockAuthComponent = new component.Component('auth-internal', function () {
|
|
379
|
+
return ({
|
|
380
|
+
getToken: function () { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
|
|
381
|
+
return [2 /*return*/, ({ accessToken: accessToken })];
|
|
382
|
+
}); }); },
|
|
383
|
+
getUid: function () { return null; },
|
|
384
|
+
addAuthTokenListener: function (listener) {
|
|
385
|
+
// Call listener once immediately with predefined accessToken.
|
|
386
|
+
listener(accessToken);
|
|
387
|
+
},
|
|
388
|
+
removeAuthTokenListener: function () { }
|
|
389
|
+
});
|
|
390
|
+
}, "PRIVATE" /* PRIVATE */);
|
|
391
|
+
app._addOrOverwriteComponent(mockAuthComponent);
|
|
392
|
+
}
|
|
393
|
+
if (databaseName) {
|
|
394
|
+
var _a = parseHost(getDatabaseHost()), hostname = _a.hostname, port = _a.port;
|
|
395
|
+
app.database().useEmulator(hostname, port);
|
|
396
|
+
// Toggle network connectivity to force a reauthentication attempt.
|
|
397
|
+
// This mitigates a minor race condition where the client can send the
|
|
398
|
+
// first database request before authenticating.
|
|
399
|
+
app.database().goOffline();
|
|
400
|
+
app.database().goOnline();
|
|
401
|
+
}
|
|
402
|
+
if (projectId) {
|
|
403
|
+
var _b = parseHost(getFirestoreHost()), hostname = _b.hostname, port = _b.port;
|
|
404
|
+
app.firestore().useEmulator(hostname, port);
|
|
405
|
+
}
|
|
406
|
+
if (storageBucket) {
|
|
407
|
+
var _c = parseHost(getStorageHost()), hostname = _c.hostname, port = _c.port;
|
|
408
|
+
app.storage().useEmulator(hostname, port);
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
Mute warnings for the previously-created database and whatever other
|
|
412
|
+
objects were just created.
|
|
413
|
+
*/
|
|
414
|
+
logger.setLogLevel(logger.LogLevel.ERROR);
|
|
415
|
+
return app;
|
|
416
|
+
}
|
|
417
|
+
function loadDatabaseRules(options) {
|
|
492
418
|
return __awaiter(this, void 0, void 0, function () {
|
|
493
|
-
var
|
|
494
|
-
return __generator(this, function (
|
|
495
|
-
switch (
|
|
419
|
+
var resp;
|
|
420
|
+
return __generator(this, function (_a) {
|
|
421
|
+
switch (_a.label) {
|
|
496
422
|
case 0:
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
423
|
+
if (!options.databaseName) {
|
|
424
|
+
throw Error('databaseName not specified');
|
|
425
|
+
}
|
|
426
|
+
if (!options.rules) {
|
|
427
|
+
throw Error('must provide rules to loadDatabaseRules');
|
|
428
|
+
}
|
|
429
|
+
return [4 /*yield*/, requestPromise(request__namespace.put, {
|
|
500
430
|
method: 'PUT',
|
|
431
|
+
uri: "http://" + getDatabaseHost() + "/.settings/rules.json?ns=" + options.databaseName,
|
|
501
432
|
headers: { Authorization: 'Bearer owner' },
|
|
502
|
-
body: rules
|
|
433
|
+
body: options.rules
|
|
503
434
|
})];
|
|
504
435
|
case 1:
|
|
505
|
-
resp =
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
case 3: return [2 /*return*/];
|
|
436
|
+
resp = _a.sent();
|
|
437
|
+
if (resp.statusCode !== 200) {
|
|
438
|
+
throw new Error(JSON.parse(resp.body.error));
|
|
439
|
+
}
|
|
440
|
+
return [2 /*return*/];
|
|
511
441
|
}
|
|
512
442
|
});
|
|
513
443
|
});
|
|
514
444
|
}
|
|
515
|
-
|
|
516
|
-
* @private
|
|
517
|
-
*/
|
|
518
|
-
function loadFirestoreRules(hostAndPort, projectId, rules) {
|
|
445
|
+
function loadFirestoreRules(options) {
|
|
519
446
|
return __awaiter(this, void 0, void 0, function () {
|
|
520
|
-
var resp
|
|
521
|
-
return __generator(this, function (
|
|
522
|
-
switch (
|
|
523
|
-
case 0:
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
447
|
+
var resp;
|
|
448
|
+
return __generator(this, function (_a) {
|
|
449
|
+
switch (_a.label) {
|
|
450
|
+
case 0:
|
|
451
|
+
if (!options.projectId) {
|
|
452
|
+
throw new Error('projectId not specified');
|
|
453
|
+
}
|
|
454
|
+
if (!options.rules) {
|
|
455
|
+
throw new Error('must provide rules to loadFirestoreRules');
|
|
456
|
+
}
|
|
457
|
+
return [4 /*yield*/, requestPromise(request__namespace.put, {
|
|
458
|
+
method: 'PUT',
|
|
459
|
+
uri: "http://" + getFirestoreHost() + "/emulator/v1/projects/" + options.projectId + ":securityRules",
|
|
460
|
+
body: JSON.stringify({
|
|
461
|
+
rules: {
|
|
462
|
+
files: [{ content: options.rules }]
|
|
463
|
+
}
|
|
464
|
+
})
|
|
465
|
+
})];
|
|
531
466
|
case 1:
|
|
532
|
-
resp =
|
|
533
|
-
if (
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
case 3: return [2 /*return*/];
|
|
467
|
+
resp = _a.sent();
|
|
468
|
+
if (resp.statusCode !== 200) {
|
|
469
|
+
throw new Error(JSON.parse(resp.body.error));
|
|
470
|
+
}
|
|
471
|
+
return [2 /*return*/];
|
|
538
472
|
}
|
|
539
473
|
});
|
|
540
474
|
});
|
|
541
475
|
}
|
|
542
|
-
|
|
543
|
-
* @private
|
|
544
|
-
*/
|
|
545
|
-
function loadStorageRules(hostAndPort, rules) {
|
|
476
|
+
function loadStorageRules(options) {
|
|
546
477
|
return __awaiter(this, void 0, void 0, function () {
|
|
547
|
-
var resp
|
|
548
|
-
return __generator(this, function (
|
|
549
|
-
switch (
|
|
550
|
-
case 0:
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
478
|
+
var resp;
|
|
479
|
+
return __generator(this, function (_a) {
|
|
480
|
+
switch (_a.label) {
|
|
481
|
+
case 0:
|
|
482
|
+
if (!options.rules) {
|
|
483
|
+
throw new Error('must provide rules to loadStorageRules');
|
|
484
|
+
}
|
|
485
|
+
return [4 /*yield*/, requestPromise(request__namespace.put, {
|
|
486
|
+
method: 'PUT',
|
|
487
|
+
uri: "http://" + getStorageHost() + "/internal/setRules",
|
|
488
|
+
headers: {
|
|
489
|
+
'Content-Type': 'application/json'
|
|
490
|
+
},
|
|
491
|
+
body: JSON.stringify({
|
|
492
|
+
rules: {
|
|
493
|
+
files: [{ name: 'storage.rules', content: options.rules }]
|
|
494
|
+
}
|
|
495
|
+
})
|
|
496
|
+
})];
|
|
561
497
|
case 1:
|
|
562
|
-
resp =
|
|
563
|
-
if (
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
case 3: return [2 /*return*/];
|
|
498
|
+
resp = _a.sent();
|
|
499
|
+
if (resp.statusCode !== 200) {
|
|
500
|
+
throw new Error(resp.body);
|
|
501
|
+
}
|
|
502
|
+
return [2 /*return*/];
|
|
568
503
|
}
|
|
569
504
|
});
|
|
570
505
|
});
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
/**
|
|
574
|
-
* @license
|
|
575
|
-
* Copyright 2021 Google LLC
|
|
576
|
-
*
|
|
577
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
578
|
-
* you may not use this file except in compliance with the License.
|
|
579
|
-
* You may obtain a copy of the License at
|
|
580
|
-
*
|
|
581
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
582
|
-
*
|
|
583
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
584
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
585
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
586
|
-
* See the License for the specific language governing permissions and
|
|
587
|
-
* limitations under the License.
|
|
588
|
-
*/
|
|
589
|
-
/**
|
|
590
|
-
* Initializes a test environment for rules unit testing. Call this function first for test setup.
|
|
591
|
-
*
|
|
592
|
-
* Requires emulators to be running. This function tries to discover those emulators via environment
|
|
593
|
-
* variables or through the Firebase Emulator hub if hosts and ports are unspecified. It is strongly
|
|
594
|
-
* recommended to specify security rules for emulators used for testing. See minimal example below.
|
|
595
|
-
*
|
|
596
|
-
* @param config the configuration for emulators. most fields are optional if they can be discovered
|
|
597
|
-
* @returns a promise that resolves with an environment ready for testing, or rejects on error.
|
|
598
|
-
* @public
|
|
599
|
-
* @example
|
|
600
|
-
* ```javascript
|
|
601
|
-
* const testEnv = await initializeTestEnvironment({
|
|
602
|
-
* firestore: {
|
|
603
|
-
* rules: fs.readFileSync("/path/to/firestore.rules", "utf8"), // Load rules from file
|
|
604
|
-
* // host and port can be omitted if they can be discovered from the hub.
|
|
605
|
-
* },
|
|
606
|
-
* // ...
|
|
607
|
-
* });
|
|
608
|
-
* ```
|
|
609
|
-
*/
|
|
610
|
-
function initializeTestEnvironment(config) {
|
|
611
|
-
var _a, _b, _c;
|
|
506
|
+
}
|
|
507
|
+
function clearFirestoreData(options) {
|
|
612
508
|
return __awaiter(this, void 0, void 0, function () {
|
|
613
|
-
var
|
|
614
|
-
return __generator(this, function (
|
|
615
|
-
switch (
|
|
509
|
+
var resp;
|
|
510
|
+
return __generator(this, function (_a) {
|
|
511
|
+
switch (_a.label) {
|
|
616
512
|
case 0:
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
throw new Error('Missing projectId option or env var GCLOUD_PROJECT! Please specify the projectId either ' +
|
|
620
|
-
'way.\n(A demo-* projectId is strongly recommended for unit tests, such as "demo-test".)');
|
|
513
|
+
if (!options.projectId) {
|
|
514
|
+
throw new Error('projectId not specified');
|
|
621
515
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
516
|
+
return [4 /*yield*/, requestPromise(request__namespace.delete, {
|
|
517
|
+
method: 'DELETE',
|
|
518
|
+
uri: "http://" + getFirestoreHost() + "/emulator/v1/projects/" + options.projectId + "/databases/(default)/documents",
|
|
519
|
+
body: JSON.stringify({
|
|
520
|
+
database: "projects/" + options.projectId + "/databases/(default)"
|
|
521
|
+
})
|
|
522
|
+
})];
|
|
626
523
|
case 1:
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
_d = undefined;
|
|
631
|
-
_f.label = 3;
|
|
632
|
-
case 3:
|
|
633
|
-
discovered = _d;
|
|
634
|
-
emulators = {};
|
|
635
|
-
if (hub) {
|
|
636
|
-
emulators.hub = hub;
|
|
637
|
-
}
|
|
638
|
-
for (_i = 0, SUPPORTED_EMULATORS_1 = SUPPORTED_EMULATORS; _i < SUPPORTED_EMULATORS_1.length; _i++) {
|
|
639
|
-
emulator = SUPPORTED_EMULATORS_1[_i];
|
|
640
|
-
hostAndPort = getEmulatorHostAndPort(emulator, config[emulator], discovered);
|
|
641
|
-
if (hostAndPort) {
|
|
642
|
-
emulators[emulator] = hostAndPort;
|
|
643
|
-
}
|
|
524
|
+
resp = _a.sent();
|
|
525
|
+
if (resp.statusCode !== 200) {
|
|
526
|
+
throw new Error(JSON.parse(resp.body.error));
|
|
644
527
|
}
|
|
645
|
-
|
|
646
|
-
assertEmulatorRunning(emulators, 'database');
|
|
647
|
-
return [4 /*yield*/, loadDatabaseRules(emulators.database, projectId, config.database.rules)];
|
|
648
|
-
case 4:
|
|
649
|
-
_f.sent();
|
|
650
|
-
_f.label = 5;
|
|
651
|
-
case 5:
|
|
652
|
-
if (!((_b = config.firestore) === null || _b === void 0 ? void 0 : _b.rules)) return [3 /*break*/, 7];
|
|
653
|
-
assertEmulatorRunning(emulators, 'firestore');
|
|
654
|
-
return [4 /*yield*/, loadFirestoreRules(emulators.firestore, projectId, config.firestore.rules)];
|
|
655
|
-
case 6:
|
|
656
|
-
_f.sent();
|
|
657
|
-
_f.label = 7;
|
|
658
|
-
case 7:
|
|
659
|
-
if (!((_c = config.storage) === null || _c === void 0 ? void 0 : _c.rules)) return [3 /*break*/, 9];
|
|
660
|
-
assertEmulatorRunning(emulators, 'storage');
|
|
661
|
-
return [4 /*yield*/, loadStorageRules(emulators.storage, config.storage.rules)];
|
|
662
|
-
case 8:
|
|
663
|
-
_f.sent();
|
|
664
|
-
_f.label = 9;
|
|
665
|
-
case 9: return [2 /*return*/, new RulesTestEnvironmentImpl(projectId, emulators)];
|
|
528
|
+
return [2 /*return*/];
|
|
666
529
|
}
|
|
667
530
|
});
|
|
668
531
|
});
|
|
669
532
|
}
|
|
670
|
-
var SUPPORTED_EMULATORS = ['database', 'firestore', 'storage'];
|
|
671
|
-
|
|
672
533
|
/**
|
|
673
|
-
*
|
|
674
|
-
*
|
|
534
|
+
* Run a setup function with background Cloud Functions triggers disabled. This can be used to
|
|
535
|
+
* import data into the Realtime Database or Cloud Firestore emulator without triggering locally
|
|
536
|
+
* emulated Cloud Functions.
|
|
675
537
|
*
|
|
676
|
-
*
|
|
677
|
-
* you may not use this file except in compliance with the License.
|
|
678
|
-
* You may obtain a copy of the License at
|
|
538
|
+
* This method only works with Firebase CLI version 8.13.0 or higher.
|
|
679
539
|
*
|
|
680
|
-
*
|
|
681
|
-
*
|
|
682
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
683
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
684
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
685
|
-
* See the License for the specific language governing permissions and
|
|
686
|
-
* limitations under the License.
|
|
540
|
+
* @param fn an function which returns a promise.
|
|
687
541
|
*/
|
|
688
|
-
function withFunctionTriggersDisabled(
|
|
542
|
+
function withFunctionTriggersDisabled(fn) {
|
|
689
543
|
return __awaiter(this, void 0, void 0, function () {
|
|
690
|
-
var
|
|
544
|
+
var hubHost, disableRes, result, enableRes;
|
|
691
545
|
return __generator(this, function (_a) {
|
|
692
546
|
switch (_a.label) {
|
|
693
547
|
case 0:
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
else {
|
|
699
|
-
hub = getEmulatorHostAndPort('hub', fnOrHub);
|
|
700
|
-
if (!maybeFn) {
|
|
701
|
-
throw new Error('The callback function must be specified!');
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
if (!hub) {
|
|
705
|
-
throw new Error('Please specify the Emulator Hub host and port via arguments or set the environment ' +
|
|
706
|
-
("varible " + EMULATOR_HOST_ENV_VARS.hub + "!"));
|
|
707
|
-
}
|
|
708
|
-
hub.host = fixHostname(hub.host);
|
|
709
|
-
makeUrl(hub, '/functions/disableBackgroundTriggers');
|
|
710
|
-
return [4 /*yield*/, fetch__default['default'](makeUrl(hub, '/functions/disableBackgroundTriggers'), {
|
|
711
|
-
method: 'PUT'
|
|
548
|
+
hubHost = getHubHost();
|
|
549
|
+
return [4 /*yield*/, requestPromise(request__namespace.put, {
|
|
550
|
+
method: 'PUT',
|
|
551
|
+
uri: "http://" + hubHost + "/functions/disableBackgroundTriggers"
|
|
712
552
|
})];
|
|
713
553
|
case 1:
|
|
714
554
|
disableRes = _a.sent();
|
|
715
|
-
if (
|
|
716
|
-
throw new Error("HTTP Error " + disableRes.
|
|
555
|
+
if (disableRes.statusCode !== 200) {
|
|
556
|
+
throw new Error("HTTP Error " + disableRes.statusCode + " when disabling functions triggers, are you using firebase-tools 8.13.0 or higher?");
|
|
717
557
|
}
|
|
718
558
|
result = undefined;
|
|
719
559
|
_a.label = 2;
|
|
720
560
|
case 2:
|
|
721
561
|
_a.trys.push([2, , 4, 6]);
|
|
722
|
-
return [4 /*yield*/,
|
|
562
|
+
return [4 /*yield*/, fn()];
|
|
723
563
|
case 3:
|
|
724
564
|
result = _a.sent();
|
|
725
565
|
return [3 /*break*/, 6];
|
|
726
|
-
case 4: return [4 /*yield*/,
|
|
727
|
-
method: 'PUT'
|
|
566
|
+
case 4: return [4 /*yield*/, requestPromise(request__namespace.put, {
|
|
567
|
+
method: 'PUT',
|
|
568
|
+
uri: "http://" + hubHost + "/functions/enableBackgroundTriggers"
|
|
728
569
|
})];
|
|
729
570
|
case 5:
|
|
730
571
|
enableRes = _a.sent();
|
|
731
|
-
if (
|
|
732
|
-
throw new Error("HTTP Error " + enableRes.
|
|
572
|
+
if (enableRes.statusCode !== 200) {
|
|
573
|
+
throw new Error("HTTP Error " + enableRes.statusCode + " when enabling functions triggers, are you using firebase-tools 8.13.0 or higher?");
|
|
733
574
|
}
|
|
734
575
|
return [7 /*endfinally*/];
|
|
735
576
|
case 6:
|
|
@@ -739,29 +580,12 @@ function withFunctionTriggersDisabled(fnOrHub, maybeFn) {
|
|
|
739
580
|
});
|
|
740
581
|
});
|
|
741
582
|
}
|
|
742
|
-
/**
|
|
743
|
-
* Assert the promise to be rejected with a "permission denied" error.
|
|
744
|
-
*
|
|
745
|
-
* Useful to assert a certain request to be denied by Security Rules. See example below.
|
|
746
|
-
* This function recognizes permission-denied errors from Database, Firestore, and Storage JS SDKs.
|
|
747
|
-
*
|
|
748
|
-
* @param pr the promise to be asserted
|
|
749
|
-
* @returns a Promise that is fulfilled if pr is rejected with "permission denied". If pr is
|
|
750
|
-
* rejected with any other error or resolved, the returned promise rejects.
|
|
751
|
-
* @public
|
|
752
|
-
* @example
|
|
753
|
-
* ```javascript
|
|
754
|
-
* const unauthed = testEnv.unauthenticatedContext();
|
|
755
|
-
* await assertFails(get(doc(unauthed.firestore(), '/private/doc'), { ... });
|
|
756
|
-
* ```
|
|
757
|
-
*/
|
|
758
583
|
function assertFails(pr) {
|
|
759
|
-
return pr.then(function () {
|
|
584
|
+
return pr.then(function (v) {
|
|
760
585
|
return Promise.reject(new Error('Expected request to fail, but it succeeded.'));
|
|
761
586
|
}, function (err) {
|
|
762
|
-
var
|
|
763
|
-
var
|
|
764
|
-
var errMessage = ((_b = err === null || err === void 0 ? void 0 : err.message) === null || _b === void 0 ? void 0 : _b.toLowerCase()) || '';
|
|
587
|
+
var errCode = (err && err.code && err.code.toLowerCase()) || '';
|
|
588
|
+
var errMessage = (err && err.message && err.message.toLowerCase()) || '';
|
|
765
589
|
var isPermissionDenied = errCode === 'permission-denied' ||
|
|
766
590
|
errCode === 'permission_denied' ||
|
|
767
591
|
errMessage.indexOf('permission_denied') >= 0 ||
|
|
@@ -774,25 +598,37 @@ function assertFails(pr) {
|
|
|
774
598
|
return err;
|
|
775
599
|
});
|
|
776
600
|
}
|
|
777
|
-
/**
|
|
778
|
-
* Assert the promise to be rejected with a "permission denied" error.
|
|
779
|
-
*
|
|
780
|
-
* This is a no-op function returning the passed promise as-is, but can be used for documentational
|
|
781
|
-
* purposes in test code to emphasize that a certain request should succeed (e.g. allowed by rules).
|
|
782
|
-
*
|
|
783
|
-
* @public
|
|
784
|
-
* @example
|
|
785
|
-
* ```javascript
|
|
786
|
-
* const alice = testEnv.authenticatedContext('alice');
|
|
787
|
-
* await assertSucceeds(get(doc(alice.firestore(), '/doc/readable/by/alice'), { ... });
|
|
788
|
-
* ```
|
|
789
|
-
*/
|
|
790
601
|
function assertSucceeds(pr) {
|
|
791
602
|
return pr;
|
|
603
|
+
}
|
|
604
|
+
function requestPromise(method, options) {
|
|
605
|
+
return new Promise(function (resolve, reject) {
|
|
606
|
+
var callback = function (err, resp, body) {
|
|
607
|
+
if (err) {
|
|
608
|
+
reject(err);
|
|
609
|
+
}
|
|
610
|
+
else {
|
|
611
|
+
resolve({ statusCode: resp.statusCode, body: body });
|
|
612
|
+
}
|
|
613
|
+
};
|
|
614
|
+
// Unfortunately request's default method is not very test-friendly so having
|
|
615
|
+
// the caler pass in the method here makes this whole thing compatible with sinon
|
|
616
|
+
method(options, callback);
|
|
617
|
+
});
|
|
792
618
|
}
|
|
793
619
|
|
|
620
|
+
exports.apps = apps;
|
|
794
621
|
exports.assertFails = assertFails;
|
|
795
622
|
exports.assertSucceeds = assertSucceeds;
|
|
796
|
-
exports.
|
|
623
|
+
exports.clearFirestoreData = clearFirestoreData;
|
|
624
|
+
exports.database = database;
|
|
625
|
+
exports.discoverEmulators = discoverEmulators;
|
|
626
|
+
exports.firestore = firestore;
|
|
627
|
+
exports.initializeAdminApp = initializeAdminApp;
|
|
628
|
+
exports.initializeTestApp = initializeTestApp;
|
|
629
|
+
exports.loadDatabaseRules = loadDatabaseRules;
|
|
630
|
+
exports.loadFirestoreRules = loadFirestoreRules;
|
|
631
|
+
exports.loadStorageRules = loadStorageRules;
|
|
632
|
+
exports.useEmulators = useEmulators;
|
|
797
633
|
exports.withFunctionTriggersDisabled = withFunctionTriggersDisabled;
|
|
798
634
|
//# sourceMappingURL=index.cjs.js.map
|