90 lines
2.8 KiB
TypeScript
90 lines
2.8 KiB
TypeScript
import { expect, test } from 'vitest';
|
|
|
|
import type {
|
|
ProfileDashboardSummary,
|
|
ProfilePlayedWorkSummary,
|
|
} from '../../../packages/shared/src/contracts/runtime';
|
|
import {
|
|
buildProfileDashboardPresentation,
|
|
formatCompactPlayTime,
|
|
formatDashboardCount,
|
|
formatPlayedWorkId,
|
|
formatPlayedWorkType,
|
|
formatTotalPlayTimeHours,
|
|
} from './rpgEntryProfileDashboardPresentation';
|
|
|
|
function buildDashboard(
|
|
overrides: Partial<ProfileDashboardSummary> = {},
|
|
): ProfileDashboardSummary {
|
|
return {
|
|
walletBalance: 12345,
|
|
totalPlayTimeMs: 3_780_000,
|
|
playedWorldCount: 7,
|
|
updatedAt: '2026-06-03T00:00:00.000Z',
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
function buildPlayedWork(
|
|
overrides: Partial<ProfilePlayedWorkSummary> = {},
|
|
): ProfilePlayedWorkSummary {
|
|
return {
|
|
worldKey: 'rpg:world-1',
|
|
ownerUserId: 'user-1',
|
|
profileId: 'profile-1',
|
|
worldType: 'custom-world',
|
|
worldTitle: '星桥',
|
|
worldSubtitle: '',
|
|
firstPlayedAt: '2026-06-03T00:00:00.000Z',
|
|
lastPlayedAt: '2026-06-03T01:00:00.000Z',
|
|
lastObservedPlayTimeMs: 60_000,
|
|
...overrides,
|
|
};
|
|
}
|
|
|
|
test('profile dashboard presentation formats compact counts', () => {
|
|
expect(formatDashboardCount(-1)).toBe('0');
|
|
expect(formatDashboardCount(9999.4)).toBe('9,999');
|
|
expect(formatDashboardCount(12000)).toBe('1.2万');
|
|
expect(formatDashboardCount(230000000)).toBe('2.3亿');
|
|
});
|
|
|
|
test('profile dashboard presentation formats play time for cards and modal rows', () => {
|
|
expect(formatTotalPlayTimeHours(0)).toBe('0小时');
|
|
expect(formatTotalPlayTimeHours(3_780_000)).toBe('1.1小时');
|
|
expect(formatCompactPlayTime(59_000)).toBe('0分');
|
|
expect(formatCompactPlayTime(3_600_000)).toBe('1.0小时');
|
|
expect(formatCompactPlayTime(3 * 24 * 60 * 60 * 1000)).toBe('3天');
|
|
expect(formatCompactPlayTime(12 * 24 * 60 * 60 * 1000)).toBe('12天');
|
|
});
|
|
|
|
test('profile dashboard presentation normalizes played work labels and ids', () => {
|
|
expect(formatPlayedWorkType('match_3d')).toBe('抓鹅');
|
|
expect(formatPlayedWorkType('square-hole')).toBe('方洞');
|
|
expect(formatPlayedWorkType('big_fish')).toBe('大鱼');
|
|
expect(formatPlayedWorkType('unknown')).toBe('RPG');
|
|
expect(formatPlayedWorkId(buildPlayedWork({ profileId: ' ' }))).toBe(
|
|
'rpg:world-1',
|
|
);
|
|
});
|
|
|
|
test('profile dashboard presentation builds stat labels from dashboard summary', () => {
|
|
expect(buildProfileDashboardPresentation(buildDashboard())).toEqual({
|
|
playedWorkCount: 7,
|
|
playedWorkCountLabel: '7个',
|
|
totalPlayTimeLabel: '1.1小时',
|
|
walletBalance: 12345,
|
|
walletBalanceLabel: '1.2万',
|
|
walletBalanceWithUnitLabel: '1.2万泥点',
|
|
});
|
|
|
|
expect(buildProfileDashboardPresentation(null)).toEqual({
|
|
playedWorkCount: 0,
|
|
playedWorkCountLabel: '0个',
|
|
totalPlayTimeLabel: '0小时',
|
|
walletBalance: 0,
|
|
walletBalanceLabel: '0',
|
|
walletBalanceWithUnitLabel: '0泥点',
|
|
});
|
|
});
|