118 lines
3.3 KiB
TypeScript
118 lines
3.3 KiB
TypeScript
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> = {},
|
|
): 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);
|
|
});
|
|
});
|