@@ -76,152 +76,98 @@ describe('RoktManager', () => {
7676 } ) ;
7777
7878 describe ( '#hashAttributes' , ( ) => {
79+ const nodeCrypto = require ( 'crypto' ) ;
80+ let shaSpy : jest . SpyInstance ;
81+
7982 beforeEach ( ( ) => {
8083 roktManager [ 'currentUser' ] = currentUser ;
84+ shaSpy = jest . spyOn ( roktManager as any , 'sha256Hex' ) ;
85+ shaSpy . mockImplementation ( ( s : string ) =>
86+ Promise . resolve ( nodeCrypto . createHash ( 'sha256' ) . update ( s ) . digest ( 'hex' ) ) ,
87+ ) ;
8188 } ) ;
8289
83- it ( 'should call kit.hashAttributes with empty attributes' , ( ) => {
84- const kit : IRoktKit = {
85- launcher : {
86- selectPlacements : jest . fn ( ) ,
87- hashAttributes : jest . fn ( ) ,
88- use : jest . fn ( ) ,
89- } ,
90- filters : undefined ,
91- filteredUser : undefined ,
92- hashAttributes : jest . fn ( ) ,
93- selectPlacements : jest . fn ( ) ,
94- setExtensionData : jest . fn ( ) ,
95- use : jest . fn ( ) ,
96- userAttributes : undefined ,
97- } ;
98-
99- roktManager . attachKit ( kit ) ;
100-
101- const attributes = { } ;
102-
103- roktManager . hashAttributes ( attributes ) ;
104- expect ( kit . hashAttributes ) . toHaveBeenCalledWith ( attributes ) ;
90+ afterEach ( ( ) => {
91+ shaSpy . mockRestore ( ) ;
10592 } ) ;
10693
107- it ( 'should call kit.hashAttributes with passed in attributes' , ( ) => {
108- const kit : IRoktKit = {
109- launcher : {
110- selectPlacements : jest . fn ( ) ,
111- hashAttributes : jest . fn ( ) ,
112- use : jest . fn ( ) ,
113- } ,
114- filters : undefined ,
115- filteredUser : undefined ,
116- hashAttributes : jest . fn ( ) ,
117- selectPlacements : jest . fn ( ) ,
118- setExtensionData : jest . fn ( ) ,
119- use : jest . fn ( ) ,
120- userAttributes : undefined ,
121- } ;
122-
123- roktManager . attachKit ( kit ) ;
124-
94+ it ( 'should hash attributes with passed in attributes' , async ( ) => {
12595 const attributes = {
1269612797 phone : '1234567890'
12898 } ;
12999
130- roktManager . hashAttributes ( attributes ) ;
131- expect ( kit . hashAttributes ) . toHaveBeenCalledWith ( attributes ) ;
100+ const result = await roktManager . hashAttributes ( attributes ) ;
101+
102+ expect ( result ) . toEqual ( {
103+ 104+ emailsha256 :
nodeCrypto . createHash ( 'sha256' ) . update ( '[email protected] ' ) . digest ( 'hex' ) , 105+ phone : '1234567890' ,
106+ phonesha256 : nodeCrypto . createHash ( 'sha256' ) . update ( '1234567890' ) . digest ( 'hex' ) ,
107+ } ) ;
132108 } ) ;
133109
134- it ( 'should queue the hashAttributes method if no launcher or kit is attached' , ( ) => {
110+ it ( 'should hash all non-null string, number, and boolean values' , async ( ) => {
135111 const attributes = {
136- 112+ 113+ age : 25 ,
114+ active : true ,
115+ nullable : null ,
116+ undefinedVal : undefined
137117 } ;
138118
139- roktManager . hashAttributes ( attributes ) ;
119+ const result = await roktManager . hashAttributes ( attributes ) ;
140120
141- expect ( roktManager [ 'kit' ] ) . toBeNull ( ) ;
142- expect ( roktManager [ 'messageQueue' ] . size ) . toBe ( 1 ) ;
143- const queuedMessage = Array . from ( roktManager [ 'messageQueue' ] . values ( ) ) [ 0 ] ;
144- expect ( queuedMessage . methodName ) . toBe ( 'hashAttributes' ) ;
145- expect ( queuedMessage . payload ) . toBe ( attributes ) ;
121+ expect ( result ) . toEqual ( {
122+ 123+ emailsha256 :
nodeCrypto . createHash ( 'sha256' ) . update ( '[email protected] ' ) . digest ( 'hex' ) , 124+ age : 25 ,
125+ agesha256 : nodeCrypto . createHash ( 'sha256' ) . update ( '25' ) . digest ( 'hex' ) ,
126+ active : true ,
127+ activesha256 : nodeCrypto . createHash ( 'sha256' ) . update ( 'true' ) . digest ( 'hex' ) ,
128+ nullable : null ,
129+ undefinedVal : undefined
130+ } ) ;
146131 } ) ;
147132
148- it ( 'should process queued hashAttributes calls once the launcher and kit are attached' , ( ) => {
149- const kit : IRoktKit = {
150- launcher : {
151- selectPlacements : jest . fn ( ) ,
152- hashAttributes : jest . fn ( ) ,
153- use : jest . fn ( ) ,
154- } ,
155- filters : undefined ,
156- filteredUser : undefined ,
157- hashAttributes : jest . fn ( ) ,
158- selectPlacements : jest . fn ( ) ,
159- setExtensionData : jest . fn ( ) ,
160- use : jest . fn ( ) ,
161- userAttributes : undefined ,
162- } ;
163-
164- const attributes = {
165- 166- } ;
167-
168- roktManager . hashAttributes ( attributes ) ;
169- expect ( roktManager [ 'kit' ] ) . toBeNull ( ) ;
170- expect ( roktManager [ 'messageQueue' ] . size ) . toBe ( 1 ) ;
171- const queuedMessage = Array . from ( roktManager [ 'messageQueue' ] . values ( ) ) [ 0 ] ;
172- expect ( queuedMessage . methodName ) . toBe ( 'hashAttributes' ) ;
173- expect ( queuedMessage . payload ) . toBe ( attributes ) ;
174- expect ( kit . hashAttributes ) . not . toHaveBeenCalled ( ) ;
175-
176- roktManager . attachKit ( kit ) ;
177- expect ( roktManager [ 'kit' ] ) . not . toBeNull ( ) ;
178- expect ( roktManager [ 'messageQueue' ] . size ) . toBe ( 0 ) ;
179- expect ( kit . hashAttributes ) . toHaveBeenCalledWith ( attributes ) ;
133+ it ( 'should return empty object if attributes is null' , async ( ) => {
134+ const result = await roktManager . hashAttributes ( null as any ) ;
135+ expect ( result ) . toEqual ( { } ) ;
180136 } ) ;
181137
182- it ( 'should pass through the correct attributes to kit.launcher.hashAttributes' , async ( ) => {
183- const kit : Partial < IRoktKit > = {
184- launcher : {
185- selectPlacements : jest . fn ( ) ,
186- hashAttributes : jest . fn ( ) ,
187- use : jest . fn ( ) ,
188- } ,
138+ it ( 'should return empty object if attributes is undefined' , async ( ) => {
139+ const result = await roktManager . hashAttributes ( undefined as any ) ;
140+ expect ( result ) . toEqual ( { } ) ;
141+ } ) ;
189142
190- // We are mocking the hashAttributes method to return the
191- // launcher's hashAttributes method and verify that
192- // both the kit's and the launcher's methods
193- // are called with the correct attributes.
194- // This will happen through the Web Kit's hashAttributes method
195- hashAttributes : jest . fn ( ) . mockImplementation ( ( attributes ) => {
196- return kit . launcher . hashAttributes ( attributes ) ;
197- } )
198- } ;
143+ it ( 'should handle empty attributes object' , async ( ) => {
144+ const result = await roktManager . hashAttributes ( { } ) ;
145+ expect ( result ) . toEqual ( { } ) ;
146+ } ) ;
199147
200- roktManager . attachKit ( kit as IRoktKit ) ;
148+ it ( 'should reject if hashSha256 throws an error' , async ( ) => {
149+ shaSpy . mockRestore ( ) ;
150+
151+ // Mock hashSha256 to throw an error
152+ const hashError = new Error ( 'Hashing failed' ) ;
153+ jest . spyOn ( roktManager , 'hashSha256' ) . mockRejectedValue ( hashError ) ;
201154
202- const attributes = {
203- 204- phone : '1234567890'
205- } ;
155+ const attributes = { email :
'[email protected] ' } ; 206156
207- roktManager . hashAttributes ( attributes ) ;
208- expect ( kit . hashAttributes ) . toHaveBeenCalledWith ( attributes ) ;
209- expect ( kit . launcher . hashAttributes ) . toHaveBeenCalledWith ( attributes ) ;
157+ await expect ( roktManager . hashAttributes ( attributes ) )
158+ . rejects
159+ . toThrow ( 'Hashing failed' ) ;
210160 } ) ;
211161 } ) ;
212162
213163 describe ( '#hashSha256' , ( ) => {
214- interface Hasher {
215- sha256Hex ( input : string ) : Promise < string >
216- }
217-
218164 const nodeCrypto = require ( 'crypto' ) ;
219165 let shaSpy : jest . SpyInstance ;
220166
221167 beforeEach ( ( ) => {
222- shaSpy = jest . spyOn ( roktManager as unknown as Hasher , 'sha256Hex' ) ;
223- shaSpy . mockImplementation ( ( s : any ) =>
224- Promise . resolve ( nodeCrypto . createHash ( 'sha256' ) . update ( String ( s ) ) . digest ( 'hex' ) ) ,
168+ shaSpy = jest . spyOn ( roktManager as any , 'sha256Hex' ) ;
169+ shaSpy . mockImplementation ( ( s : string ) =>
170+ Promise . resolve ( nodeCrypto . createHash ( 'sha256' ) . update ( s ) . digest ( 'hex' ) ) ,
225171 ) ;
226172 } ) ;
227173
@@ -556,25 +502,21 @@ describe('RoktManager', () => {
556502 it ( 'should call RoktManager methods (not kit methods directly) when processing queue' , ( ) => {
557503 // Queue some calls before kit is ready (these will be deferred)
558504 const selectOptions = { attributes : { test : 'value' } } as IRoktSelectPlacementsOptions ;
559- const hashAttrs = { email :
'[email protected] ' } ; 560505 const extensionData = { 'test-ext' : { config : true } } ;
561506 const useName = 'TestExtension' ;
562507
563508 roktManager . selectPlacements ( selectOptions ) ;
564- roktManager . hashAttributes ( hashAttrs ) ;
565509 roktManager . setExtensionData ( extensionData ) ;
566510 roktManager . use ( useName ) ;
567511
568512 // Verify calls were queued
569- expect ( roktManager [ 'messageQueue' ] . size ) . toBe ( 4 ) ;
513+ expect ( roktManager [ 'messageQueue' ] . size ) . toBe ( 3 ) ;
570514 expect ( kit . selectPlacements ) . not . toHaveBeenCalled ( ) ; // Kit methods not called yet
571- expect ( kit . hashAttributes ) . not . toHaveBeenCalled ( ) ; // Kit methods not called yet
572515 expect ( kit . setExtensionData ) . not . toHaveBeenCalled ( ) ; // Kit methods not called yet
573516 expect ( kit . use ) . not . toHaveBeenCalled ( ) ; // Kit methods not called yet
574517
575518 // Spy on RoktManager methods AFTER initial calls to track queue processing
576519 const selectPlacementsSpy = jest . spyOn ( roktManager , 'selectPlacements' ) ;
577- const hashAttributesSpy = jest . spyOn ( roktManager , 'hashAttributes' ) ;
578520 const setExtensionDataSpy = jest . spyOn ( roktManager , 'setExtensionData' ) ;
579521 const useSpy = jest . spyOn ( roktManager , 'use' ) ;
580522
@@ -585,9 +527,6 @@ describe('RoktManager', () => {
585527 expect ( selectPlacementsSpy ) . toHaveBeenCalledTimes ( 1 ) ;
586528 expect ( selectPlacementsSpy ) . toHaveBeenCalledWith ( selectOptions ) ;
587529
588- expect ( hashAttributesSpy ) . toHaveBeenCalledTimes ( 1 ) ;
589- expect ( hashAttributesSpy ) . toHaveBeenCalledWith ( hashAttrs ) ;
590-
591530 expect ( setExtensionDataSpy ) . toHaveBeenCalledTimes ( 1 ) ;
592531 expect ( setExtensionDataSpy ) . toHaveBeenCalledWith ( extensionData ) ;
593532
@@ -599,7 +538,6 @@ describe('RoktManager', () => {
599538
600539 // Clean up spies
601540 selectPlacementsSpy . mockRestore ( ) ;
602- hashAttributesSpy . mockRestore ( ) ;
603541 setExtensionDataSpy . mockRestore ( ) ;
604542 useSpy . mockRestore ( ) ;
605543 } ) ;
@@ -846,7 +784,7 @@ describe('RoktManager', () => {
846784 expect ( kit . launcher . selectPlacements ) . toHaveBeenCalledWith ( options ) ;
847785 } ) ;
848786
849- it ( 'should pass sandbox flag as an attribute through to kit.selectPlacements' , ( ) => {
787+ it ( 'should pass sandbox flag as an attribute through to kit.selectPlacements' , ( ) => {
850788 const kit : IRoktKit = {
851789 launcher : {
852790 selectPlacements : jest . fn ( ) ,
0 commit comments