Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

firestore-jest-mock

Package Overview
Dependencies
Maintainers
1
Versions
28
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

firestore-jest-mock - npm Package Compare versions

Comparing version 0.11.1 to 0.12.0

__tests__/mock-firestore-mutable.test.js

2

__tests__/full-setup-google-cloud-firestore.test.js

@@ -66,3 +66,3 @@ const { mockGoogleCloudFirestore } = require('firestore-jest-mock');

expect(mockAdd).toHaveBeenCalled();
expect(docRef).toHaveProperty('id', 'abc123');
expect(docRef).toHaveProperty('id');
});

@@ -69,0 +69,0 @@ });

@@ -87,3 +87,3 @@ const { mockFirebase } = require('firestore-jest-mock');

expect(mockAdd).toHaveBeenCalled();
expect(docRef).toHaveProperty('id', 'abc123');
expect(docRef).toHaveProperty('id');
});

@@ -336,3 +336,3 @@ });

expect(mockGet).toHaveBeenCalled();
expect(record).toHaveProperty('id', 'abc123');
expect(record).toHaveProperty('id');
expect(record.data).toBeInstanceOf(Function);

@@ -339,0 +339,0 @@ });

@@ -286,8 +286,9 @@ const { FakeFirestore } = require('firestore-jest-mock');

expect.assertions(1);
// As per docs, should have 'random' ID, but we'll use our usual 'abc123' for now.
// See https://firebase.google.com/docs/reference/js/firebase.firestore.CollectionReference#doc
// "If no path is specified, an automatically-generated unique ID will be used for the returned DocumentReference."
const newDoc = db.collection('foo').doc();
expect(newDoc.path).toBe('database/foo/abc123');
const col = db.collection('characters');
const newDoc = col.doc();
const otherIds = col.records().map(doc => doc.id);
expect(otherIds).not.toContainEqual(newDoc.id);
});
});
{
"typescript.tsdk": "node_modules/typescript/lib"
}
}

@@ -0,1 +1,4 @@

import type { FirebaseUser, FakeAuth } from './auth';
import type { FakeFirestore } from './firestore';
export interface DatabaseDocument {

@@ -15,3 +18,3 @@ id: string;

database?: DatabaseCollections;
currentUser?: unknown; // TODO: User, to be defined later
currentUser?: FirebaseUser;
}

@@ -28,4 +31,4 @@

};
auth(): unknown; // TODO: Auth, to be defined later
firestore(): unknown; // TODO: FakeFirestore, to be defined later
auth(): FakeAuth;
firestore(): FakeFirestore;
}

@@ -32,0 +35,0 @@

@@ -29,2 +29,4 @@ const mockCollectionGroup = jest.fn();

