修复推荐页切作品误报无法进入
区分推荐运行态启动 pending 与真实失败 切作品时保持封面遮罩等待自动重试 补充推荐页 pending 切换回归测试 更新玩法链路文档的失败态判断口径
This commit is contained in:
@@ -7658,6 +7658,113 @@ test('logged out home recommendation next starts the next puzzle work', async ()
|
||||
});
|
||||
});
|
||||
|
||||
test('home recommendation keeps cover while switching during a pending puzzle start', async () => {
|
||||
const user = userEvent.setup();
|
||||
const firstWork = {
|
||||
workId: 'puzzle-work-pending-next-1',
|
||||
profileId: 'puzzle-profile-pending-next-1',
|
||||
ownerUserId: 'user-2',
|
||||
sourceSessionId: 'puzzle-session-pending-next-1',
|
||||
authorDisplayName: '拼图作者',
|
||||
levelName: '雨港电路',
|
||||
summary: '第一张公开拼图仍在启动。',
|
||||
themeTags: ['雨港', '拼图'],
|
||||
coverImageSrc: null,
|
||||
coverAssetId: null,
|
||||
publicationStatus: 'published',
|
||||
updatedAt: '2026-04-25T10:00:00.000Z',
|
||||
publishedAt: '2026-04-25T10:00:00.000Z',
|
||||
playCount: 47,
|
||||
likeCount: 1,
|
||||
publishReady: true,
|
||||
} satisfies PuzzleWorkSummary;
|
||||
const secondWork = {
|
||||
...firstWork,
|
||||
workId: 'puzzle-work-pending-next-2',
|
||||
profileId: 'puzzle-profile-pending-next-2',
|
||||
ownerUserId: 'user-3',
|
||||
sourceSessionId: 'puzzle-session-pending-next-2',
|
||||
authorDisplayName: '贝壳作者',
|
||||
levelName: '贝壳潮汐',
|
||||
summary: '第二张公开拼图。',
|
||||
themeTags: ['贝壳', '拼图'],
|
||||
playCount: 1,
|
||||
likeCount: 0,
|
||||
updatedAt: '2026-04-25T09:00:00.000Z',
|
||||
publishedAt: '2026-04-25T09:00:00.000Z',
|
||||
} satisfies PuzzleWorkSummary;
|
||||
let resolveFirstRun!: (value: { run: PuzzleRunSnapshot }) => void;
|
||||
|
||||
vi.mocked(listPuzzleGallery).mockResolvedValue({
|
||||
items: [firstWork, secondWork],
|
||||
});
|
||||
vi.mocked(getPuzzleGalleryDetail).mockImplementation(async (profileId) => ({
|
||||
item: profileId === secondWork.profileId ? secondWork : firstWork,
|
||||
}));
|
||||
vi.mocked(startPuzzleRun).mockImplementationOnce(
|
||||
(async () =>
|
||||
new Promise((resolve) => {
|
||||
resolveFirstRun = resolve;
|
||||
})) as typeof startPuzzleRun,
|
||||
);
|
||||
|
||||
render(
|
||||
<TestWrapper
|
||||
authValue={createAuthValue({
|
||||
user: null,
|
||||
canAccessProtectedData: false,
|
||||
openLoginModal: () => {},
|
||||
requireAuth: (action) => action(),
|
||||
})}
|
||||
/>,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(startPuzzleRun).toHaveBeenCalledWith(
|
||||
{
|
||||
profileId: firstWork.profileId,
|
||||
levelId: null,
|
||||
},
|
||||
expect.objectContaining({
|
||||
runtimeGuestToken: 'runtime-guest-token',
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
await user.click(await screen.findByRole('button', { name: '下一个' }));
|
||||
|
||||
expect(
|
||||
screen.queryByText('作品暂时无法进入,请稍后再试。'),
|
||||
).toBeNull();
|
||||
expect(
|
||||
await screen.findByLabelText('贝壳潮汐 作品信息', undefined, {
|
||||
timeout: 3000,
|
||||
}),
|
||||
).toBeTruthy();
|
||||
expect(startPuzzleRun).toHaveBeenCalledTimes(1);
|
||||
|
||||
await act(async () => {
|
||||
resolveFirstRun({
|
||||
run: buildMockPuzzleRun(firstWork.profileId, '后端拼图关卡'),
|
||||
});
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(startPuzzleRun).toHaveBeenCalledWith(
|
||||
{
|
||||
profileId: secondWork.profileId,
|
||||
levelId: null,
|
||||
},
|
||||
expect.objectContaining({
|
||||
runtimeGuestToken: 'runtime-guest-token',
|
||||
}),
|
||||
);
|
||||
});
|
||||
expect(
|
||||
screen.queryByText('作品暂时无法进入,请稍后再试。'),
|
||||
).toBeNull();
|
||||
});
|
||||
|
||||
test('home recommendation puzzle next level uses unified recommend switching', async () => {
|
||||
const user = userEvent.setup();
|
||||
const entryWork = {
|
||||
|
||||
Reference in New Issue
Block a user