@@ -5,6 +5,7 @@ describe('BatchUploader', () => {
55 let batchUploader : BatchUploader ;
66 let mockMPInstance : IMParticleWebSDKInstance ;
77 let originalFetch : typeof global . fetch ;
8+ let mockSendBatchToForwarders : jest . Mock ;
89
910 beforeEach ( ( ) => {
1011 const now = Date . now ( ) ;
@@ -16,21 +17,36 @@ describe('BatchUploader', () => {
1617 global . fetch = jest . fn ( ) . mockResolvedValue ( { ok : true , status : 200 } ) ;
1718
1819 // Create a mock mParticle instance with mocked methods for instantiating a BatchUploader
20+ mockSendBatchToForwarders = jest . fn ( ) ;
1921 mockMPInstance = {
2022 _Store : {
2123 SDKConfig : {
22- flags : { }
23- }
24+ flags : { } ,
25+ } ,
26+ sideloadedKitsCount : 0 ,
2427 } ,
2528 _Helpers : {
2629 getFeatureFlag : jest . fn ( ) . mockReturnValue ( false ) ,
2730 createServiceUrl : jest . fn ( ) . mockReturnValue ( 'https://mock-url.com' ) ,
31+ generateUniqueId : jest . fn ( ) . mockReturnValue ( 'mock-uuid' ) ,
32+ } ,
33+ _Forwarders : {
34+ sendBatchToForwarders : mockSendBatchToForwarders ,
2835 } ,
2936 Identity : {
3037 getCurrentUser : jest . fn ( ) . mockReturnValue ( {
31- getMPID : ( ) => 'test-mpid'
32- } )
33- }
38+ getMPID : ( ) => 'test-mpid' ,
39+ getConsentState : ( ) => null ,
40+ getUserIdentities : ( ) => ( { userIdentities : { } } ) ,
41+ getAllUserAttributes : ( ) => ( { } ) ,
42+ } ) ,
43+ } ,
44+ Logger : {
45+ error : jest . fn ( ) ,
46+ warning : jest . fn ( ) ,
47+ verbose : jest . fn ( ) ,
48+ isVerbose : jest . fn ( ) . mockReturnValue ( false ) ,
49+ } ,
3450 } as unknown as IMParticleWebSDKInstance ;
3551
3652 batchUploader = new BatchUploader ( mockMPInstance , 1000 ) ;
@@ -41,6 +57,227 @@ describe('BatchUploader', () => {
4157 global . fetch = originalFetch ;
4258 } ) ;
4359
60+ describe ( 'batch forwarding to kits' , ( ) => {
61+ it ( 'should call sendBatchToForwarders for each new batch in createNewBatches' , ( ) => {
62+ const mockEvents = [
63+ {
64+ EventName : 'Test Event' ,
65+ EventDataType : 4 ,
66+ MPID : 'test-mpid' ,
67+ SessionId : 'session-1' ,
68+ EventCategory : 1 ,
69+ Timestamp : Date . now ( ) ,
70+ } ,
71+ ] ;
72+
73+ const mockUser = {
74+ getMPID : ( ) => 'test-mpid' ,
75+ getConsentState : ( ) => null ,
76+ getUserIdentities : ( ) => ( { userIdentities : { } } ) ,
77+ getAllUserAttributes : ( ) => ( { } ) ,
78+ } ;
79+
80+ BatchUploader [ 'createNewBatches' ] (
81+ mockEvents as any ,
82+ mockUser as any ,
83+ mockMPInstance
84+ ) ;
85+
86+ expect ( mockSendBatchToForwarders ) . toHaveBeenCalledTimes ( 1 ) ;
87+ expect ( mockSendBatchToForwarders ) . toHaveBeenCalledWith (
88+ expect . objectContaining ( {
89+ mpid : 'test-mpid' ,
90+ } )
91+ ) ;
92+ } ) ;
93+
94+ it ( 'should call sendBatchToForwarders before onCreateBatch' , ( ) => {
95+ const callOrder : string [ ] = [ ] ;
96+
97+ mockSendBatchToForwarders . mockImplementation ( ( ) => {
98+ callOrder . push ( 'sendBatchToForwarders' ) ;
99+ } ) ;
100+
101+ mockMPInstance . _Store . SDKConfig . onCreateBatch = ( batch ) => {
102+ callOrder . push ( 'onCreateBatch' ) ;
103+ return batch ;
104+ } ;
105+
106+ const mockEvents = [
107+ {
108+ EventName : 'Test Event' ,
109+ EventDataType : 4 ,
110+ MPID : 'test-mpid' ,
111+ SessionId : 'session-1' ,
112+ EventCategory : 1 ,
113+ Timestamp : Date . now ( ) ,
114+ } ,
115+ ] ;
116+
117+ const mockUser = {
118+ getMPID : ( ) => 'test-mpid' ,
119+ getConsentState : ( ) => null ,
120+ getUserIdentities : ( ) => ( { userIdentities : { } } ) ,
121+ getAllUserAttributes : ( ) => ( { } ) ,
122+ } ;
123+
124+ BatchUploader [ 'createNewBatches' ] (
125+ mockEvents as any ,
126+ mockUser as any ,
127+ mockMPInstance
128+ ) ;
129+
130+ expect ( callOrder ) . toEqual ( [
131+ 'sendBatchToForwarders' ,
132+ 'onCreateBatch' ,
133+ ] ) ;
134+ } ) ;
135+
136+ it ( 'should forward batch before onCreateBatch can modify it' , ( ) => {
137+ let forwardedEventCount = 0 ;
138+
139+ mockSendBatchToForwarders . mockImplementation ( ( batch ) => {
140+ forwardedEventCount = batch . events . length ;
141+ } ) ;
142+
143+ mockMPInstance . _Store . SDKConfig . onCreateBatch = ( batch ) => {
144+ batch . modified = true ;
145+ batch . events = [ ] ;
146+ return batch ;
147+ } ;
148+
149+ const mockEvents = [
150+ {
151+ EventName : 'Test Event' ,
152+ EventDataType : 4 ,
153+ MPID : 'test-mpid' ,
154+ SessionId : 'session-1' ,
155+ EventCategory : 1 ,
156+ Timestamp : Date . now ( ) ,
157+ } ,
158+ ] ;
159+
160+ const mockUser = {
161+ getMPID : ( ) => 'test-mpid' ,
162+ getConsentState : ( ) => null ,
163+ getUserIdentities : ( ) => ( { userIdentities : { } } ) ,
164+ getAllUserAttributes : ( ) => ( { } ) ,
165+ } ;
166+
167+ BatchUploader [ 'createNewBatches' ] (
168+ mockEvents as any ,
169+ mockUser as any ,
170+ mockMPInstance
171+ ) ;
172+
173+ expect ( forwardedEventCount ) . toBe ( 1 ) ;
174+ } ) ;
175+
176+ it ( 'should forward batch even when onCreateBatch drops it' , ( ) => {
177+ mockMPInstance . _Store . SDKConfig . onCreateBatch = ( ) => {
178+ return null ;
179+ } ;
180+
181+ ( mockMPInstance . Logger as any ) . warning = jest . fn ( ) ;
182+
183+ const mockEvents = [
184+ {
185+ EventName : 'Test Event' ,
186+ EventDataType : 4 ,
187+ MPID : 'test-mpid' ,
188+ SessionId : 'session-1' ,
189+ EventCategory : 1 ,
190+ Timestamp : Date . now ( ) ,
191+ } ,
192+ ] ;
193+
194+ const mockUser = {
195+ getMPID : ( ) => 'test-mpid' ,
196+ getConsentState : ( ) => null ,
197+ getUserIdentities : ( ) => ( { userIdentities : { } } ) ,
198+ getAllUserAttributes : ( ) => ( { } ) ,
199+ } ;
200+
201+ BatchUploader [ 'createNewBatches' ] (
202+ mockEvents as any ,
203+ mockUser as any ,
204+ mockMPInstance
205+ ) ;
206+
207+ expect ( mockSendBatchToForwarders ) . toHaveBeenCalledTimes ( 1 ) ;
208+ } ) ;
209+
210+ it ( 'should not throw if sendBatchToForwarders errors' , ( ) => {
211+ mockSendBatchToForwarders . mockImplementation ( ( ) => {
212+ throw new Error ( 'Kit failure' ) ;
213+ } ) ;
214+
215+ const mockEvents = [
216+ {
217+ EventName : 'Test Event' ,
218+ EventDataType : 4 ,
219+ MPID : 'test-mpid' ,
220+ SessionId : 'session-1' ,
221+ EventCategory : 1 ,
222+ Timestamp : Date . now ( ) ,
223+ } ,
224+ ] ;
225+
226+ const mockUser = {
227+ getMPID : ( ) => 'test-mpid' ,
228+ getConsentState : ( ) => null ,
229+ getUserIdentities : ( ) => ( { userIdentities : { } } ) ,
230+ getAllUserAttributes : ( ) => ( { } ) ,
231+ } ;
232+
233+ expect ( ( ) => {
234+ BatchUploader [ 'createNewBatches' ] (
235+ mockEvents as any ,
236+ mockUser as any ,
237+ mockMPInstance
238+ ) ;
239+ } ) . not . toThrow ( ) ;
240+
241+ expect ( mockMPInstance . Logger . error ) . toHaveBeenCalled ( ) ;
242+ } ) ;
243+
244+ it ( 'should create separate batches per MPID and forward each' , ( ) => {
245+ const mockEvents = [
246+ {
247+ EventName : 'Event User A' ,
248+ EventDataType : 4 ,
249+ MPID : 'mpid-a' ,
250+ SessionId : 'session-1' ,
251+ EventCategory : 1 ,
252+ Timestamp : Date . now ( ) ,
253+ } ,
254+ {
255+ EventName : 'Event User B' ,
256+ EventDataType : 4 ,
257+ MPID : 'mpid-b' ,
258+ SessionId : 'session-1' ,
259+ EventCategory : 1 ,
260+ Timestamp : Date . now ( ) ,
261+ } ,
262+ ] ;
263+
264+ const mockUser = {
265+ getMPID : ( ) => 'mpid-a' ,
266+ getConsentState : ( ) => null ,
267+ getUserIdentities : ( ) => ( { userIdentities : { } } ) ,
268+ getAllUserAttributes : ( ) => ( { } ) ,
269+ } ;
270+
271+ BatchUploader [ 'createNewBatches' ] (
272+ mockEvents as any ,
273+ mockUser as any ,
274+ mockMPInstance
275+ ) ;
276+
277+ expect ( mockSendBatchToForwarders ) . toHaveBeenCalledTimes ( 2 ) ;
278+ } ) ;
279+ } ) ;
280+
44281 describe ( 'shouldDebounceAST' , ( ) => {
45282 it ( 'should return false for first call' , ( ) => {
46283 // First call should not be debounced
0 commit comments