firestore-node-mock 0.0.1 → 0.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/README.md +20 -18
- package/mocks/firestore.js +43 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
> WIP: this was forked from `firestore-jest-mock`. It works in my tests when consuming in ESM, but your results may vary.
|
|
2
|
+
|
|
1
3
|
# Mock Firestore
|
|
2
4
|
|
|
3
|
-
>
|
|
5
|
+
> Node.js native mock for testing Google Cloud Firestore
|
|
4
6
|
|
|
5
7
|
A simple way to mock calls to Cloud Firestore, allowing you to assert that you are requesting data correctly.
|
|
6
8
|
|
|
@@ -50,20 +52,20 @@ This library provides an easy to use mocked version of firestore.
|
|
|
50
52
|
With [npm](https://www.npmjs.com):
|
|
51
53
|
|
|
52
54
|
```shell
|
|
53
|
-
npm install --save-dev firestore-
|
|
55
|
+
npm install --save-dev firestore-node-mock
|
|
54
56
|
```
|
|
55
57
|
|
|
56
58
|
With [yarn](https://yarnpkg.com/):
|
|
57
59
|
|
|
58
60
|
```shell
|
|
59
|
-
yarn add --dev firestore-
|
|
61
|
+
yarn add --dev firestore-node-mock
|
|
60
62
|
```
|
|
61
63
|
|
|
62
64
|
## Usage
|
|
63
65
|
|
|
64
66
|
### `mockFirebase`
|
|
65
67
|
|
|
66
|
-
The default method to use is `mockFirebase`, which returns a
|
|
68
|
+
The default method to use is `mockFirebase`, which returns a mock, overwriting `firebase` and `firebase-admin`. It accepts an object with two pieces:
|
|
67
69
|
|
|
68
70
|
- `database` -- A mock of your collections
|
|
69
71
|
- `currentUser` -- (optional) overwrites the currently logged in user
|
|
@@ -71,7 +73,7 @@ The default method to use is `mockFirebase`, which returns a jest mock, overwrit
|
|
|
71
73
|
Example usage:
|
|
72
74
|
|
|
73
75
|
```js
|
|
74
|
-
const { mockFirebase } = require('firestore-
|
|
76
|
+
const { mockFirebase } = require('firestore-node-mock');
|
|
75
77
|
|
|
76
78
|
// Create a fake Firestore with a `users` and `posts` collection
|
|
77
79
|
mockFirebase({
|
|
@@ -88,7 +90,7 @@ mockFirebase({
|
|
|
88
90
|
If you are using TypeScript, you can import `mockFirebase` using ES module syntax:
|
|
89
91
|
|
|
90
92
|
```TypeScript
|
|
91
|
-
import { mockFirebase } from 'firestore-
|
|
93
|
+
import { mockFirebase } from 'firestore-node-mock';
|
|
92
94
|
```
|
|
93
95
|
|
|
94
96
|
This will populate a fake database with a `users` and `posts` collection. This database is read-only by default, meaning that any Firestore write calls will not actually persist across invocations.
|
|
@@ -96,7 +98,7 @@ This will populate a fake database with a `users` and `posts` collection. This d
|
|
|
96
98
|
Now you can write queries or requests for data just as you would with Firestore:
|
|
97
99
|
|
|
98
100
|
```js
|
|
99
|
-
const { mockCollection } = require('firestore-
|
|
101
|
+
const { mockCollection } = require('firestore-node-mock/mocks/firestore');
|
|
100
102
|
|
|
101
103
|
test('testing stuff', () => {
|
|
102
104
|
const firebase = require('firebase'); // or import firebase from 'firebase';
|
|
@@ -117,7 +119,7 @@ test('testing stuff', () => {
|
|
|
117
119
|
In TypeScript, you would import `mockCollection` using ES module syntax:
|
|
118
120
|
|
|
119
121
|
```TypeScript
|
|
120
|
-
import { mockCollection } from 'firestore-
|
|
122
|
+
import { mockCollection } from 'firestore-node-mock/mocks/firestore';
|
|
121
123
|
```
|
|
122
124
|
|
|
123
125
|
The other mock functions may be imported similarly.
|
|
@@ -127,7 +129,7 @@ The other mock functions may be imported similarly.
|
|
|
127
129
|
If you use `@google-cloud/firestore`, use `mockGoogleCloudFirestore` instead of `mockFirebase` in all the documentation.
|
|
128
130
|
|
|
129
131
|
```js
|
|
130
|
-
const { mockGoogleCloudFirestore } = require('firestore-
|
|
132
|
+
const { mockGoogleCloudFirestore } = require('firestore-node-mock');
|
|
131
133
|
|
|
132
134
|
mockGoogleCloudFirestore({
|
|
133
135
|
database: {
|
|
@@ -139,7 +141,7 @@ mockGoogleCloudFirestore({
|
|
|
139
141
|
},
|
|
140
142
|
});
|
|
141
143
|
|
|
142
|
-
const { mockCollection } = require('firestore-
|
|
144
|
+
const { mockCollection } = require('firestore-node-mock/mocks/firestore');
|
|
143
145
|
|
|
144
146
|
test('testing stuff', () => {
|
|
145
147
|
const { Firestore } = require('@google-cloud/firestore');
|
|
@@ -163,7 +165,7 @@ The `Auth` module is not available for `@google-cloud/firestore` compatibility._
|
|
|
163
165
|
If you use `@react-native-firebase/firestore`, use `mockReactNativeFirestore` instead of `mockFirebase` in all the documentation.
|
|
164
166
|
|
|
165
167
|
```js
|
|
166
|
-
const { mockReactNativeFirestore } = require('firestore-
|
|
168
|
+
const { mockReactNativeFirestore } = require('firestore-node-mock');
|
|
167
169
|
|
|
168
170
|
mockReactNativeFirestore({
|
|
169
171
|
database: {
|
|
@@ -175,7 +177,7 @@ mockReactNativeFirestore({
|
|
|
175
177
|
},
|
|
176
178
|
});
|
|
177
179
|
|
|
178
|
-
const { mockCollection } = require('firestore-
|
|
180
|
+
const { mockCollection } = require('firestore-node-mock/mocks/firestore');
|
|
179
181
|
|
|
180
182
|
test('testing stuff', () => {
|
|
181
183
|
const { Firestore } = require('@react-native-firebase/firestore');
|
|
@@ -196,10 +198,10 @@ The `Auth` module is not available for `@react-native-firebase/firestore` compat
|
|
|
196
198
|
|
|
197
199
|
### Subcollections
|
|
198
200
|
|
|
199
|
-
A common Firestore use case is to store data in document [subcollections](https://firebase.google.com/docs/firestore/manage-data/structure-data#subcollections). You can model these with firestore-
|
|
201
|
+
A common Firestore use case is to store data in document [subcollections](https://firebase.google.com/docs/firestore/manage-data/structure-data#subcollections). You can model these with firestore-node-mock like so:
|
|
200
202
|
|
|
201
203
|
```js
|
|
202
|
-
const { mockFirebase } = require('firestore-
|
|
204
|
+
const { mockFirebase } = require('firestore-node-mock');
|
|
203
205
|
// Using our fake Firestore from above:
|
|
204
206
|
mockFirebase({
|
|
205
207
|
database: {
|
|
@@ -226,12 +228,12 @@ mockFirebase({
|
|
|
226
228
|
});
|
|
227
229
|
```
|
|
228
230
|
|
|
229
|
-
Similar to how the `id` key defines a document object to firestore-
|
|
231
|
+
Similar to how the `id` key defines a document object to firestore-node-mock, the `_collections` key defines a subcollection. You model each subcollection structure in the same way that `database` is modeled above: an object keyed by collection IDs and populated with document arrays.
|
|
230
232
|
|
|
231
233
|
This lets you model and validate more complex document access:
|
|
232
234
|
|
|
233
235
|
```js
|
|
234
|
-
const { mockCollection, mockDoc } = require('firestore-
|
|
236
|
+
const { mockCollection, mockDoc } = require('firestore-node-mock/mocks/firestore');
|
|
235
237
|
|
|
236
238
|
test('testing stuff', () => {
|
|
237
239
|
const firebase = require('firebase');
|
|
@@ -274,10 +276,10 @@ function maybeGetUsersInState(state) {
|
|
|
274
276
|
We have a conditional query here. If you pass `state` to this function, we will query against it; otherwise, we just get all of the users. So, you may want to write a test that ensures you are querying correctly:
|
|
275
277
|
|
|
276
278
|
```js
|
|
277
|
-
const { mockFirebase } = require('firestore-
|
|
279
|
+
const { mockFirebase } = require('firestore-node-mock');
|
|
278
280
|
|
|
279
281
|
// Import the mock versions of the functions you expect to be called
|
|
280
|
-
const { mockCollection, mockWhere } = require('firestore-
|
|
282
|
+
const { mockCollection, mockWhere } = require('firestore-node-mock/mocks/firestore');
|
|
281
283
|
describe('we can query', () => {
|
|
282
284
|
mockFirebase({
|
|
283
285
|
database: {
|
package/mocks/firestore.js
CHANGED
|
@@ -68,8 +68,9 @@ export class FakeFirestore {
|
|
|
68
68
|
mockBatch(...arguments);
|
|
69
69
|
return {
|
|
70
70
|
_ref: this,
|
|
71
|
-
delete() {
|
|
71
|
+
delete(doc) {
|
|
72
72
|
mockBatchDelete(...arguments);
|
|
73
|
+
this._ref._deleteData(doc.path);
|
|
73
74
|
return this;
|
|
74
75
|
},
|
|
75
76
|
set(doc, data, setOptions = {}) {
|
|
@@ -239,6 +240,46 @@ export class FakeFirestore {
|
|
|
239
240
|
};
|
|
240
241
|
}
|
|
241
242
|
|
|
243
|
+
_deleteData(path) {
|
|
244
|
+
// Do not update unless explicity set to mutable.
|
|
245
|
+
if (!this.options.mutable) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const pathArray = path.replace(/^\/+/, '').split('/');
|
|
250
|
+
|
|
251
|
+
// Must be document-level, so even-numbered elements
|
|
252
|
+
if (pathArray.length % 2 !== 0) {
|
|
253
|
+
throw new Error(
|
|
254
|
+
`FakeFirebaseError: Invalid document reference. Document references must have an even number of segments, but ${path} has ${pathArray.length}`,
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// The parent entry is the id of the document
|
|
259
|
+
const docId = pathArray.pop();
|
|
260
|
+
// Find the parent of docId.
|
|
261
|
+
const parent = pathArray.reduce((last, entry, index) => {
|
|
262
|
+
if (!last) return null;
|
|
263
|
+
const isCollection = index % 2 === 0;
|
|
264
|
+
if (isCollection) {
|
|
265
|
+
return last[entry];
|
|
266
|
+
} else {
|
|
267
|
+
const existingDoc = last.find(doc => doc.id === entry);
|
|
268
|
+
if (existingDoc) {
|
|
269
|
+
return existingDoc._collections;
|
|
270
|
+
}
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
}, this.database);
|
|
274
|
+
|
|
275
|
+
if (parent) {
|
|
276
|
+
const oldIndex = parent.findIndex(doc => doc.id === docId);
|
|
277
|
+
if (oldIndex >= 0) {
|
|
278
|
+
parent.splice(oldIndex, 1);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
242
283
|
recursiveDelete(ref, bulkWriter) {
|
|
243
284
|
mockRecursiveDelete(...arguments);
|
|
244
285
|
return Promise.resolve();
|
|
@@ -289,6 +330,7 @@ FakeFirestore.DocumentReference = class DocumentReference {
|
|
|
289
330
|
|
|
290
331
|
delete() {
|
|
291
332
|
mockDelete(...arguments);
|
|
333
|
+
this.firestore._deleteData(this.path);
|
|
292
334
|
return Promise.resolve();
|
|
293
335
|
}
|
|
294
336
|
|