Comments (7)
@Shaggy13spe The issue is that that field is indistinguishable from a document field that contains an array of maps, each of which might have an id
field. Our project had a few at the time that I opened this issue, and while there are certainly better ways to layout Firestore documents, sometimes you need to live with poor planning for a while π
. Besides, since Firestore (kindof) supports that case, we'd best be able to test that. My proposal is to make the distinction more explicit to better handle that case.
i.e. Since this ugly thing works, we should support it:
As a bonus, my fork restructures some things internally to cover even more canon Firestore API that we just don't have right now.
from firestore-jest-mock.
Part of the bother appears to be this line here in FakeFirestore.doc
:
const records = this.database[this.collectionName] || [];
We shouldn't always check in this.database
. What if our present spot is a document? How do we access its subcollections instead? And what if we have references exploring multiple database locations simultaneously?
One potential solution would be to document a special key in the mock database structure called _subcollections
. The leading underscore precludes it from conflicting with any actual data property called "subcollections", and this way we're not just checking the contents of every document's array property for objects with id
properties. This special document property would map to an object with collection IDs and arrays of document children. Like so:
const db = new FakeFirestore({
characters: [
{ id: 'homer', name: 'Homer', occupation: 'technician' },
{ id: 'krusty', name: 'Krusty', occupation: 'clown' },
{
id: 'bob',
name: 'Bob',
occupation: 'repairman',
_subcollections: {
family: [ // *this* is a subcollection! π
{ id: 'thing1', name: 'Thing 1', relation: 'pet' },
{ id: 'thing2', name: 'Thing 2', relation: 'pet' },
{ id: 'deborah', name: 'Deborah', relation: 'wife' },
],
},
},
],
});
Now for the fun part: how do we keep track of where we are in the object graph? Presently, everything is handled by an instance of FakeFirestore
. Each call to collection
sets a collectionName
property and resets its recordToFetch
property to null
. Then when doc
is called, the function looks in the mock database's root (this.database[this.collectionName]
) for the document to pull. It remembers that object only until collection
is called again.
Now, this works great when we have one or more references to documents at the root of the Firestore database, but this limits our view; we cannot dig any deeper!
In an effort to prevent many more persistent properties on FakeFirestore
, and to permit multilevel retrieval in more places than one at a time, I recommend we refactor the doc
and collection
mocks to instead return reference objects. These class instances would keep track of where they are in the tree by hanging onto a reference document, whose subcollections may be accessed via the _subcollections
property defined on the mock database.
from firestore-jest-mock.
Another thought: If I'm reading the code right (it is getting late for me), it looks like a new instance of FakeFirestore
is created each time we call firestore()
.
This would prevent us from overwriting our spot in the document tree, assuming first that FakeFirestore
remains the main player in working with the document tree; and second, that Firebase clients don't cache this object (say, as db
or something) to access disparate parts of the tree between calls to get
. Unfortunately, we cannot prevent this, and it's actually a fairly common pattern to get several document references and call get
on each of them in quick succession, such as in a batch or a transaction.
Unfortunately, I don't see a reliable way to juggle multiple paths down the document tree with just one referencing object. We'll likely need to do what Firestore proper does and return something like DocumentReference
and CollectionReference
instances with each call to doc
and collection
, respectively.
Thoughts?
from firestore-jest-mock.
Are there any plans to incorporate sub-collection mocking? It would be really useful for me.
from firestore-jest-mock.
@MattGoldwater I've actually implemented something for that in my own fork. I plan to take some time this weekend to bring it up to date with the master branch here and submit a PR.
from firestore-jest-mock.
Maybe I'm missing something?? I have the following mocked db:
mockFirebase({
database: {
interviews: [
{
id: '1',
recruit: 'John Doe',
screener: 'Michael Morrison',
email: '[email protected]',
currentWhiteboard: {},
interviewTimestamp: mockTimestamp,
whiteboards: [{ ///this is a subcollection in actual Firestore
id: '1',
title: 'whiteboard1',
scenario: 'scenario1',
code: '',
},
{
id: '2',
title: 'whiteboard2',
scenario: 'scenario2',
code: '',
}],
},
]
this is the code for accessing the interview doc (and it's subcollection) and updating it:
async addWhiteboard (interviewId, whiteboard) {
const ref = this.firestore.db.collection('interviews').doc(interviewId).collection('whiteboards')
await ref.doc(whiteboard.id).set(whiteboard)
}
And my unit test:
test('addWhiteboard', async () => {
expect.assertions(5)
const whiteboard = {
id: '1',
title: 'whiteboard1',
scenario: 'scenario1',
code: '',
}
const interviewService = new InterviewService()
await interviewService.addWhiteboard('2', whiteboard)
expect(mockCollection).toHaveBeenCalledWith('interviews')
expect(mockDoc).toHaveBeenCalledWith('2')
expect(mockCollection).toHaveBeenCalledWith('whiteboards')
expect(mockDoc).toHaveBeenCalledWith('1')
expect(mockSet).toHaveBeenCalledWith(whiteboard)
})
This all works. Is there some other functionality that you are needing?
from firestore-jest-mock.
from firestore-jest-mock.
Related Issues (20)
- Error in @google-cloud/firestore compatibility example HOT 4
- Module firebase-admin not found, mocking skipped HOT 2
- Firestore instance in snapshot.ref go undefined after make a document query request to the database HOT 1
- QueryDocumentSnapshot that passed to trigger functions doesn't contain createTime element HOT 1
- Firebase Cloud Messaging HOT 2
- Is Firestore mock delete() not yet implemented? HOT 6
- How to test a trigger HOT 2
- Where query on nested fields HOT 6
- Firestore mock for DocumentReference.create() HOT 7
- Checking for mockUpdate within a datasnapshot forEach HOT 3
- React Native Support HOT 3
- include firebase/admin with 'import' instead of 'require' HOT 4
- Example of multiple tests with different database data? HOT 3
- Jest, `mockDoc` validate collection type (v0.18.0)
- Requires wrong package for firebase 9 HOT 4
- firestore and auth mocks not complete on firebase-admin HOT 1
- broken links for firebase doc references
- `set` without merge overrides _collections HOT 1
- Transfer Repo HOT 9
- Is there a way to test multiple firestore states? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from firestore-jest-mock.