精简游戏评价回归测试与读取实现
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m0s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 2m55s
Project CI / Backend tests (pull_request) Successful in 5m33s
Project CI / Native shell tests (pull_request) Successful in 6m10s
Project CI / Frontend tests (pull_request) Successful in 2m18s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 10m51s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 11m16s
Project CI / Repository checks (pull_request) Successful in 2m19s
Project CI / AI game creator shell web tests (pull_request) Successful in 1m41s

将后台评价功能回归与旧库迁移验收解耦,独立准备隔离账号凭据
收窄重复输入矩阵和测试专用竞态场景,保留安全与幂等覆盖
复用公开版本判断,减少评价列表的重复过滤和中间集合
同步回归步骤与本轮验证证据
This commit is contained in:
2026-10-01 12:43:02 +08:00
parent cb689fea2a
commit 2c084d4ea4
6 changed files with 110 additions and 122 deletions
@@ -86,13 +86,7 @@ function deferred<T>() {
}
function Harness() {
const state = useGameReviews('game-1', true);
return (
<>
<button onClick={() => void state.loadMine()}>重读个人</button>
<button onClick={() => void state.loadPage(state.page)}>刷新列表</button>
<GameReviews state={state} canReview onLogin={mocks.login} />
</>
);
return <GameReviews state={state} canReview onLogin={mocks.login} />;
}
async function form() {
return screen.findByRole('textbox', { name: '评论(可选)' });
@@ -319,17 +313,14 @@ describe('游戏评价', () => {
expect(mocks.list.mock.calls[2]).toEqual(['game-1', 1]);
});
it('保存后迟到的个人与列表读取不能覆盖新记录或摘要', async () => {
const oldMine = deferred<{ review: GameDistributionReview | null }>();
it('保存后迟到的初始列表不能覆盖新摘要或结束刷新状态', async () => {
const oldList = deferred<GameDistributionReviewsResponse>();
const refreshed = deferred<GameDistributionReviewsResponse>();
const saving = deferred<{
review: GameDistributionReview;
ratingSummary: { averageScore: number; ratingCount: number };
}>();
mocks.mine
.mockResolvedValueOnce({ review: review() })
.mockReturnValueOnce(oldMine.promise);
mocks.mine.mockResolvedValueOnce({ review: review() });
mocks.list
.mockReturnValueOnce(oldList.promise)
.mockReturnValueOnce(refreshed.promise);
@@ -338,8 +329,6 @@ describe('游戏评价', () => {
fireEvent.click(await screen.findByRole('button', { name: '编辑评价' }));
fireEvent.change(await form(), { target: { value: '已保存' } });
fireEvent.click(screen.getByRole('button', { name: '提交' }));
// 保存仍在途时发出个人读取;保存成功后该读取不能覆盖权威记录。
fireEvent.click(screen.getByRole('button', { name: '重读个人' }));
const updated = review({ comment: '已保存' });
await act(async () =>
saving.resolve({
@@ -348,17 +337,15 @@ describe('游戏评价', () => {
}),
);
await screen.findByText('已保存');
mocks.list.mockReturnValueOnce(new Promise(() => {}));
fireEvent.click(screen.getByRole('button', { name: '刷新列表' }));
await act(async () => {
oldMine.resolve({ review: null });
oldList.resolve(list());
refreshed.reject(new Error('过期读取失败'));
});
expect(screen.getByText('已保存')).toBeTruthy();
expect(screen.getByText('9.0/10 · 1 人评分')).toBeTruthy();
expect(screen.queryByText('过期读取失败')).toBeNull();
expect(screen.getByText('正在加载评价…')).toBeTruthy();
await act(async () => refreshed.resolve(list([updated])));
expect(screen.queryByText('正在加载评价…')).toBeNull();
expect(screen.getAllByText('已保存')).toHaveLength(2);
});
it('快速翻页只接受最新请求,旧失败和加载结束不覆盖当前页', async () => {