import { afterEach, beforeEach, describe, expect, test, vi } from 'vitest'; import type { ProfileDashboardSummary } from '../../../packages/shared/src/contracts/runtime'; import { adjustProfileDashboardWalletBalance, reconcileProfileWalletLocalDeltaWithServerDashboard, resolveProfileWalletBalance, } from './platformProfileWalletDeltaModel'; const NOW = Date.parse('2026-06-04T04:30:00.000Z'); function buildDashboard( overrides: Partial = {}, ): ProfileDashboardSummary { return { walletBalance: 100, totalPlayTimeMs: 0, playedWorldCount: 0, updatedAt: '2026-06-01T00:00:00.000Z', ...overrides, }; } beforeEach(() => { vi.useFakeTimers(); vi.setSystemTime(NOW); }); afterEach(() => { vi.useRealTimers(); }); describe('platformProfileWalletDeltaModel', () => { test('normalizes wallet balance to a non-negative integer', () => { expect(resolveProfileWalletBalance(buildDashboard({ walletBalance: 12.8 }))).toBe( 12, ); expect( resolveProfileWalletBalance(buildDashboard({ walletBalance: -4 })), ).toBe(0); expect(resolveProfileWalletBalance({ walletBalance: Number.NaN })).toBe(0); expect(resolveProfileWalletBalance(null)).toBe(0); }); test('applies local delta and refreshes dashboard timestamp', () => { expect( adjustProfileDashboardWalletBalance(buildDashboard(), -3.8), ).toMatchObject({ walletBalance: 97, updatedAt: '2026-06-04T04:30:00.000Z', }); expect( adjustProfileDashboardWalletBalance(buildDashboard({ walletBalance: 2 }), -10), ).toMatchObject({ walletBalance: 0, }); expect(adjustProfileDashboardWalletBalance(null, 5)).toBeNull(); const dashboard = buildDashboard(); expect(adjustProfileDashboardWalletBalance(dashboard, Number.POSITIVE_INFINITY)).toBe( dashboard, ); }); test('reconciles debit delta already reflected by latest server dashboard', () => { const previous = buildDashboard({ walletBalance: 100 }); expect( reconcileProfileWalletLocalDeltaWithServerDashboard( previous, buildDashboard({ walletBalance: 98 }), -5, ), ).toBe(-3); expect( reconcileProfileWalletLocalDeltaWithServerDashboard( previous, buildDashboard({ walletBalance: 92 }), -5, ), ).toBe(0); }); test('reconciles credit delta already reflected by latest server dashboard', () => { const previous = buildDashboard({ walletBalance: 100 }); expect( reconcileProfileWalletLocalDeltaWithServerDashboard( previous, buildDashboard({ walletBalance: 103 }), 8, ), ).toBe(5); expect( reconcileProfileWalletLocalDeltaWithServerDashboard( previous, buildDashboard({ walletBalance: 120 }), 8, ), ).toBe(0); }); test('does not reconcile when server balance moves against local delta', () => { const previous = buildDashboard({ walletBalance: 100 }); expect( reconcileProfileWalletLocalDeltaWithServerDashboard( previous, buildDashboard({ walletBalance: 104 }), -5, ), ).toBe(-5); expect( reconcileProfileWalletLocalDeltaWithServerDashboard( previous, buildDashboard({ walletBalance: 96 }), 8, ), ).toBe(8); }); });