@@ -137,4 +137,196 @@ describe('Pnl store', () => {
137137 expect ( responsePageAllPages . total ) . toEqual ( 2 ) ;
138138 } ) ;
139139
140+ it ( 'Successfully retrieves daily PNL records with latest for current day and earliest for previous days' , async ( ) => {
141+ const records = [ ] ;
142+
143+ // Day 1 (Jan 1): Create records at 00:00, 06:00, 12:00, 18:00
144+ const day1Date = new Date ( '2023-01-01T00:00:00.000Z' ) ;
145+ for ( let i = 0 ; i < 24 ; i += 6 ) {
146+ const date = new Date ( day1Date ) ;
147+ date . setUTCHours ( i ) ;
148+ records . push ( {
149+ ...defaultPnl ,
150+ createdAt : date . toISOString ( ) ,
151+ createdAtHeight : ( 1000 + i ) . toString ( ) ,
152+ equity : ( 1000 + i ) . toString ( ) ,
153+ } ) ;
154+ }
155+
156+ // Day 2 (Jan 2): Create records at 00:00, 06:00, 12:00, 18:00
157+ const day2Date = new Date ( '2023-01-02T00:00:00.000Z' ) ;
158+ for ( let i = 0 ; i < 24 ; i += 6 ) {
159+ const date = new Date ( day2Date ) ;
160+ date . setUTCHours ( i ) ;
161+ records . push ( {
162+ ...defaultPnl ,
163+ createdAt : date . toISOString ( ) ,
164+ createdAtHeight : ( 2000 + i ) . toString ( ) ,
165+ equity : ( 2000 + i ) . toString ( ) ,
166+ } ) ;
167+ }
168+
169+ // Day 3 (Jan 3): Create records at 00:00, 06:00, 12:00, 18:00
170+ const day3Date = new Date ( '2023-01-03T00:00:00.000Z' ) ;
171+ for ( let i = 0 ; i < 24 ; i += 6 ) {
172+ const date = new Date ( day3Date ) ;
173+ date . setUTCHours ( i ) ;
174+ records . push ( {
175+ ...defaultPnl ,
176+ createdAt : date . toISOString ( ) ,
177+ createdAtHeight : ( 3000 + i ) . toString ( ) ,
178+ equity : ( 3000 + i ) . toString ( ) ,
179+ } ) ;
180+ }
181+
182+ // Insert all records
183+ await Promise . all ( records . map ( ( record ) => PnlTable . create ( record ) ) ) ;
184+
185+ // Get daily records
186+ const dailyResults = await PnlTable . findAllDailyPnl (
187+ { subaccountId : [ defaultSubaccountId ] } ,
188+ [ ] ,
189+ { } ,
190+ ) ;
191+
192+ // We should get exactly 3 records (one for each day)
193+ expect ( dailyResults . results . length ) . toBe ( 3 ) ;
194+
195+ // The first record should be the latest one from day 3 (18:00)
196+ expect ( dailyResults . results [ 0 ] . createdAtHeight ) . toBe ( '3018' ) ;
197+ expect ( dailyResults . results [ 0 ] . createdAt ) . toBe ( '2023-01-03T18:00:00.000Z' ) ;
198+
199+ // The second record should be the earliest one from day 2 (00:00)
200+ expect ( dailyResults . results [ 1 ] . createdAtHeight ) . toBe ( '2000' ) ;
201+ expect ( dailyResults . results [ 1 ] . createdAt ) . toBe ( '2023-01-02T00:00:00.000Z' ) ;
202+
203+ // The third record should be the earliest one from day 1 (00:00)
204+ expect ( dailyResults . results [ 2 ] . createdAtHeight ) . toBe ( '1000' ) ;
205+ expect ( dailyResults . results [ 2 ] . createdAt ) . toBe ( '2023-01-01T00:00:00.000Z' ) ;
206+
207+ // Test with pagination - first page
208+ const dailyPage1 = await PnlTable . findAllDailyPnl (
209+ {
210+ subaccountId : [ defaultSubaccountId ] ,
211+ page : 1 ,
212+ limit : 2 ,
213+ } ,
214+ [ ] ,
215+ { } ,
216+ ) ;
217+
218+ expect ( dailyPage1 . results . length ) . toBe ( 2 ) ;
219+ expect ( dailyPage1 . limit ) . toBe ( 2 ) ;
220+ expect ( dailyPage1 . offset ) . toBe ( 0 ) ;
221+ expect ( dailyPage1 . total ) . toBe ( 3 ) ;
222+
223+ // First page should have day 3 (latest) and day 2 (earliest)
224+ expect ( dailyPage1 . results [ 0 ] . createdAtHeight ) . toBe ( '3018' ) ;
225+ expect ( dailyPage1 . results [ 1 ] . createdAtHeight ) . toBe ( '2000' ) ;
226+
227+ // Test with pagination - second page
228+ const dailyPage2 = await PnlTable . findAllDailyPnl (
229+ {
230+ subaccountId : [ defaultSubaccountId ] ,
231+ page : 2 ,
232+ limit : 2 ,
233+ } ,
234+ [ ] ,
235+ { } ,
236+ ) ;
237+
238+ // The second page should have only day 1
239+ expect ( dailyPage2 . results . length ) . toBe ( 1 ) ;
240+ expect ( dailyPage2 . limit ) . toBe ( 2 ) ;
241+ expect ( dailyPage2 . offset ) . toBe ( 2 ) ;
242+ expect ( dailyPage2 . total ) . toBe ( 3 ) ;
243+ expect ( dailyPage2 . results [ 0 ] . createdAtHeight ) . toBe ( '1000' ) ;
244+
245+ // Test with date range filter
246+ const cutoffDate = new Date ( '2023-01-02T12:00:00.000Z' ) ;
247+
248+ const dailyWithDateFilter = await PnlTable . findAllDailyPnl (
249+ {
250+ subaccountId : [ defaultSubaccountId ] ,
251+ createdBeforeOrAt : cutoffDate . toISOString ( ) ,
252+ } ,
253+ [ ] ,
254+ { } ,
255+ ) ;
256+
257+ // We should get 2 records: day 1 (earliest) and day 2 (records up to 12:00)
258+ expect ( dailyWithDateFilter . results . length ) . toBe ( 2 ) ;
259+
260+ // Day 2 should be represented by the latest record before our cutoff (12:00)
261+ expect ( dailyWithDateFilter . results [ 0 ] . createdAtHeight ) . toBe ( '2012' ) ;
262+ expect ( dailyWithDateFilter . results [ 0 ] . createdAt ) . toBe ( '2023-01-02T12:00:00.000Z' ) ;
263+
264+ // Day 1 should still be the earliest record
265+ expect ( dailyWithDateFilter . results [ 1 ] . createdAtHeight ) . toBe ( '1000' ) ;
266+ expect ( dailyWithDateFilter . results [ 1 ] . createdAt ) . toBe ( '2023-01-01T00:00:00.000Z' ) ;
267+ } ) ;
268+
269+ it ( 'Successfully handles case where latest record is at midnight (00:00)' , async ( ) => {
270+ const records = [ ] ;
271+
272+ // Day 1 (Jan 1): Create records at 00:00, 06:00, 12:00, 18:00
273+ const day1Date = new Date ( '2023-01-01T00:00:00.000Z' ) ;
274+ for ( let i = 0 ; i < 24 ; i += 6 ) {
275+ const date = new Date ( day1Date ) ;
276+ date . setUTCHours ( i ) ;
277+ records . push ( {
278+ ...defaultPnl ,
279+ createdAt : date . toISOString ( ) ,
280+ createdAtHeight : ( 1000 + i ) . toString ( ) ,
281+ equity : ( 1000 + i ) . toString ( ) ,
282+ } ) ;
283+ }
284+
285+ // Day 2 (Jan 2): Create records at 00:00, 06:00, 12:00, 18:00
286+ const day2Date = new Date ( '2023-01-02T00:00:00.000Z' ) ;
287+ for ( let i = 0 ; i < 24 ; i += 6 ) {
288+ const date = new Date ( day2Date ) ;
289+ date . setUTCHours ( i ) ;
290+ records . push ( {
291+ ...defaultPnl ,
292+ createdAt : date . toISOString ( ) ,
293+ createdAtHeight : ( 2000 + i ) . toString ( ) ,
294+ equity : ( 2000 + i ) . toString ( ) ,
295+ } ) ;
296+ }
297+
298+ // Day 3 (Jan 3): Create ONLY a record at 00:00 (to test the case where latest is at midnight)
299+ // Give this record the highest height to ensure it's the latest
300+ records . push ( {
301+ ...defaultPnl ,
302+ createdAt : '2023-01-03T00:00:00.000Z' ,
303+ createdAtHeight : '3500' , // Highest height to ensure it's the latest
304+ equity : '3500' ,
305+ } ) ;
306+
307+ // Insert all records
308+ await Promise . all ( records . map ( ( record ) => PnlTable . create ( record ) ) ) ;
309+
310+ // Get daily records
311+ const dailyResults = await PnlTable . findAllDailyPnl (
312+ { subaccountId : [ defaultSubaccountId ] } ,
313+ [ ] ,
314+ { } ,
315+ ) ;
316+
317+ // We should get exactly 3 records (one for each day)
318+ expect ( dailyResults . results . length ) . toBe ( 3 ) ;
319+
320+ // The first record should be the latest one from day 3 (00:00)
321+ expect ( dailyResults . results [ 0 ] . createdAtHeight ) . toBe ( '3500' ) ;
322+ expect ( dailyResults . results [ 0 ] . createdAt ) . toBe ( '2023-01-03T00:00:00.000Z' ) ;
323+
324+ // The second record should be the earliest one from day 2 (00:00)
325+ expect ( dailyResults . results [ 1 ] . createdAtHeight ) . toBe ( '2000' ) ;
326+ expect ( dailyResults . results [ 1 ] . createdAt ) . toBe ( '2023-01-02T00:00:00.000Z' ) ;
327+
328+ // The third record should be the earliest one from day 1 (00:00)
329+ expect ( dailyResults . results [ 2 ] . createdAtHeight ) . toBe ( '1000' ) ;
330+ expect ( dailyResults . results [ 2 ] . createdAt ) . toBe ( '2023-01-01T00:00:00.000Z' ) ;
331+ } ) ;
140332} ) ;
0 commit comments