@dereekb/firebase 13.0.5 → 13.0.7
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/index.cjs.js +575 -146
- package/index.cjs.js.map +1 -1
- package/index.esm.js +573 -149
- package/index.esm.js.map +1 -1
- package/package.json +5 -5
- package/src/lib/common/firestore/accessor/document.rxjs.d.ts +55 -3
- package/src/lib/common/firestore/accessor/document.utility.d.ts +439 -128
- package/src/lib/common/firestore/query/constraint.d.ts +27 -22
- package/src/lib/common/firestore/query/constraint.template.d.ts +48 -32
- package/src/lib/common/firestore/query/iterator.d.ts +58 -2
- package/src/lib/common/firestore/query/query.iterate.d.ts +300 -96
- package/test/index.cjs.js +824 -15
- package/test/index.esm.js +826 -18
- package/test/package.json +6 -6
- package/test/src/lib/common/firestore/index.d.ts +1 -0
- package/test/src/lib/common/firestore/test.driver.utility.d.ts +7 -0
package/test/index.cjs.js
CHANGED
|
@@ -819,8 +819,8 @@ function describeFirestoreAccessorDriverTests(f) {
|
|
|
819
819
|
let mockItemFirestoreDocumentAccessor;
|
|
820
820
|
let items;
|
|
821
821
|
beforeEach(async () => {
|
|
822
|
-
mockItemFirestoreDocumentAccessor = f.instance.
|
|
823
|
-
items = await firebase.makeDocuments(f.instance.
|
|
822
|
+
mockItemFirestoreDocumentAccessor = f.instance.mockItemCollection.documentAccessor();
|
|
823
|
+
items = await firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
824
824
|
count: testDocumentCount,
|
|
825
825
|
init: (i) => {
|
|
826
826
|
return {
|
|
@@ -845,8 +845,8 @@ function describeFirestoreAccessorDriverTests(f) {
|
|
|
845
845
|
dataForUpdate: () => ({ test: false }),
|
|
846
846
|
hasRemainingDataFromFirstOfTwoUpdate: (data) => (data.tags?.length || 0) > 0 && data.tags?.[0] === 'a',
|
|
847
847
|
hasDataFromUpdate: (data) => data.test === false,
|
|
848
|
-
loadDocumentForTransaction: (transaction, ref) => f.instance.
|
|
849
|
-
loadDocumentForWriteBatch: (writeBatch, ref) => f.instance.
|
|
848
|
+
loadDocumentForTransaction: (transaction, ref) => f.instance.mockItemCollection.documentAccessorForTransaction(transaction).loadDocument(ref),
|
|
849
|
+
loadDocumentForWriteBatch: (writeBatch, ref) => f.instance.mockItemCollection.documentAccessorForWriteBatch(writeBatch).loadDocument(ref)
|
|
850
850
|
}));
|
|
851
851
|
describe('increment()', () => {
|
|
852
852
|
it(`should increase the item's value`, async () => {
|
|
@@ -887,7 +887,7 @@ function describeFirestoreAccessorDriverTests(f) {
|
|
|
887
887
|
it(`should increase the item's value`, async () => {
|
|
888
888
|
const update = { number: 3 };
|
|
889
889
|
await f.parent.firestoreContext.runTransaction(async (transaction) => {
|
|
890
|
-
const itemDocumentInTransaction = await f.instance.
|
|
890
|
+
const itemDocumentInTransaction = await f.instance.mockItemCollection.documentAccessorForTransaction(transaction).loadDocumentForId(itemDocument.id);
|
|
891
891
|
const data = await itemDocumentInTransaction.snapshotData();
|
|
892
892
|
expect(data?.number).toBe(undefined);
|
|
893
893
|
await itemDocumentInTransaction.increment(update);
|
|
@@ -900,7 +900,7 @@ function describeFirestoreAccessorDriverTests(f) {
|
|
|
900
900
|
it(`should increase the item's value`, async () => {
|
|
901
901
|
const update = { number: 3 };
|
|
902
902
|
const writeBatch = f.parent.firestoreContext.batch();
|
|
903
|
-
const itemDocumentForWriteBatch = await f.instance.
|
|
903
|
+
const itemDocumentForWriteBatch = await f.instance.mockItemCollection.documentAccessorForWriteBatch(writeBatch).loadDocumentForId(itemDocument.id);
|
|
904
904
|
await itemDocumentForWriteBatch.increment(update);
|
|
905
905
|
await writeBatch.commit();
|
|
906
906
|
const result = await itemDocument.snapshotData();
|
|
@@ -1577,7 +1577,7 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
1577
1577
|
const EVEN_TAG = 'even';
|
|
1578
1578
|
const ODD_TAG = 'odd';
|
|
1579
1579
|
beforeEach(async () => {
|
|
1580
|
-
items = await firebase.makeDocuments(f.instance.
|
|
1580
|
+
items = await firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
1581
1581
|
count: testDocumentCount,
|
|
1582
1582
|
init: (i) => {
|
|
1583
1583
|
return {
|
|
@@ -2166,7 +2166,7 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
2166
2166
|
describe('queryDocument', () => {
|
|
2167
2167
|
let queryDocument;
|
|
2168
2168
|
beforeEach(async () => {
|
|
2169
|
-
queryDocument = f.instance.
|
|
2169
|
+
queryDocument = f.instance.mockItemCollection.queryDocument;
|
|
2170
2170
|
});
|
|
2171
2171
|
describe('filter()', () => {
|
|
2172
2172
|
it('should apply the filter to the query', async () => {
|
|
@@ -2270,7 +2270,7 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
2270
2270
|
tryComplete();
|
|
2271
2271
|
});
|
|
2272
2272
|
// add one item
|
|
2273
|
-
util.waitForMs(10).then(() => firebase.makeDocuments(f.instance.
|
|
2273
|
+
util.waitForMs(10).then(() => firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
2274
2274
|
count: itemsToAdd,
|
|
2275
2275
|
init: (i) => {
|
|
2276
2276
|
return {
|
|
@@ -2346,7 +2346,7 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
2346
2346
|
tryComplete();
|
|
2347
2347
|
});
|
|
2348
2348
|
// add one item
|
|
2349
|
-
util.waitForMs(10).then(() => firebase.makeDocuments(f.instance.
|
|
2349
|
+
util.waitForMs(10).then(() => firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
2350
2350
|
count: itemsToAdd,
|
|
2351
2351
|
init: (i) => {
|
|
2352
2352
|
return {
|
|
@@ -2390,7 +2390,7 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
2390
2390
|
describe('query', () => {
|
|
2391
2391
|
let query;
|
|
2392
2392
|
beforeEach(async () => {
|
|
2393
|
-
query = f.instance.
|
|
2393
|
+
query = f.instance.mockItemCollection.query;
|
|
2394
2394
|
});
|
|
2395
2395
|
describe('streamDocs()', () => {
|
|
2396
2396
|
let sub;
|
|
@@ -2418,7 +2418,7 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
2418
2418
|
tryComplete();
|
|
2419
2419
|
});
|
|
2420
2420
|
// add one item
|
|
2421
|
-
util.waitForMs(10).then(() => firebase.makeDocuments(f.instance.
|
|
2421
|
+
util.waitForMs(10).then(() => firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
2422
2422
|
count: itemsToAdd,
|
|
2423
2423
|
init: (i) => {
|
|
2424
2424
|
return {
|
|
@@ -2643,7 +2643,7 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
2643
2643
|
const oddPrefix = mockItemIdentity.collectionType + 'd' + '/'; // similar, but not quite the same
|
|
2644
2644
|
const expectedNumberOfEvenValues = Math.ceil(testDocumentCount / 2);
|
|
2645
2645
|
beforeEach(async () => {
|
|
2646
|
-
items = await firebase.makeDocuments(f.instance.
|
|
2646
|
+
items = await firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
2647
2647
|
count: testDocumentCount,
|
|
2648
2648
|
init: (i) => {
|
|
2649
2649
|
const isEven = util.isEvenNumber(i);
|
|
@@ -2911,6 +2911,814 @@ function describeFirestoreQueryDriverTests(f) {
|
|
|
2911
2911
|
});
|
|
2912
2912
|
}
|
|
2913
2913
|
|
|
2914
|
+
/**
|
|
2915
|
+
* Describes utility driver tests, using a MockItemCollectionFixture.
|
|
2916
|
+
*
|
|
2917
|
+
* @param f
|
|
2918
|
+
*/
|
|
2919
|
+
function describeFirestoreDocumentUtilityTests(f) {
|
|
2920
|
+
describe('FirestoreDocumentUtilities', () => {
|
|
2921
|
+
const testDocumentCount = 5;
|
|
2922
|
+
let items;
|
|
2923
|
+
const startDate = dateFns.addDays(dateFns.startOfDay(new Date()), 1);
|
|
2924
|
+
const EVEN_TAG = 'even';
|
|
2925
|
+
const ODD_TAG = 'odd';
|
|
2926
|
+
beforeEach(async () => {
|
|
2927
|
+
items = await firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
2928
|
+
count: testDocumentCount,
|
|
2929
|
+
init: (i) => {
|
|
2930
|
+
return {
|
|
2931
|
+
value: `${i}`,
|
|
2932
|
+
number: i,
|
|
2933
|
+
date: dateFns.addHours(startDate, i),
|
|
2934
|
+
tags: [`${i}`, `${util.isEvenNumber(i) ? EVEN_TAG : ODD_TAG}`],
|
|
2935
|
+
test: true
|
|
2936
|
+
};
|
|
2937
|
+
}
|
|
2938
|
+
});
|
|
2939
|
+
});
|
|
2940
|
+
let sub;
|
|
2941
|
+
beforeEach(() => {
|
|
2942
|
+
sub = new rxjs.SubscriptionObject();
|
|
2943
|
+
});
|
|
2944
|
+
afterEach(() => {
|
|
2945
|
+
sub.destroy();
|
|
2946
|
+
});
|
|
2947
|
+
describe('query.util.ts', () => {
|
|
2948
|
+
// MARK: streamFromOnSnapshot
|
|
2949
|
+
describe('streamFromOnSnapshot()', () => {
|
|
2950
|
+
it('should call unsubscribe when the subscriber unsubscribes', () => {
|
|
2951
|
+
let unsubscribeCalled = false;
|
|
2952
|
+
const obs = firebase.streamFromOnSnapshot(({ next }) => {
|
|
2953
|
+
next('value');
|
|
2954
|
+
return () => {
|
|
2955
|
+
unsubscribeCalled = true;
|
|
2956
|
+
};
|
|
2957
|
+
});
|
|
2958
|
+
const subscription = obs.subscribe();
|
|
2959
|
+
expect(unsubscribeCalled).toBe(false);
|
|
2960
|
+
subscription.unsubscribe();
|
|
2961
|
+
expect(unsubscribeCalled).toBe(true);
|
|
2962
|
+
});
|
|
2963
|
+
it('should unsubscribe the onSnapshot listener when first() completes', () => {
|
|
2964
|
+
let unsubscribeCalled = false;
|
|
2965
|
+
const obs = firebase.streamFromOnSnapshot(({ next }) => {
|
|
2966
|
+
next('value');
|
|
2967
|
+
return () => {
|
|
2968
|
+
unsubscribeCalled = true;
|
|
2969
|
+
};
|
|
2970
|
+
});
|
|
2971
|
+
// first() completes the subscriber, then RxJS tears down the source
|
|
2972
|
+
const subscription = obs.pipe(rxjs$1.first()).subscribe();
|
|
2973
|
+
// After first() + subscribe complete synchronously, teardown should have run
|
|
2974
|
+
expect(subscription.closed).toBe(true);
|
|
2975
|
+
expect(unsubscribeCalled).toBe(true);
|
|
2976
|
+
});
|
|
2977
|
+
it('should unsubscribe onSnapshot listeners from document streams after subscriber unsubscribes', test.callbackTest((done) => {
|
|
2978
|
+
sub.subscription = firebase.latestSnapshotsFromDocuments(items)
|
|
2979
|
+
.pipe(rxjs$1.first())
|
|
2980
|
+
.subscribe({
|
|
2981
|
+
complete: () => {
|
|
2982
|
+
// With refCount: true on shareReplay, unsubscribing the last subscriber
|
|
2983
|
+
// tears down the source, which calls unsubscribe on each onSnapshot listener.
|
|
2984
|
+
// If this test completes without the "active listeners" error, the cleanup worked.
|
|
2985
|
+
done();
|
|
2986
|
+
}
|
|
2987
|
+
});
|
|
2988
|
+
}));
|
|
2989
|
+
});
|
|
2990
|
+
});
|
|
2991
|
+
describe('document.utility.ts', () => {
|
|
2992
|
+
// MARK: newDocuments
|
|
2993
|
+
describe('newDocuments()', () => {
|
|
2994
|
+
it('should create the specified number of document instances', () => {
|
|
2995
|
+
const count = 3;
|
|
2996
|
+
const docs = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), count);
|
|
2997
|
+
expect(docs.length).toBe(count);
|
|
2998
|
+
});
|
|
2999
|
+
it('should create documents with unique IDs', () => {
|
|
3000
|
+
const docs = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 3);
|
|
3001
|
+
const ids = docs.map((x) => x.id);
|
|
3002
|
+
expect(util.unique(ids).length).toBe(3);
|
|
3003
|
+
});
|
|
3004
|
+
it('should not persist documents to Firestore', async () => {
|
|
3005
|
+
const docs = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 2);
|
|
3006
|
+
for (const doc of docs) {
|
|
3007
|
+
const exists = await doc.exists();
|
|
3008
|
+
expect(exists).toBe(false);
|
|
3009
|
+
}
|
|
3010
|
+
});
|
|
3011
|
+
});
|
|
3012
|
+
// MARK: makeDocuments
|
|
3013
|
+
describe('makeDocuments()', () => {
|
|
3014
|
+
it('should create and persist documents in Firestore', async () => {
|
|
3015
|
+
const count = 3;
|
|
3016
|
+
const docs = await firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
3017
|
+
count,
|
|
3018
|
+
init: (i) => ({ value: `test_${i}`, test: true })
|
|
3019
|
+
});
|
|
3020
|
+
expect(docs.length).toBe(count);
|
|
3021
|
+
for (const doc of docs) {
|
|
3022
|
+
const exists = await doc.exists();
|
|
3023
|
+
expect(exists).toBe(true);
|
|
3024
|
+
}
|
|
3025
|
+
});
|
|
3026
|
+
it('should not persist documents when init returns null', async () => {
|
|
3027
|
+
const docs = await firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
3028
|
+
count: 2,
|
|
3029
|
+
init: () => null
|
|
3030
|
+
});
|
|
3031
|
+
expect(docs.length).toBe(2);
|
|
3032
|
+
for (const doc of docs) {
|
|
3033
|
+
const exists = await doc.exists();
|
|
3034
|
+
expect(exists).toBe(false);
|
|
3035
|
+
}
|
|
3036
|
+
});
|
|
3037
|
+
it('should use custom newDocument factory when provided', async () => {
|
|
3038
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3039
|
+
const customId = 'custom_doc_id';
|
|
3040
|
+
const docs = await firebase.makeDocuments(accessor, {
|
|
3041
|
+
count: 1,
|
|
3042
|
+
newDocument: (acc) => acc.loadDocumentForId(customId),
|
|
3043
|
+
init: () => ({ value: 'custom', test: true })
|
|
3044
|
+
});
|
|
3045
|
+
expect(docs.length).toBe(1);
|
|
3046
|
+
expect(docs[0].id).toBe(customId);
|
|
3047
|
+
const exists = await docs[0].exists();
|
|
3048
|
+
expect(exists).toBe(true);
|
|
3049
|
+
});
|
|
3050
|
+
});
|
|
3051
|
+
// MARK: getDocumentSnapshots
|
|
3052
|
+
describe('getDocumentSnapshots()', () => {
|
|
3053
|
+
it('should return snapshots for all documents', async () => {
|
|
3054
|
+
const snapshots = await firebase.getDocumentSnapshots(items);
|
|
3055
|
+
expect(snapshots.length).toBe(testDocumentCount);
|
|
3056
|
+
snapshots.forEach((snapshot) => {
|
|
3057
|
+
expect(snapshot.data()).toBeDefined();
|
|
3058
|
+
});
|
|
3059
|
+
});
|
|
3060
|
+
it('should preserve ordering of the input array', async () => {
|
|
3061
|
+
const snapshots = await firebase.getDocumentSnapshots(items);
|
|
3062
|
+
for (let i = 0; i < items.length; i++) {
|
|
3063
|
+
expect(snapshots[i].id).toBe(items[i].id);
|
|
3064
|
+
}
|
|
3065
|
+
});
|
|
3066
|
+
});
|
|
3067
|
+
// MARK: getDocumentSnapshotPair
|
|
3068
|
+
describe('getDocumentSnapshotPair()', () => {
|
|
3069
|
+
it('should return a pair with both document and snapshot', async () => {
|
|
3070
|
+
const pair = await firebase.getDocumentSnapshotPair(items[0]);
|
|
3071
|
+
expect(pair.document).toBe(items[0]);
|
|
3072
|
+
expect(pair.snapshot).toBeDefined();
|
|
3073
|
+
expect(pair.snapshot.data()).toBeDefined();
|
|
3074
|
+
expect(pair.snapshot.id).toBe(items[0].id);
|
|
3075
|
+
});
|
|
3076
|
+
});
|
|
3077
|
+
// MARK: getDocumentSnapshotPairs
|
|
3078
|
+
describe('getDocumentSnapshotPairs()', () => {
|
|
3079
|
+
it('should return pairs for all documents', async () => {
|
|
3080
|
+
const pairs = await firebase.getDocumentSnapshotPairs(items);
|
|
3081
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3082
|
+
pairs.forEach((pair, i) => {
|
|
3083
|
+
expect(pair.document).toBe(items[i]);
|
|
3084
|
+
expect(pair.snapshot.data()).toBeDefined();
|
|
3085
|
+
});
|
|
3086
|
+
});
|
|
3087
|
+
});
|
|
3088
|
+
// MARK: getDocumentSnapshotDataPair
|
|
3089
|
+
describe('getDocumentSnapshotDataPair()', () => {
|
|
3090
|
+
it('should return a triplet with document, snapshot, and data with id/key', async () => {
|
|
3091
|
+
const pair = await firebase.getDocumentSnapshotDataPair(items[0]);
|
|
3092
|
+
expect(pair.document).toBe(items[0]);
|
|
3093
|
+
expect(pair.snapshot).toBeDefined();
|
|
3094
|
+
expect(pair.data).toBeDefined();
|
|
3095
|
+
expect(pair.data.id).toBe(items[0].id);
|
|
3096
|
+
expect(pair.data.key).toBe(items[0].key);
|
|
3097
|
+
expect(pair.data.test).toBe(true);
|
|
3098
|
+
});
|
|
3099
|
+
it('should return undefined data for a non-existent document', async () => {
|
|
3100
|
+
const newDoc = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 1)[0];
|
|
3101
|
+
const pair = await firebase.getDocumentSnapshotDataPair(newDoc);
|
|
3102
|
+
expect(pair.document).toBe(newDoc);
|
|
3103
|
+
expect(pair.data).toBeUndefined();
|
|
3104
|
+
});
|
|
3105
|
+
});
|
|
3106
|
+
// MARK: getDocumentSnapshotDataPairs
|
|
3107
|
+
describe('getDocumentSnapshotDataPairs()', () => {
|
|
3108
|
+
it('should return triplets for all documents', async () => {
|
|
3109
|
+
const pairs = await firebase.getDocumentSnapshotDataPairs(items);
|
|
3110
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3111
|
+
pairs.forEach((pair, i) => {
|
|
3112
|
+
expect(pair.document).toBe(items[i]);
|
|
3113
|
+
expect(pair.data).toBeDefined();
|
|
3114
|
+
expect(pair.data.id).toBe(items[i].id);
|
|
3115
|
+
expect(pair.data.key).toBe(items[i].key);
|
|
3116
|
+
});
|
|
3117
|
+
});
|
|
3118
|
+
});
|
|
3119
|
+
// MARK: getDocumentSnapshotDataPairsWithData
|
|
3120
|
+
describe('getDocumentSnapshotDataPairsWithData()', () => {
|
|
3121
|
+
it('should return triplets for all existing documents', async () => {
|
|
3122
|
+
const pairs = await firebase.getDocumentSnapshotDataPairsWithData(items);
|
|
3123
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3124
|
+
pairs.forEach((pair) => {
|
|
3125
|
+
expect(pair.data).toBeDefined();
|
|
3126
|
+
expect(pair.data.id).toBeDefined();
|
|
3127
|
+
expect(pair.data.key).toBeDefined();
|
|
3128
|
+
});
|
|
3129
|
+
});
|
|
3130
|
+
it('should filter out non-existent documents', async () => {
|
|
3131
|
+
const newDoc = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 1)[0];
|
|
3132
|
+
const allDocs = [...items, newDoc];
|
|
3133
|
+
const pairs = await firebase.getDocumentSnapshotDataPairsWithData(allDocs);
|
|
3134
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3135
|
+
expect(pairs.every((p) => p.data != null)).toBe(true);
|
|
3136
|
+
});
|
|
3137
|
+
});
|
|
3138
|
+
// MARK: getDocumentSnapshotDataTuples
|
|
3139
|
+
describe('getDocumentSnapshotDataTuples()', () => {
|
|
3140
|
+
it('should return [document, data] tuples for all documents', async () => {
|
|
3141
|
+
const tuples = await firebase.getDocumentSnapshotDataTuples(items);
|
|
3142
|
+
expect(tuples.length).toBe(testDocumentCount);
|
|
3143
|
+
tuples.forEach((tuple, i) => {
|
|
3144
|
+
expect(tuple[0]).toBe(items[i]);
|
|
3145
|
+
expect(tuple[1]).toBeDefined();
|
|
3146
|
+
expect(tuple[1].test).toBe(true);
|
|
3147
|
+
});
|
|
3148
|
+
});
|
|
3149
|
+
it('should return undefined data for non-existent documents', async () => {
|
|
3150
|
+
const newDoc = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 1)[0];
|
|
3151
|
+
const tuples = await firebase.getDocumentSnapshotDataTuples([newDoc]);
|
|
3152
|
+
expect(tuples.length).toBe(1);
|
|
3153
|
+
expect(tuples[0][0]).toBe(newDoc);
|
|
3154
|
+
expect(tuples[0][1]).toBeUndefined();
|
|
3155
|
+
});
|
|
3156
|
+
});
|
|
3157
|
+
// MARK: getDocumentSnapshotData
|
|
3158
|
+
describe('getDocumentSnapshotData()', () => {
|
|
3159
|
+
it('should return data with id and key by default', async () => {
|
|
3160
|
+
const data = await firebase.getDocumentSnapshotData(items[0]);
|
|
3161
|
+
expect(data).toBeDefined();
|
|
3162
|
+
expect(data.id).toBe(items[0].id);
|
|
3163
|
+
expect(data.key).toBe(items[0].key);
|
|
3164
|
+
expect(data.test).toBe(true);
|
|
3165
|
+
});
|
|
3166
|
+
it('should return data with id and key when withId is true', async () => {
|
|
3167
|
+
const data = await firebase.getDocumentSnapshotData(items[0], true);
|
|
3168
|
+
expect(data).toBeDefined();
|
|
3169
|
+
expect(data.id).toBe(items[0].id);
|
|
3170
|
+
expect(data.key).toBe(items[0].key);
|
|
3171
|
+
});
|
|
3172
|
+
it('should return raw data without id/key when withId is false', async () => {
|
|
3173
|
+
const data = await firebase.getDocumentSnapshotData(items[0], false);
|
|
3174
|
+
expect(data).toBeDefined();
|
|
3175
|
+
expect(data.test).toBe(true);
|
|
3176
|
+
expect(data.id).toBeUndefined();
|
|
3177
|
+
expect(data.key).toBeUndefined();
|
|
3178
|
+
});
|
|
3179
|
+
it('should return undefined for a non-existent document', async () => {
|
|
3180
|
+
const newDoc = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 1)[0];
|
|
3181
|
+
const data = await firebase.getDocumentSnapshotData(newDoc);
|
|
3182
|
+
expect(data).toBeUndefined();
|
|
3183
|
+
});
|
|
3184
|
+
});
|
|
3185
|
+
// MARK: getDocumentSnapshotsData
|
|
3186
|
+
describe('getDocumentSnapshotsData()', () => {
|
|
3187
|
+
it('should return data for all existing documents with id/key by default', async () => {
|
|
3188
|
+
const data = await firebase.getDocumentSnapshotsData(items);
|
|
3189
|
+
expect(data.length).toBe(testDocumentCount);
|
|
3190
|
+
data.forEach((d) => {
|
|
3191
|
+
expect(d.id).toBeDefined();
|
|
3192
|
+
expect(d.key).toBeDefined();
|
|
3193
|
+
expect(d.test).toBe(true);
|
|
3194
|
+
});
|
|
3195
|
+
});
|
|
3196
|
+
it('should return raw data without id/key when withId is false', async () => {
|
|
3197
|
+
const data = await firebase.getDocumentSnapshotsData(items, false);
|
|
3198
|
+
expect(data.length).toBe(testDocumentCount);
|
|
3199
|
+
data.forEach((d) => {
|
|
3200
|
+
expect(d.test).toBe(true);
|
|
3201
|
+
});
|
|
3202
|
+
});
|
|
3203
|
+
});
|
|
3204
|
+
// MARK: getDataFromDocumentSnapshots
|
|
3205
|
+
describe('getDataFromDocumentSnapshots()', () => {
|
|
3206
|
+
it('should extract data with id/key from snapshots', async () => {
|
|
3207
|
+
const snapshots = await firebase.getDocumentSnapshots(items);
|
|
3208
|
+
const data = firebase.getDataFromDocumentSnapshots(snapshots);
|
|
3209
|
+
expect(data.length).toBe(testDocumentCount);
|
|
3210
|
+
data.forEach((d) => {
|
|
3211
|
+
expect(d.id).toBeDefined();
|
|
3212
|
+
expect(d.key).toBeDefined();
|
|
3213
|
+
});
|
|
3214
|
+
});
|
|
3215
|
+
it('should extract raw data when withId is false', async () => {
|
|
3216
|
+
const snapshots = await firebase.getDocumentSnapshots(items);
|
|
3217
|
+
const data = firebase.getDataFromDocumentSnapshots(snapshots, false);
|
|
3218
|
+
expect(data.length).toBe(testDocumentCount);
|
|
3219
|
+
});
|
|
3220
|
+
it('should filter out non-existent document snapshots', async () => {
|
|
3221
|
+
const newDoc = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 1)[0];
|
|
3222
|
+
const allDocs = [...items, newDoc];
|
|
3223
|
+
const snapshots = await firebase.getDocumentSnapshots(allDocs);
|
|
3224
|
+
const data = firebase.getDataFromDocumentSnapshots(snapshots);
|
|
3225
|
+
expect(data.length).toBe(testDocumentCount);
|
|
3226
|
+
});
|
|
3227
|
+
});
|
|
3228
|
+
// MARK: loadDocumentsForSnapshots
|
|
3229
|
+
describe('loadDocumentsForSnapshots()', () => {
|
|
3230
|
+
it('should load documents from a query snapshot', async () => {
|
|
3231
|
+
const querySnapshot = await f.instance.mockItemCollection.query(firebase.where('test', '==', true)).getDocs();
|
|
3232
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3233
|
+
const docs = firebase.loadDocumentsForSnapshots(accessor, querySnapshot);
|
|
3234
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3235
|
+
docs.forEach((doc) => {
|
|
3236
|
+
expect(doc).toBeDefined();
|
|
3237
|
+
expect(doc.id).toBeDefined();
|
|
3238
|
+
});
|
|
3239
|
+
});
|
|
3240
|
+
});
|
|
3241
|
+
// MARK: loadDocumentsForDocumentReferences
|
|
3242
|
+
describe('loadDocumentsForDocumentReferences()', () => {
|
|
3243
|
+
it('should load documents from references', () => {
|
|
3244
|
+
const refs = items.map((x) => x.documentRef);
|
|
3245
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3246
|
+
const docs = firebase.loadDocumentsForDocumentReferences(accessor, refs);
|
|
3247
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3248
|
+
docs.forEach((doc, i) => {
|
|
3249
|
+
expect(doc.id).toBe(items[i].id);
|
|
3250
|
+
});
|
|
3251
|
+
});
|
|
3252
|
+
});
|
|
3253
|
+
// MARK: loadDocumentsForDocumentReferencesFromValues
|
|
3254
|
+
describe('loadDocumentsForDocumentReferencesFromValues()', () => {
|
|
3255
|
+
it('should extract refs from values and load documents', () => {
|
|
3256
|
+
const values = items.map((x) => ({ ref: x.documentRef }));
|
|
3257
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3258
|
+
const docs = firebase.loadDocumentsForDocumentReferencesFromValues(accessor, values, (v) => v.ref);
|
|
3259
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3260
|
+
docs.forEach((doc, i) => {
|
|
3261
|
+
expect(doc.id).toBe(items[i].id);
|
|
3262
|
+
});
|
|
3263
|
+
});
|
|
3264
|
+
});
|
|
3265
|
+
// MARK: loadDocumentsForKeys
|
|
3266
|
+
describe('loadDocumentsForKeys()', () => {
|
|
3267
|
+
it('should load documents from keys', () => {
|
|
3268
|
+
const keys = items.map((x) => x.key);
|
|
3269
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3270
|
+
const docs = firebase.loadDocumentsForKeys(accessor, keys);
|
|
3271
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3272
|
+
docs.forEach((doc, i) => {
|
|
3273
|
+
expect(doc.key).toBe(items[i].key);
|
|
3274
|
+
});
|
|
3275
|
+
});
|
|
3276
|
+
});
|
|
3277
|
+
// MARK: loadDocumentsForKeysFromValues
|
|
3278
|
+
describe('loadDocumentsForKeysFromValues()', () => {
|
|
3279
|
+
it('should extract keys from values and load documents', () => {
|
|
3280
|
+
const values = items.map((x) => ({ k: x.key }));
|
|
3281
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3282
|
+
const docs = firebase.loadDocumentsForKeysFromValues(accessor, values, (v) => v.k);
|
|
3283
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3284
|
+
docs.forEach((doc, i) => {
|
|
3285
|
+
expect(doc.key).toBe(items[i].key);
|
|
3286
|
+
});
|
|
3287
|
+
});
|
|
3288
|
+
});
|
|
3289
|
+
// MARK: loadDocumentsForIds
|
|
3290
|
+
describe('loadDocumentsForIds()', () => {
|
|
3291
|
+
it('should load documents from IDs', () => {
|
|
3292
|
+
const ids = items.map((x) => x.id);
|
|
3293
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3294
|
+
const docs = firebase.loadDocumentsForIds(accessor, ids);
|
|
3295
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3296
|
+
docs.forEach((doc, i) => {
|
|
3297
|
+
expect(doc.id).toBe(items[i].id);
|
|
3298
|
+
});
|
|
3299
|
+
});
|
|
3300
|
+
});
|
|
3301
|
+
// MARK: loadDocumentsForIdsFromValues
|
|
3302
|
+
describe('loadDocumentsForIdsFromValues()', () => {
|
|
3303
|
+
it('should extract IDs from values and load documents', () => {
|
|
3304
|
+
const values = items.map((x) => ({ docId: x.id }));
|
|
3305
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3306
|
+
const docs = firebase.loadDocumentsForIdsFromValues(accessor, values, (v) => v.docId);
|
|
3307
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3308
|
+
docs.forEach((doc, i) => {
|
|
3309
|
+
expect(doc.id).toBe(items[i].id);
|
|
3310
|
+
});
|
|
3311
|
+
});
|
|
3312
|
+
});
|
|
3313
|
+
// MARK: firestoreDocumentLoader
|
|
3314
|
+
describe('firestoreDocumentLoader()', () => {
|
|
3315
|
+
it('should create a loader that loads documents from references', () => {
|
|
3316
|
+
const loader = firebase.firestoreDocumentLoader(f.instance.mockItemCollection);
|
|
3317
|
+
const refs = items.map((x) => x.documentRef);
|
|
3318
|
+
const docs = loader(refs);
|
|
3319
|
+
expect(docs.length).toBe(testDocumentCount);
|
|
3320
|
+
docs.forEach((doc, i) => {
|
|
3321
|
+
expect(doc.id).toBe(items[i].id);
|
|
3322
|
+
});
|
|
3323
|
+
});
|
|
3324
|
+
});
|
|
3325
|
+
// MARK: firestoreDocumentSnapshotPairsLoader
|
|
3326
|
+
describe('firestoreDocumentSnapshotPairsLoader()', () => {
|
|
3327
|
+
it('should create a loader that converts snapshots to data pairs', async () => {
|
|
3328
|
+
const loader = firebase.firestoreDocumentSnapshotPairsLoader(f.instance.mockItemCollection);
|
|
3329
|
+
const snapshots = await firebase.getDocumentSnapshots(items);
|
|
3330
|
+
const pairs = loader(snapshots);
|
|
3331
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3332
|
+
pairs.forEach((pair) => {
|
|
3333
|
+
expect(pair.document).toBeDefined();
|
|
3334
|
+
expect(pair.snapshot).toBeDefined();
|
|
3335
|
+
expect(pair.data).toBeDefined();
|
|
3336
|
+
expect(pair.data.id).toBeDefined();
|
|
3337
|
+
expect(pair.data.key).toBeDefined();
|
|
3338
|
+
});
|
|
3339
|
+
});
|
|
3340
|
+
});
|
|
3341
|
+
// MARK: documentData
|
|
3342
|
+
describe('documentData()', () => {
|
|
3343
|
+
it('should return data with id/key when withId is true', async () => {
|
|
3344
|
+
const snapshot = await items[0].accessor.get();
|
|
3345
|
+
const data = firebase.documentData(snapshot, true);
|
|
3346
|
+
expect(data).toBeDefined();
|
|
3347
|
+
expect(data.id).toBe(items[0].id);
|
|
3348
|
+
expect(data.key).toBe(items[0].key);
|
|
3349
|
+
});
|
|
3350
|
+
it('should return raw data when withId is false', async () => {
|
|
3351
|
+
const snapshot = await items[0].accessor.get();
|
|
3352
|
+
const data = firebase.documentData(snapshot, false);
|
|
3353
|
+
expect(data).toBeDefined();
|
|
3354
|
+
expect(data.test).toBe(true);
|
|
3355
|
+
});
|
|
3356
|
+
});
|
|
3357
|
+
// MARK: documentDataFunction
|
|
3358
|
+
describe('documentDataFunction()', () => {
|
|
3359
|
+
it('should return a function that extracts data with id/key when withId is true', async () => {
|
|
3360
|
+
const fn = firebase.documentDataFunction(true);
|
|
3361
|
+
const snapshot = await items[0].accessor.get();
|
|
3362
|
+
const data = fn(snapshot);
|
|
3363
|
+
expect(data).toBeDefined();
|
|
3364
|
+
expect(data.id).toBe(items[0].id);
|
|
3365
|
+
expect(data.key).toBe(items[0].key);
|
|
3366
|
+
});
|
|
3367
|
+
it('should return a function that extracts raw data when withId is false', async () => {
|
|
3368
|
+
const fn = firebase.documentDataFunction(false);
|
|
3369
|
+
const snapshot = await items[0].accessor.get();
|
|
3370
|
+
const data = fn(snapshot);
|
|
3371
|
+
expect(data).toBeDefined();
|
|
3372
|
+
expect(data.id).toBeUndefined();
|
|
3373
|
+
});
|
|
3374
|
+
});
|
|
3375
|
+
// MARK: documentDataWithIdAndKey
|
|
3376
|
+
describe('documentDataWithIdAndKey()', () => {
|
|
3377
|
+
it('should extract data with id and key from a snapshot', async () => {
|
|
3378
|
+
const snapshot = await items[0].accessor.get();
|
|
3379
|
+
const data = firebase.documentDataWithIdAndKey(snapshot);
|
|
3380
|
+
expect(data).toBeDefined();
|
|
3381
|
+
expect(data.id).toBe(items[0].id);
|
|
3382
|
+
expect(data.key).toBe(items[0].key);
|
|
3383
|
+
expect(data.test).toBe(true);
|
|
3384
|
+
});
|
|
3385
|
+
it('should return undefined for a non-existent document', async () => {
|
|
3386
|
+
const newDoc = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 1)[0];
|
|
3387
|
+
const snapshot = await newDoc.accessor.get();
|
|
3388
|
+
const data = firebase.documentDataWithIdAndKey(snapshot);
|
|
3389
|
+
expect(data).toBeUndefined();
|
|
3390
|
+
});
|
|
3391
|
+
});
|
|
3392
|
+
// MARK: setIdAndKeyFromSnapshotOnDocumentData
|
|
3393
|
+
describe('setIdAndKeyFromSnapshotOnDocumentData()', () => {
|
|
3394
|
+
it('should mutate data in-place to add id and key from snapshot', async () => {
|
|
3395
|
+
const snapshot = await items[0].accessor.get();
|
|
3396
|
+
const rawData = { test: true };
|
|
3397
|
+
const result = firebase.setIdAndKeyFromSnapshotOnDocumentData(rawData, snapshot);
|
|
3398
|
+
expect(result.id).toBe(items[0].id);
|
|
3399
|
+
expect(result.key).toBe(items[0].key);
|
|
3400
|
+
expect(result).toBe(rawData); // same reference
|
|
3401
|
+
});
|
|
3402
|
+
});
|
|
3403
|
+
// MARK: setIdAndKeyFromKeyIdRefOnDocumentData
|
|
3404
|
+
describe('setIdAndKeyFromKeyIdRefOnDocumentData()', () => {
|
|
3405
|
+
it('should mutate data in-place to add id and key from model ref', () => {
|
|
3406
|
+
const rawData = { test: true };
|
|
3407
|
+
const modelRef = { id: items[0].id, key: items[0].key };
|
|
3408
|
+
const result = firebase.setIdAndKeyFromKeyIdRefOnDocumentData(rawData, modelRef);
|
|
3409
|
+
expect(result.id).toBe(items[0].id);
|
|
3410
|
+
expect(result.key).toBe(items[0].key);
|
|
3411
|
+
expect(result).toBe(rawData);
|
|
3412
|
+
});
|
|
3413
|
+
});
|
|
3414
|
+
// MARK: useDocumentSnapshot
|
|
3415
|
+
describe('useDocumentSnapshot()', () => {
|
|
3416
|
+
it('should fetch snapshot and pass it to the use callback', async () => {
|
|
3417
|
+
const result = await firebase.useDocumentSnapshot(items[0], (snapshot) => {
|
|
3418
|
+
expect(snapshot.data()).toBeDefined();
|
|
3419
|
+
return snapshot.id;
|
|
3420
|
+
});
|
|
3421
|
+
expect(result).toBe(items[0].id);
|
|
3422
|
+
});
|
|
3423
|
+
it('should return default value when document is null', async () => {
|
|
3424
|
+
const result = await firebase.useDocumentSnapshot(null, () => 'used', 'default');
|
|
3425
|
+
expect(result).toBe('default');
|
|
3426
|
+
});
|
|
3427
|
+
});
|
|
3428
|
+
// MARK: useDocumentSnapshotData
|
|
3429
|
+
describe('useDocumentSnapshotData()', () => {
|
|
3430
|
+
it('should fetch snapshot data and pass it to the use callback', async () => {
|
|
3431
|
+
const result = await firebase.useDocumentSnapshotData(items[0], (data) => {
|
|
3432
|
+
expect(data.test).toBe(true);
|
|
3433
|
+
return data.value;
|
|
3434
|
+
});
|
|
3435
|
+
expect(result).toBe('0');
|
|
3436
|
+
});
|
|
3437
|
+
it('should return default value when document is null', async () => {
|
|
3438
|
+
const result = await firebase.useDocumentSnapshotData(null, () => 'used', 'default');
|
|
3439
|
+
expect(result).toBe('default');
|
|
3440
|
+
});
|
|
3441
|
+
});
|
|
3442
|
+
// MARK: Key Accessors
|
|
3443
|
+
describe('firestoreModelIdFromDocument()', () => {
|
|
3444
|
+
it('should return the document ID', () => {
|
|
3445
|
+
const id = firebase.firestoreModelIdFromDocument(items[0]);
|
|
3446
|
+
expect(id).toBe(items[0].id);
|
|
3447
|
+
});
|
|
3448
|
+
});
|
|
3449
|
+
describe('firestoreModelIdsFromDocuments()', () => {
|
|
3450
|
+
it('should return IDs for all documents', () => {
|
|
3451
|
+
const ids = firebase.firestoreModelIdsFromDocuments(items);
|
|
3452
|
+
expect(ids.length).toBe(testDocumentCount);
|
|
3453
|
+
ids.forEach((id, i) => {
|
|
3454
|
+
expect(id).toBe(items[i].id);
|
|
3455
|
+
});
|
|
3456
|
+
});
|
|
3457
|
+
});
|
|
3458
|
+
describe('firestoreModelKeyFromDocument()', () => {
|
|
3459
|
+
it('should return the full Firestore path', () => {
|
|
3460
|
+
const key = firebase.firestoreModelKeyFromDocument(items[0]);
|
|
3461
|
+
expect(key).toBe(items[0].key);
|
|
3462
|
+
});
|
|
3463
|
+
});
|
|
3464
|
+
describe('firestoreModelKeysFromDocuments()', () => {
|
|
3465
|
+
it('should return keys for all documents', () => {
|
|
3466
|
+
const keys = firebase.firestoreModelKeysFromDocuments(items);
|
|
3467
|
+
expect(keys.length).toBe(testDocumentCount);
|
|
3468
|
+
keys.forEach((key, i) => {
|
|
3469
|
+
expect(key).toBe(items[i].key);
|
|
3470
|
+
});
|
|
3471
|
+
});
|
|
3472
|
+
});
|
|
3473
|
+
describe('documentReferenceFromDocument()', () => {
|
|
3474
|
+
it('should return the document reference', () => {
|
|
3475
|
+
const ref = firebase.documentReferenceFromDocument(items[0]);
|
|
3476
|
+
expect(ref).toBe(items[0].documentRef);
|
|
3477
|
+
});
|
|
3478
|
+
});
|
|
3479
|
+
describe('documentReferencesFromDocuments()', () => {
|
|
3480
|
+
it('should return references for all documents', () => {
|
|
3481
|
+
const refs = firebase.documentReferencesFromDocuments(items);
|
|
3482
|
+
expect(refs.length).toBe(testDocumentCount);
|
|
3483
|
+
refs.forEach((ref, i) => {
|
|
3484
|
+
expect(ref).toBe(items[i].documentRef);
|
|
3485
|
+
});
|
|
3486
|
+
});
|
|
3487
|
+
});
|
|
3488
|
+
// MARK: limitedFirestoreDocumentAccessorSnapshotCache
|
|
3489
|
+
describe('limitedFirestoreDocumentAccessorSnapshotCache()', () => {
|
|
3490
|
+
it('should expose the underlying accessor', () => {
|
|
3491
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3492
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3493
|
+
expect(cache.accessor).toBe(accessor);
|
|
3494
|
+
});
|
|
3495
|
+
describe('getDocumentSnapshotDataPairForKey()', () => {
|
|
3496
|
+
it('should return a snapshot data pair for an existing document', async () => {
|
|
3497
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3498
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3499
|
+
const pair = await cache.getDocumentSnapshotDataPairForKey(items[0].key);
|
|
3500
|
+
expect(pair.document).toBeDefined();
|
|
3501
|
+
expect(pair.document.key).toBe(items[0].key);
|
|
3502
|
+
expect(pair.snapshot).toBeDefined();
|
|
3503
|
+
expect(pair.data).toBeDefined();
|
|
3504
|
+
expect(pair.data.id).toBe(items[0].id);
|
|
3505
|
+
expect(pair.data.key).toBe(items[0].key);
|
|
3506
|
+
});
|
|
3507
|
+
it('should return the same promise for the same key', async () => {
|
|
3508
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3509
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3510
|
+
const promise1 = cache.getDocumentSnapshotDataPairForKey(items[0].key);
|
|
3511
|
+
const promise2 = cache.getDocumentSnapshotDataPairForKey(items[0].key);
|
|
3512
|
+
expect(promise1).toBe(promise2);
|
|
3513
|
+
});
|
|
3514
|
+
it('should return undefined data for a non-existent document', async () => {
|
|
3515
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3516
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3517
|
+
const newDoc = firebase.newDocuments(accessor, 1)[0];
|
|
3518
|
+
const pair = await cache.getDocumentSnapshotDataPairForKey(newDoc.key);
|
|
3519
|
+
expect(pair.document).toBeDefined();
|
|
3520
|
+
expect(pair.data).toBeUndefined();
|
|
3521
|
+
});
|
|
3522
|
+
});
|
|
3523
|
+
describe('getDocumentSnapshotDataPairsForKeys()', () => {
|
|
3524
|
+
it('should return pairs for all keys in order', async () => {
|
|
3525
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3526
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3527
|
+
const keys = items.map((x) => x.key);
|
|
3528
|
+
const pairs = await cache.getDocumentSnapshotDataPairsForKeys(keys);
|
|
3529
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3530
|
+
pairs.forEach((pair, i) => {
|
|
3531
|
+
expect(pair.document.key).toBe(items[i].key);
|
|
3532
|
+
expect(pair.data).toBeDefined();
|
|
3533
|
+
expect(pair.data.id).toBe(items[i].id);
|
|
3534
|
+
});
|
|
3535
|
+
});
|
|
3536
|
+
it('should use the cache for duplicate keys', async () => {
|
|
3537
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3538
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3539
|
+
const key = items[0].key;
|
|
3540
|
+
const [pair1] = await cache.getDocumentSnapshotDataPairsForKeys([key]);
|
|
3541
|
+
const [pair2] = await cache.getDocumentSnapshotDataPairsForKeys([key]);
|
|
3542
|
+
expect(pair1).toBe(pair2);
|
|
3543
|
+
});
|
|
3544
|
+
});
|
|
3545
|
+
describe('getDocumentSnapshotDataPairsWithDataForKeys()', () => {
|
|
3546
|
+
it('should return pairs for all existing documents', async () => {
|
|
3547
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3548
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3549
|
+
const keys = items.map((x) => x.key);
|
|
3550
|
+
const pairs = await cache.getDocumentSnapshotDataPairsWithDataForKeys(keys);
|
|
3551
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3552
|
+
pairs.forEach((pair) => {
|
|
3553
|
+
expect(pair.data).toBeDefined();
|
|
3554
|
+
expect(pair.data.id).toBeDefined();
|
|
3555
|
+
expect(pair.data.key).toBeDefined();
|
|
3556
|
+
});
|
|
3557
|
+
});
|
|
3558
|
+
it('should filter out non-existent documents', async () => {
|
|
3559
|
+
const accessor = f.instance.mockItemCollection.documentAccessor();
|
|
3560
|
+
const cache = firebase.limitedFirestoreDocumentAccessorSnapshotCache(accessor);
|
|
3561
|
+
const newDoc = firebase.newDocuments(accessor, 1)[0];
|
|
3562
|
+
const keys = [...items.map((x) => x.key), newDoc.key];
|
|
3563
|
+
const pairs = await cache.getDocumentSnapshotDataPairsWithDataForKeys(keys);
|
|
3564
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3565
|
+
expect(pairs.every((p) => p.data != null)).toBe(true);
|
|
3566
|
+
});
|
|
3567
|
+
});
|
|
3568
|
+
});
|
|
3569
|
+
});
|
|
3570
|
+
describe('document.rxjs.ts', () => {
|
|
3571
|
+
// MARK: latestSnapshotsFromDocuments
|
|
3572
|
+
describe('latestSnapshotsFromDocuments()', () => {
|
|
3573
|
+
it('should emit snapshots for all documents', test.callbackTest((done) => {
|
|
3574
|
+
sub.subscription = firebase.latestSnapshotsFromDocuments(items)
|
|
3575
|
+
.pipe(rxjs$1.first())
|
|
3576
|
+
.subscribe((snapshots) => {
|
|
3577
|
+
expect(snapshots.length).toBe(testDocumentCount);
|
|
3578
|
+
snapshots.forEach((snapshot, i) => {
|
|
3579
|
+
expect(snapshot.data()).toBeDefined();
|
|
3580
|
+
expect(snapshot.id).toBe(items[i].id);
|
|
3581
|
+
});
|
|
3582
|
+
done();
|
|
3583
|
+
});
|
|
3584
|
+
}));
|
|
3585
|
+
it('should emit an empty array for empty input', test.callbackTest((done) => {
|
|
3586
|
+
sub.subscription = firebase.latestSnapshotsFromDocuments([])
|
|
3587
|
+
.pipe(rxjs$1.first())
|
|
3588
|
+
.subscribe((snapshots) => {
|
|
3589
|
+
expect(snapshots.length).toBe(0);
|
|
3590
|
+
done();
|
|
3591
|
+
});
|
|
3592
|
+
}));
|
|
3593
|
+
});
|
|
3594
|
+
// MARK: mapLatestSnapshotsFromDocuments
|
|
3595
|
+
describe('mapLatestSnapshotsFromDocuments()', () => {
|
|
3596
|
+
it('should apply the operator to each document stream', test.callbackTest((done) => {
|
|
3597
|
+
sub.subscription = firebase.mapLatestSnapshotsFromDocuments(items, rxjs$1.map((snapshot) => snapshot.id))
|
|
3598
|
+
.pipe(rxjs$1.first())
|
|
3599
|
+
.subscribe((ids) => {
|
|
3600
|
+
expect(ids.length).toBe(testDocumentCount);
|
|
3601
|
+
ids.forEach((id, i) => {
|
|
3602
|
+
expect(id).toBe(items[i].id);
|
|
3603
|
+
});
|
|
3604
|
+
done();
|
|
3605
|
+
});
|
|
3606
|
+
}));
|
|
3607
|
+
it('should emit an empty array for empty input', test.callbackTest((done) => {
|
|
3608
|
+
sub.subscription = firebase.mapLatestSnapshotsFromDocuments([], rxjs$1.map((snapshot) => snapshot.id))
|
|
3609
|
+
.pipe(rxjs$1.first())
|
|
3610
|
+
.subscribe((ids) => {
|
|
3611
|
+
expect(ids.length).toBe(0);
|
|
3612
|
+
done();
|
|
3613
|
+
});
|
|
3614
|
+
}));
|
|
3615
|
+
});
|
|
3616
|
+
// MARK: streamDocumentSnapshotsData
|
|
3617
|
+
describe('streamDocumentSnapshotsData()', () => {
|
|
3618
|
+
it('should emit data with id/key for all documents', test.callbackTest((done) => {
|
|
3619
|
+
sub.subscription = firebase.streamDocumentSnapshotsData(items)
|
|
3620
|
+
.pipe(rxjs$1.first())
|
|
3621
|
+
.subscribe((data) => {
|
|
3622
|
+
expect(data.length).toBe(testDocumentCount);
|
|
3623
|
+
data.forEach((d) => {
|
|
3624
|
+
expect(d.id).toBeDefined();
|
|
3625
|
+
expect(d.key).toBeDefined();
|
|
3626
|
+
expect(d.test).toBe(true);
|
|
3627
|
+
});
|
|
3628
|
+
done();
|
|
3629
|
+
});
|
|
3630
|
+
}));
|
|
3631
|
+
it('should emit an empty array for empty input', test.callbackTest((done) => {
|
|
3632
|
+
sub.subscription = firebase.streamDocumentSnapshotsData([])
|
|
3633
|
+
.pipe(rxjs$1.first())
|
|
3634
|
+
.subscribe((data) => {
|
|
3635
|
+
expect(data.length).toBe(0);
|
|
3636
|
+
done();
|
|
3637
|
+
});
|
|
3638
|
+
}));
|
|
3639
|
+
});
|
|
3640
|
+
// MARK: dataFromDocumentSnapshots operator
|
|
3641
|
+
describe('dataFromDocumentSnapshots()', () => {
|
|
3642
|
+
it('should transform snapshot arrays into data arrays with id/key', test.callbackTest((done) => {
|
|
3643
|
+
sub.subscription = firebase.latestSnapshotsFromDocuments(items)
|
|
3644
|
+
.pipe(firebase.dataFromDocumentSnapshots(), rxjs$1.first())
|
|
3645
|
+
.subscribe((data) => {
|
|
3646
|
+
expect(data.length).toBe(testDocumentCount);
|
|
3647
|
+
data.forEach((d) => {
|
|
3648
|
+
expect(d.id).toBeDefined();
|
|
3649
|
+
expect(d.key).toBeDefined();
|
|
3650
|
+
});
|
|
3651
|
+
done();
|
|
3652
|
+
});
|
|
3653
|
+
}));
|
|
3654
|
+
});
|
|
3655
|
+
// MARK: streamDocumentSnapshotDataPairs
|
|
3656
|
+
describe('streamDocumentSnapshotDataPairs()', () => {
|
|
3657
|
+
it('should emit snapshot-data pairs for all documents', test.callbackTest((done) => {
|
|
3658
|
+
sub.subscription = firebase.streamDocumentSnapshotDataPairs(items)
|
|
3659
|
+
.pipe(rxjs$1.first())
|
|
3660
|
+
.subscribe((pairs) => {
|
|
3661
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3662
|
+
pairs.forEach((pair, i) => {
|
|
3663
|
+
expect(pair.document).toBe(items[i]);
|
|
3664
|
+
expect(pair.snapshot).toBeDefined();
|
|
3665
|
+
expect(pair.snapshot.data()).toBeDefined();
|
|
3666
|
+
expect(pair.data).toBeDefined();
|
|
3667
|
+
expect(pair.data.id).toBe(items[i].id);
|
|
3668
|
+
expect(pair.data.key).toBe(items[i].key);
|
|
3669
|
+
expect(pair.data.test).toBe(true);
|
|
3670
|
+
});
|
|
3671
|
+
done();
|
|
3672
|
+
});
|
|
3673
|
+
}));
|
|
3674
|
+
it('should emit an empty array for empty input', test.callbackTest((done) => {
|
|
3675
|
+
sub.subscription = firebase.streamDocumentSnapshotDataPairs([])
|
|
3676
|
+
.pipe(rxjs$1.first())
|
|
3677
|
+
.subscribe((pairs) => {
|
|
3678
|
+
expect(pairs.length).toBe(0);
|
|
3679
|
+
done();
|
|
3680
|
+
});
|
|
3681
|
+
}));
|
|
3682
|
+
});
|
|
3683
|
+
// MARK: streamDocumentSnapshotDataPairsWithData
|
|
3684
|
+
describe('streamDocumentSnapshotDataPairsWithData()', () => {
|
|
3685
|
+
it('should emit snapshot-data pairs for all existing documents', test.callbackTest((done) => {
|
|
3686
|
+
sub.subscription = firebase.streamDocumentSnapshotDataPairsWithData(items)
|
|
3687
|
+
.pipe(rxjs$1.first())
|
|
3688
|
+
.subscribe((pairs) => {
|
|
3689
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3690
|
+
pairs.forEach((pair) => {
|
|
3691
|
+
expect(pair.data).toBeDefined();
|
|
3692
|
+
expect(pair.data.id).toBeDefined();
|
|
3693
|
+
expect(pair.data.key).toBeDefined();
|
|
3694
|
+
});
|
|
3695
|
+
done();
|
|
3696
|
+
});
|
|
3697
|
+
}));
|
|
3698
|
+
it('should filter out non-existent documents', test.callbackTest((done) => {
|
|
3699
|
+
const newDoc = firebase.newDocuments(f.instance.mockItemCollection.documentAccessor(), 1)[0];
|
|
3700
|
+
const allDocs = [...items, newDoc];
|
|
3701
|
+
sub.subscription = firebase.streamDocumentSnapshotDataPairsWithData(allDocs)
|
|
3702
|
+
.pipe(rxjs$1.first())
|
|
3703
|
+
.subscribe((pairs) => {
|
|
3704
|
+
expect(pairs.length).toBe(testDocumentCount);
|
|
3705
|
+
expect(pairs.every((p) => p.data != null)).toBe(true);
|
|
3706
|
+
done();
|
|
3707
|
+
});
|
|
3708
|
+
}));
|
|
3709
|
+
it('should emit an empty array for empty input', test.callbackTest((done) => {
|
|
3710
|
+
sub.subscription = firebase.streamDocumentSnapshotDataPairsWithData([])
|
|
3711
|
+
.pipe(rxjs$1.first())
|
|
3712
|
+
.subscribe((pairs) => {
|
|
3713
|
+
expect(pairs.length).toBe(0);
|
|
3714
|
+
done();
|
|
3715
|
+
});
|
|
3716
|
+
}));
|
|
3717
|
+
});
|
|
3718
|
+
});
|
|
3719
|
+
});
|
|
3720
|
+
}
|
|
3721
|
+
|
|
2914
3722
|
/**
|
|
2915
3723
|
* Describes accessor driver tests, using a MockItemCollectionFixture.
|
|
2916
3724
|
*
|
|
@@ -2923,8 +3731,8 @@ function describeFirestoreIterationTests(f) {
|
|
|
2923
3731
|
let items;
|
|
2924
3732
|
let sub;
|
|
2925
3733
|
beforeEach(async () => {
|
|
2926
|
-
firestoreIteration = f.instance.
|
|
2927
|
-
items = await firebase.makeDocuments(f.instance.
|
|
3734
|
+
firestoreIteration = f.instance.mockItemCollection.firestoreIteration;
|
|
3735
|
+
items = await firebase.makeDocuments(f.instance.mockItemCollection.documentAccessor(), {
|
|
2928
3736
|
count: testDocumentCount,
|
|
2929
3737
|
init: (i) => {
|
|
2930
3738
|
return {
|
|
@@ -3832,6 +4640,7 @@ exports.clearTestFirestoreContextCollections = clearTestFirestoreContextCollecti
|
|
|
3832
4640
|
exports.describeFirebaseStorageAccessorDriverTests = describeFirebaseStorageAccessorDriverTests;
|
|
3833
4641
|
exports.describeFirestoreAccessorDriverTests = describeFirestoreAccessorDriverTests;
|
|
3834
4642
|
exports.describeFirestoreDocumentAccessorTests = describeFirestoreDocumentAccessorTests;
|
|
4643
|
+
exports.describeFirestoreDocumentUtilityTests = describeFirestoreDocumentUtilityTests;
|
|
3835
4644
|
exports.describeFirestoreIterationTests = describeFirestoreIterationTests;
|
|
3836
4645
|
exports.describeFirestoreQueryDriverTests = describeFirestoreQueryDriverTests;
|
|
3837
4646
|
exports.firebaseRulesUnitTestBuilder = firebaseRulesUnitTestBuilder;
|