Merge remote-tracking branch 'origin/master' into codex/external-generation-worker-scaling
This commit is contained in:
@@ -253,7 +253,9 @@ async function openCreateTemplateHub(user: ReturnType<typeof userEvent.setup>) {
|
||||
).toBeTruthy();
|
||||
// 中文注释:真实最近创作存在时会成为默认页签,模板入口用例需显式切回模板分类。
|
||||
if (!within(panel).queryByRole('button', { name: /拼图/u })) {
|
||||
await user.click(await within(panel).findByRole('tab', { name: '热门推荐' }));
|
||||
await user.click(
|
||||
await within(panel).findByRole('tab', { name: '热门推荐' }),
|
||||
);
|
||||
}
|
||||
expect(
|
||||
await within(panel).findByRole('button', { name: /拼图/u }),
|
||||
@@ -326,6 +328,7 @@ async function openProfilePlayedWorks(
|
||||
await user.click(
|
||||
await screen.findByRole('button', { name: /已玩游戏数量/u }),
|
||||
);
|
||||
expect(await screen.findByRole('dialog', { name: '玩过' })).toBeTruthy();
|
||||
expect(await screen.findByText('可继续')).toBeTruthy();
|
||||
}
|
||||
|
||||
@@ -3798,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();
|
||||
@@ -3837,9 +3835,7 @@ test('create tab shows recent template cards when backend returns failed drafts'
|
||||
expect(
|
||||
await within(panel).findByRole('button', { name: /文字冒险/u }),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
within(panel).getByText('仅显示最近7天内使用过的模板'),
|
||||
).toBeTruthy();
|
||||
expect(within(panel).getByText('仅显示最近7天内使用过的模板')).toBeTruthy();
|
||||
expect(within(panel).getByText('经典 RPG 体验')).toBeTruthy();
|
||||
expect(within(panel).queryByText('入口可见的失败草稿')).toBeNull();
|
||||
expect(
|
||||
@@ -3864,7 +3860,9 @@ test('create tab refreshes recent works after opening from an empty draft shelf'
|
||||
render(<TestWrapper withAuth />);
|
||||
|
||||
await openDraftHub(user);
|
||||
expect(within(getPlatformTabPanel('saves')).getByText('还没有作品')).toBeTruthy();
|
||||
expect(
|
||||
within(getPlatformTabPanel('saves')).getByText('还没有作品'),
|
||||
).toBeTruthy();
|
||||
|
||||
await clickFirstButtonByName(user, '创作');
|
||||
const panel = getPlatformTabPanel('create');
|
||||
@@ -3872,9 +3870,7 @@ test('create tab refreshes recent works after opening from an empty draft shelf'
|
||||
expect(
|
||||
await within(panel).findByRole('button', { name: /文字冒险/u }),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
within(panel).getByText('仅显示最近7天内使用过的模板'),
|
||||
).toBeTruthy();
|
||||
expect(within(panel).getByText('仅显示最近7天内使用过的模板')).toBeTruthy();
|
||||
expect(within(panel).getByText('经典 RPG 体验')).toBeTruthy();
|
||||
expect(within(panel).queryByText('点击创作后出现的失败草稿')).toBeNull();
|
||||
expect(
|
||||
@@ -4037,9 +4033,9 @@ test('bark battle form checks mud points before creating image assets', async ()
|
||||
).toBeTruthy();
|
||||
expect(screen.getByText('汪汪声浪配置表单')).toBeTruthy();
|
||||
expect(screen.queryByRole('tablist', { name: '创作入口页签' })).toBeNull();
|
||||
expect((screen.getByLabelText('汪汪作品标题') as HTMLInputElement).value).toBe(
|
||||
'自定义声浪杯',
|
||||
);
|
||||
expect(
|
||||
(screen.getByLabelText('汪汪作品标题') as HTMLInputElement).value,
|
||||
).toBe('自定义声浪杯');
|
||||
expect(createBarkBattleDraft).not.toHaveBeenCalled();
|
||||
expect(generateAllBarkBattleImageAssets).not.toHaveBeenCalled();
|
||||
});
|
||||
@@ -5139,8 +5135,9 @@ test('failed parallel puzzle generations stay as separate non-generating drafts'
|
||||
const failureDialog = await screen.findByRole('dialog', {
|
||||
name: '发生错误',
|
||||
});
|
||||
expect(within(failureDialog).getByText(/拼图 VectorEngine 图片编辑失败/u))
|
||||
.toBeTruthy();
|
||||
expect(
|
||||
within(failureDialog).getByText(/拼图 VectorEngine 图片编辑失败/u),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
test('failed puzzle draft retry reuses current session instead of creating another draft', async () => {
|
||||
@@ -7387,11 +7384,53 @@ test('public code search blocks edutainment work when entry switch is disabled',
|
||||
await user.type(searchInput, 'PZ-TMENT1');
|
||||
await user.click(screen.getByRole('button', { name: '搜索' }));
|
||||
|
||||
expect(await screen.findByText('未找到结果')).toBeTruthy();
|
||||
const dialog = await screen.findByRole('dialog', { name: '未找到结果' });
|
||||
expect(within(dialog).getByText('公开编号搜索')).toBeTruthy();
|
||||
expect(within(dialog).getByText('未找到拼图作品。')).toBeTruthy();
|
||||
await user.click(
|
||||
within(dialog).getByRole('button', { name: '关闭搜索结果' }),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole('dialog', { name: '未找到结果' })).toBeNull();
|
||||
});
|
||||
expect(screen.queryByText('儿童动作热身 Demo')).toBeNull();
|
||||
expect(getPuzzleGalleryDetail).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('public code search shows public user summary in shared search result modal and clears it on close', async () => {
|
||||
const user = userEvent.setup();
|
||||
vi.mocked(authServiceMocks.getPublicAuthUserByCode).mockResolvedValue({
|
||||
id: 'public-user-yjsh',
|
||||
publicUserCode: 'SY-00000001',
|
||||
username: 'author_user',
|
||||
displayName: '公开作者',
|
||||
avatarUrl: null,
|
||||
});
|
||||
|
||||
render(<TestWrapper withAuth />);
|
||||
await openDiscoverHub(user);
|
||||
|
||||
const searchInput =
|
||||
await screen.findByPlaceholderText('搜索作品号、名称、作者、描述');
|
||||
await user.type(searchInput, '月井守望');
|
||||
await user.click(screen.getByRole('button', { name: '搜索' }));
|
||||
|
||||
const dialog = await screen.findByRole('dialog', { name: '命中用户' });
|
||||
expect(within(dialog).getByText('公开编号搜索')).toBeTruthy();
|
||||
expect(within(dialog).getByText('公开作者')).toBeTruthy();
|
||||
expect(within(dialog).getByText('陶泥号')).toBeTruthy();
|
||||
expect(within(dialog).getByText('SY-00000001')).toBeTruthy();
|
||||
|
||||
await user.click(
|
||||
within(dialog).getByRole('button', { name: '关闭搜索结果' }),
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.queryByRole('dialog', { name: '命中用户' })).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
test('creation hub clears all private work shelves immediately after logout state', async () => {
|
||||
const user = userEvent.setup();
|
||||
const loggedInAuth = createAuthValue();
|
||||
@@ -7571,7 +7610,7 @@ test('published puzzle works appear on home and mobile game category channel', a
|
||||
});
|
||||
|
||||
await clickFirstButtonByName(user, '发现');
|
||||
await user.click(screen.getByRole('button', { name: '分类' }));
|
||||
await user.click(screen.getByRole('tab', { name: '分类' }));
|
||||
|
||||
const discoverPanel = getPlatformTabPanel('category');
|
||||
expect(within(discoverPanel).getAllByText('星桥机关').length).toBeGreaterThan(
|
||||
@@ -7661,8 +7700,9 @@ test('home recommendation share opens publish share modal', async () => {
|
||||
await screen.findByRole('dialog', { name: '分享给朋友' }),
|
||||
).toBeTruthy();
|
||||
expect(screen.getByText(/作品号:PZ-SHARE001/u)).toBeTruthy();
|
||||
expect(screen.getByText(/\/gallery\/puzzle\/detail\?work=PZ-SHARE001/u))
|
||||
.toBeTruthy();
|
||||
expect(
|
||||
screen.getByText(/\/gallery\/puzzle\/detail\?work=PZ-SHARE001/u),
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
test('home recommendation wooden fish like does not call RPG gallery like', async () => {
|
||||
@@ -8046,9 +8086,7 @@ test('home recommendation keeps cover while switching during a pending puzzle st
|
||||
|
||||
await user.click(await screen.findByRole('button', { name: '下一个' }));
|
||||
|
||||
expect(
|
||||
screen.queryByText('作品暂时无法进入,请稍后再试。'),
|
||||
).toBeNull();
|
||||
expect(screen.queryByText('作品暂时无法进入,请稍后再试。')).toBeNull();
|
||||
expect(
|
||||
await screen.findByLabelText('贝壳潮汐 作品信息', undefined, {
|
||||
timeout: 3000,
|
||||
@@ -8073,9 +8111,7 @@ test('home recommendation keeps cover while switching during a pending puzzle st
|
||||
}),
|
||||
);
|
||||
});
|
||||
expect(
|
||||
screen.queryByText('作品暂时无法进入,请稍后再试。'),
|
||||
).toBeNull();
|
||||
expect(screen.queryByText('作品暂时无法进入,请稍后再试。')).toBeNull();
|
||||
});
|
||||
|
||||
test('home recommendation puzzle next level uses unified recommend switching', async () => {
|
||||
@@ -8168,7 +8204,8 @@ test('home recommendation puzzle next level uses unified recommend switching', a
|
||||
items: [entryWork, nextRecommendWork],
|
||||
});
|
||||
vi.mocked(getPuzzleGalleryDetail).mockImplementation(async (profileId) => ({
|
||||
item: profileId === nextRecommendWork.profileId ? nextRecommendWork : entryWork,
|
||||
item:
|
||||
profileId === nextRecommendWork.profileId ? nextRecommendWork : entryWork,
|
||||
}));
|
||||
vi.mocked(startPuzzleRun).mockImplementation(async (payload) => {
|
||||
const run =
|
||||
@@ -8700,7 +8737,7 @@ test('published big fish works stay hidden from platform home and game category
|
||||
expect(screen.queryByText('机械深海 大鱼吃小鱼')).toBeNull();
|
||||
|
||||
await clickFirstButtonByName(user, '发现');
|
||||
await user.click(screen.getByRole('button', { name: '分类' }));
|
||||
await user.click(screen.getByRole('tab', { name: '分类' }));
|
||||
|
||||
const discoverPanel = getPlatformTabPanel('category');
|
||||
expect(within(discoverPanel).queryByText('机械深海 大鱼吃小鱼')).toBeNull();
|
||||
@@ -8740,7 +8777,7 @@ test('published puzzle detail returns to the ranking platform tab', async () =>
|
||||
render(<TestWrapper withAuth />);
|
||||
|
||||
await clickFirstButtonByName(user, '发现');
|
||||
await user.click(await screen.findByRole('button', { name: '排行' }));
|
||||
await user.click(await screen.findByRole('tab', { name: '排行' }));
|
||||
await waitFor(() => {
|
||||
expect(document.getElementById('platform-tab-panel-category')).toBeTruthy();
|
||||
});
|
||||
@@ -9041,7 +9078,8 @@ test('embedded puzzle form maps raw bearer token errors to user-facing auth copy
|
||||
expect(createPuzzleAgentSession).toHaveBeenCalledTimes(1);
|
||||
expect(createCreativeAgentSession).not.toHaveBeenCalled();
|
||||
expect(
|
||||
(await screen.findAllByText('当前登录状态已失效,请重新登录后继续。')).length,
|
||||
(await screen.findAllByText('当前登录状态已失效,请重新登录后继续。'))
|
||||
.length,
|
||||
).toBeTruthy();
|
||||
expect(screen.queryByText('缺少 Authorization Bearer Token')).toBeNull();
|
||||
});
|
||||
@@ -10037,7 +10075,8 @@ test('missing puzzle public detail returns to platform home', async () => {
|
||||
expect(screen.queryByText('资源不存在')).toBeNull();
|
||||
});
|
||||
|
||||
test('direct missing public work detail alert returns to platform home', async () => {
|
||||
test('direct missing public work detail shows unified dialog before returning home', async () => {
|
||||
const user = userEvent.setup();
|
||||
const alertSpy = vi.spyOn(window, 'alert').mockImplementation(() => {});
|
||||
|
||||
window.history.replaceState(null, '', '/works/detail?work=PZ-7A7B18D9');
|
||||
@@ -10049,9 +10088,12 @@ test('direct missing public work detail alert returns to platform home', async (
|
||||
|
||||
expect(await screen.findByText('正在读取作品详情...')).toBeTruthy();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(alertSpy).toHaveBeenCalledWith('作品不存在或已下架,将返回首页。');
|
||||
});
|
||||
const dialog = await screen.findByRole('dialog', { name: '作品不可用' });
|
||||
expect(within(dialog).getByText('作品不存在或已下架,将返回首页。')).toBeTruthy();
|
||||
expect(alertSpy).not.toHaveBeenCalled();
|
||||
|
||||
await user.click(within(dialog).getByRole('button', { name: '知道了' }));
|
||||
|
||||
await waitFor(() => {
|
||||
expect(window.location.pathname).toBe('/');
|
||||
});
|
||||
@@ -10064,6 +10106,8 @@ test('direct missing public work detail alert returns to platform home', async (
|
||||
expect(screen.queryByText('详情')).toBeNull();
|
||||
expect(screen.queryByText('未找到拼图作品。')).toBeNull();
|
||||
expect(startPuzzleRun).toHaveBeenCalledTimes(0);
|
||||
|
||||
alertSpy.mockRestore();
|
||||
});
|
||||
|
||||
test('public code search opens a published big fish work by BF code', async () => {
|
||||
@@ -10489,7 +10533,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();
|
||||
@@ -11852,6 +11896,11 @@ test('profile page keeps save archives inside played stats panel', async () => {
|
||||
|
||||
await openProfilePlayedWorks(user);
|
||||
|
||||
const continueSectionLabel = screen.getByText('可继续');
|
||||
expect(continueSectionLabel.className).toContain('tracking-[0.18em]');
|
||||
expect(continueSectionLabel.className).toContain(
|
||||
'text-[var(--platform-text-soft)]',
|
||||
);
|
||||
expect(screen.queryByLabelText('关闭存档')).toBeNull();
|
||||
expect(screen.queryByText('SAVES')).toBeNull();
|
||||
await clickFirstAsyncButtonByName(user, /潮雾列岛/u);
|
||||
@@ -12414,7 +12463,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',
|
||||
);
|
||||
@@ -12422,12 +12471,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',
|
||||
);
|
||||
@@ -12643,7 +12692,9 @@ test('creation hub gives jump hop wooden fish and bark battle cards the shared d
|
||||
if (!shell) {
|
||||
throw new Error('作品卡应位于统一操作壳内');
|
||||
}
|
||||
await user.click(within(shell as HTMLElement).getByRole('button', { name: '删除' }));
|
||||
await user.click(
|
||||
within(shell as HTMLElement).getByRole('button', { name: '删除' }),
|
||||
);
|
||||
|
||||
const dialog = await screen.findByRole('dialog', { name: '删除作品' });
|
||||
expect(within(dialog).getByText(`确认删除《${title}》吗?`)).toBeTruthy();
|
||||
|
||||
Reference in New Issue
Block a user