81cfbae207
Project CI / AI game creator shell Rust crates (push) Successful in 2m45s
Project CI / AI game creator shell Rust lane 2/2 (push) Successful in 4m17s
Project CI / AI game creator shell Rust lane 1/2 (push) Successful in 5m27s
Project CI / Frontend tests (push) Successful in 3m4s
Project CI / Backend tests (push) Successful in 6m32s
Project CI / Native shell tests (push) Successful in 7m36s
Project CI / AI game creator shell web tests (push) Successful in 3m24s
Project CI / Repository checks (push) Successful in 6m44s
新增后台侧栏业务分组与当前页自动展开行为 补充折叠交互、路由分组和权限过滤测试 同步后台导航分组行为文档
269 lines
8.1 KiB
TypeScript
269 lines
8.1 KiB
TypeScript
import { expect, test } from 'vitest';
|
|
|
|
import {
|
|
adminRoutes,
|
|
getAccessibleAdminRoutes,
|
|
getAdminNavGroups,
|
|
resolveAccessibleAdminRoute,
|
|
resolveAdminRoute,
|
|
routeHash,
|
|
} from './adminRoutes';
|
|
|
|
test('后台侧边栏路由按业务分组且不丢失任何页签', () => {
|
|
const groups = getAdminNavGroups(adminRoutes);
|
|
const groupedRouteIds = groups.flatMap((group) =>
|
|
group.routes.map((route) => route.id),
|
|
);
|
|
|
|
expect(groups.map((group) => group.label)).toEqual([
|
|
'工作台',
|
|
'数据与监控',
|
|
'运营配置',
|
|
'充值与支付',
|
|
'AGC 管理',
|
|
'内容运营',
|
|
'账号权限',
|
|
]);
|
|
expect(groupedRouteIds).toEqual(adminRoutes.map((route) => route.id));
|
|
});
|
|
|
|
test('后台侧边栏分组只保留当前管理员可见的页签', () => {
|
|
const groups = getAdminNavGroups(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['tracking', 'game-reviews', 'accounts'],
|
|
}),
|
|
);
|
|
|
|
expect(
|
|
groups.map((group) => [group.label, group.routes.map((route) => route.id)]),
|
|
).toEqual([
|
|
['数据与监控', ['tracking']],
|
|
['内容运营', ['game-reviews']],
|
|
]);
|
|
});
|
|
|
|
test('游戏评价路由独立授权并支持游戏参数', () => {
|
|
expect(resolveAdminRoute('#game-reviews?gameId=game_1')).toBe('game-reviews');
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['game-reviews'],
|
|
}).map((route) => route.id),
|
|
).toEqual(['game-reviews']);
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['game-management'],
|
|
}).some((route) => route.id === 'game-reviews'),
|
|
).toBe(false);
|
|
});
|
|
|
|
test('客户端埋点路由遵守成员页签权限', () => {
|
|
expect(resolveAdminRoute('#agc-tracking')).toBe('agc-tracking');
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['agc-tracking'],
|
|
}).map((route) => route.id),
|
|
).toEqual(['agc-tracking']);
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['tracking'],
|
|
}).some((route) => route.id === 'agc-tracking'),
|
|
).toBe(false);
|
|
});
|
|
|
|
test('后台默认进入 Dashboard', () => {
|
|
expect(adminRoutes[0]).toEqual({
|
|
id: 'dashboard',
|
|
label: 'Dashboard',
|
|
hash: '#dashboard',
|
|
});
|
|
expect(resolveAdminRoute('')).toBe('dashboard');
|
|
expect(resolveAdminRoute('#unknown')).toBe('dashboard');
|
|
expect(routeHash('dashboard')).toBe('#dashboard');
|
|
});
|
|
|
|
test('后台模型定价路由可通过导航和 hash 访问', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'editor-generation-pricing',
|
|
label: '模型定价',
|
|
hash: '#editor-generation-pricing',
|
|
});
|
|
expect(resolveAdminRoute('#editor-generation-pricing')).toBe(
|
|
'editor-generation-pricing',
|
|
);
|
|
expect(routeHash('editor-generation-pricing')).toBe(
|
|
'#editor-generation-pricing',
|
|
);
|
|
});
|
|
|
|
test('后台灰度发布路由可通过导航和 hash 访问', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'gray-release',
|
|
label: '灰度发布',
|
|
hash: '#gray-release',
|
|
});
|
|
expect(resolveAdminRoute('#gray-release')).toBe('gray-release');
|
|
expect(routeHash('gray-release')).toBe('#gray-release');
|
|
});
|
|
|
|
test('后台素材查询路由可通过导航和 hash 访问', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'editor-assets',
|
|
label: '素材查询',
|
|
hash: '#editor-assets',
|
|
});
|
|
expect(resolveAdminRoute('#editor-assets')).toBe('editor-assets');
|
|
expect(routeHash('editor-assets')).toBe('#editor-assets');
|
|
});
|
|
|
|
test('后台精选审核路由可通过导航和 hash 访问', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'editor-showcase',
|
|
label: '精选审核',
|
|
hash: '#editor-showcase',
|
|
});
|
|
expect(resolveAdminRoute('#editor-showcase')).toBe('editor-showcase');
|
|
expect(routeHash('editor-showcase')).toBe('#editor-showcase');
|
|
});
|
|
|
|
test('后台充值管理路由可通过导航和 hash 访问', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'recharge-orders',
|
|
label: '充值管理',
|
|
hash: '#recharge-orders',
|
|
});
|
|
expect(resolveAdminRoute('#recharge-orders')).toBe('recharge-orders');
|
|
expect(routeHash('recharge-orders')).toBe('#recharge-orders');
|
|
});
|
|
|
|
test('owner 可访问全部业务 Tab 和账号管理', () => {
|
|
const routes = getAccessibleAdminRoutes({
|
|
accountRole: 'owner',
|
|
tabPermissions: [],
|
|
});
|
|
expect(routes).toEqual(adminRoutes);
|
|
expect(routes.at(-1)).toMatchObject({ id: 'accounts', ownerOnly: true });
|
|
});
|
|
|
|
test('member 只访问已分配 Tab 且无权 hash 回落到第一项', () => {
|
|
const routes = getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['tracking', 'recharge-orders'],
|
|
});
|
|
expect(routes.map((route) => route.id)).toEqual([
|
|
'tracking',
|
|
'recharge-orders',
|
|
]);
|
|
expect(resolveAccessibleAdminRoute('#accounts', routes)).toBe('tracking');
|
|
expect(resolveAccessibleAdminRoute('#recharge-orders', routes)).toBe(
|
|
'recharge-orders',
|
|
);
|
|
});
|
|
|
|
test('member 可单独获得灰度发布 Tab 权限', () => {
|
|
const routes = getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['gray-release'],
|
|
});
|
|
expect(routes.map((route) => route.id)).toEqual(['gray-release']);
|
|
expect(resolveAccessibleAdminRoute('#gray-release', routes)).toBe(
|
|
'gray-release',
|
|
);
|
|
});
|
|
|
|
test('零权限 member 不回落到 Dashboard', () => {
|
|
const routes = getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: [],
|
|
});
|
|
expect(routes).toEqual([]);
|
|
expect(resolveAccessibleAdminRoute('#dashboard', routes)).toBeNull();
|
|
});
|
|
|
|
test('项目工程入口对 owner 与已授权 member 开放且可分配权限', () => {
|
|
const route = {
|
|
id: 'project-snapshots',
|
|
label: '项目工程',
|
|
hash: '#project-snapshots',
|
|
};
|
|
expect(adminRoutes.filter((item) => !item.ownerOnly)).toContainEqual(route);
|
|
expect(resolveAdminRoute('#project-snapshots')).toBe('project-snapshots');
|
|
expect(
|
|
getAccessibleAdminRoutes({ accountRole: 'owner', tabPermissions: [] }),
|
|
).toContainEqual(route);
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['project-snapshots'],
|
|
}),
|
|
).toEqual([route]);
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['tracking'],
|
|
}),
|
|
).not.toContainEqual(route);
|
|
});
|
|
|
|
test('后台游戏审核路由可通过导航和 hash 访问', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'game-distribution',
|
|
label: '游戏审核',
|
|
hash: '#game-distribution',
|
|
});
|
|
expect(resolveAdminRoute('#game-distribution')).toBe('game-distribution');
|
|
expect(routeHash('game-distribution')).toBe('#game-distribution');
|
|
});
|
|
|
|
test('后台游戏管理路由可通过导航和 hash 访问', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'game-management',
|
|
label: '游戏管理',
|
|
hash: '#game-management',
|
|
});
|
|
expect(resolveAdminRoute('#game-management')).toBe('game-management');
|
|
expect(routeHash('game-management')).toBe('#game-management');
|
|
});
|
|
|
|
test('member 可单独获得游戏审核 Tab 权限', () => {
|
|
const routes = getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['game-distribution'],
|
|
});
|
|
expect(routes.map((route) => route.id)).toEqual(['game-distribution']);
|
|
expect(resolveAccessibleAdminRoute('#game-distribution', routes)).toBe(
|
|
'game-distribution',
|
|
);
|
|
});
|
|
|
|
test('模板管理只对 owner 或具有 agc-templates 权限的 member 可见', () => {
|
|
expect(adminRoutes).toContainEqual({
|
|
id: 'agc-templates',
|
|
label: '模板管理',
|
|
hash: '#agc-templates',
|
|
});
|
|
expect(resolveAdminRoute('#agc-templates')).toBe('agc-templates');
|
|
expect(routeHash('agc-templates')).toBe('#agc-templates');
|
|
expect(
|
|
getAccessibleAdminRoutes({ accountRole: 'owner', tabPermissions: [] }).some(
|
|
(route) => route.id === 'agc-templates',
|
|
),
|
|
).toBe(true);
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['agc-templates'],
|
|
}).map((route) => route.id),
|
|
).toEqual(['agc-templates']);
|
|
expect(
|
|
getAccessibleAdminRoutes({
|
|
accountRole: 'member',
|
|
tabPermissions: ['editor-assets'],
|
|
}).some((route) => route.id === 'agc-templates'),
|
|
).toBe(false);
|
|
});
|