@dereekb/firebase 12.6.21 → 13.0.0

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.
Files changed (84) hide show
  1. package/LICENSE +1 -1
  2. package/index.cjs.js +53 -2239
  3. package/index.esm.js +34 -2216
  4. package/package.json +21 -15
  5. package/src/lib/client/storage/driver.accessor.d.ts +1 -1
  6. package/src/lib/common/firestore/query/iterator.d.ts +0 -4
  7. package/src/lib/common/firestore/snapshot/snapshot.field.d.ts +0 -6
  8. package/src/lib/common/model/model.service.d.ts +1 -1
  9. package/src/lib/common/storage/driver/accessor.d.ts +1 -1
  10. package/src/lib/common/storage/types.d.ts +3 -3
  11. package/src/lib/model/notification/notification.api.d.ts +1 -1
  12. package/src/lib/model/notification/notification.config.d.ts +5 -5
  13. package/src/lib/model/notification/notification.d.ts +15 -15
  14. package/src/lib/model/notification/notification.details.d.ts +0 -4
  15. package/src/lib/model/notification/notification.item.d.ts +1 -1
  16. package/src/lib/model/storagefile/storagefile.api.d.ts +4 -4
  17. package/src/lib/model/storagefile/storagefile.d.ts +7 -7
  18. package/src/lib/model/storagefile/storagefile.task.d.ts +1 -13
  19. package/src/lib/model/system/system.d.ts +2 -2
  20. package/test/index.cjs.js +4043 -0
  21. package/test/index.esm.js +3957 -0
  22. package/test/package.json +27 -9
  23. package/test/src/lib/client/firebase.authorized.d.ts +2 -2
  24. package/test/src/lib/client/firebase.d.ts +4 -3
  25. package/test/src/lib/client/firestore.mock.item.fixture.authorized.d.ts +2 -2
  26. package/test/src/lib/common/firebase.instance.d.ts +7 -3
  27. package/test/src/lib/common/firestore/firestore.instance.d.ts +7 -3
  28. package/test/src/lib/common/mock/mock.item.collection.fixture.d.ts +5 -2
  29. package/test/src/lib/common/mock/mock.item.storage.fixture.d.ts +4 -4
  30. package/test/src/lib/common/storage/storage.instance.d.ts +7 -3
  31. package/test/CHANGELOG.md +0 -2114
  32. package/test/README.md +0 -11
  33. package/test/src/index.js +0 -5
  34. package/test/src/index.js.map +0 -1
  35. package/test/src/lib/client/firebase.authorized.js +0 -35
  36. package/test/src/lib/client/firebase.authorized.js.map +0 -1
  37. package/test/src/lib/client/firebase.js +0 -125
  38. package/test/src/lib/client/firebase.js.map +0 -1
  39. package/test/src/lib/client/firestore.mock.item.fixture.authorized.js +0 -19
  40. package/test/src/lib/client/firestore.mock.item.fixture.authorized.js.map +0 -1
  41. package/test/src/lib/client/index.js +0 -7
  42. package/test/src/lib/client/index.js.map +0 -1
  43. package/test/src/lib/common/firebase.instance.js +0 -35
  44. package/test/src/lib/common/firebase.instance.js.map +0 -1
  45. package/test/src/lib/common/firestore/firestore.instance.js +0 -24
  46. package/test/src/lib/common/firestore/firestore.instance.js.map +0 -1
  47. package/test/src/lib/common/firestore/firestore.js +0 -67
  48. package/test/src/lib/common/firestore/firestore.js.map +0 -1
  49. package/test/src/lib/common/firestore/index.js +0 -9
  50. package/test/src/lib/common/firestore/index.js.map +0 -1
  51. package/test/src/lib/common/firestore/test.driver.accessor.js +0 -767
  52. package/test/src/lib/common/firestore/test.driver.accessor.js.map +0 -1
  53. package/test/src/lib/common/firestore/test.driver.query.js +0 -1361
  54. package/test/src/lib/common/firestore/test.driver.query.js.map +0 -1
  55. package/test/src/lib/common/firestore/test.iterator.js +0 -221
  56. package/test/src/lib/common/firestore/test.iterator.js.map +0 -1
  57. package/test/src/lib/common/index.js +0 -8
  58. package/test/src/lib/common/index.js.map +0 -1
  59. package/test/src/lib/common/mock/index.js +0 -10
  60. package/test/src/lib/common/mock/index.js.map +0 -1
  61. package/test/src/lib/common/mock/mock.item.collection.fixture.js +0 -64
  62. package/test/src/lib/common/mock/mock.item.collection.fixture.js.map +0 -1
  63. package/test/src/lib/common/mock/mock.item.id.js +0 -3
  64. package/test/src/lib/common/mock/mock.item.id.js.map +0 -1
  65. package/test/src/lib/common/mock/mock.item.js +0 -339
  66. package/test/src/lib/common/mock/mock.item.js.map +0 -1
  67. package/test/src/lib/common/mock/mock.item.query.js +0 -33
  68. package/test/src/lib/common/mock/mock.item.query.js.map +0 -1
  69. package/test/src/lib/common/mock/mock.item.service.js +0 -77
  70. package/test/src/lib/common/mock/mock.item.service.js.map +0 -1
  71. package/test/src/lib/common/mock/mock.item.storage.fixture.js +0 -40
  72. package/test/src/lib/common/mock/mock.item.storage.fixture.js.map +0 -1
  73. package/test/src/lib/common/storage/index.js +0 -7
  74. package/test/src/lib/common/storage/index.js.map +0 -1
  75. package/test/src/lib/common/storage/storage.instance.js +0 -24
  76. package/test/src/lib/common/storage/storage.instance.js.map +0 -1
  77. package/test/src/lib/common/storage/storage.js +0 -37
  78. package/test/src/lib/common/storage/storage.js.map +0 -1
  79. package/test/src/lib/common/storage/test.driver.accessor.js +0 -669
  80. package/test/src/lib/common/storage/test.driver.accessor.js.map +0 -1
  81. package/test/src/lib/index.js +0 -6
  82. package/test/src/lib/index.js.map +0 -1
  83. /package/{index.cjs.d.ts → index.d.ts} +0 -0
  84. /package/{index.esm.d.ts → test/index.d.ts} +0 -0
