From 1298a5f72cfc1aaa7c47df7adc78e481a9c80cc8 Mon Sep 17 00:00:00 2001 From: InfinityPacer <160988576+InfinityPacer@users.noreply.github.com> Date: Mon, 3 Aug 2026 13:30:20 +0800 Subject: [PATCH] test(plugin): cover dynamic sidebar navigation (#629) --- eslint-suppressions.json | 16 -- .../default/components/DefaultLayout.vue | 45 +++-- .../__tests__/DefaultLayout.spec.ts | 172 ++++++++++++++--- src/pages/__tests__/appcenter.spec.ts | 124 ++++++++++++ src/pages/appcenter.vue | 33 ++-- .../plugin-sidebar-permission.spec.ts | 146 ++++++++++++++ src/stores/__tests__/pluginSidebarNav.spec.ts | 178 ++++++++++++++++++ src/stores/pluginSidebarNav.ts | 26 +-- src/utils/__tests__/pluginSidebarNav.spec.ts | 92 +++++++++ vite.config.ts | 21 +++ 10 files changed, 774 insertions(+), 79 deletions(-) create mode 100644 src/pages/__tests__/appcenter.spec.ts create mode 100644 src/router/__tests__/plugin-sidebar-permission.spec.ts create mode 100644 src/stores/__tests__/pluginSidebarNav.spec.ts create mode 100644 src/utils/__tests__/pluginSidebarNav.spec.ts diff --git a/eslint-suppressions.json b/eslint-suppressions.json index 1bef2924..09686ef3 100644 --- a/eslint-suppressions.json +++ b/eslint-suppressions.json @@ -688,14 +688,6 @@ "count": 1 } }, - "src/layouts/default/components/DefaultLayout.vue": { - "@typescript-eslint/no-explicit-any": { - "count": 2 - }, - "vue/valid-v-for": { - "count": 5 - } - }, "src/layouts/default/components/Footer.vue": { "@typescript-eslint/no-explicit-any": { "count": 6 @@ -814,14 +806,6 @@ "count": 2 } }, - "src/stores/pluginSidebarNav.ts": { - "@typescript-eslint/no-unused-vars": { - "count": 1 - }, - "sonarjs/no-ignored-exceptions": { - "count": 1 - } - }, "src/stores/types.ts": { "@typescript-eslint/no-explicit-any": { "count": 2 diff --git a/src/layouts/default/components/DefaultLayout.vue b/src/layouts/default/components/DefaultLayout.vue index 982dd1df..4ffb92a3 100644 --- a/src/layouts/default/components/DefaultLayout.vue +++ b/src/layouts/default/components/DefaultLayout.vue @@ -142,6 +142,10 @@ interface DynamicHeaderTab { onUpdateModelValue?: (value: string) => void // 用于通知值更新 } +type DynamicHeaderTabWindow = Window & { + __VUE_INJECT_DYNAMIC_HEADER_TAB__?: (tab: DynamicHeaderTab) => void +} + // 提供动态标签页注册和获取的方法 const dynamicHeaderTab = ref(null) const openHorizontalNavGroup = ref(null) @@ -179,7 +183,7 @@ const handleTabChange = (newValue: string) => { // 添加全局注册方法,解决注入不可用的问题 if (typeof window !== 'undefined') { // 确保在浏览器环境中 - ;(window as any).__VUE_INJECT_DYNAMIC_HEADER_TAB__ = registerDynamicHeaderTab + ;(window as DynamicHeaderTabWindow).__VUE_INJECT_DYNAMIC_HEADER_TAB__ = registerDynamicHeaderTab } // 提供给其他组件使用 @@ -233,7 +237,7 @@ onUnmounted(() => { dynamicHeaderTab.value = null // 清理全局方法 if (typeof window !== 'undefined') { - delete (window as any).__VUE_INJECT_DYNAMIC_HEADER_TAB__ + delete (window as DynamicHeaderTabWindow).__VUE_INJECT_DYNAMIC_HEADER_TAB__ } }) @@ -286,6 +290,8 @@ const getMenuList = (header: string) => { return filteredMenus.filter((item: NavMenu) => item.header === header) } +const getMenuIdentity = (item: NavMenu) => `${item.title}-${JSON.stringify(item.to ?? null)}` + /** 返回浏览历史中的上一页。 */ function goBack() { history.back() @@ -458,20 +464,29 @@ function appendPluginSidebarMenus() { } } -onMounted(async () => { - // 主题定制器由布局统一承载,监听需要尽早注册,避免异步加载菜单期间丢失打开事件。 - window.addEventListener(THEME_CUSTOMIZER_CHANGE_EVENT, handleThemeCustomizerChange) - window.addEventListener(THEME_CUSTOMIZER_OPEN_EVENT, handleThemeCustomizerOpen) - - // 获取菜单列表 +/** 从当前内置菜单、权限上下文与插件快照重建所有侧栏分组。 */ +function rebuildSidebarMenus() { startMenus.value = getMenuList(t('menu.start')) discoveryMenus.value = getMenuList(t('menu.discovery')) subscribeMenus.value = getMenuList(t('menu.subscribe')) organizeMenus.value = getMenuList(t('menu.organize')) systemMenus.value = getMenuList(t('menu.system')) - - await pluginSidebarNavStore.ensureSidebarNav() appendPluginSidebarMenus() +} + +let sidebarMenusMounted = false +watch([() => pluginSidebarNavStore.items, userPermissions], () => { + if (sidebarMenusMounted) rebuildSidebarMenus() +}) + +onMounted(async () => { + // 主题定制器由布局统一承载,监听需要尽早注册,避免异步加载菜单期间丢失打开事件。 + window.addEventListener(THEME_CUSTOMIZER_CHANGE_EVENT, handleThemeCustomizerChange) + window.addEventListener(THEME_CUSTOMIZER_OPEN_EVENT, handleThemeCustomizerOpen) + + rebuildSidebarMenus() + sidebarMenusMounted = true + await pluginSidebarNavStore.ensureSidebarNav() }) @@ -642,7 +657,7 @@ onMounted(async () => {