fix(permissions): permissions editor ignores changes

Template refs conflicted with component properties.

Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
This commit is contained in:
Grigorii K. Shartsev
2025-07-11 16:20:47 +02:00
parent 5ba7cf3a97
commit 9080ddfaef
3 changed files with 36 additions and 29 deletions

View File

@ -11,6 +11,8 @@ const ignorePatterns = [
'@nextcloud/dialogs',
'@nextcloud/vue',
'@mdi/svg',
'@vueuse/core',
'@vueuse/shared',
'bail',
'ccount', // ESM dependency of remark-gfm
'comma-separated-tokens',

View File

@ -13,38 +13,31 @@
<!-- eslint-disable-next-line vue/no-v-html -->
<p :id="dialogHeaderId" class="title" v-html="modalTitle" />
<form @submit.prevent="handleSubmitPermissions">
<NcCheckboxRadioSwitch ref="callStart"
v-model="callStart"
<NcCheckboxRadioSwitch v-model="callStart"
class="checkbox">
{{ t('spreed', 'Start a call') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch ref="lobbyIgnore"
v-model="lobbyIgnore"
<NcCheckboxRadioSwitch v-model="lobbyIgnore"
class="checkbox">
{{ t('spreed', 'Skip the lobby') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch ref="chatMessagesAndReactions"
v-model="chatMessagesAndReactions"
<NcCheckboxRadioSwitch v-model="chatMessagesAndReactions"
class="checkbox">
{{ t('spreed', 'Can post messages and reactions') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch ref="publishAudio"
v-model="publishAudio"
<NcCheckboxRadioSwitch v-model="publishAudio"
class="checkbox">
{{ t('spreed', 'Enable the microphone') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch ref="publishVideo"
v-model="publishVideo"
<NcCheckboxRadioSwitch v-model="publishVideo"
class="checkbox">
{{ t('spreed', 'Enable the camera') }}
</NcCheckboxRadioSwitch>
<NcCheckboxRadioSwitch ref="publishScreen"
v-model="publishScreen"
<NcCheckboxRadioSwitch v-model="publishScreen"
class="checkbox">
{{ t('spreed', 'Share the screen') }}
</NcCheckboxRadioSwitch>
<NcButton ref="submit"
type="submit"
<NcButton type="submit"
class="button-update-permission"
variant="primary"
:disabled="submitButtonDisabled">

View File

@ -6,13 +6,23 @@
import { mount } from '@vue/test-utils'
import { cloneDeep } from 'lodash'
import { createPinia, setActivePinia } from 'pinia'
import { nextTick } from 'vue'
import { createStore } from 'vuex'
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
import PermissionsEditor from '../../PermissionsEditor/PermissionsEditor.vue'
import ParticipantPermissionsEditor from './ParticipantPermissionsEditor.vue'
import { ATTENDEE, PARTICIPANT } from '../../../constants.ts'
import storeConfig from '../../../store/storeConfig.js'
import { useTokenStore } from '../../../stores/token.ts'
function getByText(wrappers, text) {
return wrappers.find((wrapper) => wrapper.text().trim() === text)
}
function getPermissionCheckboxes(wrapper) {
return wrapper.getComponent(PermissionsEditor).findAllComponents(NcCheckboxRadioSwitch)
}
describe('ParticipantPermissionsEditor.vue', () => {
let conversation
let participant
@ -73,26 +83,24 @@ describe('ParticipantPermissionsEditor.vue', () => {
describe('checkboxes render on mount', () => {
const testCheckboxRendering = async (participant) => {
// Arrange
const permissions = participant.permissions
|| (PARTICIPANT.PERMISSIONS.MAX_DEFAULT & ~PARTICIPANT.PERMISSIONS.LOBBY_IGNORE) // Default from component
const permissionsMap = [
{ ref: 'callStart', value: !!(permissions & PARTICIPANT.PERMISSIONS.CALL_START) },
{ ref: 'lobbyIgnore', value: !!(permissions & PARTICIPANT.PERMISSIONS.LOBBY_IGNORE) },
{ ref: 'chatMessagesAndReactions', value: !!(permissions & PARTICIPANT.PERMISSIONS.CHAT) },
{ ref: 'publishAudio', value: !!(permissions & PARTICIPANT.PERMISSIONS.PUBLISH_AUDIO) },
{ ref: 'publishVideo', value: !!(permissions & PARTICIPANT.PERMISSIONS.PUBLISH_VIDEO) },
{ ref: 'publishScreen', value: !!(permissions & PARTICIPANT.PERMISSIONS.PUBLISH_SCREEN) },
{ label: 'Start a call', value: !!(permissions & PARTICIPANT.PERMISSIONS.CALL_START) },
{ label: 'Skip the lobby', value: !!(permissions & PARTICIPANT.PERMISSIONS.LOBBY_IGNORE) },
{ label: 'Can post messages and reactions', value: !!(permissions & PARTICIPANT.PERMISSIONS.CHAT) },
{ label: 'Enable the microphone', value: !!(permissions & PARTICIPANT.PERMISSIONS.PUBLISH_AUDIO) },
{ label: 'Enable the camera', value: !!(permissions & PARTICIPANT.PERMISSIONS.PUBLISH_VIDEO) },
{ label: 'Share the screen', value: !!(permissions & PARTICIPANT.PERMISSIONS.PUBLISH_SCREEN) },
]
// Act
const wrapper = await mountParticipantPermissionsEditor(participant)
// Assert
const permissionCheckboxes = getPermissionCheckboxes(wrapper)
for (const permission of permissionsMap) {
expect(wrapper.findComponent(PermissionsEditor).findComponent({ ref: permission.ref })
.props('modelValue')).toBe(permission.value)
const checkbox = getByText(permissionCheckboxes, permission.label)
expect(checkbox.props('modelValue')).toBe(permission.value)
}
}
@ -121,10 +129,12 @@ describe('ParticipantPermissionsEditor.vue', () => {
const wrapper = await mountParticipantPermissionsEditor(participant)
// Add a permission
await wrapper.findComponent(PermissionsEditor).setData({ lobbyIgnore: true })
const permissionCheckboxes = getPermissionCheckboxes(wrapper)
getByText(permissionCheckboxes, 'Skip the lobby').vm.$emit('update:modelValue', true)
await nextTick()
// Click the submit button
await wrapper.findComponent(PermissionsEditor).findComponent({ ref: 'submit' }).trigger('click')
await wrapper.findComponent(PermissionsEditor).find('form').trigger('submit')
expect(testStoreConfig.modules.participantsStore.actions.setPermissions).toHaveBeenCalledWith(
// The first argument is the context object
@ -144,10 +154,12 @@ describe('ParticipantPermissionsEditor.vue', () => {
const wrapper = mountParticipantPermissionsEditor(participant)
// Remove a permission
await wrapper.findComponent(PermissionsEditor).setData({ publishAudio: false })
const permissionCheckboxes = getPermissionCheckboxes(wrapper)
getByText(permissionCheckboxes, 'Enable the microphone').vm.$emit('update:modelValue', false)
await nextTick()
// Click the submit button
await wrapper.findComponent(PermissionsEditor).findComponent({ ref: 'submit' }).trigger('click')
await wrapper.findComponent(PermissionsEditor).find('form').trigger('submit')
expect(testStoreConfig.modules.participantsStore.actions.setPermissions).toHaveBeenCalledWith(
// The first argument is the context object