merge master into omer_links

This commit is contained in:
Omer Levy
2017-10-08 03:52:19 +03:00
31 changed files with 1213 additions and 618 deletions

View File

@@ -13,6 +13,7 @@ import io.invertase.firebase.database.RNFirebaseDatabasePackage;
import io.invertase.firebase.firestore.RNFirebaseFirestorePackage;
import io.invertase.firebase.links.RNFirebaseLinksPackage;
import io.invertase.firebase.messaging.RNFirebaseMessagingPackage;
import io.invertase.firebase.perf.RNFirebasePerformancePackage;
import io.invertase.firebase.storage.RNFirebaseStoragePackage;
import com.oblador.vectoricons.VectorIconsPackage;
import com.facebook.react.ReactNativeHost;
@@ -46,7 +47,7 @@ public class MainApplication extends Application implements ReactApplication {
new RNFirebaseFirestorePackage(),
new RNFirebaseLinksPackage(),
new RNFirebaseMessagingPackage(),
// new RNFirebasePerformancePackage(),
new RNFirebasePerformancePackage(),
new RNFirebaseStoragePackage()
);
}

View File

@@ -129,30 +129,30 @@ PODS:
- nanopb/decode (0.3.8)
- nanopb/encode (0.3.8)
- Protobuf (3.4.0)
- React (0.49.0-rc.6):
- React/Core (= 0.49.0-rc.6)
- React/BatchedBridge (0.49.0-rc.6):
- React (0.49.1):
- React/Core (= 0.49.1)
- React/BatchedBridge (0.49.1):
- React/Core
- React/cxxreact_legacy
- React/Core (0.49.0-rc.6):
- yoga (= 0.49.0-rc.6.React)
- React/cxxreact_legacy (0.49.0-rc.6):
- React/Core (0.49.1):
- yoga (= 0.49.1.React)
- React/cxxreact_legacy (0.49.1):
- React/jschelpers_legacy
- React/fishhook (0.49.0-rc.6)
- React/jschelpers_legacy (0.49.0-rc.6)
- React/RCTBlob (0.49.0-rc.6):
- React/fishhook (0.49.1)
- React/jschelpers_legacy (0.49.1)
- React/RCTBlob (0.49.1):
- React/Core
- React/RCTNetwork (0.49.0-rc.6):
- React/RCTNetwork (0.49.1):
- React/Core
- React/RCTText (0.49.0-rc.6):
- React/RCTText (0.49.1):
- React/Core
- React/RCTWebSocket (0.49.0-rc.6):
- React/RCTWebSocket (0.49.1):
- React/Core
- React/fishhook
- React/RCTBlob
- RNFirebase (3.0.0):
- React
- yoga (0.49.0-rc.6.React)
- yoga (0.49.1.React)
DEPENDENCIES:
- Firebase/AdMob
@@ -207,9 +207,9 @@ SPEC CHECKSUMS:
leveldb-library: 10fb39c39e243db4af1828441162405bbcec1404
nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3
Protobuf: 03eef2ee0b674770735cf79d9c4d3659cf6908e8
React: e6ef6a41ec6dd1b7941417d60ca582bf5e9c739d
RNFirebase: 2ceda3aef595ea1379bf5bfcc1cd9ee7d6c05d3b
yoga: f9485d2ebf0ca773db2d727ea71b1aa8c9f3e075
React: cf892fb84b7d06bf5fea7f328e554c6dcabe85ee
RNFirebase: 901a473c68fcbaa28125c56a911923f2fbe5d61b
yoga: 3abf02d6d9aeeb139b4c930eb1367feae690a35a
PODFILE CHECKSUM: b5674be55653f5dda937c8b794d0479900643d45

View File

