fix(communication): display project chat state and refresh room visibility

This commit is contained in:
2026-10-03 14:38:39 +02:00
parent fdcb9bfc1d
commit efa6ea90a2
6 changed files with 127 additions and 7 deletions

View File

@@ -35,6 +35,12 @@ function setup(api = fixture(), query = {}) {
const auth = vue.reactive({ user: { id: 'user-1' }, activeTenant: '1' })
const route = vue.reactive({ query })
const calls = [], toasts = [], timers = new Map()
const listeners = new Map()
const events = {
addEventListener: (event, handler) => listeners.set(event, handler),
removeEventListener: event => listeners.delete(event),
}
const document = { hidden: false, ...events }
let mount, unmount, timerId = 0
const scope = vue.effectScope()
const context = vm.createContext({
@@ -44,11 +50,11 @@ function setup(api = fixture(), query = {}) {
useRouter: () => ({ replace: async location => { route.query = location.query } }),
useNuxtApp: () => ({ $api: (url, options) => { calls.push({ url, options }); return api(url, options) } }),
onMounted: handler => { mount = handler }, onBeforeUnmount: handler => { unmount = handler },
window: { setInterval: handler => { timers.set(++timerId, handler); return timerId } },
clearInterval: id => timers.delete(id), document: { hidden: false },
window: { ...events, setInterval: handler => { timers.set(++timerId, handler); return timerId } },
clearInterval: id => timers.delete(id), document,
})
scope.run(() => vm.runInContext(source, context))
return { auth, route, calls, toasts, timers, mount, close: () => { unmount(); scope.stop() }, run: code => vm.runInContext(code, context) }
return { auth, route, calls, toasts, timers, listeners, document, mount, close: () => { unmount(); scope.stop() }, run: code => vm.runInContext(code, context) }
}
test('only member rooms enter normal chat, with separate keys, groups and unread counts', async t => {
@@ -235,6 +241,7 @@ test('unmount cancels both polling timers and ignores pending lists', async () =
pending.resolve({ rooms: [sharedRoom], invitations: [] })
await settle()
assert.equal(ui.timers.size, 0)
assert.equal(ui.listeners.size, 0)
assert.equal(ui.run('collaborationRooms.value.length'), 0)
assert.equal(ui.run('messages.value.length'), 0)
})
@@ -327,3 +334,25 @@ test('removing an active project from the permitted room list clears its message
assert.equal(ui.run('messages.value.length'), 0)
assert.equal(ui.run('members.value.length'), 0)
})
test('returning to chat immediately reflects a disabled or re-enabled project without waiting for polling', 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()
disabled = true
ui.document.hidden = true
ui.listeners.get('visibilitychange')()
await settle()
assert.equal(ui.run('activeRoom.value.key'), 'project_1')
ui.document.hidden = false
ui.listeners.get('visibilitychange')()
await settle()
assert.equal(ui.run('activeRoom.value'), null)
assert.equal(ui.run('messages.value.length'), 0)
disabled = false
ui.listeners.get('focus')()
await settle()
assert.equal(ui.run('groupedRooms.value.find(group => group.label === "Projekte").rooms[0].key'), 'project_1')
})