Skip to content

Commit 4cadaa0

Browse files
Merge pull request #61545 from nextcloud/backport/61505/stable32
[stable32] fix(settings): correct heading order in account management sidebar
2 parents e9053ef + 37c8362 commit 4cadaa0

7 files changed

Lines changed: 71 additions & 15 deletions
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/**
2+
* SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: AGPL-3.0-or-later
4+
*/
5+
6+
import { mount } from '@vue/test-utils'
7+
import { ref } from 'vue'
8+
import { describe, expect, it, vi } from 'vitest'
9+
import NcAppNavigationCaption from '@nextcloud/vue/components/NcAppNavigationCaption'
10+
import AppNavigationGroupList from './AppNavigationGroupList.vue'
11+
12+
// The component builds a real Vuex store via useStore(); mock it so this stays
13+
// a focused component test that controls its own data.
14+
vi.mock('../store/index.js', () => ({
15+
useStore: () => ({
16+
getters: {
17+
getServerData: { isAdmin: false, isDelegatedAdmin: false },
18+
getSortedGroups: [],
19+
getSubAdminGroups: [],
20+
getSearchQuery: '',
21+
},
22+
commit: vi.fn(),
23+
dispatch: vi.fn(),
24+
}),
25+
}))
26+
27+
vi.mock('vue-router/composables', async (importActual) => ({
28+
...(await importActual<object>()),
29+
useRoute: () => ({ params: {} }),
30+
useRouter: () => ({ push: vi.fn() }),
31+
}))
32+
33+
vi.mock('../service/groups.ts', () => ({
34+
searchGroups: () => Promise.resolve([]),
35+
}))
36+
37+
vi.mock('@vueuse/core', async (importActual) => ({
38+
...(await importActual<object>()),
39+
useElementVisibility: () => ref(false),
40+
}))
41+
42+
describe('AppNavigationGroupList', () => {
43+
it('does not expose the group list as a heading (BITV 9.1.3.1a)', () => {
44+
const wrapper = mount(AppNavigationGroupList)
45+
46+
// The sidebar group list is navigation, not document structure. It must
47+
// not emit a heading, which would sit before the page <h1> in the DOM
48+
// and produce an out-of-order outline (h2 before h1).
49+
const caption = wrapper.findComponent(NcAppNavigationCaption)
50+
expect(caption.exists()).toBe(true)
51+
expect(caption.find('h1,h2,h3,h4,h5,h6').exists()).toBe(false)
52+
53+
// The "Groups" label is still rendered, just not as a heading.
54+
expect(caption.text()).toContain('Groups')
55+
})
56+
})

apps/settings/src/components/AppNavigationGroupList.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
:disabled="loadingAddGroup"
1010
:aria-label="loadingAddGroup ? t('settings', 'Creating group…') : t('settings', 'Create group')"
1111
force-menu
12-
is-heading
1312
:open.sync="isAddGroupOpen">
1413
<template v-if="isAdminOrDelegatedAdmin" #actionsTriggerIcon>
1514
<NcLoadingIcon v-if="loadingAddGroup" />
@@ -40,6 +39,7 @@
4039
{{ t('settings', 'List of groups. This list is not fully populated for performance reasons. The groups will be loaded as you navigate or search through the list.') }}
4140
</p>
4241
<NcAppNavigationList class="account-management__group-list"
42+
:aria-label="t('settings', 'Groups')"
4343
aria-describedby="group-list-desc"
4444
data-cy-users-settings-navigation-groups="custom">
4545
<GroupListItem v-for="group in filteredGroups"

cypress/e2e/settings/users_groups.cy.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -248,16 +248,16 @@ describe('Settings: Sort groups in the UI', () => {
248248

249249
it('See that the groups are sorted by the member count', () => {
250250
cy.get('ul[data-cy-users-settings-navigation-groups="custom"]').within(() => {
251-
cy.get('li').eq(0).should('contain', 'B') // 1 member
252-
cy.get('li').eq(1).should('contain', 'A') // 0 members
251+
cy.get('li').not('.app-navigation-caption').eq(0).should('contain', 'B') // 1 member
252+
cy.get('li').not('.app-navigation-caption').eq(1).should('contain', 'A') // 0 members
253253
})
254254
})
255255

256256
it('See that the order is preserved after a reload', () => {
257257
cy.reload()
258258
cy.get('ul[data-cy-users-settings-navigation-groups="custom"]').within(() => {
259-
cy.get('li').eq(0).should('contain', 'B') // 1 member
260-
cy.get('li').eq(1).should('contain', 'A') // 0 members
259+
cy.get('li').not('.app-navigation-caption').eq(0).should('contain', 'B') // 1 member
260+
cy.get('li').not('.app-navigation-caption').eq(1).should('contain', 'A') // 0 members
261261
})
262262
})
263263

@@ -276,16 +276,16 @@ describe('Settings: Sort groups in the UI', () => {
276276

277277
it('See that the groups are sorted by the user count', () => {
278278
cy.get('ul[data-cy-users-settings-navigation-groups="custom"]').within(() => {
279-
cy.get('li').eq(0).should('contain', 'A')
280-
cy.get('li').eq(1).should('contain', 'B')
279+
cy.get('li').not('.app-navigation-caption').eq(0).should('contain', 'A')
280+
cy.get('li').not('.app-navigation-caption').eq(1).should('contain', 'B')
281281
})
282282
})
283283

284284
it('See that the order is preserved after a reload', () => {
285285
cy.reload()
286286
cy.get('ul[data-cy-users-settings-navigation-groups="custom"]').within(() => {
287-
cy.get('li').eq(0).should('contain', 'A')
288-
cy.get('li').eq(1).should('contain', 'B')
287+
cy.get('li').not('.app-navigation-caption').eq(0).should('contain', 'A')
288+
cy.get('li').not('.app-navigation-caption').eq(1).should('contain', 'B')
289289
})
290290
})
291291
})

dist/settings-users-3239.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/settings-users-3239.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/settings-vue-settings-apps-users-management.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/settings-vue-settings-apps-users-management.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)