@@ -80,7 +80,7 @@ describe('exportInterviewLogTask', () => {
8080 timestamp_sec : 5 ,
8181 event_date : new Date ( 5 * 1000 ) ,
8282 values_by_path : { 'response.household.carNumber' : 1 , 'response.household.bikeNumber' : 10 , 'validations.household.carNumber' : false , 'validations.household.bikeNumber' : true } ,
83- unset_paths : [ 'validations.home.region' , 'validation .home.country' ]
83+ unset_paths : [ 'validations.home.region' , 'validations .home.country' ]
8484 } , {
8585 // No participant response in values_by_path and unset_paths
8686 ...commonInterviewData ,
@@ -142,13 +142,13 @@ describe('exportInterviewLogTask', () => {
142142 expect ( logRows [ i ] ) . toEqual ( expect . objectContaining ( {
143143 ...commonInterviewDataInRows
144144 } ) ) ;
145- const modifiedKeys = Object . entries ( logs [ i ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
146- const initializedKeys = Object . entries ( logs [ i ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
145+ const modifiedKeys = Object . entries ( logs [ i ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
146+ const initializedKeys = Object . entries ( logs [ i ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
147147 expect ( logRows [ i ] . timestampMs ) . toEqual ( String ( ( i + 1 ) * 1000 ) ) ;
148148 expect ( logRows [ i ] . event_date ) . toEqual ( new Date ( ( i + 1 ) * 1000 ) . toISOString ( ) ) ;
149149 expect ( logRows [ i ] . modifiedFields ) . toEqual ( modifiedKeys ) ;
150150 expect ( logRows [ i ] . initializedFields ) . toEqual ( initializedKeys ) ;
151- expect ( logRows [ i ] . unsetFields ) . toEqual ( logs [ i ] . unset_paths !== undefined ? logs [ i ] . unset_paths . join ( '|' ) : '' ) ;
151+ expect ( logRows [ i ] . unsetFields ) . toEqual ( logs [ i ] . unset_paths !== undefined ? logs [ i ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ) ;
152152 expect ( logRows [ i ] . widgetType ) . toEqual ( '' ) ;
153153 expect ( logRows [ i ] . widgetPath ) . toEqual ( '' ) ;
154154 }
@@ -362,15 +362,17 @@ describe('exportInterviewLogTask', () => {
362362 ...commonInterviewDataInRows ,
363363 event_type : 'widget_interaction'
364364 } ) ) ;
365- const modifiedKeys = Object . entries ( log . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
366- const initializedKeys = Object . entries ( log . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
365+ const modifiedKeys = Object . entries ( log . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
366+ const initializedKeys = Object . entries ( log . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
367367 expect ( currentLog . timestampMs ) . toEqual ( String ( ( 1 ) * 1000 ) ) ;
368368 expect ( currentLog . event_date ) . toEqual ( new Date ( ( 1 ) * 1000 ) . toISOString ( ) ) ;
369369 expect ( currentLog . modifiedFields ) . toEqual ( modifiedKeys ) ;
370370 expect ( currentLog . initializedFields ) . toEqual ( initializedKeys ) ;
371- expect ( currentLog . unsetFields ) . toEqual ( log . unset_paths !== undefined ? log . unset_paths . join ( '|' ) : '' ) ;
371+ expect ( currentLog . unsetFields ) . toEqual ( log . unset_paths !== undefined ? log . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ) ;
372372 expect ( currentLog . widgetType ) . toEqual ( userAction . widgetType ) ;
373373 expect ( currentLog . widgetPath ) . toEqual ( userAction . path ) ;
374+ expect ( currentLog . invalidFields ) . toEqual ( '' ) ;
375+ expect ( currentLog . validFields ) . toEqual ( 'home.geography' ) ;
374376 } ) ;
375377
376378 test ( 'Test with an event of type widget_interaction with user action, with values' , async ( ) => {
@@ -490,34 +492,38 @@ describe('exportInterviewLogTask', () => {
490492 expect ( logRows . length ) . toEqual ( buttonLogs . length ) ;
491493
492494 // Test the row values
493- const modifiedKeysLog1 = Object . entries ( buttonLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
494- const initializedKeysLog1 = Object . entries ( buttonLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
495+ const modifiedKeysLog1 = Object . entries ( buttonLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
496+ const initializedKeysLog1 = Object . entries ( buttonLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
495497 expect ( logRows [ 0 ] ) . toEqual ( {
496498 ...commonInterviewDataInRows ,
497499 event_type : 'button_click' ,
498500 timestampMs : String ( ( 1 ) * 1000 ) ,
499501 event_date : new Date ( ( 1 ) * 1000 ) . toISOString ( ) ,
500502 modifiedFields : modifiedKeysLog1 ,
501503 initializedFields : initializedKeysLog1 ,
502- unsetFields : buttonLogs [ 0 ] . unset_paths !== undefined ? buttonLogs [ 0 ] . unset_paths . join ( '|' ) : '' ,
504+ unsetFields : buttonLogs [ 0 ] . unset_paths !== undefined ? buttonLogs [ 0 ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ,
503505 widgetType : '' ,
504506 widgetPath : userAction . buttonId ,
505507 hiddenWidgets : '' ,
508+ invalidFields : '' ,
509+ validFields : 'home.geography'
506510 } ) ;
507511
508- const modifiedKeys = Object . entries ( buttonLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
509- const initializedKeys = Object . entries ( buttonLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
512+ const modifiedKeys = Object . entries ( buttonLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
513+ const initializedKeys = Object . entries ( buttonLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
510514 expect ( logRows [ 1 ] ) . toEqual ( {
511515 ...commonInterviewDataInRows ,
512516 event_type : 'button_click' ,
513517 timestampMs : String ( ( 2 ) * 1000 ) ,
514518 event_date : new Date ( ( 2 ) * 1000 ) . toISOString ( ) ,
515519 modifiedFields : modifiedKeys ,
516520 initializedFields : initializedKeys ,
517- unsetFields : buttonLogs [ 1 ] . unset_paths !== undefined ? buttonLogs [ 1 ] . unset_paths . join ( '|' ) : '' ,
521+ unsetFields : buttonLogs [ 1 ] . unset_paths !== undefined ? buttonLogs [ 1 ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ,
518522 widgetType : '' ,
519523 widgetPath : userActionWithHidden . buttonId ,
520524 hiddenWidgets : userActionWithHidden . hiddenWidgets . join ( '|' ) ,
525+ invalidFields : '' ,
526+ validFields : ''
521527 } ) ;
522528 } ) ;
523529
@@ -563,34 +569,38 @@ describe('exportInterviewLogTask', () => {
563569 expect ( logRows . length ) . toEqual ( sectionChangeLogs . length ) ;
564570
565571 // Test the row values
566- const modifiedKeys = Object . entries ( sectionChangeLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
567- const initializedKeys = Object . entries ( sectionChangeLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
572+ const modifiedKeys = Object . entries ( sectionChangeLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
573+ const initializedKeys = Object . entries ( sectionChangeLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
568574 expect ( logRows [ 0 ] ) . toEqual ( {
569575 ...commonInterviewDataInRows ,
570576 event_type : 'section_change' ,
571577 timestampMs : String ( ( 1 ) * 1000 ) ,
572578 event_date : new Date ( ( 1 ) * 1000 ) . toISOString ( ) ,
573579 modifiedFields : modifiedKeys ,
574580 initializedFields : initializedKeys ,
575- unsetFields : sectionChangeLogs [ 0 ] . unset_paths !== undefined ? sectionChangeLogs [ 0 ] . unset_paths . join ( '|' ) : '' ,
581+ unsetFields : sectionChangeLogs [ 0 ] . unset_paths !== undefined ? sectionChangeLogs [ 0 ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ,
576582 widgetType : '' ,
577583 widgetPath : userAction . targetSection . sectionShortname ,
578584 hiddenWidgets : '' ,
585+ invalidFields : '' ,
586+ validFields : 'home.geography'
579587 } ) ;
580588
581- const modifiedKeys2 = Object . entries ( sectionChangeLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
582- const initializedKeys2 = Object . entries ( sectionChangeLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
589+ const modifiedKeys2 = Object . entries ( sectionChangeLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
590+ const initializedKeys2 = Object . entries ( sectionChangeLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
583591 expect ( logRows [ 1 ] ) . toEqual ( {
584592 ...commonInterviewDataInRows ,
585593 event_type : 'section_change' ,
586594 timestampMs : String ( ( 2 ) * 1000 ) ,
587595 event_date : new Date ( ( 2 ) * 1000 ) . toISOString ( ) ,
588596 modifiedFields : modifiedKeys2 ,
589597 initializedFields : initializedKeys2 ,
590- unsetFields : sectionChangeLogs [ 1 ] . unset_paths !== undefined ? sectionChangeLogs [ 1 ] . unset_paths . join ( '|' ) : '' ,
598+ unsetFields : sectionChangeLogs [ 1 ] . unset_paths !== undefined ? sectionChangeLogs [ 1 ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ,
591599 widgetType : '' ,
592600 widgetPath : userAction . targetSection . sectionShortname + '/' + ( userActionWithHidden . targetSection . iterationContext || [ ] ) . join ( '/' ) ,
593601 hiddenWidgets : userActionWithHidden . hiddenWidgets . join ( '|' ) ,
602+ invalidFields : '' ,
603+ validFields : ''
594604 } ) ;
595605
596606 } ) ;
@@ -629,19 +639,21 @@ describe('exportInterviewLogTask', () => {
629639 expect ( logRows . length ) . toEqual ( languageLogs . length ) ;
630640
631641 // Test the row values
632- const modifiedKeysLog1 = Object . entries ( languageLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
633- const initializedKeysLog1 = Object . entries ( languageLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
642+ const modifiedKeysLog1 = Object . entries ( languageLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
643+ const initializedKeysLog1 = Object . entries ( languageLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
634644 expect ( logRows [ 0 ] ) . toEqual ( {
635645 ...commonInterviewDataInRows ,
636646 event_type : 'language_change' ,
637647 timestampMs : String ( ( 1 ) * 1000 ) ,
638648 event_date : new Date ( ( 1 ) * 1000 ) . toISOString ( ) ,
639649 modifiedFields : modifiedKeysLog1 ,
640650 initializedFields : initializedKeysLog1 ,
641- unsetFields : languageLogs [ 0 ] . unset_paths !== undefined ? languageLogs [ 0 ] . unset_paths . join ( '|' ) : '' ,
651+ unsetFields : languageLogs [ 0 ] . unset_paths !== undefined ? languageLogs [ 0 ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ,
642652 widgetType : '' ,
643653 widgetPath : '' ,
644654 hiddenWidgets : '' ,
655+ invalidFields : '' ,
656+ validFields : 'home.geography'
645657 } ) ;
646658 } ) ;
647659
@@ -679,19 +691,121 @@ describe('exportInterviewLogTask', () => {
679691 expect ( logRows . length ) . toEqual ( interviewOpenLogs . length ) ;
680692
681693 // Test the row values
682- const modifiedKeysLog1 = Object . entries ( interviewOpenLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
683- const initializedKeysLog1 = Object . entries ( interviewOpenLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
694+ const modifiedKeysLog1 = Object . entries ( interviewOpenLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
695+ const initializedKeysLog1 = Object . entries ( interviewOpenLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
684696 expect ( logRows [ 0 ] ) . toEqual ( {
685697 ...commonInterviewDataInRows ,
686698 event_type : 'interview_open' ,
687699 timestampMs : String ( ( 1 ) * 1000 ) ,
688700 event_date : new Date ( ( 1 ) * 1000 ) . toISOString ( ) ,
689701 modifiedFields : modifiedKeysLog1 ,
690702 initializedFields : initializedKeysLog1 ,
691- unsetFields : interviewOpenLogs [ 0 ] . unset_paths !== undefined ? interviewOpenLogs [ 0 ] . unset_paths . join ( '|' ) : '' ,
703+ unsetFields : interviewOpenLogs [ 0 ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) ,
692704 widgetType : '' ,
693705 widgetPath : '' ,
694706 hiddenWidgets : '' ,
707+ invalidFields : '' ,
708+ validFields : 'home.geography'
709+ } ) ;
710+ } ) ;
711+
712+ test ( 'Test with various events, with validations `true` and `false`' , async ( ) => {
713+ // Add some log statements with validations data: first statement has only true, second has one false, third has both true and false
714+ const interviewLogs : { [ key : string ] : any } [ ] = [ {
715+ ...commonInterviewData ,
716+ event_type : 'button_click' ,
717+ timestamp_sec : 1 ,
718+ event_date : new Date ( 1 * 1000 ) ,
719+ values_by_path : { 'response.home.geography' : { type : 'Point' , coordinates : [ 1 , 1 ] } , 'validations.home.geography' : true , 'response.household.size' : 3 , 'response._activeTripId' : null } ,
720+ unset_paths : [ 'response.home.someField' , 'validations.home.someField' ] ,
721+ user_action : { type : 'buttonClick' , buttonId : 'response.someField' }
722+ } , {
723+ ...commonInterviewData ,
724+ event_type : 'widget_interaction' ,
725+ timestamp_sec : 2 ,
726+ event_date : new Date ( 2 * 1000 ) ,
727+ values_by_path : { 'validations.home.someField' : false } ,
728+ user_action : { type : 'widgetInteraction' , path : 'response.home.someField' , value : 'someValue' , widgetType : 'radio' }
729+ } , {
730+ ...commonInterviewData ,
731+ event_type : 'button_click' ,
732+ timestamp_sec : 3 ,
733+ event_date : new Date ( 3 * 1000 ) ,
734+ values_by_path : { 'validations.home.geography' : true , 'validations.home.household.size' : false , 'validations.home.someField' : false } ,
735+ unset_paths : [ 'response.home.someField' ] ,
736+ user_action : { type : 'buttonClick' , buttonId : 'response.someField' }
737+ } ] ;
738+ // Add the logs to the stream
739+ mockGetInterviewLogsStream . mockReturnValue ( new ObjectReadableMock ( interviewLogs ) as any ) ;
740+
741+ const fileName = await exportInterviewLogTask ( { } ) ;
742+
743+ // Check the file content of the exported logs
744+ expect ( mockCreateStream ) . toHaveBeenCalledTimes ( 1 ) ;
745+ expect ( mockGetInterviewLogsStream ) . toHaveBeenCalledWith ( undefined ) ;
746+
747+ const csvFileName = Object . keys ( fileStreams ) . find ( ( filename ) => filename . endsWith ( fileName ) ) ;
748+ expect ( csvFileName ) . toBeDefined ( ) ;
749+
750+ const csvStream = fileStreams [ csvFileName as string ] ;
751+ // There should be one row per log
752+ expect ( csvStream . data . length ) . toEqual ( interviewLogs . length ) ;
753+
754+ // Get the actual rows in the file data
755+ const logRows = await getCsvFileRows ( csvStream . data ) ;
756+ // There should be one row per log
757+ expect ( logRows . length ) . toEqual ( interviewLogs . length ) ;
758+
759+ // Test the row values
760+ const modifiedKeysLog1 = Object . entries ( interviewLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
761+ const initializedKeysLog1 = Object . entries ( interviewLogs [ 0 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
762+ expect ( logRows [ 0 ] ) . toEqual ( {
763+ ...commonInterviewDataInRows ,
764+ event_type : 'button_click' ,
765+ timestampMs : String ( ( 1 ) * 1000 ) ,
766+ event_date : new Date ( ( 1 ) * 1000 ) . toISOString ( ) ,
767+ modifiedFields : modifiedKeysLog1 ,
768+ initializedFields : initializedKeysLog1 ,
769+ unsetFields : interviewLogs [ 0 ] . unset_paths !== undefined ? interviewLogs [ 0 ] . unset_paths . filter ( ( path : string ) => ! path . startsWith ( 'validations.' ) ) . join ( '|' ) : '' ,
770+ widgetType : '' ,
771+ widgetPath : interviewLogs [ 0 ] . user_action . buttonId ,
772+ hiddenWidgets : '' ,
773+ invalidFields : '' ,
774+ validFields : 'home.geography'
775+ } ) ;
776+
777+ const modifiedKeysLog2 = Object . entries ( interviewLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
778+ const initializedKeysLog2 = Object . entries ( interviewLogs [ 1 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
779+ expect ( logRows [ 1 ] ) . toEqual ( {
780+ ...commonInterviewDataInRows ,
781+ event_type : 'widget_interaction' ,
782+ timestampMs : String ( ( 2 ) * 1000 ) ,
783+ event_date : new Date ( ( 2 ) * 1000 ) . toISOString ( ) ,
784+ modifiedFields : modifiedKeysLog2 ,
785+ initializedFields : initializedKeysLog2 ,
786+ unsetFields : interviewLogs [ 1 ] . unset_paths !== undefined ? interviewLogs [ 1 ] . unset_paths . join ( '|' ) : '' ,
787+ widgetType : interviewLogs [ 1 ] . user_action . widgetType ,
788+ widgetPath : interviewLogs [ 1 ] . user_action . path ,
789+ hiddenWidgets : '' ,
790+ invalidFields : 'home.someField' ,
791+ validFields : ''
792+ } ) ;
793+
794+ const modifiedKeysLog3 = Object . entries ( interviewLogs [ 2 ] . values_by_path ) . filter ( ( [ key , value ] ) => value !== null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
795+ const initializedKeysLog3 = Object . entries ( interviewLogs [ 2 ] . values_by_path ) . filter ( ( [ key , value ] ) => value === null && ! key . startsWith ( 'validations.' ) ) . map ( ( [ key , value ] ) => key ) . join ( '|' ) ;
796+ expect ( logRows [ 2 ] ) . toEqual ( {
797+ ...commonInterviewDataInRows ,
798+ event_type : 'button_click' ,
799+ timestampMs : String ( ( 3 ) * 1000 ) ,
800+ event_date : new Date ( ( 3 ) * 1000 ) . toISOString ( ) ,
801+ modifiedFields : modifiedKeysLog3 ,
802+ initializedFields : initializedKeysLog3 ,
803+ unsetFields : interviewLogs [ 2 ] . unset_paths !== undefined ? interviewLogs [ 2 ] . unset_paths . join ( '|' ) : '' ,
804+ widgetType : '' ,
805+ widgetPath : interviewLogs [ 2 ] . user_action . buttonId ,
806+ hiddenWidgets : '' ,
807+ invalidFields : [ 'home.household.size' , 'home.someField' ] . join ( '|' ) ,
808+ validFields : 'home.geography'
695809 } ) ;
696810 } ) ;
697811
0 commit comments