This repository has been archived on 2026-02-15. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
breakpilot-pwa/backend/frontend/tests/studio-panels.test.js
Benjamin Admin 21a844cb8a fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.

This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).

Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 09:51:32 +01:00

850 lines
25 KiB
JavaScript

/**
* Unit Tests for Studio Panel Navigation
*
* These tests verify the panel navigation functions in studio.js
* Run with: npm test (requires Jest and jsdom)
*/
// Mock DOM elements
const mockElements = {};
function createMockElement(id, display = 'none') {
return {
id,
style: { display },
classList: {
_classes: new Set(),
add(cls) { this._classes.add(cls); },
remove(cls) { this._classes.delete(cls); },
contains(cls) { return this._classes.has(cls); }
}
};
}
// Setup mock DOM before tests
function setupMockDOM() {
mockElements['panel-compare'] = createMockElement('panel-compare', 'flex');
mockElements['panel-tiles'] = createMockElement('panel-tiles');
mockElements['panel-messenger'] = createMockElement('panel-messenger');
mockElements['panel-video'] = createMockElement('panel-video');
mockElements['panel-correction'] = createMockElement('panel-correction');
mockElements['panel-letters'] = createMockElement('panel-letters');
mockElements['studio-sub-menu'] = createMockElement('studio-sub-menu', 'flex');
mockElements['sub-worksheets'] = createMockElement('sub-worksheets');
mockElements['sub-tiles'] = createMockElement('sub-tiles');
mockElements['sidebar-studio'] = createMockElement('sidebar-studio');
mockElements['sidebar-correction'] = createMockElement('sidebar-correction');
mockElements['sidebar-messenger'] = createMockElement('sidebar-messenger');
mockElements['sidebar-video'] = createMockElement('sidebar-video');
mockElements['sidebar-letters'] = createMockElement('sidebar-letters');
global.document = {
getElementById: (id) => mockElements[id] || null,
querySelectorAll: (selector) => {
if (selector === '.sidebar-item') {
return Object.values(mockElements).filter(el => el.id.startsWith('sidebar-'));
}
if (selector === '.sidebar-sub-item') {
return Object.values(mockElements).filter(el => el.id.startsWith('sub-'));
}
return [];
}
};
global.console = { log: jest.fn(), error: jest.fn() };
}
// Import functions (in real setup, these would be imported from studio.js)
function hideAllPanels() {
const panels = [
'panel-compare',
'panel-tiles',
'panel-correction',
'panel-letters',
'panel-messenger',
'panel-video'
];
panels.forEach(panelId => {
const panel = document.getElementById(panelId);
if (panel) {
panel.style.display = 'none';
}
});
}
function hideStudioSubMenu() {
const subMenu = document.getElementById('studio-sub-menu');
if (subMenu) {
subMenu.style.display = 'none';
}
}
function updateSidebarActive(activeSidebarId) {
document.querySelectorAll('.sidebar-item').forEach(item => {
item.classList.remove('active');
});
const activeItem = document.getElementById(activeSidebarId);
if (activeItem) {
activeItem.classList.add('active');
}
}
function updateSubNavActive(activeSubId) {
document.querySelectorAll('.sidebar-sub-item').forEach(item => {
item.classList.remove('active');
});
const activeItem = document.getElementById(activeSubId);
if (activeItem) {
activeItem.classList.add('active');
}
}
function showWorksheetTab() {
const panelCompare = document.getElementById('panel-compare');
const panelTiles = document.getElementById('panel-tiles');
if (panelCompare) panelCompare.style.display = 'flex';
if (panelTiles) panelTiles.style.display = 'none';
updateSubNavActive('sub-worksheets');
}
function showTilesTab() {
const panelCompare = document.getElementById('panel-compare');
const panelTiles = document.getElementById('panel-tiles');
if (panelCompare) panelCompare.style.display = 'none';
if (panelTiles) panelTiles.style.display = 'flex';
updateSubNavActive('sub-tiles');
}
function showStudioPanel() {
hideAllPanels();
const subMenu = document.getElementById('studio-sub-menu');
if (subMenu) {
subMenu.style.display = 'flex';
}
showWorksheetTab();
updateSidebarActive('sidebar-studio');
}
function showCorrectionPanel() {
hideAllPanels();
hideStudioSubMenu();
const correctionPanel = document.getElementById('panel-correction');
if (correctionPanel) {
correctionPanel.style.display = 'flex';
}
updateSidebarActive('sidebar-correction');
}
function showMessengerPanel() {
hideAllPanels();
hideStudioSubMenu();
const messengerPanel = document.getElementById('panel-messenger');
if (messengerPanel) {
messengerPanel.style.display = 'flex';
}
updateSidebarActive('sidebar-messenger');
}
function showVideoPanel() {
hideAllPanels();
hideStudioSubMenu();
const videoPanel = document.getElementById('panel-video');
if (videoPanel) {
videoPanel.style.display = 'flex';
}
updateSidebarActive('sidebar-video');
}
// Legacy alias
function showCommunicationPanel() {
showMessengerPanel();
}
function showLettersPanel() {
hideAllPanels();
hideStudioSubMenu();
const lettersPanel = document.getElementById('panel-letters');
if (lettersPanel) {
lettersPanel.style.display = 'flex';
}
updateSidebarActive('sidebar-letters');
}
// Tests
describe('Panel Navigation Functions', () => {
beforeEach(() => {
setupMockDOM();
});
describe('hideAllPanels', () => {
test('should hide all panels', () => {
// Set some panels to visible
mockElements['panel-compare'].style.display = 'flex';
mockElements['panel-tiles'].style.display = 'flex';
hideAllPanels();
expect(mockElements['panel-compare'].style.display).toBe('none');
expect(mockElements['panel-tiles'].style.display).toBe('none');
expect(mockElements['panel-messenger'].style.display).toBe('none');
expect(mockElements['panel-video'].style.display).toBe('none');
expect(mockElements['panel-correction'].style.display).toBe('none');
expect(mockElements['panel-letters'].style.display).toBe('none');
});
});
describe('hideStudioSubMenu', () => {
test('should hide studio sub-menu', () => {
mockElements['studio-sub-menu'].style.display = 'flex';
hideStudioSubMenu();
expect(mockElements['studio-sub-menu'].style.display).toBe('none');
});
});
describe('showWorksheetTab', () => {
test('should show panel-compare and hide panel-tiles', () => {
mockElements['panel-tiles'].style.display = 'flex';
showWorksheetTab();
expect(mockElements['panel-compare'].style.display).toBe('flex');
expect(mockElements['panel-tiles'].style.display).toBe('none');
});
test('should activate sub-worksheets in sub-navigation', () => {
showWorksheetTab();
expect(mockElements['sub-worksheets'].classList.contains('active')).toBe(true);
expect(mockElements['sub-tiles'].classList.contains('active')).toBe(false);
});
});
describe('showTilesTab', () => {
test('should show panel-tiles and hide panel-compare', () => {
mockElements['panel-compare'].style.display = 'flex';
showTilesTab();
expect(mockElements['panel-compare'].style.display).toBe('none');
expect(mockElements['panel-tiles'].style.display).toBe('flex');
});
test('should activate sub-tiles in sub-navigation', () => {
showTilesTab();
expect(mockElements['sub-tiles'].classList.contains('active')).toBe(true);
expect(mockElements['sub-worksheets'].classList.contains('active')).toBe(false);
});
});
describe('showStudioPanel', () => {
test('should hide all panels first', () => {
mockElements['panel-correction'].style.display = 'flex';
showStudioPanel();
expect(mockElements['panel-correction'].style.display).toBe('none');
});
test('should show sub-menu', () => {
mockElements['studio-sub-menu'].style.display = 'none';
showStudioPanel();
expect(mockElements['studio-sub-menu'].style.display).toBe('flex');
});
test('should show worksheet tab by default', () => {
showStudioPanel();
expect(mockElements['panel-compare'].style.display).toBe('flex');
expect(mockElements['panel-tiles'].style.display).toBe('none');
});
test('should activate sidebar-studio', () => {
showStudioPanel();
expect(mockElements['sidebar-studio'].classList.contains('active')).toBe(true);
});
});
describe('showCorrectionPanel', () => {
test('should hide all panels and show correction panel', () => {
mockElements['panel-compare'].style.display = 'flex';
showCorrectionPanel();
expect(mockElements['panel-compare'].style.display).toBe('none');
expect(mockElements['panel-correction'].style.display).toBe('flex');
});
test('should hide studio sub-menu', () => {
mockElements['studio-sub-menu'].style.display = 'flex';
showCorrectionPanel();
expect(mockElements['studio-sub-menu'].style.display).toBe('none');
});
test('should activate sidebar-correction', () => {
showCorrectionPanel();
expect(mockElements['sidebar-correction'].classList.contains('active')).toBe(true);
});
});
describe('showMessengerPanel', () => {
test('should hide all panels and show messenger panel', () => {
mockElements['panel-compare'].style.display = 'flex';
showMessengerPanel();
expect(mockElements['panel-compare'].style.display).toBe('none');
expect(mockElements['panel-messenger'].style.display).toBe('flex');
});
test('should hide studio sub-menu', () => {
mockElements['studio-sub-menu'].style.display = 'flex';
showMessengerPanel();
expect(mockElements['studio-sub-menu'].style.display).toBe('none');
});
test('should activate sidebar-messenger', () => {
showMessengerPanel();
expect(mockElements['sidebar-messenger'].classList.contains('active')).toBe(true);
});
});
describe('showVideoPanel', () => {
test('should hide all panels and show video panel', () => {
mockElements['panel-compare'].style.display = 'flex';
showVideoPanel();
expect(mockElements['panel-compare'].style.display).toBe('none');
expect(mockElements['panel-video'].style.display).toBe('flex');
});
test('should hide studio sub-menu', () => {
mockElements['studio-sub-menu'].style.display = 'flex';
showVideoPanel();
expect(mockElements['studio-sub-menu'].style.display).toBe('none');
});
test('should activate sidebar-video', () => {
showVideoPanel();
expect(mockElements['sidebar-video'].classList.contains('active')).toBe(true);
});
});
describe('showLettersPanel', () => {
test('should hide all panels and show letters panel', () => {
mockElements['panel-compare'].style.display = 'flex';
showLettersPanel();
expect(mockElements['panel-compare'].style.display).toBe('none');
expect(mockElements['panel-letters'].style.display).toBe('flex');
});
test('should hide studio sub-menu', () => {
mockElements['studio-sub-menu'].style.display = 'flex';
showLettersPanel();
expect(mockElements['studio-sub-menu'].style.display).toBe('none');
});
});
});
describe('Sidebar Active State', () => {
beforeEach(() => {
setupMockDOM();
});
test('updateSidebarActive should remove active from all items', () => {
mockElements['sidebar-studio'].classList.add('active');
mockElements['sidebar-correction'].classList.add('active');
updateSidebarActive('sidebar-letters');
expect(mockElements['sidebar-studio'].classList.contains('active')).toBe(false);
expect(mockElements['sidebar-correction'].classList.contains('active')).toBe(false);
expect(mockElements['sidebar-letters'].classList.contains('active')).toBe(true);
});
});
describe('Sub-Navigation Active State', () => {
beforeEach(() => {
setupMockDOM();
});
test('updateSubNavActive should toggle active state correctly', () => {
mockElements['sub-worksheets'].classList.add('active');
updateSubNavActive('sub-tiles');
expect(mockElements['sub-worksheets'].classList.contains('active')).toBe(false);
expect(mockElements['sub-tiles'].classList.contains('active')).toBe(true);
});
});
// ============================================
// JITSI VIDEOKONFERENZ MODULE TESTS
// ============================================
// Mock additional elements for Jitsi tests
function setupJitsiMockDOM() {
setupMockDOM();
// Jitsi-specific elements
mockElements['meeting-name'] = {
id: 'meeting-name',
value: 'Test Meeting',
style: { display: 'block' }
};
mockElements['jitsi-container'] = createMockElement('jitsi-container');
mockElements['jitsi-container'].innerHTML = '';
mockElements['jitsi-placeholder'] = createMockElement('jitsi-placeholder', 'flex');
mockElements['jitsi-controls'] = createMockElement('jitsi-controls');
mockElements['btn-mute'] = createMockElement('btn-mute');
mockElements['btn-mute'].textContent = '🎤 Stumm';
mockElements['btn-video'] = createMockElement('btn-video');
mockElements['btn-video'].textContent = '📹 Video aus';
mockElements['meeting-link-display'] = createMockElement('meeting-link-display');
mockElements['meeting-url'] = {
id: 'meeting-url',
textContent: '',
style: { display: 'block' }
};
// Override document methods for extended elements
global.document.getElementById = (id) => mockElements[id] || null;
global.document.createElement = (tag) => {
return {
tagName: tag.toUpperCase(),
style: {},
setAttribute: jest.fn(),
appendChild: jest.fn()
};
};
// Mock clipboard API
global.navigator = {
clipboard: {
writeText: jest.fn().mockResolvedValue(undefined)
}
};
// Mock alert
global.alert = jest.fn();
}
// Jitsi module state
let currentJitsiMeetingUrl = null;
let jitsiMicMuted = false;
let jitsiVideoOff = false;
// Jitsi functions (copied from studio.js for testing)
async function startInstantMeeting() {
console.log('Starting instant meeting...');
const meetingNameEl = document.getElementById('meeting-name');
const meetingName = meetingNameEl?.value || '';
try {
const roomId = 'bp-' + Date.now().toString(36) + Math.random().toString(36).substr(2, 5);
const jitsiDomain = 'meet.jit.si';
currentJitsiMeetingUrl = `https://${jitsiDomain}/${roomId}`;
const container = document.getElementById('jitsi-container');
const placeholder = document.getElementById('jitsi-placeholder');
const controls = document.getElementById('jitsi-controls');
const linkDisplay = document.getElementById('meeting-link-display');
const urlDisplay = document.getElementById('meeting-url');
if (placeholder) placeholder.style.display = 'none';
if (controls) controls.style.display = 'flex';
if (linkDisplay) linkDisplay.style.display = 'flex';
if (urlDisplay) urlDisplay.textContent = currentJitsiMeetingUrl;
if (container) {
const iframe = document.createElement('iframe');
iframe.setAttribute('src', `${currentJitsiMeetingUrl}#config.prejoinPageEnabled=false`);
iframe.setAttribute('allow', 'camera; microphone; fullscreen; display-capture');
container.appendChild(iframe);
}
return { success: true, url: currentJitsiMeetingUrl };
} catch (error) {
console.error('Error starting meeting:', error);
return { success: false, error };
}
}
function leaveJitsiMeeting() {
const container = document.getElementById('jitsi-container');
const placeholder = document.getElementById('jitsi-placeholder');
const controls = document.getElementById('jitsi-controls');
const linkDisplay = document.getElementById('meeting-link-display');
if (container) container.innerHTML = '';
if (placeholder) placeholder.style.display = 'flex';
if (controls) controls.style.display = 'none';
if (linkDisplay) linkDisplay.style.display = 'none';
currentJitsiMeetingUrl = null;
jitsiMicMuted = false;
jitsiVideoOff = false;
}
function toggleJitsiMute() {
jitsiMicMuted = !jitsiMicMuted;
const btn = document.getElementById('btn-mute');
if (btn) {
btn.textContent = jitsiMicMuted ? '🔇 Unmute' : '🎤 Stumm';
}
return jitsiMicMuted;
}
function toggleJitsiVideo() {
jitsiVideoOff = !jitsiVideoOff;
const btn = document.getElementById('btn-video');
if (btn) {
btn.textContent = jitsiVideoOff ? '📷 Video an' : '📹 Video aus';
}
return jitsiVideoOff;
}
async function copyMeetingLink() {
if (currentJitsiMeetingUrl) {
await navigator.clipboard.writeText(currentJitsiMeetingUrl);
alert('Meeting-Link wurde kopiert!');
return true;
}
return false;
}
function joinScheduledMeeting(meetingId) {
console.log('Joining scheduled meeting:', meetingId);
const jitsiDomain = 'meet.jit.si';
currentJitsiMeetingUrl = `https://${jitsiDomain}/${meetingId}`;
const container = document.getElementById('jitsi-container');
const placeholder = document.getElementById('jitsi-placeholder');
const controls = document.getElementById('jitsi-controls');
if (placeholder) placeholder.style.display = 'none';
if (controls) controls.style.display = 'flex';
if (container) {
const iframe = document.createElement('iframe');
iframe.setAttribute('src', `${currentJitsiMeetingUrl}#config.prejoinPageEnabled=false`);
container.appendChild(iframe);
}
return currentJitsiMeetingUrl;
}
describe('Jitsi Videokonferenz Module', () => {
beforeEach(() => {
setupJitsiMockDOM();
currentJitsiMeetingUrl = null;
jitsiMicMuted = false;
jitsiVideoOff = false;
});
describe('startInstantMeeting', () => {
test('should create a meeting URL with bp- prefix', async () => {
const result = await startInstantMeeting();
expect(result.success).toBe(true);
expect(result.url).toMatch(/^https:\/\/meet\.jit\.si\/bp-/);
expect(currentJitsiMeetingUrl).toBe(result.url);
});
test('should hide placeholder and show controls', async () => {
await startInstantMeeting();
expect(mockElements['jitsi-placeholder'].style.display).toBe('none');
expect(mockElements['jitsi-controls'].style.display).toBe('flex');
expect(mockElements['meeting-link-display'].style.display).toBe('flex');
});
test('should update meeting URL display', async () => {
await startInstantMeeting();
expect(mockElements['meeting-url'].textContent).toMatch(/^https:\/\/meet\.jit\.si\/bp-/);
});
});
describe('leaveJitsiMeeting', () => {
test('should reset all meeting state', async () => {
await startInstantMeeting();
expect(currentJitsiMeetingUrl).not.toBeNull();
leaveJitsiMeeting();
expect(currentJitsiMeetingUrl).toBeNull();
expect(jitsiMicMuted).toBe(false);
expect(jitsiVideoOff).toBe(false);
});
test('should show placeholder and hide controls', async () => {
await startInstantMeeting();
leaveJitsiMeeting();
expect(mockElements['jitsi-placeholder'].style.display).toBe('flex');
expect(mockElements['jitsi-controls'].style.display).toBe('none');
expect(mockElements['meeting-link-display'].style.display).toBe('none');
});
});
describe('toggleJitsiMute', () => {
test('should toggle mute state', () => {
expect(jitsiMicMuted).toBe(false);
const result1 = toggleJitsiMute();
expect(result1).toBe(true);
expect(jitsiMicMuted).toBe(true);
const result2 = toggleJitsiMute();
expect(result2).toBe(false);
expect(jitsiMicMuted).toBe(false);
});
test('should update button text', () => {
toggleJitsiMute();
expect(mockElements['btn-mute'].textContent).toBe('🔇 Unmute');
toggleJitsiMute();
expect(mockElements['btn-mute'].textContent).toBe('🎤 Stumm');
});
});
describe('toggleJitsiVideo', () => {
test('should toggle video state', () => {
expect(jitsiVideoOff).toBe(false);
const result1 = toggleJitsiVideo();
expect(result1).toBe(true);
expect(jitsiVideoOff).toBe(true);
const result2 = toggleJitsiVideo();
expect(result2).toBe(false);
expect(jitsiVideoOff).toBe(false);
});
test('should update button text', () => {
toggleJitsiVideo();
expect(mockElements['btn-video'].textContent).toBe('📷 Video an');
toggleJitsiVideo();
expect(mockElements['btn-video'].textContent).toBe('📹 Video aus');
});
});
describe('copyMeetingLink', () => {
test('should copy meeting URL to clipboard when active', async () => {
await startInstantMeeting();
const result = await copyMeetingLink();
expect(result).toBe(true);
expect(navigator.clipboard.writeText).toHaveBeenCalledWith(currentJitsiMeetingUrl);
expect(alert).toHaveBeenCalledWith('Meeting-Link wurde kopiert!');
});
test('should return false when no active meeting', async () => {
const result = await copyMeetingLink();
expect(result).toBe(false);
expect(navigator.clipboard.writeText).not.toHaveBeenCalled();
});
});
describe('joinScheduledMeeting', () => {
test('should create meeting URL with provided ID', () => {
const meetingId = 'scheduled-meeting-123';
const url = joinScheduledMeeting(meetingId);
expect(url).toBe(`https://meet.jit.si/${meetingId}`);
expect(currentJitsiMeetingUrl).toBe(url);
});
test('should hide placeholder and show controls', () => {
joinScheduledMeeting('test-meeting');
expect(mockElements['jitsi-placeholder'].style.display).toBe('none');
expect(mockElements['jitsi-controls'].style.display).toBe('flex');
});
});
});
// ============================================
// MATRIX MESSENGER MODULE TESTS
// ============================================
// Messenger stub functions (copied from studio.js)
function startQuickMeeting() {
showVideoPanel();
// In real implementation: setTimeout(() => startInstantMeeting(), 100);
return 'video-panel-shown';
}
function createClassRoom() {
console.log('Creating class room...');
alert('Klassenraum-Erstellung wird in Phase 2 implementiert.');
return 'stub';
}
function scheduleParentMeeting() {
console.log('Scheduling parent meeting...');
alert('Elterngespräch-Planung wird in Phase 2 implementiert.');
return 'stub';
}
function selectRoom(roomId) {
console.log('Selecting room:', roomId);
// Stub: Would load room messages
return roomId;
}
function sendMessage() {
const input = document.getElementById('messenger-input');
const message = input?.value?.trim();
if (!message) {
console.log('Empty message, not sending');
return false;
}
console.log('Sending message:', message);
// Stub: Would send via Matrix API
if (input) input.value = '';
return true;
}
// Setup Messenger mock DOM
function setupMessengerMockDOM() {
setupMockDOM();
mockElements['messenger-input'] = {
id: 'messenger-input',
value: '',
style: { display: 'block' }
};
}
describe('Matrix Messenger Module', () => {
beforeEach(() => {
setupMessengerMockDOM();
});
describe('startQuickMeeting', () => {
test('should show video panel', () => {
const result = startQuickMeeting();
expect(result).toBe('video-panel-shown');
expect(mockElements['panel-video'].style.display).toBe('flex');
});
});
describe('createClassRoom', () => {
test('should return stub indicator', () => {
const result = createClassRoom();
expect(result).toBe('stub');
expect(alert).toHaveBeenCalledWith('Klassenraum-Erstellung wird in Phase 2 implementiert.');
});
});
describe('scheduleParentMeeting', () => {
test('should return stub indicator', () => {
const result = scheduleParentMeeting();
expect(result).toBe('stub');
expect(alert).toHaveBeenCalledWith('Elterngespräch-Planung wird in Phase 2 implementiert.');
});
});
describe('selectRoom', () => {
test('should return room ID', () => {
const roomId = 'room-123';
const result = selectRoom(roomId);
expect(result).toBe(roomId);
});
});
describe('sendMessage', () => {
test('should return false for empty message', () => {
mockElements['messenger-input'].value = '';
const result = sendMessage();
expect(result).toBe(false);
});
test('should return false for whitespace-only message', () => {
mockElements['messenger-input'].value = ' ';
const result = sendMessage();
expect(result).toBe(false);
});
test('should return true and clear input for valid message', () => {
mockElements['messenger-input'].value = 'Hello World';
const result = sendMessage();
expect(result).toBe(true);
expect(mockElements['messenger-input'].value).toBe('');
});
});
});
// ============================================
// INTEGRATION TESTS
// ============================================
describe('Panel Integration', () => {
beforeEach(() => {
setupJitsiMockDOM();
});
test('switching from messenger to video should preserve panel state', () => {
showMessengerPanel();
expect(mockElements['panel-messenger'].style.display).toBe('flex');
expect(mockElements['sidebar-messenger'].classList.contains('active')).toBe(true);
showVideoPanel();
expect(mockElements['panel-messenger'].style.display).toBe('none');
expect(mockElements['panel-video'].style.display).toBe('flex');
expect(mockElements['sidebar-messenger'].classList.contains('active')).toBe(false);
expect(mockElements['sidebar-video'].classList.contains('active')).toBe(true);
});
test('video panel should be accessible via startQuickMeeting', () => {
showMessengerPanel();
startQuickMeeting();
expect(mockElements['panel-video'].style.display).toBe('flex');
expect(mockElements['sidebar-video'].classList.contains('active')).toBe(true);
});
});