test(族谱): 钉住「热度排序/主干线判据=自身 playCount」而非子树合计
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled

This commit is contained in:
2026-10-07 11:19:26 +08:00
parent 0b6c7a110e
commit 088f467dcc
2 changed files with 69 additions and 0 deletions
@@ -3133,6 +3133,72 @@ describe('GameLineagePage 筛选器 / 主干线 / 信息面板(文档对齐)
);
});
it('热度排序判据 = 自身 playCount(子树合计更高的兄弟排后面)', async () => {
// self-hot:自身 100、无子代(合计 100)。deep-hot:自身 5、但子代 200(合计 205)。
getGameLineageMock.mockResolvedValueOnce({
rootGameId: 'game-root',
root: createLineageNode({
gameId: 'game-root',
title: '母版',
generation: 0,
parentGameId: null,
playCount: 1,
}),
nodes: [
createLineageNode({
gameId: 'game-root',
title: '母版',
generation: 0,
parentGameId: null,
playCount: 1,
}),
createLineageNode({
gameId: 'self-hot',
title: '自身热',
generation: 1,
parentGameId: 'game-root',
playCount: 100,
}),
createLineageNode({
gameId: 'deep-hot',
title: '后代热',
generation: 1,
parentGameId: 'game-root',
playCount: 5,
}),
createLineageNode({
gameId: 'deep-child',
title: '爆款孙代',
generation: 2,
parentGameId: 'deep-hot',
playCount: 200,
}),
],
truncated: false,
});
render(
<GameLineagePage
rootGameId="game-root"
onBack={vi.fn()}
onOpenDetail={vi.fn()}
/>,
);
await screen.findByText('自身热');
fireEvent.click(screen.getByRole('checkbox', { name: '按热度排序' }));
// 判据是自身:自身热(100)排在 后代热(自身 5 / 合计 205)**前面**。
expect(parseFloat((await cardOf('自身热')).style.left)).toBeLessThan(
parseFloat((await cardOf('后代热')).style.left),
);
// 主干线同理,仍然选「自身热」。
expect(
(await cardOf('自身热')).querySelector('.game-lineage-node__trunk'),
).not.toBeNull();
expect(
(await cardOf('后代热')).querySelector('.game-lineage-node__trunk'),
).toBeNull();
});
it('主干线:每代热度最高的节点带「主干」角标,主干边单独标记', async () => {
getGameLineageMock.mockResolvedValueOnce(tree);
render(
@@ -347,6 +347,9 @@ export function GameLineagePage({
/**
* 顶部筛选器:按世代筛选(保留该代及其祖先,树不断链)与按热度排序
* (同代内 `playCount` 倒序;关闭时保持服务端顺序 = 创建时间序)。
*
* 注意排序判据是**自身** `playCount`(服务端字段原值),与主干线同裁定:热度表达的是
* 「这一版自己有多热」,不是子树合计(显示口径见 §3.6.3)。别改成 `...Totals`。
*/
const filteredNodes = useMemo(() => {
const kept =