feat(communication): add room visibility and project chat controls
This commit is contained in:
@@ -19,6 +19,7 @@ function fixture(override = () => undefined) {
|
||||
const result = override(url, options)
|
||||
if (result !== undefined) return result
|
||||
if (url === '/api/collaboration') return { rooms: [sharedRoom], invitations: [], managedRooms: [{ id: 'admin-only' }] }
|
||||
if (url === '/api/communication/chat/room-preferences') return { hiddenRoomKeys: [] }
|
||||
if (url === '/api/communication/chat/rooms') return { rooms: [nativeRoom] }
|
||||
if (url.endsWith('/project-rooms') || url.endsWith('/direct-rooms')) return { rooms: [] }
|
||||
if (url.endsWith('/unread')) return { rooms: { allgemein: { count: 2 } } }
|
||||
@@ -237,3 +238,92 @@ test('unmount cancels both polling timers and ignores pending lists', async () =
|
||||
assert.equal(ui.run('collaborationRooms.value.length'), 0)
|
||||
assert.equal(ui.run('messages.value.length'), 0)
|
||||
})
|
||||
|
||||
test('hiding the active room persists the preference, switches away and allows restoring it', async t => {
|
||||
const ui = setup()
|
||||
t.after(ui.close)
|
||||
ui.mount()
|
||||
await settle()
|
||||
await ui.run('setRoomHidden(activeRoom.value, true)')
|
||||
assert.equal(ui.run('hiddenRooms.value[0].key'), 'allgemein')
|
||||
assert.equal(ui.run('visibleRooms.value.some(room => room.key === "allgemein")'), false)
|
||||
assert.equal(ui.run('isCollaboration.value'), true)
|
||||
assert.equal(ui.run('messages.value.length'), 0)
|
||||
const save = ui.calls.find(call => call.url.endsWith('/room-preferences') && call.options?.method === 'PUT')
|
||||
assert.equal(save.options.body.roomKey, 'allgemein')
|
||||
assert.equal(save.options.body.hidden, true)
|
||||
await ui.run('setRoomHidden(hiddenRooms.value[0], false)')
|
||||
assert.equal(ui.run('hiddenRooms.value.length'), 0)
|
||||
assert.equal(ui.run('activeRoomKey.value'), 'allgemein')
|
||||
assert.equal(ui.run('messages.value[0].body'), 'Interne Nachricht')
|
||||
})
|
||||
|
||||
test('saved hidden rooms stay hidden on reload, including federated room deep links', async t => {
|
||||
const ui = setup(fixture(url => url.endsWith('/room-preferences') ? { hiddenRoomKeys: ['collaboration:shared-room', 'allgemein'] } : undefined), { room: 'collaboration:shared-room' })
|
||||
t.after(ui.close)
|
||||
ui.mount()
|
||||
await settle()
|
||||
assert.equal(ui.run('visibleRooms.value.length'), 0)
|
||||
assert.equal(ui.run('activeRoom.value'), null)
|
||||
assert.equal(ui.calls.some(({ url }) => /\/rooms\/.+\/(messages|read)/.test(url)), false)
|
||||
await ui.run('selectRoom(decoratedRooms.value[0])')
|
||||
assert.equal(ui.run('activeRoom.value'), null)
|
||||
await ui.run('setRoomHidden(hiddenRooms.value.find(r => r.source === "collaboration"), false)')
|
||||
assert.equal(ui.run('isCollaboration.value'), true)
|
||||
})
|
||||
|
||||
test('preference save failure leaves the active conversation and list unchanged', async t => {
|
||||
const ui = setup(fixture((url, options) => {
|
||||
if (url.endsWith('/room-preferences') && options?.method === 'PUT') throw { data: { message: 'Speichern fehlgeschlagen' } }
|
||||
}))
|
||||
t.after(ui.close)
|
||||
ui.mount()
|
||||
await settle()
|
||||
await ui.run('setRoomHidden(activeRoom.value, true)')
|
||||
assert.equal(ui.run('hiddenRooms.value.length'), 0)
|
||||
assert.equal(ui.run('activeRoomKey.value'), 'allgemein')
|
||||
assert.equal(ui.run('messages.value[0].body'), 'Interne Nachricht')
|
||||
assert.equal(ui.toasts.at(-1).title, 'Speichern fehlgeschlagen')
|
||||
})
|
||||
|
||||
test('pending hide operations cannot change a new tenant, and hiding the last room clears its content', async t => {
|
||||
const pending = deferred()
|
||||
const ui = setup(fixture((url, options) => {
|
||||
if (url.endsWith('/room-preferences') && options?.method === 'PUT') return pending.promise
|
||||
}))
|
||||
t.after(ui.close)
|
||||
ui.mount()
|
||||
await settle()
|
||||
const hiding = ui.run('setRoomHidden(activeRoom.value, true)')
|
||||
ui.auth.activeTenant = '2'
|
||||
await settle()
|
||||
pending.resolve({ hidden: true, roomKey: 'allgemein' })
|
||||
await hiding
|
||||
assert.equal(ui.run('hiddenRoomKeys.value.length'), 0)
|
||||
assert.equal(ui.run('activeRoomKey.value'), 'allgemein')
|
||||
const single = setup(fixture(url => url === '/api/collaboration' ? { rooms: [], invitations: [] } : undefined))
|
||||
t.after(single.close)
|
||||
single.mount()
|
||||
await settle()
|
||||
await single.run('setRoomHidden(activeRoom.value, true)')
|
||||
await settle()
|
||||
assert.equal(single.run('activeRoom.value'), null)
|
||||
assert.equal(single.run('messages.value.length'), 0)
|
||||
assert.equal(single.run('members.value.length'), 0)
|
||||
assert.equal(single.run('visibleRooms.value.length'), 0)
|
||||
})
|
||||
|
||||
test('removing an active project from the permitted room list clears its messages and members', async t => {
|
||||
let disabled = false
|
||||
const ui = setup(fixture(url => url.endsWith('/project-rooms') ? { rooms: disabled ? [] : [{ key: 'project_1', exists: true, type: 'project' }] } : undefined), { room: 'project_1' })
|
||||
t.after(ui.close)
|
||||
ui.mount()
|
||||
await settle()
|
||||
assert.equal(ui.run('messages.value.length'), 1)
|
||||
disabled = true
|
||||
await ui.run('loadRoomLists()')
|
||||
await settle()
|
||||
assert.equal(ui.run('activeRoom.value'), null)
|
||||
assert.equal(ui.run('messages.value.length'), 0)
|
||||
assert.equal(ui.run('members.value.length'), 0)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user