Files
Genarrative/src/components/platform-entry/platformProfileWalletDeltaModel.test.ts
T
kdletters 071faa482c 统一 Rust 与 TypeScript 格式化门禁
纳入 AGC Cargo workspace 的统一 rustfmt 检查与格式化入口

完成项目 TypeScript/Prettier 与 Rust 全量格式化

修复 Pingora expected executable 门禁的空白敏感误报

同步开发运维文档与 AGC skill pack 格式化忽略规则
2026-09-01 16:28:34 +08:00

121 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);
});
});