refactor: 收口平台钱包余额 delta
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user