const _randomId = () => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString();
class FakeFirestore {

@@ -55,2 +57,3 @@ constructor(stubbedDatabase = {}, options = {}) {

return {
_ref: this,
delete() {

@@ -60,8 +63,10 @@ mockBatchDelete(...arguments);

},
set() {
set(doc, data, setOptions = {}) {
mockBatchSet(...arguments);
this._ref._updateData(doc.path, data, setOptions.merge);
return this;
},
update() {
update(doc, data) {
mockBatchUpdate(...arguments);
this._ref._updateData(doc.path, data, true);
return this;

@@ -122,2 +127,48 @@ },

}
_updateData(path, object, merge) {
// Do not update unless explicity set to mutable.
if (!this.options.mutable) {
return;
}
// note: this logic could be deduplicated
const pathArray = path
.replace(/^\/+/, '')
.split('/')
.slice(1);
// Must be document-level, so even-numbered elements
if (pathArray.length % 2) {
throw new Error('The path array must be document-level');
}
// The parent entry is the id of the document
const docId = pathArray.pop();
// Find the parent of docId. Run through the path, creating missing entries
const parent = pathArray.reduce((last, entry, index) => {
const isCollection = index % 2 === 0;
if (isCollection) {
return last[entry] || (last[entry] = []);
} else {
const existingDoc = last.find(doc => doc.id === entry);
if (existingDoc) {
// return _collections, creating it if it doesn't already exist
return existingDoc._collections || (existingDoc._collections = {});
}
const _collections = {};
last.push({ id: entry, _collections });
return _collections;
}
}, this.database);
// parent should now be an array of documents
// Replace existing data, if it's there, or add to the end of the array
const oldIndex = parent.findIndex(doc => doc.id === docId);
parent[oldIndex >= 0 ? oldIndex : parent.length] = {
...(merge ? parent[oldIndex] : undefined),
...object,
id: docId,
};
}
}

@@ -165,2 +216,3 @@

} else {
// eslint-disable-next-line no-unused-vars
[options, callback, errorCallback] = arguments;

@@ -186,40 +238,4 @@ }

query.mocks.mockGet(...arguments);
// Ignore leading slash
const pathArray = this.path.replace(/^\/+/, '').split('/');
pathArray.shift(); // drop 'database'; it's always first
let requestedRecords = this.firestore.database[pathArray.shift()];
let document = null;
if (requestedRecords) {
const documentId = pathArray.shift();
document = requestedRecords.find(record => record.id === documentId);
} else {
return Promise.resolve({ exists: false, data: () => undefined, id: this.id });
}
for (let index = 0; index < pathArray.length; index += 2) {
const collectionId = pathArray[index];
const documentId = pathArray[index + 1];
if (!document || !document._collections) {
return Promise.resolve({ exists: false, data: () => undefined, id: this.id });
}
requestedRecords = document._collections[collectionId] || [];
if (requestedRecords.length === 0) {
return Promise.resolve({ exists: false, data: () => undefined, id: this.id });
}
document = requestedRecords.find(record => record.id === documentId);
if (!document) {
return Promise.resolve({ exists: false, data: () => undefined, id: this.id });
}
// +2 skips to next document
}
if (!!document || false) {
document._ref = this;
return Promise.resolve(buildDocFromHash(document));
}
return Promise.resolve({ exists: false, data: () => undefined, id: this.id, ref: this });
const data = this._get();
return Promise.resolve(data);
}

@@ -229,7 +245,11 @@

mockUpdate(...arguments);
if (this._get().exists) {
this.firestore._updateData(this.path, object, true);
}
return Promise.resolve(buildDocFromHash({ ...object, _ref: this }));
}
set(object) {
set(object, setOptions = {}) {
mockSet(...arguments);
this.firestore._updateData(this.path, object, setOptions.merge);
return Promise.resolve(buildDocFromHash({ ...object, _ref: this }));

@@ -266,2 +286,43 @@ }

_get() {
// Ignore leading slash
const pathArray = this.path.replace(/^\/+/, '').split('/');
pathArray.shift(); // drop 'database'; it's always first
let requestedRecords = this.firestore.database[pathArray.shift()];
let document = null;
if (requestedRecords) {
const documentId = pathArray.shift();
document = requestedRecords.find(record => record.id === documentId);
} else {
return { exists: false, data: () => undefined, id: this.id };
}
for (let index = 0; index < pathArray.length; index += 2) {
const collectionId = pathArray[index];
const documentId = pathArray[index + 1];
if (!document || !document._collections) {
return { exists: false, data: () => undefined, id: this.id };
}
requestedRecords = document._collections[collectionId] || [];
if (requestedRecords.length === 0) {
return { exists: false, data: () => undefined, id: this.id };
}
document = requestedRecords.find(record => record.id === documentId);
if (!document) {
return { exists: false, data: () => undefined, id: this.id };
}
// +2 skips to next document
}
if (!!document || false) {
document._ref = this;
return buildDocFromHash(document);
}
return { exists: false, data: () => undefined, id: this.id, ref: this };
}
withConverter() {

@@ -292,8 +353,10 @@ query.mocks.mockWithConverter(...arguments);

add() {
add(object) {
mockAdd(...arguments);
return Promise.resolve(new FakeFirestore.DocumentReference('abc123', this));
const newDoc = new FakeFirestore.DocumentReference(_randomId(), this);
this.firestore._updateData(newDoc.path, object);
return Promise.resolve(newDoc);
}
doc(id = 'abc123') {
doc(id = _randomId()) {
mockDoc(id);

@@ -300,0 +363,0 @@ return new FakeFirestore.DocumentReference(id, this, this.firestore);

@@ -18,2 +18,3 @@ const defaultOptions = require('./helpers/defaultMockOptions');

Transaction: FakeFirestore.Transaction,
/** @type {Firestore.constructor} */
Firestore,

@@ -20,0 +21,0 @@ };

@@ -1,2 +0,2 @@

import type { FakeFirestore } from '../firestore';
import type { FakeFirestore, FakeFirestoreDatabase } from '../firestore';

@@ -7,3 +7,3 @@ export type DocumentData = { [field: string]: unknown };

id?: string;
_collections: unknown; // TODO: FakeFirestore subcollections, to be defined later
_collections: FakeFirestoreDatabase;
_ref: typeof FakeFirestore.DocumentReference;

@@ -10,0 +10,0 @@ }

export const includeIdsInData: boolean;
export const mutable: boolean;
{
"name": "firestore-jest-mock",
"version": "0.11.1",
"version": "0.12.0",
"description": "Jest helper for mocking Google Cloud Firestore",

@@ -5,0 +5,0 @@ "author": "",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc