overtime-live-trading-utils 2.1.30 → 2.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "overtime-live-trading-utils",
3
- "version": "2.1.30",
3
+ "version": "2.1.31",
4
4
  "description": "",
5
5
  "main": "main.js",
6
6
  "scripts": {
@@ -568,6 +568,64 @@ describe('Resolution Utils', () => {
568
568
 
569
569
  expect(result).toBeNull();
570
570
  });
571
+
572
+ it('Bug Fix: Should NOT mark current period as complete when future periods have data (live in period 3)', () => {
573
+ // This tests the bug where OpticOdds API includes future period data with scores (including zeros)
574
+ // Period 3 is currently being played, period 4 has 0-0 scores but hasn't started
575
+ const event = {
576
+ status: 'live',
577
+ is_live: true,
578
+ in_play: { period: '3' },
579
+ scores: {
580
+ home: { periods: { period_1: 33, period_2: 32, period_3: 12, period_4: 0 } },
581
+ away: { periods: { period_1: 23, period_2: 27, period_3: 18, period_4: 0 } },
582
+ },
583
+ };
584
+
585
+ const result = detectCompletedPeriods(event);
586
+
587
+ expect(result).not.toBeNull();
588
+ expect(result?.completedPeriods).toEqual([1, 2]); // Only periods 1 and 2 are complete
589
+ expect(result?.currentPeriod).toBe(3);
590
+ // Period 3 is currently being played, so NOT complete
591
+ // Period 4 has data (0-0) but hasn't started, so NOT complete
592
+ });
593
+
594
+ it('Bug Fix: Should mark all periods as complete for completed game', () => {
595
+ const event = {
596
+ status: 'completed',
597
+ is_live: false,
598
+ scores: {
599
+ home: { periods: { period_1: 33, period_2: 32, period_3: 25, period_4: 20 } },
600
+ away: { periods: { period_1: 23, period_2: 27, period_3: 18, period_4: 22 } },
601
+ },
602
+ };
603
+
604
+ const result = detectCompletedPeriods(event);
605
+
606
+ expect(result).not.toBeNull();
607
+ expect(result?.completedPeriods).toEqual([1, 2, 3, 4]);
608
+ // All periods complete because game status is 'completed'
609
+ });
610
+
611
+ it('Bug Fix: Should NOT mark current period as complete during transition to period 4', () => {
612
+ const event = {
613
+ status: 'live',
614
+ is_live: true,
615
+ in_play: { period: '4' },
616
+ scores: {
617
+ home: { periods: { period_1: 33, period_2: 32, period_3: 25, period_4: 5 } },
618
+ away: { periods: { period_1: 23, period_2: 27, period_3: 18, period_4: 3 } },
619
+ },
620
+ };
621
+
622
+ const result = detectCompletedPeriods(event);
623
+
624
+ expect(result).not.toBeNull();
625
+ expect(result?.completedPeriods).toEqual([1, 2, 3]); // Periods 1, 2, 3 are complete
626
+ expect(result?.currentPeriod).toBe(4);
627
+ // Period 4 is currently in_play, so NOT complete yet
628
+ });
571
629
  });
572
630
 
573
631
 
@@ -60,26 +60,27 @@ export const detectCompletedPeriods = (
60
60
  periodScores[`period${periodNum}`] = { home: homeScore, away: awayScore };
61
61
 
62
62
  // Period is complete if:
63
- // 1. Next period exists in periods data, OR
64
- // 2. Game is completed, OR
65
- // 3. Game is live with numeric period AND current live period is greater than this period, OR
66
- // 4. Game is in overtime (all regulation periods are complete)
67
- const nextPeriodKey = `period_${periodNum + 1}`;
63
+ // 1. Game is completed (status = completed/finished), OR
64
+ // 2. Game is live AND in_play.period is GREATER than this period, OR
65
+ // 3. Game is in overtime (all regulation periods are complete)
66
+ //
67
+ // Note: We do NOT check if next period exists in data, as OpticOdds may include
68
+ // future periods with scores (including zeros). Only in_play.period is
69
+ // the source of truth for live games.
68
70
  const isCompleted = status === 'completed' || status === 'complete' || status === 'finished';
69
- const hasNextPeriod = homePeriods[nextPeriodKey] !== undefined && awayPeriods[nextPeriodKey] !== undefined;
70
71
  const isCompletedInLiveGame = isLive && currentLivePeriod !== null && currentLivePeriod > periodNum;
71
72
 
72
- if (hasNextPeriod || isCompleted || isCompletedInLiveGame || isInOvertime) {
73
+ if (isCompleted || isCompletedInLiveGame || isInOvertime) {
73
74
  completedPeriods.push(periodNum);
74
75
  }
75
76
  }
76
77
  }
77
78
 
78
79
  // Determine current period
79
- // If we have a numeric in_play period and it's greater than highest period in data, use it
80
+ // For live games with numeric in_play period, use that as the authoritative current period
80
81
  // Otherwise use highest period number from the data
81
82
  const highestPeriodInData = periodKeys.length > 0 ? Math.max(...periodKeys) : undefined;
82
- const currentPeriod = currentLivePeriod && currentLivePeriod > (highestPeriodInData || 0)
83
+ const currentPeriod = isLive && currentLivePeriod !== null
83
84
  ? currentLivePeriod
84
85
  : highestPeriodInData;
85
86