- Closes #2556 - Closes #2450 **Key intended features:** - go2rtc compatible - 100% test coverage to significantly improve ability to test, maintain and work around browser weirdnesses (e.g. Safari). - Written from the ground up in the style of the rest of the project. **To use:** - Change `live_provider` from `go2rtc` to `go2rtc-experimental`.
105 lines
3.4 KiB
TypeScript
105 lines
3.4 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
|
|
import { ProviderErrorDetector } from '../../../../../src/components-lib/live/liveness/detectors/provider-error';
|
|
|
|
const LIVE_ERROR_EVENT = 'advanced-camera-card:live:error';
|
|
|
|
const createHostInDocument = (): HTMLElement => {
|
|
const host = document.createElement('div');
|
|
document.body.append(host);
|
|
return host;
|
|
};
|
|
|
|
// @vitest-environment jsdom
|
|
describe('ProviderErrorDetector', () => {
|
|
it('should start unknown', () => {
|
|
const detector = new ProviderErrorDetector(document.createElement('div'), vi.fn());
|
|
|
|
expect(detector.getVerdict()).toEqual({ state: 'unknown' });
|
|
});
|
|
|
|
it('should report not live on a provider error, leaving the provider mounted', () => {
|
|
const host = createHostInDocument();
|
|
const onChange = vi.fn();
|
|
const detector = new ProviderErrorDetector(host, onChange);
|
|
detector.subscribe();
|
|
|
|
host.dispatchEvent(new Event(LIVE_ERROR_EVENT, { bubbles: true }));
|
|
|
|
// not_live but no renderPlaceholder: the provider renders its own error.
|
|
expect(detector.getVerdict()).toEqual({
|
|
state: 'not_live',
|
|
authority: 'hard',
|
|
reason: 'playback_error',
|
|
});
|
|
expect(onChange).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should adopt the specific reason carried on the event', () => {
|
|
const host = createHostInDocument();
|
|
const detector = new ProviderErrorDetector(host, vi.fn());
|
|
detector.subscribe();
|
|
|
|
host.dispatchEvent(
|
|
new CustomEvent(LIVE_ERROR_EVENT, { bubbles: true, detail: 'unsupported' }),
|
|
);
|
|
|
|
expect(detector.getVerdict()).toEqual({
|
|
state: 'not_live',
|
|
authority: 'hard',
|
|
reason: 'unsupported',
|
|
});
|
|
});
|
|
|
|
it('should notify only on the transition to not live', () => {
|
|
const host = createHostInDocument();
|
|
const onChange = vi.fn();
|
|
const detector = new ProviderErrorDetector(host, onChange);
|
|
detector.subscribe();
|
|
|
|
host.dispatchEvent(new Event(LIVE_ERROR_EVENT, { bubbles: true }));
|
|
host.dispatchEvent(new Event(LIVE_ERROR_EVENT, { bubbles: true }));
|
|
|
|
expect(onChange).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should stop the error from propagating past the host', () => {
|
|
const host = createHostInDocument();
|
|
const parentListener = vi.fn();
|
|
document.body.addEventListener(LIVE_ERROR_EVENT, parentListener);
|
|
const detector = new ProviderErrorDetector(host, vi.fn());
|
|
detector.subscribe();
|
|
|
|
host.dispatchEvent(new Event(LIVE_ERROR_EVENT, { bubbles: true }));
|
|
|
|
expect(parentListener).not.toHaveBeenCalled();
|
|
|
|
document.body.removeEventListener(LIVE_ERROR_EVENT, parentListener);
|
|
});
|
|
|
|
it('should discard the verdict on reset', () => {
|
|
const host = createHostInDocument();
|
|
const detector = new ProviderErrorDetector(host, vi.fn());
|
|
detector.subscribe();
|
|
host.dispatchEvent(new Event(LIVE_ERROR_EVENT, { bubbles: true }));
|
|
expect(detector.getVerdict().state).toBe('not_live');
|
|
|
|
detector.reset();
|
|
|
|
expect(detector.getVerdict()).toEqual({ state: 'unknown' });
|
|
});
|
|
|
|
it('should ignore errors after unsubscribe', () => {
|
|
const host = createHostInDocument();
|
|
const onChange = vi.fn();
|
|
const detector = new ProviderErrorDetector(host, onChange);
|
|
detector.subscribe();
|
|
detector.unsubscribe();
|
|
|
|
host.dispatchEvent(new Event(LIVE_ERROR_EVENT, { bubbles: true }));
|
|
|
|
expect(detector.getVerdict().state).toBe('unknown');
|
|
expect(onChange).not.toHaveBeenCalled();
|
|
});
|
|
});
|