1
- /* eslint-disable unused-imports/no-unused-imports-ts */
2
- /* eslint-disable @typescript-eslint/no-unused-vars */
3
1
/**
4
2
* @license
5
3
* Copyright 2024 Google LLC
@@ -21,22 +19,17 @@ import { deleteApp, FirebaseApp, initializeApp } from '@firebase/app';
21
19
import { expect } from 'chai' ;
22
20
import * as chai from 'chai' ;
23
21
import chaiAsPromised from 'chai-as-promised' ;
24
- import * as sinon from 'sinon' ;
25
22
26
23
import {
27
24
DataConnect ,
28
25
DataConnectOptions ,
29
26
DataSource ,
30
- executeQuery ,
31
27
getDataConnect ,
32
- mutationRef ,
33
- queryRef ,
34
28
QueryResult ,
35
29
SerializedRef ,
36
30
SOURCE_SERVER
37
31
} from '../../src' ;
38
32
import { BackingDataObject , Cache , StubDataObject } from '../../src/core/Cache' ;
39
- import { Code , DataConnectError } from '../../src/core/error' ;
40
33
chai . use ( chaiAsPromised ) ;
41
34
42
35
// Helper to create a mock QueryResult object for tests
@@ -97,6 +90,7 @@ interface Review extends StubDataObject {
97
90
text : string ;
98
91
reviewer : Reviewer ;
99
92
}
93
+
100
94
interface Movie extends StubDataObject {
101
95
__typename : 'Movie' ;
102
96
__id : string ;
@@ -121,7 +115,7 @@ const review1: Review = {
121
115
reviewer : reviewer1
122
116
} ;
123
117
124
- const movie1 : Movie = {
118
+ const movieWithReviews : Movie = {
125
119
__typename : 'Movie' ,
126
120
__id : '1' ,
127
121
id : '1' ,
@@ -130,7 +124,7 @@ const movie1: Movie = {
130
124
reviews : [ review1 ]
131
125
} ;
132
126
133
- const movie2 : Movie = {
127
+ const movieWithoutReviews : Movie = {
134
128
__typename : 'Movie' ,
135
129
__id : '2' ,
136
130
id : '2' ,
@@ -181,12 +175,44 @@ describe('Normalized Cache Tests', () => {
181
175
} ) ;
182
176
183
177
describe ( 'updateCache' , ( ) => {
184
- it ( 'should create new BDOs for a list of new entities' , ( ) => {
178
+ it ( 'should create a new BDO for a new returned entity' , ( ) => {
179
+ // This test validates the `createBdo` path for multiple entities.
180
+ const queryResult = createMockQueryResult (
181
+ 'getMovie' ,
182
+ { id : '2' } ,
183
+ { movie : movieWithoutReviews } ,
184
+ options ,
185
+ dc
186
+ ) ;
187
+ cache . updateCache ( queryResult ) ;
188
+
189
+ // 1. Check Result Tree Cache for the list of stubs
190
+ const resultTreeKey = Cache . makeResultTreeCacheKey ( 'getMovie' , {
191
+ id : '2'
192
+ } ) ;
193
+ const resultTree = cache . resultTreeCache . get ( resultTreeKey ) ! ;
194
+ const stubDataObject = resultTree . movie as StubDataObject ;
195
+ expect ( stubDataObject ) . to . not . be . a ( 'StubDataObjectList' ) ;
196
+ expect ( stubDataObject ) . to . not . be . an ( 'array' ) ;
197
+ // expect(stubDataObject).to.be.a('StubDataObject');
198
+ expect ( stubDataObject . title ) . to . equal ( 'The Matrix' ) ;
199
+
200
+ // 2. Check that four new BDOs were created in the BDO Cache
201
+ expect ( cache . bdoCache . size ) . to . equal ( 1 ) ; // movie1
202
+ const bdo = cache . bdoCache . get ( Cache . makeBdoCacheKey ( 'Movie' , '2' ) ) ! ;
203
+ expect ( bdo ) . to . exist . and . be . an . instanceof ( BackingDataObject ) ;
204
+
205
+ // 3. White-box test: Check that each BDO has the correct stub as a listener.
206
+ const listeners = bdo . listeners ;
207
+ expect ( listeners . has ( stubDataObject ) ) . to . be . true ;
208
+ } ) ;
209
+
210
+ it ( 'should create new BDOs for a list of new returned entities' , ( ) => {
185
211
// This test validates the `createBdo` path for multiple entities.
186
212
const queryResult = createMockQueryResult (
187
213
'listMovies' ,
188
214
{ limit : 2 } ,
189
- { movies : [ movie1 , movie2 ] } ,
215
+ { movies : [ movieWithReviews , movieWithoutReviews ] } ,
190
216
options ,
191
217
dc
192
218
) ;
@@ -223,7 +249,7 @@ describe('Normalized Cache Tests', () => {
223
249
'listMovies' ,
224
250
{ } ,
225
251
{
226
- movies : [ movie1 ]
252
+ movies : [ movieWithoutReviews ]
227
253
} ,
228
254
options ,
229
255
dc
@@ -233,40 +259,40 @@ describe('Normalized Cache Tests', () => {
233
259
// Get the original stub from the list to check it later
234
260
const resultTreeKey = Cache . makeResultTreeCacheKey ( 'listMovies' , { } ) ;
235
261
const originalStub = cache . resultTreeCache . get ( resultTreeKey ) ! . movies [ 0 ] ;
236
- expect ( originalStub . title ) . to . equal ( 'Inception ' ) ;
237
- expect ( cache . bdoCache . size ) . to . equal ( 3 ) ; // movie1, review1, reviewer1
262
+ expect ( originalStub . title ) . to . equal ( 'The Matrix ' ) ;
263
+ expect ( cache . bdoCache . size ) . to . equal ( 1 ) ; // movie1
238
264
239
265
// Step 2: A new query result comes in with updated data for the same movie.
240
266
// This should trigger the `updateBdo` logic path.
241
- const updatedMovie1 = {
242
- ...movie1 ,
243
- title : "Inception (Director's Cut)"
267
+ const updatedMovie2 = {
268
+ ...movieWithoutReviews ,
269
+ title : 'The Matrix Reloaded'
244
270
} ;
245
271
const singleQueryResult = createMockQueryResult (
246
272
'getMovie' ,
247
- { id : '1 ' } ,
248
- { movie : updatedMovie1 } ,
273
+ { id : '2 ' } ,
274
+ { movie : updatedMovie2 } ,
249
275
options ,
250
276
dc
251
277
) ;
252
278
cache . updateCache ( singleQueryResult ) ;
253
279
254
280
// Assertions
255
281
// 1. No new BDO was created; the existing one was found and updated.
256
- expect ( cache . bdoCache . size ) . to . equal ( 3 ) ;
282
+ expect ( cache . bdoCache . size ) . to . equal ( 1 ) ;
257
283
258
284
// 2. The new stub from the getMovie query has the new title.
259
285
const newStub = cache . resultTreeCache . get (
260
- Cache . makeResultTreeCacheKey ( 'getMovie' , { id : '1 ' } )
286
+ Cache . makeResultTreeCacheKey ( 'getMovie' , { id : '2 ' } )
261
287
) ! . movie as StubDataObject ;
262
- expect ( newStub . title ) . to . equal ( "Inception (Director's Cut)" ) ;
288
+ expect ( newStub . title ) . to . equal ( 'The Matrix Reloaded' ) ;
263
289
264
290
// 3. CRITICAL: The original stub in the list was also updated via the listener mechanism.
265
291
// This confirms that `updateFromServer` correctly notified all listeners.
266
- expect ( originalStub . title ) . to . equal ( "Inception (Director's Cut)" ) ;
292
+ expect ( originalStub . title ) . to . equal ( 'The Matrix Reloaded' ) ;
267
293
268
294
// 4. White-box test: The BDO now has two listeners (the original list stub and the new single-item stub).
269
- const bdo = cache . bdoCache . get ( Cache . makeBdoCacheKey ( 'Movie' , '1 ' ) ) ! ;
295
+ const bdo = cache . bdoCache . get ( Cache . makeBdoCacheKey ( 'Movie' , '2 ' ) ) ! ;
270
296
const listeners = bdo . listeners ;
271
297
expect ( listeners . size ) . to . equal ( 2 ) ;
272
298
expect ( listeners . has ( originalStub ) ) . to . be . true ;
@@ -296,7 +322,7 @@ describe('Normalized Cache Tests', () => {
296
322
const queryResult = createMockQueryResult (
297
323
'getMovieWithReviews' ,
298
324
{ id : '1' } ,
299
- { movie : movie1 } ,
325
+ { movie : movieWithReviews } ,
300
326
options ,
301
327
dc
302
328
) ;
@@ -325,15 +351,14 @@ describe('Normalized Cache Tests', () => {
325
351
// 3. Check that stubs are distinct objects from BDOs
326
352
const movieBdo = cache . bdoCache . get ( Cache . makeBdoCacheKey ( 'Movie' , '1' ) ) ! ;
327
353
expect ( movieStub ) . to . not . equal ( movieBdo ) ;
328
- expect ( { ...movieStub } ) . to . equal ( { ...movieBdo } ) ;
329
354
} ) ;
330
355
331
356
it ( 'should propagate changes from a nested entity to all parent listeners' , ( ) => {
332
357
// 1. Cache a movie with its review
333
358
const movieQueryResult = createMockQueryResult (
334
359
'getMovie' ,
335
360
{ id : '1' } ,
336
- { movie : movie1 } ,
361
+ { movie : movieWithReviews } ,
337
362
options ,
338
363
dc
339
364
) ;
@@ -367,7 +392,7 @@ describe('Normalized Cache Tests', () => {
367
392
// Movie with an aggregate field and a related object without a primary key
368
393
const queryData = {
369
394
movie : {
370
- ...movie1 ,
395
+ ...movieWithReviews ,
371
396
__typename : 'Movie' ,
372
397
__id : '1' ,
373
398
// Non-normalizable aggregate field
@@ -412,7 +437,7 @@ describe('Normalized Cache Tests', () => {
412
437
it ( 'should handle null values in query results gracefully' , ( ) => {
413
438
const queryData = {
414
439
movie : {
415
- ...movie1 ,
440
+ ...movieWithReviews ,
416
441
reviews : null // The list of reviews is null
417
442
}
418
443
} ;
@@ -431,9 +456,7 @@ describe('Normalized Cache Tests', () => {
431
456
const movieStub = resultTree . movie as Movie ;
432
457
expect ( movieStub . title ) . to . equal ( 'Inception' ) ;
433
458
expect ( movieStub . reviews ) . to . be . null ;
434
- // BDOs for movie, review, and reviewer from the original `movie1` object
435
- // should still be created, as the normalization happens recursively before nulling.
436
- expect ( cache . bdoCache . size ) . to . equal ( 3 ) ;
459
+ expect ( cache . bdoCache . size ) . to . equal ( 1 ) ;
437
460
} ) ;
438
461
} ) ;
439
462
} ) ;
0 commit comments