合入最新 master
合并 origin/master 并保留平台入口运行态与推荐链路语义 修正合并后基于 tab 语义变化的前端断言
This commit is contained in:
@@ -3801,11 +3801,6 @@ test('create tab shows template tabs and embeds puzzle form by default', async (
|
||||
expect(await findCreationTypeButton('汪汪声浪')).toBeTruthy();
|
||||
expect(await findCreationTypeButton('宝贝识物')).toBeTruthy();
|
||||
expect(queryCreationTypeButton('智能创作')).toBeNull();
|
||||
expect(
|
||||
screen
|
||||
.getByRole('tab', { name: '热门推荐' })
|
||||
.querySelector('[class*="bg-[#d9793f]"]'),
|
||||
).toBeTruthy();
|
||||
expect(screen.queryByRole('button', { name: /智能创作/u })).toBeNull();
|
||||
expect(screen.queryByPlaceholderText('问一问陶泥儿')).toBeNull();
|
||||
expect(screen.queryByRole('button', { name: /角色扮演/u })).toBeNull();
|
||||
@@ -7855,6 +7850,113 @@ test('logged out home recommendation next starts the next puzzle work', async ()
|
||||
});
|
||||
});
|
||||
|
||||
test('home recommendation next follows the same scored queue shown in preview', async () => {
|
||||
const user = userEvent.setup();
|
||||
const quietWork = {
|
||||
workId: 'puzzle-work-public-quiet',
|
||||
profileId: 'puzzle-profile-public-quiet',
|
||||
ownerUserId: 'user-2',
|
||||
sourceSessionId: 'puzzle-session-public-quiet',
|
||||
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: 40,
|
||||
likeCount: 0,
|
||||
publishReady: true,
|
||||
} satisfies PuzzleWorkSummary;
|
||||
const hotWork = {
|
||||
...quietWork,
|
||||
workId: 'puzzle-work-public-hot',
|
||||
profileId: 'puzzle-profile-public-hot',
|
||||
sourceSessionId: 'puzzle-session-public-hot',
|
||||
levelName: '热门拼图',
|
||||
summary: '推荐评分更高,应该先展示。',
|
||||
playCount: 120,
|
||||
updatedAt: '2026-04-25T09:00:00.000Z',
|
||||
publishedAt: '2026-04-25T09:00:00.000Z',
|
||||
} satisfies PuzzleWorkSummary;
|
||||
const middleWork = {
|
||||
...quietWork,
|
||||
workId: 'puzzle-work-public-middle',
|
||||
profileId: 'puzzle-profile-public-middle',
|
||||
sourceSessionId: 'puzzle-session-public-middle',
|
||||
levelName: '中间拼图',
|
||||
summary: '推荐评分排在后面。',
|
||||
playCount: 0,
|
||||
updatedAt: '2026-04-25T08:00:00.000Z',
|
||||
publishedAt: '2026-04-25T08:00:00.000Z',
|
||||
} satisfies PuzzleWorkSummary;
|
||||
|
||||
vi.mocked(listPuzzleGallery).mockResolvedValue({
|
||||
items: [quietWork, hotWork, middleWork],
|
||||
});
|
||||
vi.mocked(getPuzzleGalleryDetail).mockImplementation(async (profileId) => ({
|
||||
item:
|
||||
profileId === hotWork.profileId
|
||||
? hotWork
|
||||
: profileId === middleWork.profileId
|
||||
? middleWork
|
||||
: quietWork,
|
||||
}));
|
||||
vi.mocked(startPuzzleRun).mockImplementation(async (payload) => ({
|
||||
run: buildMockPuzzleRun(
|
||||
payload.profileId,
|
||||
payload.profileId === hotWork.profileId
|
||||
? hotWork.levelName
|
||||
: payload.profileId === middleWork.profileId
|
||||
? middleWork.levelName
|
||||
: quietWork.levelName,
|
||||
),
|
||||
}));
|
||||
|
||||
render(<TestWrapper withAuth />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(startPuzzleRun).toHaveBeenCalledWith(
|
||||
{
|
||||
profileId: hotWork.profileId,
|
||||
levelId: null,
|
||||
},
|
||||
LOGGED_IN_RECOMMEND_RUNTIME_AUTH_OPTIONS,
|
||||
);
|
||||
});
|
||||
expect(
|
||||
await screen.findByLabelText('热门拼图 作品信息', undefined, {
|
||||
timeout: 3000,
|
||||
}),
|
||||
).toBeTruthy();
|
||||
const nextPreview = document.querySelector(
|
||||
'.platform-recommend-swipe-page--next',
|
||||
);
|
||||
expect(nextPreview).toBeTruthy();
|
||||
expect(
|
||||
within(nextPreview as HTMLElement).getByLabelText('安静拼图 作品信息'),
|
||||
).toBeTruthy();
|
||||
|
||||
await user.click(await screen.findByRole('button', { name: '下一个' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(startPuzzleRun).toHaveBeenCalledWith(
|
||||
{
|
||||
profileId: quietWork.profileId,
|
||||
levelId: null,
|
||||
},
|
||||
LOGGED_IN_RECOMMEND_RUNTIME_AUTH_OPTIONS,
|
||||
);
|
||||
});
|
||||
expect(
|
||||
await screen.findByLabelText('安静拼图 作品信息', undefined, {
|
||||
timeout: 3000,
|
||||
}),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
test('home recommendation keeps cover while switching during a pending puzzle start', async () => {
|
||||
const user = userEvent.setup();
|
||||
const firstWork = {
|
||||
@@ -8184,6 +8286,54 @@ test('home recommendation Match3D runtime keeps profile generated models when ca
|
||||
});
|
||||
});
|
||||
|
||||
test('logged out home recommendation Match3D runtime skips protected detail and starts with guest auth', async () => {
|
||||
const match3dCard: Match3DWorkSummary = {
|
||||
workId: 'match3d-work-card-guest',
|
||||
profileId: 'match3d-profile-card-guest',
|
||||
ownerUserId: 'user-2',
|
||||
sourceSessionId: 'match3d-session-card-guest',
|
||||
gameName: '游客抓大鹅',
|
||||
themeText: '游客果园',
|
||||
summary: '游客可直接游玩。',
|
||||
tags: ['果园', '抓大鹅'],
|
||||
coverImageSrc: null,
|
||||
referenceImageSrc: null,
|
||||
clearCount: 3,
|
||||
difficulty: 5,
|
||||
publicationStatus: 'published',
|
||||
playCount: 3,
|
||||
updatedAt: '2026-04-25T10:30:00.000Z',
|
||||
publishedAt: '2026-04-25T10:30:00.000Z',
|
||||
publishReady: true,
|
||||
generatedItemAssets: [],
|
||||
};
|
||||
|
||||
vi.mocked(listMatch3DGallery).mockResolvedValue({
|
||||
items: [match3dCard],
|
||||
});
|
||||
vi.mocked(getMatch3DWorkDetail).mockResolvedValue({
|
||||
item: match3dCard,
|
||||
});
|
||||
match3dServerRuntimeAdapterMock.startRun.mockResolvedValue({
|
||||
run: buildMockMatch3DRun(match3dCard.profileId),
|
||||
});
|
||||
|
||||
render(<TestWrapper />);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(match3dServerRuntimeAdapterMock.startRun).toHaveBeenCalledWith(
|
||||
'match3d-profile-card-guest',
|
||||
expect.objectContaining({
|
||||
runtimeGuestToken: 'runtime-guest-token',
|
||||
skipRefresh: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
expect(getMatch3DWorkDetail).not.toHaveBeenCalledWith(
|
||||
'match3d-profile-card-guest',
|
||||
);
|
||||
});
|
||||
|
||||
test('home recommendation Match3D runtime keeps image, music and UI assets without requiring models', async () => {
|
||||
const match3dCard: Match3DWorkSummary = {
|
||||
workId: 'match3d-work-card-image-only',
|
||||
@@ -9400,6 +9550,7 @@ test('formal puzzle runtime uses frontend move merge logic and backend leaderboa
|
||||
elapsedMs: 18_000,
|
||||
nickname: '测试玩家',
|
||||
},
|
||||
LOGGED_IN_RECOMMEND_RUNTIME_AUTH_OPTIONS,
|
||||
);
|
||||
});
|
||||
|
||||
@@ -9420,6 +9571,7 @@ test('formal puzzle runtime uses frontend move merge logic and backend leaderboa
|
||||
expect(advancePuzzleNextLevel).toHaveBeenCalledWith(
|
||||
clearedFirstLevel.runId,
|
||||
{},
|
||||
LOGGED_IN_RECOMMEND_RUNTIME_AUTH_OPTIONS,
|
||||
);
|
||||
});
|
||||
expect(
|
||||
@@ -9582,6 +9734,7 @@ test('formal puzzle similar work keeps current run level progression', async ()
|
||||
expect(advancePuzzleNextLevel).toHaveBeenCalledWith(
|
||||
clearedThirdLevel.runId,
|
||||
{ targetProfileId: 'puzzle-profile-similar-2' },
|
||||
LOGGED_IN_RECOMMEND_RUNTIME_AUTH_OPTIONS,
|
||||
);
|
||||
});
|
||||
expect(startPuzzleRun).not.toHaveBeenCalled();
|
||||
@@ -10326,7 +10479,7 @@ test('existing draft sessions open result page refinement instead of agent dialo
|
||||
expect(screen.getByText(/基本设定/u)).toBeTruthy();
|
||||
expect(screen.queryByRole('button', { name: /新增场景角色/u })).toBeNull();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /场景角色/u }));
|
||||
await user.click(screen.getByRole('tab', { name: /场景角色/u }));
|
||||
expect(screen.getByRole('button', { name: /顾潮音/u })).toBeTruthy();
|
||||
await user.click(screen.getByRole('button', { name: /顾潮音/u }));
|
||||
expect(await screen.findByText(/编辑场景角色:顾潮音/u)).toBeTruthy();
|
||||
@@ -12256,7 +12409,7 @@ test('creation hub published work edit keeps loaded detail profile assets instea
|
||||
document.querySelector('video[src="/assets/custom-world/opening.mp4"]'),
|
||||
).toBeTruthy();
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /场景\s+2/u }));
|
||||
await user.click(screen.getByRole('tab', { name: /场景\s+2/u }));
|
||||
expect((await screen.findByAltText('废都营地')).getAttribute('src')).toBe(
|
||||
'/assets/custom-world/star-waste-camp.png',
|
||||
);
|
||||
@@ -12264,12 +12417,12 @@ test('creation hub published work edit keeps loaded detail profile assets instea
|
||||
'/assets/custom-world/act-stardust-opening-1.png',
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /可扮演角色\s+1/u }));
|
||||
await user.click(screen.getByRole('tab', { name: /可扮演角色\s+1/u }));
|
||||
expect((await screen.findByAltText('砂眠')).getAttribute('src')).toBe(
|
||||
'/assets/custom-world/playable-stardust-1.png',
|
||||
);
|
||||
|
||||
await user.click(screen.getByRole('button', { name: /场景角色\s+1/u }));
|
||||
await user.click(screen.getByRole('tab', { name: /场景角色\s+1/u }));
|
||||
expect((await screen.findByAltText('钟守')).getAttribute('src')).toBe(
|
||||
'/assets/custom-world/story-clock-keeper-1.png',
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user