@@ -3454,6 +3454,18 @@ describe('Rokt Forwarder', () => {
34543454 window . mParticle . _Store . localSessionAttributes . should . deepEqual ( {
34553455 hasUrl : true ,
34563456 } ) ;
3457+
3458+ window . mParticle . _Store . localSessionAttributes = { } ;
3459+ window . mParticle . forwarder . process ( {
3460+ EventName : 'Browse' ,
3461+ EventCategory : EventType . Unknown ,
3462+ EventDataType : MessageType . PageView ,
3463+ EventAttributes : {
3464+ someOtherAttribute : 'value' ,
3465+ } ,
3466+ } ) ;
3467+
3468+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( { } ) ;
34573469 } ) ;
34583470
34593471 it ( 'should evaluate equals for placementEventAttributeMapping conditions' , async ( ) => {
@@ -3555,6 +3567,177 @@ describe('Rokt Forwarder', () => {
35553567 } ) ;
35563568 } ) ;
35573569
3570+ it ( 'should correctly match attribute values for different type cases' , async ( ) => {
3571+ const placementEventAttributeMapping = JSON . stringify ( [
3572+ {
3573+ jsmap : null ,
3574+ map : 'boolAttr' ,
3575+ maptype : 'EventAttributeClass.Name' ,
3576+ value : 'lowerCaseMatches' ,
3577+ conditions : [
3578+ {
3579+ operator : 'equals' ,
3580+ attributeValue : 'true' ,
3581+ } ,
3582+ ] ,
3583+ } ,
3584+ {
3585+ jsmap : null ,
3586+ map : 'boolAttr' ,
3587+ maptype : 'EventAttributeClass.Name' ,
3588+ value : 'titleCaseMatches' ,
3589+ conditions : [
3590+ {
3591+ operator : 'equals' ,
3592+ attributeValue : 'True' ,
3593+ } ,
3594+ ] ,
3595+ } ,
3596+ {
3597+ jsmap : null ,
3598+ map : 'boolAttr' ,
3599+ maptype : 'EventAttributeClass.Name' ,
3600+ value : 'upperCaseMatches' ,
3601+ conditions : [
3602+ {
3603+ operator : 'equals' ,
3604+ attributeValue : 'TRUE' ,
3605+ } ,
3606+ ] ,
3607+ } ,
3608+ {
3609+ jsmap : null ,
3610+ map : 'zeroAttr' ,
3611+ maptype : 'EventAttributeClass.Name' ,
3612+ value : 'falseMatches' ,
3613+ conditions : [
3614+ {
3615+ operator : 'equals' ,
3616+ attributeValue : false ,
3617+ } ,
3618+ ] ,
3619+ } ,
3620+ {
3621+ jsmap : null ,
3622+ map : 'zeroAttr' ,
3623+ maptype : 'EventAttributeClass.Name' ,
3624+ value : 'emptyMatches' ,
3625+ conditions : [
3626+ {
3627+ operator : 'equals' ,
3628+ attributeValue : '' ,
3629+ } ,
3630+ ] ,
3631+ } ,
3632+ {
3633+ jsmap : null ,
3634+ map : 'zeroAttr' ,
3635+ maptype : 'EventAttributeClass.Name' ,
3636+ value : 'zeroMatches' ,
3637+ conditions : [
3638+ {
3639+ operator : 'equals' ,
3640+ attributeValue : '0' ,
3641+ } ,
3642+ ] ,
3643+ } ,
3644+ {
3645+ jsmap : null ,
3646+ map : 'numAttr' ,
3647+ maptype : 'EventAttributeClass.Name' ,
3648+ value : 'digitMatches' ,
3649+ conditions : [
3650+ {
3651+ operator : 'contains' ,
3652+ attributeValue : '2' ,
3653+ } ,
3654+ ] ,
3655+ } ,
3656+ ] ) ;
3657+
3658+ await window . mParticle . forwarder . init (
3659+ {
3660+ accountId : '123456' ,
3661+ placementEventAttributeMapping,
3662+ } ,
3663+ reportService . cb ,
3664+ true ,
3665+ null ,
3666+ { }
3667+ ) ;
3668+
3669+ await waitForCondition ( ( ) => window . mParticle . Rokt . attachKitCalled ) ;
3670+
3671+ window . mParticle . _Store . localSessionAttributes = { } ;
3672+ window . mParticle . forwarder . process ( {
3673+ EventName : 'Test' ,
3674+ EventCategory : EventType . Unknown ,
3675+ EventDataType : MessageType . PageView ,
3676+ EventAttributes : {
3677+ boolAttr : true ,
3678+ zeroAttr : 0 ,
3679+ numAttr : 123 ,
3680+ } ,
3681+ } ) ;
3682+
3683+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( {
3684+ lowerCaseMatches : true ,
3685+ zeroMatches : true ,
3686+ digitMatches : true ,
3687+ } ) ;
3688+ } ) ;
3689+
3690+ it ( 'should not match when attribute key is missing or EventAttributes is absent' , async ( ) => {
3691+ const placementEventAttributeMapping = JSON . stringify ( [
3692+ {
3693+ jsmap : null ,
3694+ map : 'missingAttr' ,
3695+ maptype : 'EventAttributeClass.Name' ,
3696+ value : 'shouldNotMatch' ,
3697+ conditions : [
3698+ {
3699+ operator : 'equals' ,
3700+ attributeValue : 'testValue' ,
3701+ } ,
3702+ ] ,
3703+ } ,
3704+ ] ) ;
3705+
3706+ await window . mParticle . forwarder . init (
3707+ {
3708+ accountId : '123456' ,
3709+ placementEventAttributeMapping,
3710+ } ,
3711+ reportService . cb ,
3712+ true ,
3713+ null ,
3714+ { }
3715+ ) ;
3716+
3717+ await waitForCondition ( ( ) => window . mParticle . Rokt . attachKitCalled ) ;
3718+
3719+ window . mParticle . _Store . localSessionAttributes = { } ;
3720+ window . mParticle . forwarder . process ( {
3721+ EventName : 'Test' ,
3722+ EventCategory : EventType . Unknown ,
3723+ EventDataType : MessageType . PageView ,
3724+ EventAttributes : {
3725+ otherAttr : 'value' ,
3726+ } ,
3727+ } ) ;
3728+
3729+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( { } ) ;
3730+
3731+ window . mParticle . _Store . localSessionAttributes = { } ;
3732+ window . mParticle . forwarder . process ( {
3733+ EventName : 'Test' ,
3734+ EventCategory : EventType . Unknown ,
3735+ EventDataType : MessageType . PageView ,
3736+ } ) ;
3737+
3738+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( { } ) ;
3739+ } ) ;
3740+
35583741 it ( 'should require ALL rules for the same mapped key to match (AND across rules)' , async ( ) => {
35593742 const placementEventAttributeMapping = JSON . stringify ( [
35603743 {
@@ -3693,6 +3876,180 @@ describe('Rokt Forwarder', () => {
36933876 saleSeeker1 : true ,
36943877 } ) ;
36953878 } ) ;
3879+ it ( 'should treat falsy attribute values as existing' , async ( ) => {
3880+ const placementEventAttributeMapping = JSON . stringify ( [
3881+ {
3882+ jsmap : null ,
3883+ map : 'zeroProp' ,
3884+ maptype : 'EventAttributeClass.Name' ,
3885+ value : 'zeroExists' ,
3886+ conditions : [ { operator : 'exists' } ] ,
3887+ } ,
3888+ {
3889+ jsmap : null ,
3890+ map : 'falseProp' ,
3891+ maptype : 'EventAttributeClass.Name' ,
3892+ value : 'falseExists' ,
3893+ conditions : [ { operator : 'exists' } ] ,
3894+ } ,
3895+ {
3896+ jsmap : null ,
3897+ map : 'emptyStringProp' ,
3898+ maptype : 'EventAttributeClass.Name' ,
3899+ value : 'emptyStringExists' ,
3900+ conditions : [ { operator : 'exists' } ] ,
3901+ } ,
3902+ ] ) ;
3903+
3904+ await window . mParticle . forwarder . init (
3905+ {
3906+ accountId : '123456' ,
3907+ placementEventAttributeMapping,
3908+ } ,
3909+ reportService . cb ,
3910+ true ,
3911+ null ,
3912+ { }
3913+ ) ;
3914+
3915+ await waitForCondition ( ( ) => window . mParticle . Rokt . attachKitCalled ) ;
3916+
3917+ window . mParticle . _Store . localSessionAttributes = { } ;
3918+ window . mParticle . forwarder . process ( {
3919+ EventName : 'Test' ,
3920+ EventCategory : EventType . Unknown ,
3921+ EventDataType : MessageType . PageView ,
3922+ EventAttributes : {
3923+ zeroProp : 0 ,
3924+ falseProp : false ,
3925+ emptyStringProp : '' ,
3926+ } ,
3927+ } ) ;
3928+
3929+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( {
3930+ zeroExists : true ,
3931+ falseExists : true ,
3932+ emptyStringExists : true ,
3933+ } ) ;
3934+ } ) ;
3935+
3936+ it ( 'should not match when condition has an unrecognized operator' , async ( ) => {
3937+ const placementEventAttributeMapping = JSON . stringify ( [
3938+ {
3939+ jsmap : null ,
3940+ map : 'URL' ,
3941+ maptype : 'EventAttributeClass.Name' ,
3942+ value : 'shouldNotMatch' ,
3943+ conditions : [
3944+ {
3945+ operator : 'testOperator' ,
3946+ attributeValue : 'https' ,
3947+ } ,
3948+ ] ,
3949+ } ,
3950+ ] ) ;
3951+
3952+ await window . mParticle . forwarder . init (
3953+ {
3954+ accountId : '123456' ,
3955+ placementEventAttributeMapping,
3956+ } ,
3957+ reportService . cb ,
3958+ true ,
3959+ null ,
3960+ { }
3961+ ) ;
3962+
3963+ await waitForCondition ( ( ) => window . mParticle . Rokt . attachKitCalled ) ;
3964+
3965+ window . mParticle . _Store . localSessionAttributes = { } ;
3966+ window . mParticle . forwarder . process ( {
3967+ EventName : 'Browse' ,
3968+ EventCategory : EventType . Unknown ,
3969+ EventDataType : MessageType . PageView ,
3970+ EventAttributes : {
3971+ URL : 'https://example.com' ,
3972+ } ,
3973+ } ) ;
3974+
3975+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( { } ) ;
3976+ } ) ;
3977+
3978+ it ( 'should support both placementEventMapping and placementEventAttributeMapping together' , async ( ) => {
3979+ const placementEventMapping = JSON . stringify ( [
3980+ {
3981+ jsmap : 'hashed-<48Video Watched>-value' ,
3982+ map : '123466' ,
3983+ maptype : 'EventClass.Id' ,
3984+ value : 'foo-mapped-flag' ,
3985+ } ,
3986+ ] ) ;
3987+
3988+ const placementEventAttributeMapping = JSON . stringify ( [
3989+ {
3990+ jsmap : null ,
3991+ map : 'URL' ,
3992+ maptype : 'EventAttributeClass.Name' ,
3993+ value : 'hasUrl' ,
3994+ conditions : [ { operator : 'exists' } ] ,
3995+ } ,
3996+ ] ) ;
3997+
3998+ await window . mParticle . forwarder . init (
3999+ {
4000+ accountId : '123456' ,
4001+ placementEventMapping,
4002+ placementEventAttributeMapping,
4003+ } ,
4004+ reportService . cb ,
4005+ true ,
4006+ null ,
4007+ { }
4008+ ) ;
4009+
4010+ await waitForCondition ( ( ) => window . mParticle . Rokt . attachKitCalled ) ;
4011+
4012+ window . mParticle . _Store . localSessionAttributes = { } ;
4013+ window . mParticle . forwarder . process ( {
4014+ EventName : 'Browse' ,
4015+ EventCategory : EventType . Unknown ,
4016+ EventDataType : MessageType . PageView ,
4017+ EventAttributes : {
4018+ URL : 'https://example.com/anything' ,
4019+ } ,
4020+ } ) ;
4021+
4022+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( {
4023+ hasUrl : true ,
4024+ } ) ;
4025+
4026+ window . mParticle . _Store . localSessionAttributes = { } ;
4027+ window . mParticle . forwarder . process ( {
4028+ EventName : 'Video Watched' ,
4029+ EventCategory : EventType . Other ,
4030+ EventDataType : MessageType . PageEvent ,
4031+ EventAttributes : {
4032+ URL : 'https://example.com/video' ,
4033+ } ,
4034+ } ) ;
4035+
4036+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( {
4037+ hasUrl : true ,
4038+ 'foo-mapped-flag' : true ,
4039+ } ) ;
4040+
4041+ window . mParticle . _Store . localSessionAttributes = { } ;
4042+ window . mParticle . forwarder . process ( {
4043+ EventName : 'Video Watched' ,
4044+ EventCategory : EventType . Other ,
4045+ EventDataType : MessageType . PageEvent ,
4046+ } ) ;
4047+
4048+ window . mParticle . _Store . localSessionAttributes . should . deepEqual ( {
4049+ 'foo-mapped-flag' : true ,
4050+ } ) ;
4051+ } ) ;
4052+
36964053 it ( 'should add the event to the event queue if the kit is not initialized' , async ( ) => {
36974054 await window . mParticle . forwarder . init (
36984055 {
0 commit comments