@@ -19,6 +19,8 @@ import { expect } from 'chai';
1919
2020import {
2121 DocumentReference ,
22+ DocumentSnapshot ,
23+ QuerySnapshot ,
2224 connectFirestoreEmulator ,
2325 loadBundle ,
2426 refEqual ,
@@ -31,6 +33,7 @@ import {
3133 collectionReference ,
3234 documentReference ,
3335 documentSnapshot ,
36+ firestore ,
3437 newTestFirestore ,
3538 query ,
3639 querySnapshot
@@ -88,6 +91,117 @@ describe('DocumentReference', () => {
8891 } ) ;
8992 } ) ;
9093
94+ it ( 'fromJSON() throws with invalid data' , ( ) => {
95+ const db = newTestFirestore ( ) ;
96+ expect ( ( ) => {
97+ DocumentReference . fromJSON ( db , { } ) ;
98+ } ) . to . throw ;
99+ } ) ;
100+
101+ it ( 'fromJSON() throws with missing type data' , ( ) => {
102+ const db = newTestFirestore ( ) ;
103+ expect ( ( ) => {
104+ DocumentSnapshot . fromJSON ( db , {
105+ bundleSource : 'DocumentSnapshot' ,
106+ bundleName : 'test name' ,
107+ bundle : 'test bundle'
108+ } ) ;
109+ } ) . to . throw ;
110+ } ) ;
111+
112+ it ( 'fromJSON() throws with invalid type data' , ( ) => {
113+ const db = newTestFirestore ( ) ;
114+ expect ( ( ) => {
115+ DocumentSnapshot . fromJSON ( db , {
116+ type : 1 ,
117+ bundleSource : 'DocumentSnapshot' ,
118+ bundleName : 'test name' ,
119+ bundle : 'test bundle'
120+ } ) ;
121+ } ) . to . throw ;
122+ } ) ;
123+
124+ it ( 'fromJSON() throws with missing bundleSource' , ( ) => {
125+ const db = newTestFirestore ( ) ;
126+ expect ( ( ) => {
127+ DocumentSnapshot . fromJSON ( db , {
128+ type : DocumentSnapshot . _jsonSchemaVersion ,
129+ bundleName : 'test name' ,
130+ bundle : 'test bundle'
131+ } ) ;
132+ } ) . to . throw ;
133+ } ) ;
134+
135+ it ( 'fromJSON() throws with invalid bundleSource type' , ( ) => {
136+ const db = newTestFirestore ( ) ;
137+ expect ( ( ) => {
138+ DocumentSnapshot . fromJSON ( db , {
139+ type : DocumentSnapshot . _jsonSchemaVersion ,
140+ bundleSource : 1 ,
141+ bundleName : 'test name' ,
142+ bundle : 'test bundle'
143+ } ) ;
144+ } ) . to . throw ;
145+ } ) ;
146+
147+ it ( 'fromJSON() throws with invalid bundleSource value' , ( ) => {
148+ const db = newTestFirestore ( ) ;
149+ expect ( ( ) => {
150+ DocumentSnapshot . fromJSON ( db , {
151+ type : DocumentSnapshot . _jsonSchemaVersion ,
152+ bundleSource : 'QuerySnapshot' ,
153+ bundleName : 'test name' ,
154+ bundle : 'test bundle'
155+ } ) ;
156+ } ) . to . throw ;
157+ } ) ;
158+
159+ it ( 'fromJSON() throws with missing bundleName' , ( ) => {
160+ const db = newTestFirestore ( ) ;
161+ expect ( ( ) => {
162+ DocumentSnapshot . fromJSON ( db , {
163+ type : DocumentSnapshot . _jsonSchemaVersion ,
164+ bundleSource : 'DocumentSnapshot' ,
165+ bundle : 'test bundle'
166+ } ) ;
167+ } ) . to . throw ;
168+ } ) ;
169+
170+ it ( 'fromJSON() throws with invalid bundleName' , ( ) => {
171+ const db = newTestFirestore ( ) ;
172+ expect ( ( ) => {
173+ DocumentSnapshot . fromJSON ( db , {
174+ type : DocumentSnapshot . _jsonSchemaVersion ,
175+ bundleSource : 'DocumentSnapshot' ,
176+ bundleName : 1 ,
177+ bundle : 'test bundle'
178+ } ) ;
179+ } ) . to . throw ;
180+ } ) ;
181+
182+ it ( 'fromJSON() throws with missing bundle' , ( ) => {
183+ const db = newTestFirestore ( ) ;
184+ expect ( ( ) => {
185+ DocumentSnapshot . fromJSON ( db , {
186+ type : DocumentSnapshot . _jsonSchemaVersion ,
187+ bundleSource : 'DocumentSnapshot' ,
188+ bundleName : 'test name'
189+ } ) ;
190+ } ) . to . throw ;
191+ } ) ;
192+
193+ it ( 'fromJSON() throws with invalid bundle' , ( ) => {
194+ const db = newTestFirestore ( ) ;
195+ expect ( ( ) => {
196+ DocumentSnapshot . fromJSON ( db , {
197+ type : DocumentSnapshot . _jsonSchemaVersion ,
198+ bundleSource : 'DocumentSnapshot' ,
199+ bundleName : 'test name' ,
200+ bundle : 1
201+ } ) ;
202+ } ) . to . throw ;
203+ } ) ;
204+
91205 it ( 'fromJSON() does not throw' , ( ) => {
92206 const db = newTestFirestore ( ) ;
93207 const docRef = documentReference ( 'foo/bar' ) ;
@@ -190,6 +304,34 @@ describe('DocumentSnapshot', () => {
190304 `Await waitForPendingWrites() before invoking toJSON().`
191305 ) ;
192306 } ) ;
307+
308+ it ( 'fromJSON parses toJSON result' , ( ) => {
309+ const docSnap = documentSnapshot ( 'foo/bar' , { a : 1 } , /*fromCache=*/ true ) ;
310+ const json = docSnap . toJSON ( ) ;
311+ expect ( ( ) => {
312+ DocumentSnapshot . fromJSON ( docSnap . _firestore , json ) ;
313+ } ) . to . not . throw ;
314+ } ) ;
315+
316+ it ( 'fromJSON produces valid snapshot data.' , ( ) => {
317+ const json = documentSnapshot (
318+ 'foo/bar' ,
319+ { a : 1 } ,
320+ /*fromCache=*/ true
321+ ) . toJSON ( ) ;
322+ const db = firestore ( ) ;
323+ const docSnap = DocumentSnapshot . fromJSON ( db , json ) ;
324+ expect ( docSnap ) . to . exist ;
325+ const data = docSnap . data ( ) ;
326+ expect ( data ) . to . not . be . undefined ;
327+ expect ( data ) . to . not . be . null ;
328+ if ( data ) {
329+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
330+ expect ( ( data as any ) . a ) . to . exist ;
331+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
332+ expect ( ( data as any ) . a ) . to . equal ( 1 ) ;
333+ }
334+ } ) ;
193335} ) ;
194336
195337describe ( 'Query' , ( ) => {
@@ -318,7 +460,7 @@ describe('QuerySnapshot', () => {
318460 'foo' ,
319461 { } ,
320462 { a : { a : 1 } } ,
321- keys ( ) ,
463+ keys ( ) , // An empty set of mutaded document keys signifies that there are no pending writes.
322464 false ,
323465 false
324466 ) . toJSON ( ) ;
@@ -342,15 +484,173 @@ describe('QuerySnapshot', () => {
342484 'foo' ,
343485 { } ,
344486 { a : { a : 1 } } ,
345- keys ( 'foo/a' ) ,
346- true ,
347- true
487+ keys ( 'foo/a' ) , // A non empty set of mutated keys signifies pending writes.
488+ false ,
489+ false
348490 ) . toJSON ( )
349491 ) . to . throw (
350492 `QuerySnapshot.toJSON() attempted to serialize a document with pending writes. ` +
351493 `Await waitForPendingWrites() before invoking toJSON().`
352494 ) ;
353495 } ) ;
496+
497+ it ( 'fromJSON() throws with invalid data' , ( ) => {
498+ const db = newTestFirestore ( ) ;
499+ expect ( ( ) => {
500+ QuerySnapshot . fromJSON ( db , { } ) ;
501+ } ) . to . throw ;
502+ } ) ;
503+
504+ it ( 'fromJSON() throws with missing type data' , ( ) => {
505+ const db = newTestFirestore ( ) ;
506+ expect ( ( ) => {
507+ QuerySnapshot . fromJSON ( db , {
508+ bundleSource : 'QuerySnapshot' ,
509+ bundleName : 'test name' ,
510+ bundle : 'test bundle'
511+ } ) ;
512+ } ) . to . throw ;
513+ } ) ;
514+
515+ it ( 'fromJSON() throws with invalid type data' , ( ) => {
516+ const db = newTestFirestore ( ) ;
517+ expect ( ( ) => {
518+ QuerySnapshot . fromJSON ( db , {
519+ type : 1 ,
520+ bundleSource : 'QuerySnapshot' ,
521+ bundleName : 'test name' ,
522+ bundle : 'test bundle'
523+ } ) ;
524+ } ) . to . throw ;
525+ } ) ;
526+
527+ it ( 'fromJSON() throws with invalid type data' , ( ) => {
528+ const db = newTestFirestore ( ) ;
529+ expect ( ( ) => {
530+ QuerySnapshot . fromJSON ( db , {
531+ type : QuerySnapshot . _jsonSchemaVersion ,
532+ bundleName : 'test name' ,
533+ bundle : 'test bundle'
534+ } ) ;
535+ } ) . to . throw ;
536+ } ) ;
537+
538+ it ( 'fromJSON() throws with invalid bundleSource type' , ( ) => {
539+ const db = newTestFirestore ( ) ;
540+ expect ( ( ) => {
541+ QuerySnapshot . fromJSON ( db , {
542+ type : QuerySnapshot . _jsonSchemaVersion ,
543+ bundleSource : 1 ,
544+ bundleName : 'test name' ,
545+ bundle : 'test bundle'
546+ } ) ;
547+ } ) . to . throw ;
548+ } ) ;
549+
550+ it ( 'fromJSON() throws with invalid bundleSource value' , ( ) => {
551+ const db = newTestFirestore ( ) ;
552+ expect ( ( ) => {
553+ QuerySnapshot . fromJSON ( db , {
554+ type : QuerySnapshot . _jsonSchemaVersion ,
555+ bundleSource : 'DocumentSnapshot' ,
556+ bundleName : 'test name' ,
557+ bundle : 'test bundle'
558+ } ) ;
559+ } ) . to . throw ;
560+ } ) ;
561+
562+ it ( 'fromJSON() throws with missing bundleName' , ( ) => {
563+ const db = newTestFirestore ( ) ;
564+ expect ( ( ) => {
565+ QuerySnapshot . fromJSON ( db , {
566+ type : QuerySnapshot . _jsonSchemaVersion ,
567+ bundleSource : 'QuerySnapshot' ,
568+ bundle : 'test bundle'
569+ } ) ;
570+ } ) . to . throw ;
571+ } ) ;
572+
573+ it ( 'fromJSON() throws with invalid bundleName' , ( ) => {
574+ const db = newTestFirestore ( ) ;
575+ expect ( ( ) => {
576+ QuerySnapshot . fromJSON ( db , {
577+ type : QuerySnapshot . _jsonSchemaVersion ,
578+ bundleSource : 'QuerySnapshot' ,
579+ bundleName : 1 ,
580+ bundle : 'test bundle'
581+ } ) ;
582+ } ) . to . throw ;
583+ } ) ;
584+
585+ it ( 'fromJSON() throws with missing bundle data' , ( ) => {
586+ const db = newTestFirestore ( ) ;
587+ expect ( ( ) => {
588+ QuerySnapshot . fromJSON ( db , {
589+ type : QuerySnapshot . _jsonSchemaVersion ,
590+ bundleSource : 'QuerySnapshot' ,
591+ bundleName : 'test name'
592+ } ) ;
593+ } ) . to . throw ;
594+ } ) ;
595+
596+ it ( 'fromJSON() throws with invalid bundle data' , ( ) => {
597+ const db = newTestFirestore ( ) ;
598+ expect ( ( ) => {
599+ QuerySnapshot . fromJSON ( db , {
600+ type : QuerySnapshot . _jsonSchemaVersion ,
601+ bundleSource : 'QuerySnapshot' ,
602+ bundleName : 'test name' ,
603+ bundle : 1
604+ } ) ;
605+ } ) . to . throw ;
606+ } ) ;
607+
608+ it ( 'fromJSON does not throw' , ( ) => {
609+ const json = querySnapshot (
610+ 'foo' ,
611+ { } ,
612+ { a : { a : 1 } } ,
613+ keys ( ) , // An empty set of mutaded document keys signifies that there are no pending writes.
614+ false ,
615+ false
616+ ) . toJSON ( ) ;
617+
618+ const db = firestore ( ) ;
619+ expect ( ( ) => {
620+ QuerySnapshot . fromJSON ( db , json ) ;
621+ } ) . to . not . throw ;
622+ } ) ;
623+
624+ it ( 'fromJSON parses produces valid snapshot data' , ( ) => {
625+ const json = querySnapshot (
626+ 'foo' ,
627+ { } ,
628+ { a : { a : 1 } } ,
629+ keys ( ) , // An empty set of mutaded document keys signifies that there are no pending writes.
630+ false ,
631+ false
632+ ) . toJSON ( ) ;
633+
634+ const db = firestore ( ) ;
635+ const querySnap = QuerySnapshot . fromJSON ( db , json ) ;
636+ expect ( querySnap ) . to . exist ;
637+ if ( querySnap !== undefined ) {
638+ const docs = querySnap . docs ;
639+ expect ( docs ) . to . not . be . undefined ;
640+ expect ( docs ) . to . not . be . null ;
641+ if ( docs ) {
642+ expect ( docs . length ) . to . equal ( 1 ) ;
643+ docs . map ( document => {
644+ const docData = document . data ( ) ;
645+ expect ( docData ) . to . exist ;
646+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
647+ expect ( ( docData as any ) . a ) . to . exist ;
648+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
649+ expect ( ( docData as any ) . a ) . to . equal ( 1 ) ;
650+ } ) ;
651+ }
652+ }
653+ } ) ;
354654} ) ;
355655
356656describe ( 'SnapshotMetadata' , ( ) => {
0 commit comments