From e7c4efec9de2a893d389cb3bb5ebcc0b9bf6f328 Mon Sep 17 00:00:00 2001 From: Peter Ringelmann Date: Mon, 22 Jun 2026 16:25:17 +0200 Subject: [PATCH 1/3] fix(settings): correct heading order in account management sidebar Signed-off-by: Peter Ringelmann --- .../components/AppNavigationGroupList.spec.ts | 57 ++++++++++++++++++ .../src/components/AppNavigationGroupList.vue | 58 +++++++++---------- 2 files changed, 85 insertions(+), 30 deletions(-) create mode 100644 apps/settings/src/components/AppNavigationGroupList.spec.ts diff --git a/apps/settings/src/components/AppNavigationGroupList.spec.ts b/apps/settings/src/components/AppNavigationGroupList.spec.ts new file mode 100644 index 0000000000000..01b53caf27bb3 --- /dev/null +++ b/apps/settings/src/components/AppNavigationGroupList.spec.ts @@ -0,0 +1,57 @@ +/** + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { mount } from '@vue/test-utils' +import { ref } from 'vue' +import { describe, expect, it, vi } from 'vitest' +import NcAppNavigationCaption from '@nextcloud/vue/components/NcAppNavigationCaption' + +// The component builds a real Vuex store via useStore(); mock it so this stays +// a focused component test that controls its own data. +vi.mock('../store/index.js', () => ({ + useStore: () => ({ + getters: { + getServerData: { isAdmin: false, isDelegatedAdmin: false }, + getSortedGroups: [], + getSubAdminGroups: [], + getSearchQuery: '', + }, + commit: vi.fn(), + dispatch: vi.fn(), + }), +})) + +vi.mock('vue-router/composables', async (importActual) => ({ + ...(await importActual()), + useRoute: () => ({ params: {} }), + useRouter: () => ({ push: vi.fn() }), +})) + +vi.mock('../service/groups.ts', () => ({ + searchGroups: () => Promise.resolve([]), +})) + +vi.mock('@vueuse/core', async (importActual) => ({ + ...(await importActual()), + useElementVisibility: () => ref(false), +})) + +import AppNavigationGroupList from './AppNavigationGroupList.vue' + +describe('AppNavigationGroupList', () => { + it('does not expose the group list as a heading (BITV 9.1.3.1a)', () => { + const wrapper = mount(AppNavigationGroupList) + + // The sidebar group list is navigation, not document structure. It must + // not emit a heading, which would sit before the page

in the DOM + // and produce an out-of-order outline (h2 before h1). + const caption = wrapper.findComponent(NcAppNavigationCaption) + expect(caption.exists()).toBe(true) + expect(caption.find('h1,h2,h3,h4,h5,h6').exists()).toBe(false) + + // The "Groups" label is still rendered, just not as a heading. + expect(caption.text()).toContain('Groups') + }) +}) diff --git a/apps/settings/src/components/AppNavigationGroupList.vue b/apps/settings/src/components/AppNavigationGroupList.vue index 1a9d214cdd69e..2de76b591a1b5 100644 --- a/apps/settings/src/components/AppNavigationGroupList.vue +++ b/apps/settings/src/components/AppNavigationGroupList.vue @@ -5,36 +5,6 @@