@@ -34,9 +34,12 @@ import {
34
34
testLab ,
35
35
eventarc ,
36
36
https ,
37
+ firestore ,
37
38
} from 'firebase-functions/v2' ;
38
39
import { defineString } from 'firebase-functions/params' ;
39
40
import { makeDataSnapshot } from '../src/providers/database' ;
41
+ import { makeDocumentSnapshot } from '../src/providers/firestore' ;
42
+ import { inspect } from 'util' ;
40
43
41
44
describe ( 'v2' , ( ) => {
42
45
describe ( '#wrapV2' , ( ) => {
@@ -460,6 +463,275 @@ describe('v2', () => {
460
463
} ) ;
461
464
} ) ;
462
465
466
+ describe ( 'firestore' , ( ) => {
467
+ describe ( 'document path' , ( ) => {
468
+ it ( 'should resolve default document path' , ( ) => {
469
+ const cloudFn = firestore . onDocumentCreated ( 'foo/bar/baz' , handler ) ;
470
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
471
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
472
+
473
+ expect ( cloudEvent . document ) . equal ( 'foo/bar/baz' ) ;
474
+ } ) ;
475
+
476
+ it ( 'should resolve default document given StringParam' , ( ) => {
477
+ process . env . doc_path = 'foo/StringParam/baz' ;
478
+ const cloudFn = firestore . onDocumentCreated ( '' , handler ) ;
479
+ cloudFn . __endpoint . eventTrigger . eventFilterPathPatterns . document = defineString (
480
+ 'doc_path'
481
+ ) ;
482
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
483
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
484
+
485
+ expect ( cloudEvent . document ) . equal ( 'foo/StringParam/baz' ) ;
486
+ } ) ;
487
+
488
+ it ( 'should resolve using params' , ( ) => {
489
+ const cloudFn = firestore . onDocumentCreated ( 'users/{user}' , handler ) ;
490
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
491
+ const partial = {
492
+ params : {
493
+ user : '123' ,
494
+ } ,
495
+ } ;
496
+ const cloudEvent = cloudFnWrap ( partial ) . cloudEvent ;
497
+
498
+ expect ( cloudEvent . document ) . equal ( 'users/123' ) ;
499
+ } ) ;
500
+
501
+ it ( 'should resolve with undefined string if variable is missing' , ( ) => {
502
+ const cloudFn = firestore . onDocumentCreated ( 'users/{user}' , handler ) ;
503
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
504
+ const partial = {
505
+ params : { } ,
506
+ } ;
507
+ const cloudEvent = cloudFnWrap ( partial ) . cloudEvent ;
508
+
509
+ expect ( cloudEvent . document ) . equal ( 'users/undefined' ) ;
510
+ } ) ;
511
+ } ) ;
512
+
513
+ describe ( 'document options' , ( ) => {
514
+ it ( 'resolves default document options correctly' , ( ) => {
515
+ const cloudFn = firestore . onDocumentCreated ( 'foo/bar/baz' , handler ) ;
516
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
517
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
518
+
519
+ expect ( cloudEvent . document ) . equal ( 'foo/bar/baz' ) ;
520
+ expect ( cloudEvent . database ) . equal ( '(default)' ) ;
521
+ expect ( cloudEvent . namespace ) . equal ( '(default)' ) ;
522
+ } ) ;
523
+
524
+ it ( 'reads custom DocumentOptions correctly' , ( ) => {
525
+ const documentOptions = {
526
+ document : 'foo/bar/baz' ,
527
+ database : 'custom-database' ,
528
+ namespace : 'custom-namespace' ,
529
+ } ;
530
+ const cloudFn = firestore . onDocumentCreated ( documentOptions , handler ) ;
531
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
532
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
533
+
534
+ expect ( cloudEvent . document ) . equal ( documentOptions . document ) ;
535
+ expect ( cloudEvent . database ) . equal ( documentOptions . database ) ;
536
+ expect ( cloudEvent . namespace ) . equal ( documentOptions . namespace ) ;
537
+ } ) ;
538
+ } ) ;
539
+
540
+ describe ( 'firestore.onDocumentCreated' , ( ) => {
541
+ it ( 'should update CloudEvent appropriately' , ( ) => {
542
+ const cloudFn = firestore . onDocumentCreated ( 'foo/bar/baz' , handler ) ;
543
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
544
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
545
+
546
+ expect ( cloudEvent ) . deep . equal ( {
547
+ id : cloudEvent . id ,
548
+ time : cloudEvent . time ,
549
+ specversion : '1.0' ,
550
+ type : 'google.cloud.firestore.document.v1.created' ,
551
+ source : '' ,
552
+
553
+ data : cloudEvent . data ,
554
+ location : 'us-central1' ,
555
+ project : 'testproject' ,
556
+ database : '(default)' ,
557
+ namespace : '(default)' ,
558
+ document : 'foo/bar/baz' ,
559
+ params : { } ,
560
+ } ) ;
561
+ } ) ;
562
+
563
+ it ( 'should use overridden data' , ( ) => {
564
+ const cloudFn = firestore . onDocumentCreated ( 'foo/bar/baz' , handler ) ;
565
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
566
+ const docData = { foo : 'bar' } ;
567
+ const data = makeDocumentSnapshot ( docData , 'foo/bar/baz' ) ;
568
+ const cloudEvent = cloudFnWrap ( { data } ) . cloudEvent ;
569
+
570
+ expect ( cloudEvent . data . data ( ) ) . deep . equal ( docData ) ;
571
+ } ) ;
572
+
573
+ it ( 'should accept json data' , ( ) => {
574
+ const cloudFn = firestore . onDocumentCreated ( 'foo/bar/baz' , handler ) ;
575
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
576
+ const docData = { foo : 'bar' } ;
577
+ const cloudEvent = cloudFnWrap ( { data : docData } ) . cloudEvent ;
578
+
579
+ expect ( cloudEvent . data . data ( ) ) . deep . equal ( docData ) ;
580
+ } ) ;
581
+ } ) ;
582
+
583
+ describe ( 'firestore.onDocumentDeleted()' , ( ) => {
584
+ it ( 'should update CloudEvent appropriately' , ( ) => {
585
+ const cloudFn = firestore . onDocumentDeleted ( 'foo/bar/baz' , handler ) ;
586
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
587
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
588
+
589
+ expect ( cloudEvent ) . deep . equal ( {
590
+ id : cloudEvent . id ,
591
+ time : cloudEvent . time ,
592
+ specversion : '1.0' ,
593
+ type : 'google.cloud.firestore.document.v1.deleted' ,
594
+ source : '' ,
595
+
596
+ data : cloudEvent . data ,
597
+ location : 'us-central1' ,
598
+ project : 'testproject' ,
599
+ database : '(default)' ,
600
+ namespace : '(default)' ,
601
+ document : 'foo/bar/baz' ,
602
+ params : { } ,
603
+ } ) ;
604
+ } ) ;
605
+
606
+ it ( 'should use overridden data' , ( ) => {
607
+ const cloudFn = firestore . onDocumentDeleted ( 'foo/bar/baz' , handler ) ;
608
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
609
+ const docData = { foo : 'bar' } ;
610
+ const data = makeDocumentSnapshot ( docData , 'foo/bar/baz' ) ;
611
+ const cloudEvent = cloudFnWrap ( { data } ) . cloudEvent ;
612
+
613
+ expect ( cloudEvent . data . data ( ) ) . deep . equal ( docData ) ;
614
+ } ) ;
615
+
616
+ it ( 'should accept json data' , ( ) => {
617
+ const cloudFn = firestore . onDocumentDeleted ( 'foo/bar/baz' , handler ) ;
618
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
619
+ const docData = { foo : 'bar' } ;
620
+ const cloudEvent = cloudFnWrap ( { data : docData } ) . cloudEvent ;
621
+
622
+ expect ( cloudEvent . data . data ( ) ) . deep . equal ( docData ) ;
623
+ } ) ;
624
+ } ) ;
625
+
626
+ describe ( 'firestore.onDocumentUpdated' , ( ) => {
627
+ it ( 'should update CloudEvent appropriately' , ( ) => {
628
+ const cloudFn = firestore . onDocumentUpdated ( 'foo/bar/baz' , handler ) ;
629
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
630
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
631
+
632
+ expect ( cloudEvent ) . deep . equal ( {
633
+ id : cloudEvent . id ,
634
+ time : cloudEvent . time ,
635
+ specversion : '1.0' ,
636
+ type : 'google.cloud.firestore.document.v1.updated' ,
637
+ source : '' ,
638
+
639
+ data : cloudEvent . data ,
640
+ location : 'us-central1' ,
641
+ project : 'testproject' ,
642
+ database : '(default)' ,
643
+ namespace : '(default)' ,
644
+ document : 'foo/bar/baz' ,
645
+ params : { } ,
646
+ } ) ;
647
+ } ) ;
648
+
649
+ it ( 'should use overridden data' , ( ) => {
650
+ const cloudFn = firestore . onDocumentUpdated ( 'foo/bar/baz' , handler ) ;
651
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
652
+
653
+ const afterDataVal = { snapshot : 'after' } ;
654
+ const after = makeDocumentSnapshot ( afterDataVal , 'foo/bar/baz' ) ;
655
+
656
+ const beforeDataVal = { snapshot : 'before' } ;
657
+ const before = makeDocumentSnapshot ( beforeDataVal , 'foo/bar/baz' ) ;
658
+
659
+ const data = { before, after } ;
660
+ const cloudEvent = cloudFnWrap ( { data } ) . cloudEvent ;
661
+
662
+ expect ( cloudEvent . data . before . data ( ) ) . deep . equal ( beforeDataVal ) ;
663
+ expect ( cloudEvent . data . after . data ( ) ) . deep . equal ( afterDataVal ) ;
664
+ } ) ;
665
+
666
+ it ( 'should accept json data' , ( ) => {
667
+ const cloudFn = firestore . onDocumentUpdated ( 'foo/bar/baz' , handler ) ;
668
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
669
+ const afterDataVal = { snapshot : 'after' } ;
670
+ const beforeDataVal = { snapshot : 'before' } ;
671
+
672
+ const data = { before : beforeDataVal , after : afterDataVal } ;
673
+ const cloudEvent = cloudFnWrap ( { data } ) . cloudEvent ;
674
+
675
+ expect ( cloudEvent . data . before . data ( ) ) . deep . equal ( beforeDataVal ) ;
676
+ expect ( cloudEvent . data . after . data ( ) ) . deep . equal ( afterDataVal ) ;
677
+ } ) ;
678
+ } ) ;
679
+
680
+ describe ( 'firestore.onDocumentWritten' , ( ) => {
681
+ it ( 'should update CloudEvent appropriately' , ( ) => {
682
+ const cloudFn = firestore . onDocumentWritten ( 'foo/bar/baz' , handler ) ;
683
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
684
+ const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
685
+
686
+ expect ( cloudEvent ) . deep . equal ( {
687
+ id : cloudEvent . id ,
688
+ time : cloudEvent . time ,
689
+ specversion : '1.0' ,
690
+ type : 'google.cloud.firestore.document.v1.written' ,
691
+ source : '' ,
692
+
693
+ data : cloudEvent . data ,
694
+ location : 'us-central1' ,
695
+ project : 'testproject' ,
696
+ database : '(default)' ,
697
+ namespace : '(default)' ,
698
+ document : 'foo/bar/baz' ,
699
+ params : { } ,
700
+ } ) ;
701
+ } ) ;
702
+
703
+ it ( 'should use overridden data' , ( ) => {
704
+ const cloudFn = firestore . onDocumentWritten ( 'foo/bar/baz' , handler ) ;
705
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
706
+
707
+ const afterDataVal = { snapshot : 'after' } ;
708
+ const after = makeDocumentSnapshot ( afterDataVal , 'foo/bar/baz' ) ;
709
+
710
+ const beforeDataVal = { snapshot : 'before' } ;
711
+ const before = makeDocumentSnapshot ( beforeDataVal , 'foo/bar/baz' ) ;
712
+
713
+ const data = { before, after } ;
714
+ const cloudEvent = cloudFnWrap ( { data } ) . cloudEvent ;
715
+
716
+ expect ( cloudEvent . data . before . data ( ) ) . deep . equal ( beforeDataVal ) ;
717
+ expect ( cloudEvent . data . after . data ( ) ) . deep . equal ( afterDataVal ) ;
718
+ } ) ;
719
+
720
+ it ( 'should accept json data' , ( ) => {
721
+ const cloudFn = firestore . onDocumentWritten ( 'foo/bar/baz' , handler ) ;
722
+ const cloudFnWrap = wrapV2 ( cloudFn ) ;
723
+ const afterDataVal = { snapshot : 'after' } ;
724
+ const beforeDataVal = { snapshot : 'before' } ;
725
+
726
+ const data = { before : beforeDataVal , after : afterDataVal } ;
727
+ const cloudEvent = cloudFnWrap ( { data } ) . cloudEvent ;
728
+
729
+ expect ( cloudEvent . data . before . data ( ) ) . deep . equal ( beforeDataVal ) ;
730
+ expect ( cloudEvent . data . after . data ( ) ) . deep . equal ( afterDataVal ) ;
731
+ } ) ;
732
+ } ) ;
733
+ } ) ;
734
+
463
735
describe ( 'database' , ( ) => {
464
736
describe ( 'ref' , ( ) => {
465
737
it ( 'should resolve default ref' , ( ) => {
@@ -488,23 +760,23 @@ describe('v2', () => {
488
760
expect ( cloudEvent . ref ) . equal ( 'foo/StringParam/baz' ) ;
489
761
} ) ;
490
762
491
- it . skip ( 'should resolve default ref given TernaryExpression' , ( ) => {
492
- const ref1 = defineString ( 'rtdb_ref_1' ) ;
493
- process . env . rtdb_ref_1 = 'foo/StringParam/1' ;
494
- const ref2 = defineString ( 'rtdb_ref_2' ) ;
495
- process . env . rtdb_ref_2 = 'foo/StringParam/2' ;
496
- const referenceOptions = {
497
- ref : '' ,
498
- instance : 'instance-1' ,
499
- } ;
500
- const cloudFn = database . onValueCreated ( referenceOptions , handler ) ;
501
- cloudFn . __endpoint . eventTrigger . eventFilterPathPatterns . ref = ref1
502
- . equals ( 'aa' )
503
- . then ( 'rtdb_ref_1' , 'rtdb_ref_2' ) ;
504
- const cloudFnWrap = wrapV2 ( cloudFn ) ;
505
- const cloudEvent = cloudFnWrap ( ) . cloudEvent ;
506
- expect ( cloudEvent . ref ) . equal ( 'rtdb_ref_2' ) ;
507
- } ) ;
763
+ // it ('should resolve default ref given TernaryExpression', () => {
764
+ // const ref1 = defineString('rtdb_ref_1');
765
+ // process.env.rtdb_ref_1 = 'foo/StringParam/1';
766
+ // const ref2 = defineString('rtdb_ref_2');
767
+ // process.env.rtdb_ref_2 = 'foo/StringParam/2';
768
+ // const referenceOptions = {
769
+ // ref: '',
770
+ // instance: 'instance-1',
771
+ // };
772
+ // const cloudFn = database.onValueCreated(referenceOptions, handler);
773
+ // cloudFn.__endpoint.eventTrigger.eventFilterPathPatterns.ref = ref1
774
+ // .equals('aa')
775
+ // .then('rtdb_ref_1', 'rtdb_ref_2');
776
+ // const cloudFnWrap = wrapV2(cloudFn);
777
+ // const cloudEvent = cloudFnWrap().cloudEvent;
778
+ // expect(cloudEvent.ref).equal('rtdb_ref_2');
779
+ // });
508
780
509
781
it ( 'should resolve using params' , ( ) => {
510
782
const referenceOptions = {
0 commit comments