@@ -48,13 +48,14 @@ function coreTests({ describe, it }) {
it('it should provide an array of apps', () => {
should.equal(!!RNFirebase.apps.length, true);
should.equal(RNFirebase.apps[0]._name, RNFirebase.DEFAULT_APP_NAME);
should.equal(RNFirebase.apps[0]._name, RNFirebase.utils.DEFAULT_APP_NAME);
should.equal(RNFirebase.apps[0].name, '[DEFAULT]');
return Promise.resolve();
});
// todo move to UTILS module tests
it('it should provide the sdk version', () => {
should.equal(!!RNFirebase.SDK_VERSION.length, true);
should.equal(!!RNFirebase.utils.VERSIONS['react-native-firebase'].length, true);
return Promise.resolve();
});

View File

@@ -53,262 +53,360 @@ function collectionReferenceTests({ describe, it, context, firebase }) {
});
context('onSnapshot()', () => {
it('calls callback with the initial data and then when document changes', () => {
return new Promise(async (resolve) => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
it('calls callback with the initial data and then when document changes', async () => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
const callback = sinon.spy();
const callback = sinon.spy();
// Test
// Test
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDocValue);
callback.should.be.calledTwice();
// Tear down
unsubscribe();
resolve();
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDocValue);
callback.should.be.calledTwice();
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('calls callback with the initial data and then when document is added', () => {
return new Promise(async (resolve) => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
it('calls callback with the initial data and then when document is added', async () => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
const callback = sinon.spy();
const callback = sinon.spy();
// Test
// Test
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc2');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(currentDocValue);
callback.should.be.calledWith(newDocValue);
callback.should.be.calledThrice();
// Tear down
unsubscribe();
resolve();
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc2');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(currentDocValue);
callback.should.be.calledWith(newDocValue);
callback.should.be.calledThrice();
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('doesn\'t call callback when the ref is updated with the same value', async () => {
return new Promise(async (resolve) => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const callback = sinon.spy();
const callback = sinon.spy();
// Test
// Test
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = collectionRef.onSnapshot((snapshot) => {
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(currentDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledOnce(); // Callback is not called again
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('allows binding multiple callbacks to the same ref', async () => {
// Setup
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
const callbackA = sinon.spy();
const callbackB = sinon.spy();
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackA(doc.data()));
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackB(doc.data()));
resolve2();
});
});
callbackA.should.be.calledWith(currentDocValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDocValue);
callbackB.should.be.calledOnce();
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDocValue);
callbackB.should.be.calledWith(newDocValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Tear down
unsubscribeA();
unsubscribeB();
});
});
context('onSnapshot()', () => {
it('listener stops listening when unsubscribed', async () => {
// Setup
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
const callbackA = sinon.spy();
const callbackB = sinon.spy();
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackA(doc.data()));
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackB(doc.data()));
resolve2();
});
});
callbackA.should.be.calledWith(currentDocValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDocValue);
callbackB.should.be.calledOnce();
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDocValue);
callbackB.should.be.calledWith(newDocValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Unsubscribe A
unsubscribeA();
await docRef.set(currentDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackB.should.be.calledWith(currentDocValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
// Unsubscribe B
unsubscribeB();
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
});
});
context('onSnapshot()', () => {
it('supports options and callback', async () => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
const callback = sinon.spy();
// Test
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = collectionRef.onSnapshot({ includeQueryMetadataChanges: true, includeDocumentMetadataChanges: true }, (snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDocValue);
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('supports observer', async () => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
const callback = sinon.spy();
// Test
let unsubscribe;
await new Promise((resolve2) => {
const observer = {
next: (snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(currentDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledOnce(); // Callback is not called again
// Tear down
unsubscribe();
resolve();
},
};
unsubscribe = collectionRef.onSnapshot(observer);
});
callback.should.be.calledWith(currentDocValue);
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDocValue);
callback.should.be.calledTwice();
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('allows binding multiple callbacks to the same ref', () => {
return new Promise(async (resolve) => {
// Setup
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
it('supports options and observer', async () => {
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
const callbackA = sinon.spy();
const callbackB = sinon.spy();
const callback = sinon.spy();
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackA(doc.data()));
// Test
let unsubscribe;
await new Promise((resolve2) => {
const observer = {
next: (snapshot) => {
snapshot.forEach(doc => callback(doc.data()));
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackB(doc.data()));
resolve2();
});
});
callbackA.should.be.calledWith(currentDocValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDocValue);
callbackB.should.be.calledOnce();
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDocValue);
callbackB.should.be.calledWith(newDocValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Tear down
unsubscribeA();
unsubscribeB();
resolve();
},
};
unsubscribe = collectionRef.onSnapshot({ includeQueryMetadataChanges: true, includeDocumentMetadataChanges: true }, observer);
});
});
});
context('onSnapshot()', () => {
it('listener stops listening when unsubscribed', () => {
return new Promise(async (resolve) => {
// Setup
const collectionRef = firebase.native.firestore().collection('document-tests');
const currentDocValue = { name: 'doc1' };
const newDocValue = { name: 'updated' };
callback.should.be.calledWith(currentDocValue);
const callbackA = sinon.spy();
const callbackB = sinon.spy();
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackA(doc.data()));
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = collectionRef.onSnapshot((snapshot) => {
snapshot.forEach(doc => callbackB(doc.data()));
resolve2();
});
});
callbackA.should.be.calledWith(currentDocValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDocValue);
callbackB.should.be.calledOnce();
const docRef = firebase.native.firestore().doc('document-tests/doc1');
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDocValue);
callbackB.should.be.calledWith(newDocValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Unsubscribe A
unsubscribeA();
await docRef.set(currentDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackB.should.be.calledWith(currentDocValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
// Unsubscribe B
unsubscribeB();
await docRef.set(newDocValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
resolve();
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDocValue);
// Tear down
unsubscribe();
});
});

View File

@@ -2,7 +2,7 @@ import sinon from 'sinon';
import 'should-sinon';
import should from 'should';
function collectionReferenceTests({ describe, it, context, firebase }) {
function documentReferenceTests({ describe, it, context, firebase }) {
describe('DocumentReference', () => {
context('class', () => {
it('should return instance methods', () => {
@@ -29,219 +29,324 @@ function collectionReferenceTests({ describe, it, context, firebase }) {
});
context('onSnapshot()', () => {
it('calls callback with the initial data and then when value changes', () => {
return new Promise(async (resolve) => {
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
it('calls callback with the initial data and then when value changes', async () => {
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
const callback = sinon.spy();
const callback = sinon.spy();
// Test
// Test
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = docRef.onSnapshot((snapshot) => {
callback(snapshot.data());
resolve2();
});
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = docRef.onSnapshot((snapshot) => {
callback(snapshot.data());
resolve2();
});
callback.should.be.calledWith(currentDataValue);
// Update the document
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDataValue);
callback.should.be.calledTwice();
// Tear down
unsubscribe();
resolve();
});
callback.should.be.calledWith(currentDataValue);
// Update the document
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDataValue);
callback.should.be.calledTwice();
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('doesn\'t call callback when the ref is updated with the same value', async () => {
return new Promise(async (resolve) => {
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const callback = sinon.spy();
const callback = sinon.spy();
// Test
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = docRef.onSnapshot((snapshot) => {
callback(snapshot.data());
resolve2();
});
});
callback.should.be.calledWith(currentDataValue);
await docRef.set(currentDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledOnce(); // Callback is not called again
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('allows binding multiple callbacks to the same ref', async () => {
// Setup
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
const callbackA = sinon.spy();
const callbackB = sinon.spy();
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = docRef.onSnapshot((snapshot) => {
callbackA(snapshot.data());
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = docRef.onSnapshot((snapshot) => {
callbackB(snapshot.data());
resolve2();
});
});
callbackA.should.be.calledWith(currentDataValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDataValue);
callbackB.should.be.calledOnce();
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDataValue);
callbackB.should.be.calledWith(newDataValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Tear down
unsubscribeA();
unsubscribeB();
});
});
context('onSnapshot()', () => {
it('listener stops listening when unsubscribed', async () => {
// Setup
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
const callbackA = sinon.spy();
const callbackB = sinon.spy();
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = docRef.onSnapshot((snapshot) => {
callbackA(snapshot.data());
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = docRef.onSnapshot((snapshot) => {
callbackB(snapshot.data());
resolve2();
});
});
callbackA.should.be.calledWith(currentDataValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDataValue);
callbackB.should.be.calledOnce();
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDataValue);
callbackB.should.be.calledWith(newDataValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Unsubscribe A
unsubscribeA();
await docRef.set(currentDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackB.should.be.calledWith(currentDataValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
// Unsubscribe B
unsubscribeB();
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
});
});
context('onSnapshot()', () => {
it('supports options and callbacks', async () => {
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
const callback = sinon.spy();
// Test
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = docRef.onSnapshot((snapshot) => {
callback(snapshot.data());
resolve2();
});
let unsubscribe;
await new Promise((resolve2) => {
unsubscribe = docRef.onSnapshot({ includeMetadataChanges: true }, (snapshot) => {
callback(snapshot.data());
resolve2();
});
});
callback.should.be.calledWith(currentDataValue);
callback.should.be.calledWith(currentDataValue);
await docRef.set(currentDataValue);
// Update the document
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledOnce(); // Callback is not called again
callback.should.be.calledWith(newDataValue);
// Tear down
unsubscribe();
resolve();
});
unsubscribe();
});
});
context('onSnapshot()', () => {
it('allows binding multiple callbacks to the same ref', () => {
return new Promise(async (resolve) => {
// Setup
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
it('supports observer', async () => {
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
const callbackA = sinon.spy();
const callbackB = sinon.spy();
const callback = sinon.spy();
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = docRef.onSnapshot((snapshot) => {
callbackA(snapshot.data());
// Test
let unsubscribe;
await new Promise((resolve2) => {
const observer = {
next: (snapshot) => {
callback(snapshot.data());
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = docRef.onSnapshot((snapshot) => {
callbackB(snapshot.data());
resolve2();
});
});
callbackA.should.be.calledWith(currentDataValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDataValue);
callbackB.should.be.calledOnce();
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDataValue);
callbackB.should.be.calledWith(newDataValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Tear down
unsubscribeA();
unsubscribeB();
resolve();
},
};
unsubscribe = docRef.onSnapshot(observer);
});
callback.should.be.calledWith(currentDataValue);
// Update the document
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDataValue);
callback.should.be.calledTwice();
// Tear down
unsubscribe();
});
});
context('onSnapshot()', () => {
it('listener stops listening when unsubscribed', () => {
return new Promise(async (resolve) => {
// Setup
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
it('supports options and observer', async () => {
const docRef = firebase.native.firestore().doc('document-tests/doc1');
const currentDataValue = { name: 'doc1' };
const newDataValue = { name: 'updated' };
const callbackA = sinon.spy();
const callbackB = sinon.spy();
const callback = sinon.spy();
// Test
let unsubscribeA;
let unsubscribeB;
await new Promise((resolve2) => {
unsubscribeA = docRef.onSnapshot((snapshot) => {
callbackA(snapshot.data());
// Test
let unsubscribe;
await new Promise((resolve2) => {
const observer = {
next: (snapshot) => {
callback(snapshot.data());
resolve2();
});
});
await new Promise((resolve2) => {
unsubscribeB = docRef.onSnapshot((snapshot) => {
callbackB(snapshot.data());
resolve2();
});
});
callbackA.should.be.calledWith(currentDataValue);
callbackA.should.be.calledOnce();
callbackB.should.be.calledWith(currentDataValue);
callbackB.should.be.calledOnce();
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledWith(newDataValue);
callbackB.should.be.calledWith(newDataValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledTwice();
// Unsubscribe A
unsubscribeA();
await docRef.set(currentDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackB.should.be.calledWith(currentDataValue);
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
// Unsubscribe B
unsubscribeB();
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
callbackA.should.be.calledTwice();
callbackB.should.be.calledThrice();
resolve();
},
};
unsubscribe = docRef.onSnapshot({ includeMetadataChanges: true }, observer);
});
callback.should.be.calledWith(currentDataValue);
// Update the document
await docRef.set(newDataValue);
await new Promise((resolve2) => {
setTimeout(() => resolve2(), 5);
});
// Assertions
callback.should.be.calledWith(newDataValue);
// Tear down
unsubscribe();
});
});
@@ -283,10 +388,22 @@ function collectionReferenceTests({ describe, it, context, firebase }) {
});
context('update()', () => {
it('should update Document', () => {
it('should update Document using object', () => {
return firebase.native.firestore()
.doc('document-tests/doc1')
.set({ name: 'updated' })
.update({ name: 'updated' })
.then(async () => {
const doc = await firebase.native.firestore().doc('document-tests/doc1').get();
doc.data().name.should.equal('updated');
});
});
});
context('update()', () => {
it('should update Document using key/value pairs', () => {
return firebase.native.firestore()
.doc('document-tests/doc1')
.update('name', 'updated')
.then(async () => {
const doc = await firebase.native.firestore().doc('document-tests/doc1').get();
doc.data().name.should.equal('updated');
@@ -296,4 +413,4 @@ function collectionReferenceTests({ describe, it, context, firebase }) {
});
}
export default collectionReferenceTests;
export default documentReferenceTests;

View File

@@ -36,7 +36,7 @@ function firestoreTests({ describe, it, context, firebase }) {
.set(nycRef, { name: 'New York City' })
.set(sfRef, { name: 'San Francisco' })
.update(nycRef, { population: 1000000 })
.update(sfRef, { name: 'San Fran' })
.update(sfRef, 'name', 'San Fran')
.set(lRef, { population: 3000000 }, { merge: true })
.delete(ayRef)
.commit()