rx-player
Version:
Canal+ HTML5 Video Player
1,201 lines (1,118 loc) • 36.3 kB
text/typescript
import { describe, beforeEach, it, expect, vi } from "vitest";
import type { IParsedAdaptation, IParsedPeriod } from "../../../parsers/manifest";
import type Adaptation from "../adaptation";
import CodecSupportCache from "../codec_support_cache";
import type IPeriod from "../period";
describe("Manifest - Period", () => {
beforeEach(() => {
vi.resetModules();
});
it("should throw if no adaptation is given", async () => {
const mockAdaptation = vi.fn((arg: IParsedAdaptation) => ({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}));
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const args = { id: "12", adaptations: {}, start: 0, thumbnailTracks: [] };
let period: IPeriod | null = null;
let errorReceived: unknown = null;
const unsupportedAdaptations: Adaptation[] = [];
try {
const codecSupportCache = new CodecSupportCache([]);
period = new Period(args, unsupportedAdaptations, codecSupportCache);
} catch (e) {
errorReceived = e;
}
expect(unsupportedAdaptations).toHaveLength(0);
expect(period).toBe(null);
expect(errorReceived).not.toBe(null);
expect(errorReceived).toBeInstanceOf(Error);
// Impossible check to shut-up TypeScript
if (!(errorReceived instanceof Error)) {
throw new Error("Impossible: already checked it was an Error instance");
}
expect((errorReceived as { code?: string }).code).toBe("MANIFEST_PARSE_ERROR");
expect(errorReceived.message).toContain("No supported audio and video tracks.");
expect(mockAdaptation).not.toHaveBeenCalled();
});
it("should throw if no audio nor video adaptation is given", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const fooAda1 = {
type: "foo",
id: "54",
representations: [{}],
};
const fooAda2 = {
type: "foo",
id: "55",
representations: [{}],
};
const foo = [fooAda1, fooAda2];
const args: IParsedPeriod = {
id: "12",
adaptations: { foo },
start: 0,
thumbnailTracks: [],
} as unknown as IParsedPeriod;
let period: IPeriod | null = null;
let errorReceived: unknown = null;
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
try {
period = new Period(args, unsupportedAdaptations, codecSupportCache);
} catch (e) {
errorReceived = e;
}
expect(unsupportedAdaptations).toHaveLength(0);
expect(period).toBe(null);
expect(errorReceived).not.toBe(null);
expect(errorReceived).toBeInstanceOf(Error);
// Impossible check to shut-up TypeScript
if (!(errorReceived instanceof Error)) {
throw new Error("Impossible: already checked it was an Error instance");
}
expect((errorReceived as { code?: string }).code).toBe("MANIFEST_PARSE_ERROR");
expect((errorReceived as { type?: string }).type).toBe("MEDIA_ERROR");
expect(errorReceived.message).toContain("No supported audio and video tracks.");
expect(mockAdaptation).toHaveBeenCalledTimes(2);
expect(mockAdaptation).toHaveBeenNthCalledWith(1, fooAda1, codecSupportCache, {});
expect(mockAdaptation).toHaveBeenNthCalledWith(2, fooAda2, codecSupportCache, {});
});
it("should throw if only empty audio and/or video adaptations is given", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const args = {
id: "12",
thumbnailTracks: [],
adaptations: { video: [], audio: [] },
start: 0,
};
let period: IPeriod | null = null;
let errorReceived: unknown = null;
const unsupportedAdaptations: Adaptation[] = [];
try {
const codecSupportCache = new CodecSupportCache([]);
period = new Period(args, unsupportedAdaptations, codecSupportCache);
} catch (e) {
errorReceived = e;
}
expect(unsupportedAdaptations).toHaveLength(0);
expect(period).toBe(null);
expect(errorReceived).not.toBe(null);
expect(errorReceived).toBeInstanceOf(Error);
// Impossible check to shut-up TypeScript
if (!(errorReceived instanceof Error)) {
throw new Error("Impossible: already checked it was an Error instance");
}
expect((errorReceived as { code?: string }).code).toBe("MANIFEST_PARSE_ERROR");
expect((errorReceived as { type?: string }).type).toBe("MEDIA_ERROR");
expect(errorReceived.message).toContain("No supported audio and video tracks.");
expect(mockAdaptation).toHaveBeenCalledTimes(0);
});
it("should throw if we are left with no audio representation", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "56",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const videoAda3 = {
type: "video",
id: "57",
representations: [{}],
toVideoTrack() {
return videoAda3;
},
};
const video = [videoAda1, videoAda2, videoAda3];
const audioAda1 = {
type: "audio",
id: "58",
representations: [],
toAudioTrack() {
return audioAda1;
},
};
const audioAda2 = {
type: "audio",
id: "59",
representations: [],
toAudioTrack() {
return audioAda2;
},
};
const audio = [audioAda1, audioAda2];
const args: IParsedPeriod = {
id: "12",
adaptations: { video, audio },
thumbnailTracks: [],
start: 0,
} as unknown as IParsedPeriod;
let period: IPeriod | null = null;
let errorReceived: unknown = null;
const unsupportedAdaptations: Adaptation[] = [];
try {
const codecSupportCache = new CodecSupportCache([]);
period = new Period(args, unsupportedAdaptations, codecSupportCache);
} catch (e) {
errorReceived = e;
}
expect(unsupportedAdaptations).toHaveLength(0);
expect(period).toBe(null);
expect(errorReceived).not.toBe(null);
expect(errorReceived).toBeInstanceOf(Error);
// Impossible check to shut-up TypeScript
if (!(errorReceived instanceof Error)) {
throw new Error("Impossible: already checked it was an Error instance");
}
expect((errorReceived as { code?: string }).code).toBe(
"MANIFEST_INCOMPATIBLE_CODECS_ERROR",
);
expect((errorReceived as { type?: string }).type).toBe("MEDIA_ERROR");
expect(errorReceived.message).toContain("No supported audio adaptations");
});
it("should throw if no audio Adaptation is supported", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: arg.type !== "audio",
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const videoAda3 = {
type: "video",
id: "56",
representations: [{}],
toVideoTrack() {
return videoAda3;
},
};
const video: IParsedAdaptation[] = [
videoAda1,
videoAda2,
videoAda3,
] as unknown as IParsedAdaptation[];
const audioAda1 = {
type: "audio",
id: "57",
representations: [{}],
toAudioTrack() {
return audioAda1;
},
};
const audioAda2 = {
type: "audio",
id: "58",
representations: [{}],
toAudioTrack() {
return audioAda1;
},
};
const audio: IParsedAdaptation[] = [
audioAda1,
audioAda2,
] as unknown as IParsedAdaptation[];
const args: IParsedPeriod = {
id: "12",
adaptations: { video, audio },
start: 0,
thumbnailTracks: [],
};
let period: IPeriod | null = null;
let errorReceived: unknown = null;
const unsupportedAdaptations: Adaptation[] = [];
try {
const codecSupportCache = new CodecSupportCache([]);
period = new Period(args, unsupportedAdaptations, codecSupportCache);
} catch (e) {
errorReceived = e;
}
expect(period).toBe(null);
expect(errorReceived).not.toBe(null);
expect(errorReceived).toBeInstanceOf(Error);
expect(unsupportedAdaptations).toHaveLength(2);
expect(unsupportedAdaptations[0].id).toEqual("57");
expect(unsupportedAdaptations[1].id).toEqual("58");
// Impossible check to shut-up TypeScript
if (!(errorReceived instanceof Error)) {
throw new Error("Impossible: already checked it was an Error instance");
}
expect((errorReceived as { code?: string }).code).toBe(
"MANIFEST_INCOMPATIBLE_CODECS_ERROR",
);
expect((errorReceived as { type?: string }).type).toBe("MEDIA_ERROR");
expect(errorReceived.message).toContain("No supported audio adaptations");
});
it("should throw if we are left with no video representation", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [],
toVideoTrack() {
return videoAda2;
},
};
const videoAda3 = {
type: "video",
id: "56",
representations: [],
toVideoTrack() {
return videoAda3;
},
};
const video: IParsedAdaptation[] = [
videoAda1,
videoAda2,
videoAda3,
] as unknown as IParsedAdaptation[];
const audioAda1 = {
type: "audio",
id: "58",
representations: [{}],
toAudioTrack() {
return audioAda1;
},
};
const audioAda2 = {
type: "audio",
id: "59",
representations: [{}],
toAudioTrack() {
return audioAda2;
},
};
const audio: IParsedAdaptation[] = [
audioAda1,
audioAda2,
] as unknown as IParsedAdaptation[];
const args: IParsedPeriod = {
id: "12",
adaptations: { video, audio },
start: 0,
thumbnailTracks: [],
};
let period: IPeriod | null = null;
let errorReceived: unknown = null;
const unsupportedAdaptations: Adaptation[] = [];
try {
const codecSupportCache = new CodecSupportCache([]);
period = new Period(args, unsupportedAdaptations, codecSupportCache);
} catch (e) {
errorReceived = e;
}
expect(unsupportedAdaptations).toHaveLength(0);
expect(period).toBe(null);
expect(errorReceived).not.toBe(null);
expect(errorReceived).toBeInstanceOf(Error);
// Impossible check to shut-up TypeScript
if (!(errorReceived instanceof Error)) {
throw new Error("Impossible: already checked it was an Error instance");
}
expect((errorReceived as { code?: string }).code).toBe(
"MANIFEST_INCOMPATIBLE_CODECS_ERROR",
);
expect((errorReceived as { type?: string }).type).toBe("MEDIA_ERROR");
expect(errorReceived.message).toContain("No supported video adaptation");
});
it("should throw if no video adaptation is supported", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: arg.type !== "video",
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const videoAda3 = {
type: "video",
id: "56",
representations: [{}],
toVideoTrack() {
return videoAda3;
},
};
const video: IParsedAdaptation[] = [
videoAda1,
videoAda2,
videoAda3,
] as unknown as IParsedAdaptation[];
const audioAda1 = {
type: "audio",
id: "58",
representations: [{}],
toAudioTrack() {
return audioAda1;
},
};
const audioAda2 = {
type: "audio",
id: "59",
representations: [{}],
toAudioTrack() {
return audioAda2;
},
};
const audio = [audioAda1, audioAda2] as unknown as IParsedAdaptation[];
const args = {
id: "12",
adaptations: { video, audio },
start: 0,
thumbnailTracks: [],
};
let period: IPeriod | null = null;
let errorReceived: unknown = null;
const unsupportedAdaptations: Adaptation[] = [];
try {
const codecSupportCache = new CodecSupportCache([]);
period = new Period(args, unsupportedAdaptations, codecSupportCache);
} catch (e) {
errorReceived = e;
}
expect(period).toBe(null);
expect(errorReceived).not.toBe(null);
expect(errorReceived).toBeInstanceOf(Error);
expect(unsupportedAdaptations).toHaveLength(3);
// Impossible check to shut-up TypeScript
if (!(errorReceived instanceof Error)) {
throw new Error("Impossible: already checked it was an Error instance");
}
expect((errorReceived as { code?: string }).code).toBe(
"MANIFEST_INCOMPATIBLE_CODECS_ERROR",
);
expect((errorReceived as { type?: string }).type).toBe("MEDIA_ERROR");
expect(errorReceived.message).toContain("No supported video adaptation");
});
it("should set a parsing error if an unsupported adaptation is given", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: arg.id !== "56",
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const video = [videoAda1] as unknown as IParsedAdaptation[];
const videoAda2 = {
type: "video",
id: "56",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const video2 = [videoAda2] as unknown as IParsedAdaptation[];
const args = {
id: "12",
adaptations: { video, video2 },
start: 0,
thumbnailTracks: [],
};
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(1);
expect(mockAdaptation).toHaveBeenCalledTimes(2);
expect(mockAdaptation).toHaveReturnedTimes(2);
expect(mockAdaptation).toHaveBeenCalledWith(videoAda1, codecSupportCache, {});
expect(mockAdaptation).toHaveBeenCalledWith(videoAda2, codecSupportCache, {});
expect(mockAdaptation).toHaveReturnedWith(period.adaptations.video?.[0]);
const [adap] = unsupportedAdaptations;
expect(adap.id).toBe("56");
expect(adap.supportStatus.hasSupportedCodec).toBe(false);
});
it("should not set a parsing error if an empty unsupported adaptation is given", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text", "foo"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const video = [videoAda1] as unknown as IParsedAdaptation[];
const bar = undefined;
const args = { id: "12", thumbnailTracks: [], adaptations: { bar, video }, start: 0 };
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, unsupportedAdaptations, codecSupportCache);
expect(period.adaptations).toEqual({
video: video.map((v) => ({
...v,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
})),
});
expect(unsupportedAdaptations).toHaveLength(0);
expect(mockAdaptation).toHaveBeenCalledTimes(1);
expect(mockAdaptation).toHaveBeenCalledWith(videoAda1, codecSupportCache, {});
});
it("should give a representationFilter to the adaptation", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
const representationFilter = vi.fn();
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const args = { id: "12", adaptations: { video }, start: 0, thumbnailTracks: [] };
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(
args,
unsupportedAdaptations,
codecSupportCache,
representationFilter,
);
expect(unsupportedAdaptations).toHaveLength(0);
expect(period.adaptations.video).toHaveLength(2);
expect(mockAdaptation).toHaveBeenCalledTimes(2);
expect(mockAdaptation).toHaveBeenNthCalledWith(1, videoAda1, codecSupportCache, {
representationFilter,
});
expect(mockAdaptation).toHaveBeenNthCalledWith(2, videoAda2, codecSupportCache, {
representationFilter,
});
expect(representationFilter).not.toHaveBeenCalled();
});
it("should report if Adaptations are not supported", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: arg.id === "55",
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const fooAda1 = {
type: "foo",
id: "12",
representations: [{}],
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const foo = [fooAda1];
const args = { id: "12", thumbnailTracks: [], adaptations: { video, foo }, start: 0 };
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(2);
const [adap1, adap2] = unsupportedAdaptations;
expect((adap1 as { id: string }).id).toBe("54");
expect((adap2 as { id: string }).id).toBe("12");
});
it("should not report if an Adaptation has no Representation", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const fooAda1 = {
type: "foo",
id: "12",
representations: [],
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const foo = [fooAda1];
const args = { id: "12", thumbnailTracks: [], adaptations: { video, foo }, start: 0 };
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(0);
});
it("should set the given start", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const args = { id: "12", adaptations: { video }, start: 72, thumbnailTracks: [] };
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(0);
expect(period.start).toEqual(72);
expect(period.duration).toEqual(undefined);
expect(period.end).toEqual(undefined);
});
it("should set a given duration", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const args = {
id: "12",
adaptations: { video },
start: 0,
duration: 12,
thumbnailTracks: [],
};
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(0);
expect(period.start).toEqual(0);
expect(period.duration).toEqual(12);
expect(period.end).toEqual(12);
});
it("should infer the end from the start and the duration", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const args = {
id: "12",
adaptations: { video },
start: 50,
duration: 12,
thumbnailTracks: [],
};
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(0);
expect(period.start).toEqual(50);
expect(period.duration).toEqual(12);
expect(period.end).toEqual(62);
});
it("should return every Adaptations combined with `getAdaptations`", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const audioAda1 = {
type: "audio",
id: "56",
representations: [{}],
toAudioTrack() {
return audioAda1;
},
};
const audio = [audioAda1] as unknown as IParsedAdaptation[];
const args = {
id: "12",
thumbnailTracks: [],
adaptations: { video, audio },
start: 50,
duration: 12,
};
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(0);
expect(period.getAdaptations()).toHaveLength(3);
expect(period.getAdaptations()).toContain(period.adaptations.video?.[0]);
expect(period.getAdaptations()).toContain(period.adaptations.video?.[1]);
expect(period.getAdaptations()).toContain(period.adaptations.audio?.[0]);
});
it("should return every Adaptations from a given type with `getAdaptationsForType`", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const video = [videoAda1, videoAda2] as unknown as IParsedAdaptation[];
const audioAda1 = {
type: "audio",
id: "56",
representations: [{}],
toAudioTrack() {
return audioAda1;
},
};
const audio = [audioAda1] as unknown as IParsedAdaptation[];
const args = {
id: "12",
thumbnailTracks: [],
adaptations: { video, audio },
start: 50,
duration: 12,
};
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, unsupportedAdaptations, codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(0);
expect(period.getAdaptationsForType("video")).toHaveLength(2);
expect(period.getAdaptationsForType("video")).toEqual([
period.adaptations.video?.[0],
period.adaptations.video?.[1],
]);
expect(period.getAdaptationsForType("audio")).toHaveLength(1);
expect(period.getAdaptationsForType("audio")).toEqual([
period.adaptations.audio?.[0],
]);
expect(period.getAdaptationsForType("text")).toHaveLength(0);
});
it("should return the first Adaptations with a given Id when calling `getAdaptation`", async () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
const Period = (await vi.importActual("../period")).default as typeof IPeriod;
const videoAda1 = {
type: "video",
id: "54",
representations: [{}],
toVideoTrack() {
return videoAda1;
},
};
const videoAda2 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda2;
},
};
const videoAda3 = {
type: "video",
id: "55",
representations: [{}],
toVideoTrack() {
return videoAda3;
},
};
const video = [videoAda1, videoAda2, videoAda3] as unknown as IParsedAdaptation[];
const audioAda1 = {
type: "audio",
id: "56",
representations: [{}],
toAudioTrack() {
return audioAda1;
},
};
const audio = [audioAda1] as unknown as IParsedAdaptation[];
const args = {
id: "12",
thumbnailTracks: [],
adaptations: { video, audio },
start: 50,
duration: 12,
};
const unsupportedAdaptations: Adaptation[] = [];
const codecSupportCache = new CodecSupportCache([]);
const period = new Period(args, [], codecSupportCache);
expect(unsupportedAdaptations).toHaveLength(0);
expect(period.getAdaptation("54")).toEqual(period.adaptations.video?.[0]);
expect(period.getAdaptation("55")).toEqual(period.adaptations.video?.[1]);
expect(period.getAdaptation("56")).toEqual(period.adaptations.audio?.[0]);
});
it("should return undefind if no adaptation has the given Id when calling `getAdaptation`", () => {
const mockAdaptation = vi.fn(
(arg: IParsedAdaptation): Adaptation =>
({
...arg,
supportStatus: {
hasSupportedCodec: undefined,
hasCodecWithUndefinedSupport: true,
isDecipherable: undefined,
},
}) as unknown as Adaptation,
);
vi.doMock("../adaptation", () => ({
default: mockAdaptation,
SUPPORTED_ADAPTATIONS_TYPE: ["audio", "video", "text"],
}));
});
});