refactor: 收口每日任务 ViewModel
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import { expect, test } from 'vitest';
|
||||
|
||||
import type {
|
||||
ProfileTaskCenterResponse,
|
||||
ProfileTaskItem,
|
||||
} from '../../../packages/shared/src/contracts/runtime';
|
||||
import {
|
||||
buildProfileTaskCardSummary,
|
||||
buildProfileTaskProgressLabel,
|
||||
getProfileTaskClaimButtonLabel,
|
||||
getProfileTaskStatusLabel,
|
||||
selectProfileTaskCardTask,
|
||||
selectProfileTaskCenterTasks,
|
||||
} from './rpgEntryProfileTaskViewModel';
|
||||
|
||||
function buildTask(
|
||||
overrides: Partial<ProfileTaskItem> = {},
|
||||
): ProfileTaskItem {
|
||||
return {
|
||||
taskId: 'task-1',
|
||||
title: '游玩一次',
|
||||
description: '完成一次游戏',
|
||||
eventKey: 'work_play_start',
|
||||
cycle: 'daily',
|
||||
threshold: 1,
|
||||
progressCount: 0,
|
||||
rewardPoints: 10,
|
||||
status: 'incomplete',
|
||||
dayKey: 20260603,
|
||||
claimedAt: null,
|
||||
updatedAt: '2026-06-03T00:00:00.000Z',
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function buildCenter(
|
||||
tasks: ProfileTaskItem[],
|
||||
): ProfileTaskCenterResponse {
|
||||
return {
|
||||
dayKey: 20260603,
|
||||
walletBalance: 12,
|
||||
tasks,
|
||||
updatedAt: '2026-06-03T00:00:00.000Z',
|
||||
};
|
||||
}
|
||||
|
||||
test('profile task ViewModel selects one actionable task by status priority and original order', () => {
|
||||
const firstIncomplete = buildTask({
|
||||
taskId: 'incomplete-1',
|
||||
status: 'incomplete',
|
||||
});
|
||||
const secondIncomplete = buildTask({
|
||||
taskId: 'incomplete-2',
|
||||
status: 'incomplete',
|
||||
});
|
||||
const claimable = buildTask({
|
||||
taskId: 'claimable-1',
|
||||
status: 'claimable',
|
||||
});
|
||||
|
||||
expect(
|
||||
selectProfileTaskCenterTasks([
|
||||
firstIncomplete,
|
||||
secondIncomplete,
|
||||
claimable,
|
||||
]),
|
||||
).toEqual([claimable]);
|
||||
expect(selectProfileTaskCenterTasks([firstIncomplete, secondIncomplete])).toEqual(
|
||||
[firstIncomplete],
|
||||
);
|
||||
});
|
||||
|
||||
test('profile task ViewModel falls back from card task to claimed and enabled tasks', () => {
|
||||
const claimed = buildTask({ taskId: 'claimed-1', status: 'claimed' });
|
||||
const disabled = buildTask({ taskId: 'disabled-1', status: 'disabled' });
|
||||
const incomplete = buildTask({
|
||||
taskId: 'incomplete-1',
|
||||
status: 'incomplete',
|
||||
});
|
||||
|
||||
expect(selectProfileTaskCardTask([disabled, claimed])).toBe(claimed);
|
||||
expect(selectProfileTaskCardTask([disabled, incomplete])).toBe(incomplete);
|
||||
expect(selectProfileTaskCardTask([disabled])).toBeNull();
|
||||
});
|
||||
|
||||
test('profile task ViewModel builds card summary with reward fallback and clamped progress', () => {
|
||||
expect(buildProfileTaskCardSummary(null)).toEqual({
|
||||
actionLabel: '去完成',
|
||||
progressCount: 0,
|
||||
progressPercent: 0,
|
||||
rewardPoints: 10,
|
||||
threshold: 1,
|
||||
});
|
||||
|
||||
expect(
|
||||
buildProfileTaskCardSummary(
|
||||
buildCenter([
|
||||
buildTask({
|
||||
progressCount: 5,
|
||||
rewardPoints: 25,
|
||||
status: 'claimable',
|
||||
threshold: 3,
|
||||
}),
|
||||
]),
|
||||
),
|
||||
).toEqual({
|
||||
actionLabel: '领取',
|
||||
progressCount: 3,
|
||||
progressPercent: 100,
|
||||
rewardPoints: 25,
|
||||
threshold: 3,
|
||||
});
|
||||
});
|
||||
|
||||
test('profile task ViewModel exposes task labels for the modal', () => {
|
||||
const task = buildTask({ progressCount: -1, threshold: 0 });
|
||||
|
||||
expect(getProfileTaskStatusLabel('claimable')).toBe('可领取');
|
||||
expect(buildProfileTaskProgressLabel(task)).toBe('0/1');
|
||||
expect(getProfileTaskClaimButtonLabel(task, true)).toBe('领取中');
|
||||
expect(getProfileTaskClaimButtonLabel(buildTask({ status: 'claimed' }), false)).toBe(
|
||||
'已领取',
|
||||
);
|
||||
expect(
|
||||
getProfileTaskClaimButtonLabel(buildTask({ status: 'claimable' }), false),
|
||||
).toBe('领取');
|
||||
});
|
||||
Reference in New Issue
Block a user