Files
Genarrative/apps/admin-web/src/pages/AdminProfileWalletConfigPage.test.tsx
T
k88936 1a106eadef 每日免费发放额为 0 时前端隐藏该池
- 后端:module-runtime 的 daily_free_points_per_day 校验由「必须大于 0」放宽为只校验上界,错误变体改名 DailyFreePointsPerDayOverflow
- 前端共享层:mudPoints 新增 shouldShowProfileDailyFreePool,判定 remaining > 0 || reset > 0,判定收口一处
- 钱包入口:PlatformMudPointWalletEntry 在每日免费发放额为 0 且无存量时隐藏该行
- 充值弹层:PlatformProfileRechargeModal 池概览按可见池渲染(三列变两列),扣点顺序提示与泥点确认页文案随可见性切换
- Admin Web:账号配置页每日免费泥点允许填 0(校验、min 与文案同步)
- 测试:删除「每日免费必然存在」断言,新增隐藏 / 有存量仍显示 / 发放额为正三类用例,并修正钱包入口测试在 HEAD 上失效的选择器
- 文档:更新会员与泥点前端改造设计文档 §14 与 shared-memory 决策记录
2026-10-03 16:48:12 +08:00

147 lines
4.5 KiB
TypeScript

/* @vitest-environment jsdom */
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { beforeEach, expect, test, vi } from 'vitest';
import {
getProfileWalletConfig,
upsertProfileWalletConfig,
} from '../api/adminApiClient';
import type { ProfileWalletConfigAdminResponse } from '../api/adminApiTypes';
import { AdminProfileWalletConfigPage } from './AdminProfileWalletConfigPage';
vi.mock('../api/adminApiClient', () => ({
formatAdminApiError: vi.fn((error: unknown) =>
error instanceof Error ? error.message : '请求失败',
),
getProfileWalletConfig: vi.fn(),
isAdminApiError: vi.fn(() => false),
upsertProfileWalletConfig: vi.fn(),
}));
const configResponse: ProfileWalletConfigAdminResponse = {
configId: 'profile_wallet',
initialMudPoints: 100,
dailyFreePointsPerDay: 20,
createdBy: 'owner-1',
createdByDisplayName: '管理员',
createdAt: '2026-07-31T01:00:00Z',
updatedBy: 'owner-1',
updatedByDisplayName: '管理员',
updatedAt: '2026-07-31T01:00:00Z',
};
beforeEach(() => {
vi.clearAllMocks();
vi.mocked(getProfileWalletConfig).mockResolvedValue(configResponse);
vi.mocked(upsertProfileWalletConfig).mockResolvedValue({
...configResponse,
initialMudPoints: 120,
dailyFreePointsPerDay: 35,
});
});
test('账号配置页加载并展示每日免费泥点', async () => {
render(
<AdminProfileWalletConfigPage
token="admin-token"
result={configResponse}
onUnauthorized={vi.fn()}
onResultChange={vi.fn()}
/>,
);
expect(
((await screen.findByLabelText('每日免费泥点数')) as HTMLInputElement)
.value,
).toBe('20');
expect(getProfileWalletConfig).toHaveBeenCalledWith('admin-token');
expect(screen.getByText('每日免费泥点')).toBeTruthy();
});
test('账号配置页一次保存初始和每日免费泥点', async () => {
const user = userEvent.setup();
const onResultChange = vi.fn();
render(
<AdminProfileWalletConfigPage
token="admin-token"
result={configResponse}
onUnauthorized={vi.fn()}
onResultChange={onResultChange}
/>,
);
await screen.findByLabelText('每日免费泥点数');
fireEvent.change(screen.getByLabelText('账号初始泥点数'), {
target: { value: '120' },
});
fireEvent.change(screen.getByLabelText('每日免费泥点数'), {
target: { value: '35' },
});
await user.click(screen.getByRole('button', { name: '保存' }));
expect(screen.getByText('初始 120 泥点,每日免费 35 泥点')).toBeTruthy();
await user.click(screen.getByRole('button', { name: '确认' }));
await waitFor(() =>
expect(upsertProfileWalletConfig).toHaveBeenCalledWith('admin-token', {
initialMudPoints: 120,
dailyFreePointsPerDay: 35,
}),
);
expect(onResultChange).toHaveBeenLastCalledWith(
expect.objectContaining({
initialMudPoints: 120,
dailyFreePointsPerDay: 35,
}),
);
});
test('账号配置页拒绝负数或非整数每日免费额度', async () => {
render(
<AdminProfileWalletConfigPage
token="admin-token"
result={configResponse}
onUnauthorized={vi.fn()}
onResultChange={vi.fn()}
/>,
);
const input = await screen.findByLabelText('每日免费泥点数');
fireEvent.change(input, { target: { value: '1.5' } });
expect(
(screen.getByRole('button', { name: '保存' }) as HTMLButtonElement)
.disabled,
).toBe(true);
fireEvent.change(input, { target: { value: '-1' } });
expect(
(screen.getByRole('button', { name: '保存' }) as HTMLButtonElement)
.disabled,
).toBe(true);
expect(upsertProfileWalletConfig).not.toHaveBeenCalled();
});
test('账号配置页允许把每日免费泥点配置为 0', async () => {
const user = userEvent.setup();
vi.mocked(upsertProfileWalletConfig).mockResolvedValue({
...configResponse,
dailyFreePointsPerDay: 0,
});
render(
<AdminProfileWalletConfigPage
token="admin-token"
result={configResponse}
onUnauthorized={vi.fn()}
onResultChange={vi.fn()}
/>,
);
fireEvent.change(await screen.findByLabelText('每日免费泥点数'), {
target: { value: '0' },
});
await user.click(screen.getByRole('button', { name: '保存' }));
expect(screen.getByText('初始 100 泥点,每日免费 0 泥点')).toBeTruthy();
await user.click(screen.getByRole('button', { name: '确认' }));
await waitFor(() =>
expect(upsertProfileWalletConfig).toHaveBeenCalledWith('admin-token', {
initialMudPoints: 100,
dailyFreePointsPerDay: 0,
}),
);
});