@@ -5,20 +5,32 @@ import { Events } from "./api/resources/events/client/Client";
55import { CreateEventRequestBody } from "./api" ;
66import { Logger } from "./logger" ;
77
8+ process . env . NODE_ENV = "test" ;
9+
810jest . useFakeTimers ( ) ;
911
1012describe ( "EventBuffer" , ( ) => {
1113 let mockEventsApi : jest . Mocked < Events > ;
1214 let mockLogger : jest . Mocked < Logger > ;
1315
1416 beforeEach ( ( ) => {
17+ const mockResponse = {
18+ data : {
19+ events : [ ] ,
20+ } ,
21+ params : { } ,
22+ } ;
23+
1524 mockEventsApi = {
16- createEventBatch : jest . fn ( ) . mockResolvedValue ( undefined ) ,
25+ createEventBatch : jest . fn ( ) . mockResolvedValue ( mockResponse ) ,
1726 } as any ;
1827
1928 mockLogger = {
2029 error : jest . fn ( ) ,
2130 log : jest . fn ( ) ,
31+ warn : jest . fn ( ) ,
32+ info : jest . fn ( ) ,
33+ debug : jest . fn ( ) ,
2234 } as any ;
2335 } ) ;
2436
@@ -70,9 +82,12 @@ describe("EventBuffer", () => {
7082 // The rest of the tests remain unchanged as they don't directly test the maxSize behavior
7183 it ( "should log error if flushing fails" , async ( ) => {
7284 mockEventsApi . createEventBatch . mockRejectedValue ( new Error ( "Flush error" ) ) ;
85+
7386 const buffer = new EventBuffer ( mockEventsApi , {
7487 logger : mockLogger ,
7588 interval : 1000 ,
89+ maxRetries : 1 ,
90+ initialRetryDelay : 1 ,
7691 } ) ;
7792
7893 const event : CreateEventRequestBody = {
@@ -87,10 +102,14 @@ describe("EventBuffer", () => {
87102 await buffer . push ( event ) ;
88103 await buffer . push ( event ) ;
89104
90- // Manually trigger flush
105+ // Since we're skipping delays in test environment,
106+ // we can just call flush directly
91107 await buffer . flush ( ) ;
92108
93- expect ( mockLogger . error ) . toHaveBeenCalledWith ( "Failed to flush events" , expect . any ( Error ) ) ;
109+ expect ( mockLogger . error ) . toHaveBeenCalledWith (
110+ "Event batch submission failed after 1 retries:" ,
111+ expect . any ( Error )
112+ ) ;
94113 } ) ;
95114
96115 it ( "should stop accepting events after stop is called" , async ( ) => {
@@ -166,4 +185,45 @@ describe("EventBuffer", () => {
166185
167186 expect ( mockEventsApi . createEventBatch ) . not . toHaveBeenCalled ( ) ;
168187 } ) ;
188+
189+ it ( "should retry and succeed after a failure" , async ( ) => {
190+ const mockResponse = {
191+ data : {
192+ events : [ ] ,
193+ } ,
194+ params : { } ,
195+ } ;
196+
197+ // First call fails, second succeeds
198+ mockEventsApi . createEventBatch
199+ . mockRejectedValueOnce ( new Error ( "Temporary failure" ) )
200+ . mockResolvedValueOnce ( mockResponse ) ;
201+
202+ const buffer = new EventBuffer ( mockEventsApi , {
203+ logger : mockLogger ,
204+ interval : 1000 ,
205+ maxRetries : 3 ,
206+ initialRetryDelay : 1 ,
207+ } ) ;
208+
209+ const event : CreateEventRequestBody = {
210+ body : {
211+ company : { id : "test-company" } ,
212+ event : "test-event" ,
213+ user : { id : "test-user" } ,
214+ } ,
215+ eventType : "track" ,
216+ sentAt : new Date ( ) ,
217+ } ;
218+ await buffer . push ( event ) ;
219+
220+ // Since we're skipping delays in test environment,
221+ // we can just call flush directly
222+ await buffer . flush ( ) ;
223+
224+ // Verify that the createEventBatch was called twice (once failed, once succeeded)
225+ expect ( mockEventsApi . createEventBatch ) . toHaveBeenCalledTimes ( 2 ) ;
226+
227+ expect ( mockLogger . info ) . toHaveBeenCalledWith ( "Event batch submission succeeded after 1 retries" ) ;
228+ } ) ;
169229} ) ;
0 commit comments