test: add comprehensive WebRTC test suite
Add test coverage for WebRTC signaling and detection: Backend tests (socket-webrtc.test.js): - WebRTC offer/answer relay via Socket.IO - ICE candidate exchange - Authorization checks for match access - Full WebRTC signaling flow - All 7 tests passing Frontend tests (ready for test runner): - webrtcDetection.test.js: Browser WebRTC capability detection - WebRTCWarning.test.jsx: Warning component rendering and interaction Note: Frontend tests require test runner setup (e.g., Vitest)
This commit is contained in:
195
frontend/src/components/__tests__/WebRTCWarning.test.jsx
Normal file
195
frontend/src/components/__tests__/WebRTCWarning.test.jsx
Normal file
@@ -0,0 +1,195 @@
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import WebRTCWarning from '../WebRTCWarning';
|
||||
|
||||
describe('WebRTCWarning Component', () => {
|
||||
describe('Rendering', () => {
|
||||
it('should not render when WebRTC is working correctly', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: true,
|
||||
error: null,
|
||||
};
|
||||
|
||||
const { container } = render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
it('should render warning when RTCPeerConnection not supported', () => {
|
||||
const detection = {
|
||||
supported: false,
|
||||
hasIceCandidates: false,
|
||||
error: 'RTCPeerConnection not available',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
expect(screen.getByText('WebRTC Not Supported')).toBeInTheDocument();
|
||||
expect(screen.getByText(/does not support WebRTC/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render warning when ICE candidates blocked', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'ICE candidates not generated',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
expect(screen.getByText('WebRTC Blocked')).toBeInTheDocument();
|
||||
expect(screen.getByText(/blocked by browser settings/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show fix suggestions for unsupported browser', () => {
|
||||
const detection = {
|
||||
supported: false,
|
||||
hasIceCandidates: false,
|
||||
error: 'RTCPeerConnection not available',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
expect(screen.getByText(/Update your browser/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Try using Chrome, Firefox, or Edge/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show fix suggestions for blocked WebRTC', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'ICE candidates not generated',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
expect(screen.getByText(/privacy settings/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/VPN extensions/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/incognito/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show fallback option message', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'ICE candidates not generated',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
expect(screen.getByText(/You can still send video links/i)).toBeInTheDocument();
|
||||
expect(screen.getByText(/Google Drive, Dropbox/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Dismiss Functionality', () => {
|
||||
it('should call onDismiss callback when dismiss button clicked', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'blocked',
|
||||
};
|
||||
const mockOnDismiss = jest.fn();
|
||||
|
||||
render(<WebRTCWarning detection={detection} onDismiss={mockOnDismiss} />);
|
||||
|
||||
const dismissButton = screen.getByLabelText('Dismiss warning');
|
||||
fireEvent.click(dismissButton);
|
||||
|
||||
expect(mockOnDismiss).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('should hide warning after dismissal', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'blocked',
|
||||
};
|
||||
|
||||
const { container } = render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
// Should be visible initially
|
||||
expect(screen.getByText('WebRTC Blocked')).toBeInTheDocument();
|
||||
|
||||
// Click dismiss
|
||||
const dismissButton = screen.getByLabelText('Dismiss warning');
|
||||
fireEvent.click(dismissButton);
|
||||
|
||||
// Should be hidden
|
||||
expect(container.firstChild).toBeNull();
|
||||
});
|
||||
|
||||
it('should work without onDismiss callback', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'blocked',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
const dismissButton = screen.getByLabelText('Dismiss warning');
|
||||
|
||||
// Should not throw error
|
||||
expect(() => fireEvent.click(dismissButton)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Different Error Messages', () => {
|
||||
it('should show generic error when error is unknown', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'Some unknown error',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
expect(screen.getByText('WebRTC Error')).toBeInTheDocument();
|
||||
expect(screen.getByText(/Some unknown error/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should handle null error gracefully', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: null,
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
// Should still show warning for blocked ICE candidates
|
||||
expect(screen.getByText('WebRTC Blocked')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Accessibility', () => {
|
||||
it('should have accessible dismiss button', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'blocked',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
const dismissButton = screen.getByLabelText('Dismiss warning');
|
||||
expect(dismissButton).toBeInTheDocument();
|
||||
expect(dismissButton).toHaveAttribute('aria-label', 'Dismiss warning');
|
||||
});
|
||||
|
||||
it('should have proper heading structure', () => {
|
||||
const detection = {
|
||||
supported: true,
|
||||
hasIceCandidates: false,
|
||||
error: 'blocked',
|
||||
};
|
||||
|
||||
render(<WebRTCWarning detection={detection} />);
|
||||
|
||||
const heading = screen.getByRole('heading', { level: 3 });
|
||||
expect(heading).toHaveTextContent('WebRTC Blocked');
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user