UNPKG

rx-player

Version:
375 lines (348 loc) 11.2 kB
import { describe, beforeEach, afterEach, it, expect, vi } from "vitest"; import isNullOrUndefined from "../../../../../utils/is_null_or_undefined"; import probeDecodingInfos from "../../probers/decodingInfo"; import type { IMediaConfiguration } from "../../types"; import { ProberStatus } from "../../types"; const origDecodingInfo = navigator.mediaCapabilities; const origMediaCapabilities = navigator.mediaCapabilities; /** * Stub decodingInfo API to resolve. * @param {boolean} isSupported * @param {undefined|boolean} mustReject */ function stubDecodingInfo(isSupported: boolean, mustReject?: boolean) { const decodingInfoStub = vi.fn(() => { if (mustReject === true) { return Promise.reject(); } else { return Promise.resolve({ supported: isSupported, }); } }); const mockMediaCapabilities = { decodingInfo: decodingInfoStub, }; // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for // now, we're going through JSDom through so that's OK. navigator.mediaCapabilities = mockMediaCapabilities; return decodingInfoStub; } /** * Reset decodingInfo to native implementation. */ function resetDecodingInfos(): void { // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for // now, we're going through JSDom through so that's OK. navigator.mediaCapabilities = origDecodingInfo; } describe("MediaCapabilitiesProber probers - decodingInfo", () => { beforeEach(() => { vi.resetModules(); }); afterEach(() => { // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for // now, we're going through JSDom through so that's OK. navigator.mediaCapabilities = origMediaCapabilities; }); it("should throw if no video and audio config", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration = { type: "media-source" as const, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(() => { resetDecodingInfos(); }) .catch(({ message }: { message: string }) => { expect(message).toEqual( "MediaCapabilitiesProber >>> API_CALL: " + "Not enough arguments for calling mediaCapabilites.", ); expect(decodingInfoStub).not.toHaveBeenCalled(); resetDecodingInfos(); }); }); it("should throw if incomplete video config", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration = { type: "media-source" as const, video: { contentType: "video/wmv", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(() => { resetDecodingInfos(); }) .catch(({ message }: { message: string }) => { expect(message).toEqual( "MediaCapabilitiesProber >>> API_CALL: " + "Not enough arguments for calling mediaCapabilites.", ); expect(decodingInfoStub).not.toHaveBeenCalled(); resetDecodingInfos(); }); }); it("should throw if incomplete audio config", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration = { type: "media-source" as const, audio: { contentType: "audio/wma", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(() => { resetDecodingInfos(); }) .catch(({ message }: { message: string }) => { expect(message).toEqual( "MediaCapabilitiesProber >>> API_CALL: " + "Not enough arguments for calling mediaCapabilites.", ); expect(decodingInfoStub).not.toHaveBeenCalled(); resetDecodingInfos(); }); }); it("should throw if no type in config", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration = { audio: { contentType: "audio/wma", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(() => { resetDecodingInfos(); }) .catch(({ message }: { message: string }) => { expect(message).toEqual( "MediaCapabilitiesProber >>> API_CALL: " + "Not enough arguments for calling mediaCapabilites.", ); expect(decodingInfoStub).not.toHaveBeenCalled(); resetDecodingInfos(); }); }); it("should throw if empty config", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration = {}; expect.assertions(2); return probeDecodingInfos(configuration) .then(() => { resetDecodingInfos(); }) .catch(({ message }: { message: string }) => { expect(message).toEqual( "MediaCapabilitiesProber >>> API_CALL: " + "Not enough arguments for calling mediaCapabilites.", ); expect(decodingInfoStub).not.toHaveBeenCalled(); resetDecodingInfos(); }); }); it("should throw if API mediaCapabilities not available", async () => { // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for // now, we're going through JSDom through so that's OK. delete navigator.mediaCapabilities; await expect(probeDecodingInfos({})).rejects.toThrowError( "MediaCapabilitiesProber >>> API_CALL: MediaCapabilities API not available", ); }); it("should throw if API decodingInfo not available", async () => { if (!isNullOrUndefined(navigator.mediaCapabilities)) { // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for // now, we're going through JSDom through so that's OK. delete navigator.mediaCapabilities.decodingInfo; } else { // @ts-expect-error: `navigator.mediaCapabilities` is read-only normally, for // now, we're going through JSDom through so that's OK. navigator.mediaCapabilities = {}; } await expect(probeDecodingInfos({})).rejects.toThrowError( "MediaCapabilitiesProber >>> API_CALL: Decoding Info not available", ); }); it("should resolve with `Supported` if decodingInfo supports (video only)", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration: IMediaConfiguration = { type: "media-source", video: { contentType: "audio/wma", bitrate: 5000, framerate: "24", height: 1080, width: 1920, }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(([res]) => { expect(res).toBe(ProberStatus.Supported); expect(decodingInfoStub).toHaveBeenCalledTimes(1); resetDecodingInfos(); }) .catch(() => { resetDecodingInfos(); }); }); it("should resolve with `Supported` if decodingInfo supports (audio only)", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration: IMediaConfiguration = { type: "media-source", audio: { contentType: "audio/wma", bitrate: 5000, samplerate: 44100, channels: "5.1", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(([res]) => { expect(res).toBe(ProberStatus.Supported); expect(decodingInfoStub).toHaveBeenCalledTimes(1); resetDecodingInfos(); }) .catch(() => { resetDecodingInfos(); }); }); it("should resolve with `Supported` if decodingInfo supports video + audio", () => { const decodingInfoStub = stubDecodingInfo(true); const configuration: IMediaConfiguration = { type: "media-source", video: { contentType: "audio/wma", bitrate: 5000, framerate: "24", height: 1080, width: 1920, }, audio: { contentType: "audio/wma", bitrate: 5000, samplerate: 44100, channels: "5.1", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(([res]) => { expect(res).toBe(ProberStatus.Supported); expect(decodingInfoStub).toHaveBeenCalledTimes(1); resetDecodingInfos(); }) .catch(() => { resetDecodingInfos(); }); }); it("should return `NotSupported` if no decodingInfo support (video only)", () => { const decodingInfoStub = stubDecodingInfo(false); const configuration: IMediaConfiguration = { type: "media-source", video: { contentType: "audio/wma", bitrate: 5000, framerate: "24", height: 1080, width: 1920, }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(([res]) => { expect(res).toBe(ProberStatus.NotSupported); expect(decodingInfoStub).toHaveBeenCalledTimes(1); resetDecodingInfos(); }) .catch(() => { resetDecodingInfos(); }); }); it("should return `NotSupported` if no decodingInfo support (audio only)", () => { const decodingInfoStub = stubDecodingInfo(false); const configuration: IMediaConfiguration = { type: "media-source", audio: { contentType: "audio/wma", bitrate: 5000, samplerate: 44100, channels: "5.1", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(([res]) => { expect(res).toBe(ProberStatus.NotSupported); expect(decodingInfoStub).toHaveBeenCalledTimes(1); resetDecodingInfos(); }) .catch(() => { resetDecodingInfos(); }); }); it("should return `NotSupported` if no decodingInfo support", () => { const decodingInfoStub = stubDecodingInfo(false); const configuration: IMediaConfiguration = { type: "media-source", video: { contentType: "audio/wma", bitrate: 5000, framerate: "24", height: 1080, width: 1920, }, audio: { contentType: "audio/wma", bitrate: 5000, samplerate: 44100, channels: "5.1", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(([res]) => { expect(res).toBe(ProberStatus.NotSupported); expect(decodingInfoStub).toHaveBeenCalledTimes(1); resetDecodingInfos(); }) .catch(() => { resetDecodingInfos(); }); }); it("should resolve with `NotSupported` if decodingInfo throws", () => { const decodingInfoStub = stubDecodingInfo(true, true); const configuration: IMediaConfiguration = { type: "media-source", video: { contentType: "audio/wma", bitrate: 5000, framerate: "24", height: 1080, width: 1920, }, audio: { contentType: "audio/wma", bitrate: 5000, samplerate: 44100, channels: "5.1", }, }; expect.assertions(2); return probeDecodingInfos(configuration) .then(([res]) => { expect(res).toBe(ProberStatus.NotSupported); expect(decodingInfoStub).toHaveBeenCalledTimes(1); resetDecodingInfos(); }) .catch(() => { resetDecodingInfos(); }); }); });