@@ -1,767 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.describeFirestoreAccessorDriverTests = describeFirestoreAccessorDriverTests;
4
- exports.describeFirestoreDocumentAccessorTests = describeFirestoreDocumentAccessorTests;
5
- const test_1 = require("@dereekb/util/test");
6
- const rxjs_1 = require("rxjs");
7
- const rxjs_2 = require("@dereekb/rxjs");
8
- const firebase_1 = require("@dereekb/firebase");
9
- const mock_1 = require("../mock");
10
- /**
11
- * Describes accessor driver tests, using a MockItemCollectionFixture.
12
- *
13
- * @param f
14
- */
15
- function describeFirestoreAccessorDriverTests(f) {
16
- describe('FirestoreAccessorDriver', () => {
17
- const testDocumentCount = 5;
18
- let mockItemFirestoreDocumentAccessor;
19
- let items;
20
- beforeEach(async () => {
21
- mockItemFirestoreDocumentAccessor = f.instance.firestoreCollection.documentAccessor();
22
- items = await (0, firebase_1.makeDocuments)(f.instance.firestoreCollection.documentAccessor(), {
23
- count: testDocumentCount,
24
- init: (i) => {
25
- return {
26
- value: `${i}`,
27
- test: true,
28
- string: ''
29
- };
30
- }
31
- });
32
- });
33
- describe('MockItem', () => {
34
- let itemDocument;
35
- let accessor;
36
- beforeEach(() => {
37
- itemDocument = items[0];
38
- accessor = itemDocument.accessor;
39
- });
40
- describe('accessors', () => {
41
- describeFirestoreDocumentAccessorTests(() => ({
42
- context: f.parent.firestoreContext,
43
- firestoreDocument: () => itemDocument,
44
- dataForFirstOfTwoUpdates: () => ({ test: true, tags: ['a'] }),
45
- dataForUpdate: () => ({ test: false }),
46
- hasRemainingDataFromFirstOfTwoUpdate: (data) => (data.tags?.length || 0) > 0 && data.tags?.[0] === 'a',
47
- hasDataFromUpdate: (data) => data.test === false,
48
- loadDocumentForTransaction: (transaction, ref) => f.instance.firestoreCollection.documentAccessorForTransaction(transaction).loadDocument(ref),
49
- loadDocumentForWriteBatch: (writeBatch, ref) => f.instance.firestoreCollection.documentAccessorForWriteBatch(writeBatch).loadDocument(ref)
50
- }));
51
- describe('increment()', () => {
52
- it(`should increase the item's value`, async () => {
53
- let data = await itemDocument.snapshotData();
54
- expect(data?.number).toBe(undefined);
55
- const update = { number: 3 };
56
- await itemDocument.increment(update);
57
- data = await itemDocument.snapshotData();
58
- expect(data?.number).toBe(update.number);
59
- // increment again
60
- await itemDocument.increment(update);
61
- data = await itemDocument.snapshotData();
62
- expect(data?.number).toBe(update.number * 2);
63
- });
64
- it(`should decrease the item's value`, async () => {
65
- let data = await itemDocument.snapshotData();
66
- expect(data?.number).toBe(undefined);
67
- const update = { number: -3 };
68
- await itemDocument.increment(update);
69
- data = await itemDocument.snapshotData();
70
- expect(data?.number).toBe(update.number);
71
- // increment again
72
- await itemDocument.increment(update);
73
- data = await itemDocument.snapshotData();
74
- expect(data?.number).toBe(update.number * 2);
75
- });
76
- it(`should increase and decrease the item's value`, async () => {
77
- let data = await itemDocument.snapshotData();
78
- expect(data?.number).toBe(undefined);
79
- const update = { number: 3 };
80
- await itemDocument.increment(update);
81
- const update2 = { number: -6 };
82
- await itemDocument.increment(update2);
83
- data = await itemDocument.snapshotData();
84
- expect(data?.number).toBe(update.number + update2.number);
85
- });
86
- describe('in transaction', () => {
87
- it(`should increase the item's value`, async () => {
88
- const update = { number: 3 };
89
- await f.parent.firestoreContext.runTransaction(async (transaction) => {
90
- const itemDocumentInTransaction = await f.instance.firestoreCollection.documentAccessorForTransaction(transaction).loadDocumentForId(itemDocument.id);
91
- const data = await itemDocumentInTransaction.snapshotData();
92
- expect(data?.number).toBe(undefined);
93
- await itemDocumentInTransaction.increment(update);
94
- });
95
- const result = await itemDocument.snapshotData();
96
- expect(result?.number).toBe(update.number);
97
- });
98
- });
99
- describe('in write batch', () => {
100
- it(`should increase the item's value`, async () => {
101
- const update = { number: 3 };
102
- const writeBatch = f.parent.firestoreContext.batch();
103
- const itemDocumentForWriteBatch = await f.instance.firestoreCollection.documentAccessorForWriteBatch(writeBatch).loadDocumentForId(itemDocument.id);
104
- await itemDocumentForWriteBatch.increment(update);
105
- await writeBatch.commit();
106
- const result = await itemDocument.snapshotData();
107
- expect(result?.number).toBe(update.number);
108
- });
109
- });
110
- });
111
- describe('arrayUpdate()', () => {
112
- describe('union', () => {
113
- it('should add to the array', async () => {
114
- await itemDocument.accessor.update({
115
- tags: ['a']
116
- });
117
- await itemDocument.arrayUpdate({
118
- union: {
119
- tags: ['b', 'c']
120
- }
121
- });
122
- const result = await itemDocument.snapshotData();
123
- expect(result?.tags).toEqual(['a', 'b', 'c']);
124
- });
125
- });
126
- describe('remove', () => {
127
- it('should remove from the array', async () => {
128
- await itemDocument.accessor.update({
129
- tags: ['a', 'b', 'c']
130
- });
131
- await itemDocument.arrayUpdate({
132
- remove: {
133
- tags: ['a', 'b']
134
- }
135
- });
136
- const result = await itemDocument.snapshotData();
137
- expect(result?.tags).toEqual(['c']);
138
- });
139
- });
140
- });
141
- });
142
- describe('Subcollections', () => {
143
- describe('singleItemFirestoreCollection (MockItemUser)', () => {
144
- let testUserId;
145
- let mockItemUserFirestoreCollection;
146
- let itemUserDataDocument;
147
- let userDataAccessor;
148
- beforeEach(() => {
149
- testUserId = 'userid' + Math.ceil(Math.random() * 100000);
150
- mockItemUserFirestoreCollection = f.instance.collections.mockItemUserCollectionFactory(itemDocument);
151
- itemUserDataDocument = mockItemUserFirestoreCollection.documentAccessor().loadDocumentForId(testUserId);
152
- userDataAccessor = itemUserDataDocument.accessor;
153
- });
154
- describe('create()', () => {
155
- describe('mockItemUserAccessorFactory usage', () => {
156
- it('should copy the documents identifier to the uid field on create.', async () => {
157
- await itemUserDataDocument.accessor.create({
158
- uid: '', // the mockItemUserAccessorFactory silently enforces the uid to be the same as the document.
159
- name: 'hello'
160
- });
161
- const snapshot = await itemUserDataDocument.accessor.get();
162
- expect(snapshot.data()?.uid).toBe(testUserId);
163
- });
164
- });
165
- });
166
- describe('set()', () => {
167
- describe('mockItemUserAccessorFactory usage', () => {
168
- it('should copy the documents identifier to the uid field on set.', async () => {
169
- await itemUserDataDocument.accessor.set({
170
- uid: '', // the mockItemUserAccessorFactory silently enforces the uid to be the same as the document.
171
- name: 'hello'
172
- });
173
- const snapshot = await itemUserDataDocument.accessor.get();
174
- expect(snapshot.data()?.uid).toBe(testUserId);
175
- });
176
- });
177
- });
178
- });
179
- describe('singleItemFirestoreCollection (MockItemPrivate)', () => {
180
- let mockItemPrivateFirestoreCollection;
181
- let itemPrivateDataDocument;
182
- let privateDataAccessor;
183
- let privateSub;
184
- beforeEach(() => {
185
- mockItemPrivateFirestoreCollection = f.instance.collections.mockItemPrivateCollectionFactory(itemDocument);
186
- itemPrivateDataDocument = mockItemPrivateFirestoreCollection.loadDocument();
187
- privateDataAccessor = itemPrivateDataDocument.accessor;
188
- privateSub = new rxjs_2.SubscriptionObject();
189
- });
190
- afterEach(() => {
191
- privateSub.destroy();
192
- });
193
- describe('singleItemFirestoreCollection accessor', () => {
194
- it('should implement FirestoreSingleDocumentAccessor', () => {
195
- expect(mockItemPrivateFirestoreCollection.singleItemIdentifier).toBeDefined();
196
- expect(mockItemPrivateFirestoreCollection.documentRef).toBeDefined();
197
- expect(mockItemPrivateFirestoreCollection.loadDocument).toBeDefined();
198
- expect(mockItemPrivateFirestoreCollection.loadDocumentForTransaction).toBeDefined();
199
- expect(mockItemPrivateFirestoreCollection.loadDocumentForWriteBatch).toBeDefined();
200
- });
201
- });
202
- describe('get()', () => {
203
- it('should read that data using the configured converter', async () => {
204
- await itemPrivateDataDocument.accessor.set({ values: null });
205
- const dataWithoutConverter = (await itemPrivateDataDocument.accessor.getWithConverter(null)).data();
206
- expect(dataWithoutConverter).toBeDefined();
207
- expect(dataWithoutConverter.values).toBeNull();
208
- // converter on client, _converter on server
209
- expect(itemPrivateDataDocument.documentRef.converter ?? itemPrivateDataDocument.documentRef._converter).toBeDefined();
210
- const data = await itemPrivateDataDocument.snapshotData();
211
- expect(data?.values).toBeDefined();
212
- expect(data?.values).not.toBeNull(); // should not be null due to the snapshot converter config
213
- });
214
- });
215
- describe('getWithConverter()', () => {
216
- it('should get the results with the input converter', async () => {
217
- await itemPrivateDataDocument.accessor.set({ values: null });
218
- const data = await itemPrivateDataDocument.snapshotData();
219
- expect(data?.values).toBeDefined();
220
- const dataWithoutConverter = (await itemPrivateDataDocument.accessor.getWithConverter(null)).data();
221
- expect(dataWithoutConverter).toBeDefined();
222
- expect(dataWithoutConverter.values).toBeNull();
223
- });
224
- it('should get the results with the input converter with a type', async () => {
225
- await itemPrivateDataDocument.accessor.set({ values: null });
226
- const data = await itemPrivateDataDocument.snapshotData();
227
- expect(data?.values).toBeDefined();
228
- const converter = mock_1.mockItemConverter;
229
- const dataWithoutConverter = await itemPrivateDataDocument.accessor.getWithConverter(converter);
230
- expect(dataWithoutConverter).toBeDefined();
231
- });
232
- });
233
- describe('update()', () => {
234
- (0, test_1.itShouldFail)('if the item does not exist', async () => {
235
- const exists = await itemPrivateDataDocument.accessor.exists();
236
- expect(exists).toBe(false);
237
- await (0, test_1.expectFail)(() => itemPrivateDataDocument.update({ createdAt: new Date() }));
238
- });
239
- it('should update the item if it exist', async () => {
240
- await itemPrivateDataDocument.create({
241
- createdAt: new Date(),
242
- num: 0,
243
- values: [],
244
- settings: {
245
- test: {
246
- north: true,
247
- south: true
248
- }
249
- }
250
- });
251
- const newDate = new Date(0);
252
- const exists = await itemPrivateDataDocument.accessor.exists();
253
- expect(exists).toBe(true);
254
- await itemPrivateDataDocument.update({ createdAt: newDate });
255
- const data = await itemPrivateDataDocument.snapshotData();
256
- expect(data?.createdAt.getTime()).toBe(newDate.getTime());
257
- // check was not modified
258
- expect(data?.settings['test'].north).toBe(true);
259
- expect(data?.settings['test'].south).toBe(true);
260
- expect(data?.settings['test'].east).toBeUndefined();
261
- expect(data?.settings['test'].west).toBeUndefined();
262
- });
263
- });
264
- describe('set()', () => {
265
- it('should create the item', async () => {
266
- let exists = await privateDataAccessor.exists();
267
- expect(exists).toBe(false);
268
- const createdAt = new Date();
269
- const settings = {
270
- test: {
271
- north: true
272
- }
273
- };
274
- await privateDataAccessor.set({
275
- values: [],
276
- num: 0,
277
- createdAt,
278
- settings
279
- });
280
- exists = await privateDataAccessor.exists();
281
- expect(exists).toBe(true);
282
- const getResult = await privateDataAccessor.get();
283
- const data = getResult.data();
284
- expect(data).toBeDefined();
285
- expect(data?.num).toBe(0);
286
- expect(data?.values).toEqual([]);
287
- expect(data?.createdAt).toBeInstanceOf(Date);
288
- expect(data?.createdAt.toISOString()).toBe(createdAt.toISOString());
289
- expect(data?.settings).toEqual(settings);
290
- });
291
- });
292
- describe('with item', () => {
293
- beforeEach(async () => {
294
- await privateDataAccessor.set({ num: 0, values: [], createdAt: new Date(), settings: {} });
295
- });
296
- describe('increment()', () => {
297
- it(`should increase the item's value`, async () => {
298
- let data = await itemPrivateDataDocument.snapshotData();
299
- expect(data?.num).toBe(0);
300
- const update = { num: 3 };
301
- await itemPrivateDataDocument.increment(update);
302
- data = await itemPrivateDataDocument.snapshotData();
303
- expect(data?.num).toBe(update.num);
304
- });
305
- });
306
- describe('accessors', () => {
307
- const TEST_COMMENTS = 'test';
308
- describeFirestoreDocumentAccessorTests(() => ({
309
- context: f.parent.firestoreContext,
310
- firestoreDocument: () => itemPrivateDataDocument,
311
- dataForFirstOfTwoUpdates: () => ({ comments: 'not_test_comments', values: ['a'] }),
312
- hasRemainingDataFromFirstOfTwoUpdate: (data) => data.values.length > 0 && data.values[0] === 'a',
313
- dataForUpdate: () => ({ comments: TEST_COMMENTS }),
314
- hasDataFromUpdate: (data) => data.comments === TEST_COMMENTS,
315
- loadDocumentForTransaction: (transaction, ref) => mockItemPrivateFirestoreCollection.loadDocumentForTransaction(transaction),
316
- loadDocumentForWriteBatch: (writeBatch, ref) => mockItemPrivateFirestoreCollection.loadDocumentForWriteBatch(writeBatch)
317
- }));
318
- });
319
- });
320
- });
321
- describe('MockItemSubItem', () => {
322
- let subItemDocument;
323
- beforeEach(async () => {
324
- subItemDocument = f.instance.collections.mockItemSubItemCollectionFactory(itemDocument).documentAccessor().newDocument();
325
- await subItemDocument.accessor.set({ value: 0 });
326
- });
327
- describe('firestoreCollectionWithParent (MockItemSubItem)', () => {
328
- let mockItemSubItemFirestoreCollection;
329
- beforeEach(() => {
330
- mockItemSubItemFirestoreCollection = f.instance.collections.mockItemSubItemCollectionFactory(itemDocument);
331
- });
332
- describe('with item', () => {
333
- describe('accessors', () => {
334
- const TEST_VALUE = 1234;
335
- describeFirestoreDocumentAccessorTests(() => ({
336
- context: f.parent.firestoreContext,
337
- firestoreDocument: () => subItemDocument,
338
- dataForFirstOfTwoUpdates: () => ({ value: TEST_VALUE - 10 }),
339
- dataForUpdate: () => ({ value: TEST_VALUE }),
340
- hasDataFromUpdate: (data) => data.value === TEST_VALUE,
341
- loadDocumentForTransaction: (transaction, ref) => mockItemSubItemFirestoreCollection.documentAccessorForTransaction(transaction).loadDocument(ref),
342
- loadDocumentForWriteBatch: (writeBatch, ref) => mockItemSubItemFirestoreCollection.documentAccessorForWriteBatch(writeBatch).loadDocument(ref)
343
- }));
344
- });
345
- });
346
- });
347
- describe('firestoreCollectionGroup (MockItemSubItem)', () => {
348
- let mockItemSubItemFirestoreCollectionGroup;
349
- beforeEach(() => {
350
- mockItemSubItemFirestoreCollectionGroup = f.instance.collections.mockItemSubItemCollectionGroup;
351
- });
352
- describe('with item', () => {
353
- describe('accessors', () => {
354
- const TEST_VALUE = 1234;
355
- describeFirestoreDocumentAccessorTests(() => ({
356
- context: f.parent.firestoreContext,
357
- firestoreDocument: () => subItemDocument,
358
- dataForFirstOfTwoUpdates: () => ({ value: TEST_VALUE - 10 }),
359
- dataForUpdate: () => ({ value: TEST_VALUE }),
360
- hasDataFromUpdate: (data) => data.value === TEST_VALUE,
361
- loadDocumentForTransaction: (transaction, ref) => mockItemSubItemFirestoreCollectionGroup.documentAccessorForTransaction(transaction).loadDocument(ref),
362
- loadDocumentForWriteBatch: (writeBatch, ref) => mockItemSubItemFirestoreCollectionGroup.documentAccessorForWriteBatch(writeBatch).loadDocument(ref)
363
- }));
364
- });
365
- });
366
- });
367
- });
368
- });
369
- });
370
- describe('documentAccessor()', () => {
371
- describe('loadDocumentForKey()', () => {
372
- it('should load an existing document from the path.', async () => {
373
- const document = mockItemFirestoreDocumentAccessor.loadDocumentForKey(items[0].key);
374
- const exists = await document.accessor.exists();
375
- expect(exists).toBe(true);
376
- });
377
- (0, test_1.itShouldFail)('if the path is invalid (points to collection)', () => {
378
- (0, test_1.expectFail)(() => {
379
- mockItemFirestoreDocumentAccessor.loadDocumentForKey('path');
380
- });
381
- });
382
- (0, test_1.itShouldFail)('if the path points to a different type/collection', () => {
383
- (0, test_1.expectFail)(() => {
384
- mockItemFirestoreDocumentAccessor.loadDocumentForKey('path/id');
385
- });
386
- });
387
- (0, test_1.itShouldFail)('if the path is empty.', () => {
388
- (0, test_1.expectFail)(() => {
389
- mockItemFirestoreDocumentAccessor.loadDocumentForKey('');
390
- });
391
- });
392
- (0, test_1.itShouldFail)('if the path is undefined.', () => {
393
- (0, test_1.expectFail)(() => {
394
- mockItemFirestoreDocumentAccessor.loadDocumentForKey(undefined);
395
- });
396
- });
397
- (0, test_1.itShouldFail)('if the path is null.', () => {
398
- (0, test_1.expectFail)(() => {
399
- mockItemFirestoreDocumentAccessor.loadDocumentForKey(null);
400
- });
401
- });
402
- });
403
- describe('loadDocumentForId()', () => {
404
- it('should return a document with the given id.', () => {
405
- const document = mockItemFirestoreDocumentAccessor.loadDocumentForId('id');
406
- expect(document).toBeDefined();
407
- });
408
- (0, test_1.itShouldFail)('if the id is empty.', () => {
409
- (0, test_1.expectFail)(() => {
410
- mockItemFirestoreDocumentAccessor.loadDocumentForId('');
411
- });
412
- });
413
- (0, test_1.itShouldFail)('if the id is undefined.', () => {
414
- (0, test_1.expectFail)(() => {
415
- mockItemFirestoreDocumentAccessor.loadDocumentForId(undefined);
416
- });
417
- });
418
- });
419
- });
420
- });
421
- }
422
- function describeFirestoreDocumentAccessorTests(init) {
423
- let c;
424
- let sub;
425
- let firestoreDocument;
426
- let accessor;
427
- beforeEach(() => {
428
- sub = new rxjs_2.SubscriptionObject();
429
- c = init();
430
- firestoreDocument = c.firestoreDocument();
431
- accessor = firestoreDocument.accessor;
432
- });
433
- afterEach(() => {
434
- sub.destroy();
435
- });
436
- describe('utilities', () => {
437
- describe('getDocumentSnapshotPairs()', () => {
438
- it('should return the document and snapshot pairs for the input.', async () => {
439
- const pairs = await (0, firebase_1.getDocumentSnapshotPairs)([firestoreDocument]);
440
- expect(pairs.length).toBe(1);
441
- expect(pairs[0]).toBeDefined();
442
- expect(pairs[0].document).toBe(firestoreDocument);
443
- expect(pairs[0].snapshot).toBeDefined();
444
- expect(pairs[0].snapshot.data()).toBeDefined();
445
- });
446
- });
447
- describe('useDocumentSnapshot()', () => {
448
- it(`should use the input document value if it exists`, async () => {
449
- const exists = await firestoreDocument.exists();
450
- expect(exists).toBe(true);
451
- let snapshotUsed = false;
452
- await (0, firebase_1.useDocumentSnapshot)(firestoreDocument, (snapshot) => {
453
- expect(snapshot).toBeDefined();
454
- snapshotUsed = true;
455
- });
456
- expect(snapshotUsed).toBe(true);
457
- });
458
- it(`should not use the input undefined value`, async () => {
459
- let snapshotUsed = false;
460
- await (0, firebase_1.useDocumentSnapshot)(undefined, (snapshot) => {
461
- expect(snapshot).toBeDefined();
462
- snapshotUsed = true;
463
- });
464
- expect(snapshotUsed).toBe(false);
465
- });
466
- });
467
- describe('useDocumentSnapshotData()', () => {
468
- it(`should use the input document's snapshot data if it exists`, async () => {
469
- const exists = await firestoreDocument.exists();
470
- expect(exists).toBe(true);
471
- let snapshotUsed = false;
472
- await (0, firebase_1.useDocumentSnapshotData)(firestoreDocument, (data) => {
473
- expect(data).toBeDefined();
474
- snapshotUsed = true;
475
- });
476
- expect(snapshotUsed).toBe(true);
477
- });
478
- });
479
- });
480
- describe('AbstractFirestoreDocument', () => {
481
- describe('snapshot()', () => {
482
- it('should return the snapshot.', async () => {
483
- const snapshot = await firestoreDocument.snapshot();
484
- expect(snapshot).toBeDefined();
485
- });
486
- });
487
- describe('snapshotData()', () => {
488
- it('should return the snapshot data if the model exists.', async () => {
489
- const exists = await firestoreDocument.exists();
490
- expect(exists).toBe(true);
491
- const data = await firestoreDocument.snapshotData();
492
- expect(data).toBeDefined();
493
- });
494
- it('should return the undefined if the model does not exist.', async () => {
495
- await accessor.delete();
496
- const exists = await firestoreDocument.exists();
497
- expect(exists).toBe(false);
498
- const data = await firestoreDocument.snapshotData();
499
- expect(data).toBeUndefined();
500
- });
501
- });
502
- describe('create()', () => {
503
- it('should create the document if it does not exist.', async () => {
504
- const snapshot = await firestoreDocument.snapshot();
505
- await accessor.delete();
506
- let exists = await firestoreDocument.exists();
507
- expect(exists).toBe(false);
508
- await firestoreDocument.create(snapshot.data());
509
- exists = await firestoreDocument.exists();
510
- expect(exists).toBe(true);
511
- });
512
- (0, test_1.itShouldFail)('if the document exists.', async () => {
513
- const snapshot = await firestoreDocument.snapshot();
514
- const exists = await firestoreDocument.exists();
515
- expect(exists).toBe(true);
516
- await (0, test_1.expectFail)(() => firestoreDocument.create(snapshot.data()));
517
- });
518
- });
519
- describe('update()', () => {
520
- it('should update the data if the document exists.', async () => {
521
- const data = c.dataForUpdate();
522
- await firestoreDocument.update(data);
523
- const snapshot = await firestoreDocument.snapshot();
524
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
525
- });
526
- (0, test_1.itShouldFail)('if the document does not exist.', async () => {
527
- await accessor.delete();
528
- const snapshot = await firestoreDocument.snapshot();
529
- expect(snapshot.data()).toBe(undefined);
530
- const exists = await firestoreDocument.exists();
531
- expect(exists).toBe(false);
532
- await (0, test_1.expectFail)(() => firestoreDocument.update(c.dataForUpdate()));
533
- });
534
- it('should not throw an error if the input update data is empty.', async () => {
535
- await firestoreDocument.update({});
536
- });
537
- });
538
- describe('transaction', () => {
539
- describe('stream$', () => {
540
- it('should not cause the transaction to fail if the document is loaded after changes have begun.', async () => {
541
- await c.context.runTransaction(async (transaction) => {
542
- const transactionDocument = await c.loadDocumentForTransaction(transaction, firestoreDocument.documentRef);
543
- const currentData = await transactionDocument.snapshotData();
544
- expect(currentData).toBeDefined();
545
- const data = c.dataForUpdate();
546
- await transactionDocument.update(data);
547
- // stream$ and data$ do not call stream() until called directly.
548
- const secondLoading = await c.loadDocumentForTransaction(transaction, firestoreDocument.documentRef);
549
- expect(secondLoading).toBeDefined();
550
- });
551
- });
552
- (0, test_1.itShouldFail)('if stream$ is called after an update has occured in the transaction', async () => {
553
- await (0, test_1.expectFail)(() => c.context.runTransaction(async (transaction) => {
554
- const transactionDocument = await c.loadDocumentForTransaction(transaction, firestoreDocument.documentRef);
555
- const currentData = await transactionDocument.snapshotData();
556
- expect(currentData).toBeDefined();
557
- const data = c.dataForUpdate();
558
- await transactionDocument.update(data);
559
- // read the stream using a promise so the error is captured
560
- await (0, rxjs_1.firstValueFrom)(c.loadDocumentForTransaction(transaction, firestoreDocument.documentRef).stream$);
561
- }));
562
- });
563
- });
564
- describe('update()', () => {
565
- it('should update the data if the document exists.', async () => {
566
- await c.context.runTransaction(async (transaction) => {
567
- const transactionDocument = await c.loadDocumentForTransaction(transaction, firestoreDocument.documentRef);
568
- const currentData = await transactionDocument.snapshotData();
569
- expect(currentData).toBeDefined();
570
- const data = c.dataForUpdate();
571
- await transactionDocument.update(data);
572
- });
573
- const snapshot = await firestoreDocument.snapshot();
574
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
575
- });
576
- describe('multiple updates', () => {
577
- it('should merge the updates together and override the values from the first update that are defined in the second update', async () => {
578
- await c.context.runTransaction(async (transaction) => {
579
- const transactionDocument = await c.loadDocumentForTransaction(transaction, firestoreDocument.documentRef);
580
- const currentData = await transactionDocument.snapshotData();
581
- expect(currentData).toBeDefined();
582
- const firstData = c.dataForFirstOfTwoUpdates();
583
- await transactionDocument.update(firstData);
584
- const data = c.dataForUpdate();
585
- await transactionDocument.update(data);
586
- });
587
- const snapshot = await firestoreDocument.snapshot();
588
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
589
- if (c.hasRemainingDataFromFirstOfTwoUpdate != null) {
590
- expect(c.hasRemainingDataFromFirstOfTwoUpdate(snapshot.data())).toBe(true);
591
- }
592
- });
593
- });
594
- });
595
- });
596
- describe('write batch', () => {
597
- describe('update()', () => {
598
- it('should update the data if the document exists.', async () => {
599
- const batch = c.context.batch();
600
- const batchDocument = await c.loadDocumentForWriteBatch(batch, firestoreDocument.documentRef);
601
- const data = c.dataForUpdate();
602
- await batchDocument.update(data);
603
- await batch.commit();
604
- const snapshot = await firestoreDocument.snapshot();
605
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
606
- });
607
- });
608
- });
609
- });
610
- describe('accessor', () => {
611
- describe('stream()', () => {
612
- it('should return a snapshot stream', async () => {
613
- const result = await accessor.stream();
614
- expect(result).toBeDefined();
615
- });
616
- it('should emit values on updates from the observable.', (done) => {
617
- let count = 0;
618
- sub.subscription = accessor.stream().subscribe((item) => {
619
- count += 1;
620
- if (count === 1) {
621
- expect(c.hasDataFromUpdate(item.data())).toBe(false);
622
- }
623
- else if (count === 2) {
624
- expect(c.hasDataFromUpdate(item.data())).toBe(true);
625
- done();
626
- }
627
- });
628
- setTimeout(() => {
629
- accessor.update(c.dataForUpdate());
630
- }, 100);
631
- });
632
- describe('in transition context', () => {
633
- let runTransaction;
634
- beforeEach(() => {
635
- runTransaction = c.context.runTransaction;
636
- });
637
- it('should return the first emitted value (observable completes immediately)', async () => {
638
- await runTransaction(async (transaction) => {
639
- const transactionItemDocument = c.loadDocumentForTransaction(transaction, accessor.documentRef);
640
- // load the value
641
- const value = await (0, rxjs_1.firstValueFrom)(transactionItemDocument.accessor.stream());
642
- expect(value).toBeDefined();
643
- // set to make the transaction valid
644
- await transactionItemDocument.accessor.set({ value: 0 }, { merge: true });
645
- return value;
646
- });
647
- });
648
- });
649
- describe('in batch context', () => {
650
- it('should return the first emitted value (observable completes immediately)', async () => {
651
- const writeBatch = c.context.batch();
652
- const batchItemDocument = c.loadDocumentForWriteBatch(writeBatch, accessor.documentRef);
653
- // load the value
654
- const value = await (0, rxjs_1.firstValueFrom)(batchItemDocument.accessor.stream());
655
- expect(value).toBeDefined();
656
- // set to make the batch changes valid
657
- await batchItemDocument.accessor.set({ value: 0 }, { merge: true });
658
- // commit the changes
659
- await writeBatch.commit();
660
- });
661
- });
662
- });
663
- describe('create()', () => {
664
- it('should create the document if it does not exist.', async () => {
665
- const snapshot = await accessor.get();
666
- await accessor.delete();
667
- let exists = await accessor.exists();
668
- expect(exists).toBe(false);
669
- await accessor.create(snapshot.data());
670
- exists = await accessor.exists();
671
- expect(exists).toBe(true);
672
- });
673
- (0, test_1.itShouldFail)('if the document exists.', async () => {
674
- const snapshot = await accessor.get();
675
- const exists = await accessor.exists();
676
- expect(exists).toBe(true);
677
- await (0, test_1.expectFail)(() => accessor.create(snapshot.data()));
678
- });
679
- });
680
- describe('get()', () => {
681
- it('should return a snapshot', async () => {
682
- const result = await accessor.get();
683
- expect(result).toBeDefined();
684
- expect(result.id).toBeDefined();
685
- });
686
- });
687
- describe('exists()', () => {
688
- it('should return true if the document exists', async () => {
689
- const exists = await accessor.exists();
690
- expect(exists).toBe(true);
691
- });
692
- it('should return false if the document does not exist', async () => {
693
- await accessor.delete();
694
- const exists = await accessor.exists();
695
- expect(exists).toBe(false);
696
- });
697
- });
698
- describe('update()', () => {
699
- it('should update the data if the document exists.', async () => {
700
- const data = c.dataForUpdate();
701
- await accessor.update(data);
702
- const snapshot = await accessor.get();
703
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
704
- });
705
- (0, test_1.itShouldFail)('if the document does not exist.', async () => {
706
- await accessor.delete();
707
- const snapshot = await accessor.get();
708
- expect(snapshot.data()).toBe(undefined);
709
- const exists = await accessor.exists();
710
- expect(exists).toBe(false);
711
- await (0, test_1.expectFail)(() => accessor.update(c.dataForUpdate()));
712
- });
713
- (0, test_1.itShouldFail)('if the input is an empty object.', async () => {
714
- await (0, test_1.expectFail)(() => accessor.update({}));
715
- });
716
- // TODO(TEST): test that update does not call the converter when setting values.
717
- });
718
- describe('set()', () => {
719
- it('should create the object if it does not exist.', async () => {
720
- await accessor.delete();
721
- let exists = await accessor.exists();
722
- expect(exists).toBe(false);
723
- const data = c.dataForUpdate();
724
- await accessor.set(data);
725
- exists = await accessor.exists();
726
- expect(exists).toBe(true);
727
- const snapshot = await accessor.get();
728
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
729
- });
730
- it('should update the data on the document for fields that are not undefined.', async () => {
731
- const data = c.dataForUpdate();
732
- await accessor.set(data);
733
- const snapshot = await accessor.get();
734
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
735
- });
736
- describe('merge=true', () => {
737
- it('should update the data if the document exists.', async () => {
738
- const data = c.dataForUpdate();
739
- await accessor.set(data, { merge: true });
740
- const snapshot = await accessor.get();
741
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
742
- });
743
- it('should succeed if the document does not exist.', async () => {
744
- await accessor.delete();
745
- let snapshot = await accessor.get();
746
- expect(snapshot.data()).toBe(undefined);
747
- const exists = await accessor.exists();
748
- expect(exists).toBe(false);
749
- await accessor.set(c.dataForUpdate(), { merge: true });
750
- snapshot = await accessor.get();
751
- expect(c.hasDataFromUpdate(snapshot.data())).toBe(true);
752
- });
753
- });
754
- // TODO(TEST): test that set calls the converter when setting values.
755
- });
756
- describe('delete()', () => {
757
- it('should delete the document.', async () => {
758
- await accessor.delete();
759
- const snapshot = await accessor.get();
760
- expect(snapshot.data()).toBe(undefined);
761
- const exists = await accessor.exists();
762
- expect(exists).toBe(false);
763
- });
764
- });
765
- });
766
- }
767
- //# sourceMappingURL=test.driver.accessor.js.map