Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions apps/settings/src/mixins/UserRowMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,18 @@ export default {
userSubAdminGroups: this.user.subadmin.map((id) => ({ id, name: id })),
}
},
created() {
// Initialize group names from store
// This fixes the issue where group IDs were shown instead of names in the NcSelect
this.userGroups = this.user.groups.map(id => {
const group = this.$store.state.users.groups.find(g => g.id === id)
return group ? { id: group.id, name: group.name } : { id, name: id }
})
this.userSubAdminGroups = this.user.subadmin.map(id => {
const group = this.$store.state.users.groups.find(g => g.id === id)
return group ? { id: group.id, name: group.name } : { id, name: id }
})
},
computed: {
showConfig() {
return this.$store.getters.getShowConfig
Expand Down
89 changes: 89 additions & 0 deletions cypress/e2e/settings/users_groups_display_name.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*
* Regression test for: https://github.com/nextcloud/server/issues/55785
*
* Tests that group display names are shown correctly in the user editor,
* even when the group ID differs from the display name (e.g., when long
* group names get hashed to create the group ID).
*/

import { User } from '@nextcloud/e2e-test-server/cypress'
import { randomString } from '../../support/utils/randomString.ts'
import { getUserListRow, handlePasswordConfirmation, toggleEditButton } from './usersUtils.ts'

const admin = new User('admin', 'admin')

describe('Settings: Group names persist after reload (issue #55785)', { testIsolation: false }, () => {
let testUser: User
// Use a very long name to ensure Nextcloud hashes it to create the group ID.
// This creates a test case where group ID !== group display name.
const randomPart = randomString(80)
const groupName = `Test Group with Very Long Name ${randomPart}`

after(() => cy.deleteUser(testUser))
before(() => {
cy.createRandomUser().then((user) => {
testUser = user
})
cy.runOccCommand(`group:add '${groupName}'`).then(() => {
// Verify that the group ID is different from the display name
// (this confirms our test case is valid)
cy.runOccCommand('group:list --output=json').then((result) => {
const groups = JSON.parse(result.stdout)
const groupEntry = Object.entries(groups).find(([, displayName]) => (displayName as string).includes(randomPart))
if (groupEntry) {
const [groupId, displayName] = groupEntry
cy.log(`Group ID: ${groupId}`)
cy.log(`Display name: ${displayName}`)
// Assert that ID and name are different (this is what triggers the bug)
expect(groupId).to.not.equal(displayName)
}
})
})
cy.login(admin)
cy.intercept('GET', '**/ocs/v2.php/cloud/groups/details?search=&offset=*&limit=*').as('loadGroups')
cy.visit('/settings/users')
cy.wait('@loadGroups')
})

it('Assign user to group', () => {
toggleEditButton(testUser)

getUserListRow(testUser.userId)
.find('[data-cy-user-list-input-groups] input')
.click({ force: true })

getUserListRow(testUser.userId)
.find('[data-cy-user-list-input-groups] input')
.type(randomPart.slice(0, 10))

cy.contains('li.vs__dropdown-option', groupName)
.should('exist')
.click({ force: true })

handlePasswordConfirmation(admin.password)

toggleEditButton(testUser, false)
})

it('After page reload, selected group still shows correct name', () => {
// Visit the users page again to simulate a fresh page load
cy.visit('/settings/users')

toggleEditButton(testUser)

// Verify the selected group displays the name, not the hashed ID
getUserListRow(testUser.userId)
.find('[data-cy-user-list-input-groups]')
.should('exist')
.within(() => {
cy.get('.vs__selected').invoke('text').then((displayedText) => {
expect(displayedText.trim()).to.include('Test Group with Very Long Name')
})
})

toggleEditButton(testUser, false)
})
})
4 changes: 2 additions & 2 deletions dist/settings-users-3239.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-users-3239.js.map

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions dist/settings-vue-settings-apps-users-management.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/settings-vue-settings-apps-users-management.js.map

Large diffs are not rendered by default.

Loading