frontend: Enhance unit tests for WebComponent attributes, commands, events, and lifecycle handling
This commit is contained in:
parent
082aa8480c
commit
0368ab83e6
@ -1,6 +1,6 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
import { OpenViduMeet } from '../../src/components/OpenViduMeet';
|
||||
import { WebComponentProperty } from '@openvidu-meet/typings';
|
||||
import { OpenViduMeet } from '../../src/components/OpenViduMeet';
|
||||
import '../../src/index';
|
||||
|
||||
describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
@ -20,6 +20,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
// IFRAME SETUP
|
||||
// ==========================================
|
||||
describe('Iframe Configuration', () => {
|
||||
// Verify iframe 'allow' media permissions are set correctly for camera/microphone/display
|
||||
it('should render iframe with correct media permissions', () => {
|
||||
const iframe = component.shadowRoot?.querySelector('iframe');
|
||||
expect(iframe).not.toBeNull();
|
||||
@ -33,6 +34,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(allowAttribute).toContain('compute-pressure');
|
||||
});
|
||||
|
||||
// Ensure iframe element is present and is an HTMLIFrameElement in shadow DOM
|
||||
it('should have iframe ready in shadow DOM', () => {
|
||||
const iframe = component.shadowRoot?.querySelector('iframe');
|
||||
expect(iframe).toBeInstanceOf(HTMLIFrameElement);
|
||||
@ -43,6 +45,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
// REQUIRED ATTRIBUTES (room-url | recording-url)
|
||||
// ==========================================
|
||||
describe('Required Attributes', () => {
|
||||
// When no room or recording URL is provided, the component must not set the iframe src and should log an error
|
||||
it('should reject iframe src when both room-url and recording-url are missing', () => {
|
||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
@ -58,6 +61,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
consoleErrorSpy.mockRestore();
|
||||
});
|
||||
|
||||
// Setting `room-url` attribute must result in iframe src being set to that URL
|
||||
it('should set iframe src when room-url attribute is provided', () => {
|
||||
const roomUrl = 'https://example.com/room/testRoom-123';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, roomUrl);
|
||||
@ -68,6 +72,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(iframe?.src).toBe(roomUrl);
|
||||
});
|
||||
|
||||
// Setting `recording-url` attribute (without room-url) must set iframe src to recording URL
|
||||
it('should set iframe src when recording-url attribute is provided', () => {
|
||||
const recordingUrl = 'https://example.com/recordings/recording-abc-123';
|
||||
component.setAttribute(WebComponentProperty.RECORDING_URL, recordingUrl);
|
||||
@ -78,6 +83,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(iframe?.src).toBe(recordingUrl);
|
||||
});
|
||||
|
||||
// If both `room-url` and `recording-url` are present, `room-url` must take precedence
|
||||
it('should prefer room-url over recording-url when both are provided', () => {
|
||||
const roomUrl = 'https://example.com/room/testRoom-123';
|
||||
const recordingUrl = 'https://example.com/recordings/recording-abc-123';
|
||||
@ -91,6 +97,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(iframe?.src).toBe(roomUrl);
|
||||
});
|
||||
|
||||
// Extract and set target origin from `room-url`, propagate to managers
|
||||
it('should extract origin from room-url and set as target origin', () => {
|
||||
const domain = 'https://example.com';
|
||||
const roomUrl = `${domain}/room/testRoom-123?secret=123456`;
|
||||
@ -103,6 +110,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect((component as any).eventsManager.targetIframeOrigin).toBe(domain);
|
||||
});
|
||||
|
||||
// Extract and set target origin from `recording-url`, propagate to managers
|
||||
it('should extract origin from recording-url and set as target origin', () => {
|
||||
const domain = 'https://recordings.example.com';
|
||||
const recordingUrl = `${domain}/recordings/recording-abc-123`;
|
||||
@ -115,6 +123,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect((component as any).eventsManager.targetIframeOrigin).toBe(domain);
|
||||
});
|
||||
|
||||
// Updating the `room-url` attribute should update the iframe's src accordingly
|
||||
it('should update iframe src when room-url attribute changes', () => {
|
||||
const roomUrl1 = 'https://example.com/room/room-1';
|
||||
const roomUrl2 = 'https://example.com/room/room-2';
|
||||
@ -139,6 +148,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
describe('Optional Attributes as Query Parameters', () => {
|
||||
const baseRoomUrl = 'https://example.com/room/testRoom';
|
||||
|
||||
// Add `participant-name` attribute should append it as a query parameter to the iframe URL
|
||||
it('should add participant-name as query parameter', () => {
|
||||
const participantName = 'John Doe';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
@ -151,6 +161,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.PARTICIPANT_NAME)).toBe(participantName);
|
||||
});
|
||||
|
||||
// Add `e2ee-key` attribute should append it as a query parameter to the iframe URL
|
||||
it('should add e2ee-key as query parameter', () => {
|
||||
const e2eeKey = 'secret-encryption-key-123';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
@ -163,6 +174,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.E2EE_KEY)).toBe(e2eeKey);
|
||||
});
|
||||
|
||||
// Add `leave-redirect-url` attribute should append it as a query parameter to the iframe URL
|
||||
it('should add leave-redirect-url as query parameter', () => {
|
||||
const redirectUrl = 'https://example.com/goodbye';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
@ -175,6 +187,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.LEAVE_REDIRECT_URL)).toBe(redirectUrl);
|
||||
});
|
||||
|
||||
// Add `show-only-recordings` boolean-like attribute should be passed through as a query string
|
||||
it('should add show-only-recordings as query parameter', () => {
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
component.setAttribute(WebComponentProperty.SHOW_ONLY_RECORDINGS, 'true');
|
||||
@ -186,6 +199,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.SHOW_ONLY_RECORDINGS)).toBe('true');
|
||||
});
|
||||
|
||||
// Multiple optional attributes should all be included as query parameters
|
||||
it('should add multiple optional attributes as query parameters', () => {
|
||||
const participantName = 'Jane Smith';
|
||||
const e2eeKey = 'encryption-key-456';
|
||||
@ -208,6 +222,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.SHOW_ONLY_RECORDINGS)).toBe('false');
|
||||
});
|
||||
|
||||
// The base `room-url`/`recording-url` should not appear as query parameters
|
||||
it('should NOT add room-url or recording-url as query parameters', () => {
|
||||
const roomUrl = 'https://example.com/room/testRoom?secret=abc';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, roomUrl);
|
||||
@ -222,6 +237,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.has(WebComponentProperty.RECORDING_URL)).toBe(false);
|
||||
});
|
||||
|
||||
// Existing query parameters in the provided `room-url` must be preserved and merged with new ones
|
||||
it('should preserve existing query parameters in room-url', () => {
|
||||
const roomUrl = 'https://example.com/room/testRoom?secret=abc123&role=moderator';
|
||||
const participantName = 'Alice';
|
||||
@ -246,6 +262,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
// CUSTOM/UNKNOWN ATTRIBUTES
|
||||
// ==========================================
|
||||
describe('Custom Attributes as Query Parameters', () => {
|
||||
// Arbitrary custom attributes present on the element should be forwarded as query parameters
|
||||
it('should add custom attributes as query parameters', () => {
|
||||
const baseRoomUrl = 'https://example.com/room/testRoom';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
@ -261,6 +278,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get('another-param')).toBe('another-value');
|
||||
});
|
||||
|
||||
// Attribute names containing dashes or special characters should be preserved in query params
|
||||
it('should handle attribute names with special characters', () => {
|
||||
const baseRoomUrl = 'https://example.com/room/testRoom';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
@ -279,6 +297,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
// EDGE CASES
|
||||
// ==========================================
|
||||
describe('Edge Cases', () => {
|
||||
// Empty string attribute values should still be included as query parameters (empty value)
|
||||
it('should handle empty string attributes', () => {
|
||||
const baseRoomUrl = 'https://example.com/room/testRoom';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
@ -294,6 +313,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.PARTICIPANT_NAME)).toBe('');
|
||||
});
|
||||
|
||||
// Values with spaces and special characters must be encoded and decoded properly in URLSearchParams
|
||||
it('should handle special characters in attribute values', () => {
|
||||
const baseRoomUrl = 'https://example.com/room/testRoom';
|
||||
const specialName = 'User Name With Spaces & Special=Chars';
|
||||
@ -309,6 +329,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.PARTICIPANT_NAME)).toBe(specialName);
|
||||
});
|
||||
|
||||
// Updating attributes after initial render should change the iframe src and include new params
|
||||
it('should handle updating attributes after initial render', () => {
|
||||
const baseRoomUrl = 'https://example.com/room/testRoom';
|
||||
component.setAttribute(WebComponentProperty.ROOM_URL, baseRoomUrl);
|
||||
@ -328,6 +349,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect(url.searchParams.get(WebComponentProperty.PARTICIPANT_NAME)).toBe('Updated Name');
|
||||
});
|
||||
|
||||
// An invalid URL should be caught and logged without throwing uncaught exceptions
|
||||
it('should handle invalid URL gracefully', () => {
|
||||
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
@ -348,6 +370,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
// INTEGRATION TESTS
|
||||
// ==========================================
|
||||
describe('Integration Tests', () => {
|
||||
// Full scenario: room-url with existing params and several optional attributes should be merged correctly
|
||||
it('should handle complete real-world scenario with room-url and multiple attributes', () => {
|
||||
const roomUrl = 'https://meet.example.com/room/team-standup?secret=xyz789';
|
||||
const participantName = 'John Doe';
|
||||
@ -378,6 +401,7 @@ describe('OpenViduMeet WebComponent Attributes', () => {
|
||||
expect((component as any).targetIframeOrigin).toBe('https://meet.example.com');
|
||||
});
|
||||
|
||||
// Full scenario using `recording-url`: ensure base path and query params are correct and origin set
|
||||
it('should handle complete real-world scenario with recording-url', () => {
|
||||
const recordingUrl = 'https://recordings.example.com/view/rec-20231115-abc123';
|
||||
const participantName = 'Viewer';
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
import { WebComponentCommand, WebComponentEvent } from '@openvidu-meet/typings';
|
||||
import { CommandsManager } from '../../src/components/CommandsManager';
|
||||
import { OpenViduMeet } from '../../src/components/OpenViduMeet';
|
||||
import '../../src/index';
|
||||
import { WebComponentCommand, WebComponentEvent } from '@openvidu-meet/typings';
|
||||
|
||||
describe('OpenViduMeet WebComponent Commands', () => {
|
||||
let component: OpenViduMeet;
|
||||
@ -20,6 +20,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
// setTargetOrigin should update the internal target origin used when sending messages
|
||||
it('should update allowedOrigin when setAllowedOrigin is called', () => {
|
||||
const testOrigin = 'https://example.com';
|
||||
commandsManager.setTargetOrigin(testOrigin);
|
||||
@ -29,6 +30,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect((component as any).commandsManager.targetIframeOrigin).toBe(testOrigin);
|
||||
});
|
||||
|
||||
// initialize() should send an INITIALIZE command with the current window origin
|
||||
it('should send initialize command with initialize()', () => {
|
||||
const spy = jest.spyOn(commandsManager as any, 'sendMessage');
|
||||
|
||||
@ -45,6 +47,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// on() should register a listener on the component and invoke the callback when event is dispatched
|
||||
it('should subscribe and trigger event with on()', () => {
|
||||
const callback = jest.fn();
|
||||
commandsManager.on(component, WebComponentEvent.READY, callback);
|
||||
@ -55,6 +58,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect(callback).toHaveBeenCalledWith({ foo: 'bar' });
|
||||
});
|
||||
|
||||
// on() should ignore unsupported event types and not trigger callbacks
|
||||
it('should not subscribe unsupported events with on()', () => {
|
||||
const callback = jest.fn();
|
||||
commandsManager.on(component, 'not-supported' as any, callback);
|
||||
@ -65,6 +69,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// once() should register a handler that runs only the first time the event occurs
|
||||
it('should subscribe and trigger event only once with once()', () => {
|
||||
const callback = jest.fn();
|
||||
commandsManager.once(component, WebComponentEvent.READY, callback);
|
||||
@ -77,6 +82,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect(callback).toHaveBeenCalledWith(123);
|
||||
});
|
||||
|
||||
// off() with a specific handler should remove just that handler for the event
|
||||
it('should unsubscribe a specific handler with off()', () => {
|
||||
const callback = jest.fn();
|
||||
commandsManager.on(component, WebComponentEvent.READY, callback);
|
||||
@ -89,6 +95,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// off() without a handler should remove all handlers for the provided event
|
||||
it('should unsubscribe all handlers for an event with off()', () => {
|
||||
const cb1 = jest.fn();
|
||||
const cb2 = jest.fn();
|
||||
@ -104,6 +111,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect(cb2).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Component.leaveRoom() should delegate to commandsManager.leaveRoom and send a LEAVE_ROOM command
|
||||
it('should call commandsManager.leaveRoom when leaveRoom is called', () => {
|
||||
const leaveRoomSpy = jest.spyOn(component['commandsManager'], 'leaveRoom');
|
||||
const sendMessageSpy = jest.spyOn(commandsManager, 'sendMessage' as keyof CommandsManager);
|
||||
@ -114,6 +122,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect(sendMessageSpy).toHaveBeenCalledWith({ command: WebComponentCommand.LEAVE_ROOM });
|
||||
});
|
||||
|
||||
// Component.endMeeting() should delegate to commandsManager.endMeeting and send END_MEETING
|
||||
it('should call commandsManager.endMeeting when endMeeting is called', () => {
|
||||
const endMeetingSpy = jest.spyOn(component['commandsManager'], 'endMeeting');
|
||||
const sendMessageSpy = jest.spyOn(commandsManager, 'sendMessage' as keyof CommandsManager);
|
||||
@ -124,6 +133,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
expect(sendMessageSpy).toHaveBeenCalledWith({ command: WebComponentCommand.END_MEETING });
|
||||
});
|
||||
|
||||
// Component.kickParticipant(identity) should call manager and send KICK_PARTICIPANT with payload
|
||||
it('should call commandsManager.kickParticipant when kickParticipant is called', () => {
|
||||
const participantIdentity = 'test-participant';
|
||||
const kickParticipantSpy = jest.spyOn(component['commandsManager'], 'kickParticipant');
|
||||
@ -138,6 +148,7 @@ describe('OpenViduMeet WebComponent Commands', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// sendMessage should postMessage to iframe.contentWindow using the configured target origin
|
||||
it('should send message to iframe with correct origin', () => {
|
||||
// Mock iframe contentWindow and postMessage
|
||||
const mockPostMessage = jest.fn();
|
||||
|
||||
@ -20,6 +20,7 @@ describe('OpenViduMeet WebComponent Events', () => {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
// setTargetOrigin should update the target origin used to validate incoming messages
|
||||
it('should update allowedOrigin when setAllowedOrigin is called', () => {
|
||||
eventsManager.setTargetOrigin(testOrigin);
|
||||
|
||||
@ -28,6 +29,7 @@ describe('OpenViduMeet WebComponent Events', () => {
|
||||
expect((component as any).eventsManager.targetIframeOrigin).toBe(testOrigin);
|
||||
});
|
||||
|
||||
// connectedCallback should register a 'message' listener on window for postMessage events
|
||||
it('should register message event listener on connection', () => {
|
||||
const addEventListenerSpy = jest.spyOn(window, 'addEventListener');
|
||||
|
||||
@ -36,6 +38,7 @@ describe('OpenViduMeet WebComponent Events', () => {
|
||||
expect(addEventListenerSpy).toHaveBeenCalledWith('message', expect.any(Function));
|
||||
});
|
||||
|
||||
// Invalid message payloads should be ignored and not dispatched as component events
|
||||
it('should ignore invalid messages', () => {
|
||||
eventsManager.setTargetOrigin(testOrigin);
|
||||
const dispatchEventSpy = jest.spyOn(component, 'dispatchEvent');
|
||||
@ -48,6 +51,7 @@ describe('OpenViduMeet WebComponent Events', () => {
|
||||
expect(dispatchEventSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Messages from origins other than the configured target should be ignored
|
||||
it('should ignore messages from unknown origins', () => {
|
||||
const dispatchEventSpy = jest.spyOn(component, 'dispatchEvent');
|
||||
const event = new MessageEvent('message', {
|
||||
@ -59,6 +63,7 @@ describe('OpenViduMeet WebComponent Events', () => {
|
||||
expect(dispatchEventSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// Valid messages from the allowed origin should be converted to CustomEvent and dispatched
|
||||
it('should dispatch event for valid messages from allowed origin', () => {
|
||||
eventsManager.setTargetOrigin(testOrigin);
|
||||
const dispatchEventSpy = jest.spyOn(component, 'dispatchEvent');
|
||||
@ -76,6 +81,7 @@ describe('OpenViduMeet WebComponent Events', () => {
|
||||
);
|
||||
});
|
||||
|
||||
// Messages lacking an 'event' property should be ignored and not dispatch component events
|
||||
it('should ignore messages without an event property', () => {
|
||||
eventsManager.setTargetOrigin(testOrigin);
|
||||
const dispatchEventSpy = jest.spyOn(component, 'dispatchEvent');
|
||||
@ -88,6 +94,7 @@ describe('OpenViduMeet WebComponent Events', () => {
|
||||
expect(dispatchEventSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// cleanup() should remove the previously registered window 'message' listener
|
||||
it('should remove message event listener on cleanup', () => {
|
||||
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener');
|
||||
eventsManager.cleanup();
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { afterEach, beforeEach, describe, expect, it, jest } from '@jest/globals';
|
||||
import { WebComponentCommand } from '@openvidu-meet/typings';
|
||||
import { CommandsManager } from '../../src/components/CommandsManager';
|
||||
import { OpenViduMeet } from '../../src/components/OpenViduMeet';
|
||||
import '../../src/index';
|
||||
import { WebComponentCommand } from '@openvidu-meet/typings';
|
||||
|
||||
describe('OpenViduMeet Event Handling', () => {
|
||||
const testOrigin = window.location.origin;
|
||||
@ -22,6 +22,7 @@ describe('OpenViduMeet Event Handling', () => {
|
||||
document.body.innerHTML = '';
|
||||
});
|
||||
|
||||
// When a 'ready' message is received from the iframe origin, component should initialize via sendMessage
|
||||
it('should call sendMessage when ready event is received', () => {
|
||||
const sendMessageSpy = jest.spyOn(commandsManager, 'sendMessage' as keyof CommandsManager);
|
||||
|
||||
@ -44,6 +45,7 @@ describe('OpenViduMeet Event Handling', () => {
|
||||
expect(sendMessageSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
// Incoming messages should be converted into custom events and dispatched from the component
|
||||
it('should dispatch custom events when receiving messages', () => {
|
||||
// Create a spy for dispatchEvent
|
||||
const dispatchEventSpy = jest.spyOn(component, 'dispatchEvent');
|
||||
@ -72,6 +74,7 @@ describe('OpenViduMeet Event Handling', () => {
|
||||
expect((dispatchEventSpy.mock.calls[0][0] as any).detail.foo).toBe('bar');
|
||||
});
|
||||
|
||||
// disconnectedCallback should clear timeouts and call eventsManager.cleanup to free resources
|
||||
it('should clean up resources when removed from DOM', () => {
|
||||
// Set up spies
|
||||
const clearTimeoutSpy = jest.spyOn(window, 'clearTimeout');
|
||||
@ -88,6 +91,7 @@ describe('OpenViduMeet Event Handling', () => {
|
||||
expect(eventsCleanupSpy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
// showErrorState() should replace iframe with an error UI containing the provided message
|
||||
it('should re-render when showing error state', () => {
|
||||
document.body.appendChild(component);
|
||||
|
||||
@ -107,6 +111,7 @@ describe('OpenViduMeet Event Handling', () => {
|
||||
expect(errorContainer?.querySelector('.error-message')?.textContent).toBe('Test error');
|
||||
});
|
||||
|
||||
// updateIframeSrc() should merge existing room URL query params with element attributes
|
||||
it('should properly update iframe src with query parameters', () => {
|
||||
document.body.appendChild(component);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user