UNPKG

rx-player

Version:
235 lines (222 loc) 8.48 kB
import { describe, beforeEach, it, expect, vi } from "vitest"; import type IParseContentProtection from "../ContentProtection"; function testStringAttribute(attributeName: string, variableName?: string): void { const _variableName = variableName ?? attributeName; it(`should correctly parse a ContentProtection element with a correct ${attributeName} attribute`, async () => { const parseContentProtection = (await vi.importActual("../ContentProtection")) .default as typeof IParseContentProtection; const element1 = new DOMParser().parseFromString( `<ContentProtection ${attributeName}="foobar" />`, "text/xml", ).childNodes[0] as Element; expect(parseContentProtection(element1)).toEqual([ { attributes: { [_variableName]: "foobar" }, children: { cencPssh: [] } }, [], ]); const element2 = new DOMParser().parseFromString( `<ContentProtection ${attributeName}="" />`, "text/xml", ).childNodes[0] as Element; expect(parseContentProtection(element2)).toEqual([ { attributes: { [_variableName]: "" }, children: { cencPssh: [] } }, [], ]); }); } describe("DASH Node Parsers - ContentProtection", () => { beforeEach(() => { vi.resetModules(); }); it("should correctly parse a ContentProtection element without attributes", async () => { const parseContentProtection = (await vi.importActual("../ContentProtection")) .default as typeof IParseContentProtection; const element = new DOMParser().parseFromString("<ContentProtection />", "text/xml") .childNodes[0] as Element; expect(parseContentProtection(element)).toEqual([ { attributes: {}, children: { cencPssh: [] } }, [], ]); }); testStringAttribute("schemeIdUri"); testStringAttribute("value"); it("should correctly parse a ContentProtection element with a correct cenc:default_KID attribute", async () => { const keyId = new Uint8Array([0, 1, 2, 3]); const mockHexToBytes = vi.fn().mockImplementation(() => { return keyId; }); vi.doMock("../../../../../../utils/string_parsing", () => ({ hexToBytes: mockHexToBytes, })); const parseContentProtection = (await vi.importActual("../ContentProtection")) .default as typeof IParseContentProtection; const element1 = new DOMParser() .parseFromString( `<?xml version="1.0" encoding="utf-8"?> <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready" xmlns:scte35="urn:scte:scte35:2014:xml+bin"> <ContentProtection cenc:default_KID="dead-beef" /> </MPD> `, "text/xml", ) .getElementsByTagName("ContentProtection")[0]; expect(parseContentProtection(element1)).toEqual([ { attributes: { keyId }, children: { cencPssh: [] } }, [], ]); expect(mockHexToBytes).toHaveBeenCalledTimes(1); expect(mockHexToBytes).toHaveBeenCalledWith("deadbeef"); }); it("should correctly parse a ContentProtection with every attributes", async () => { const keyId = new Uint8Array([0, 1, 2, 3]); const mockHexToBytes = vi.fn().mockImplementation(() => { return keyId; }); vi.doMock("../../../../../../utils/string_parsing", () => ({ hexToBytes: mockHexToBytes, })); const parseContentProtection = (await vi.importActual("../ContentProtection")) .default as typeof IParseContentProtection; const element = new DOMParser() .parseFromString( `<?xml version="1.0" encoding="utf-8"?> <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready" xmlns:scte35="urn:scte:scte35:2014:xml+bin"> <ContentProtection schemeIdUri="foo" value="bar" cenc:default_KID="dead-beef" /> </MPD> `, "text/xml", ) .getElementsByTagName("ContentProtection")[0]; expect(parseContentProtection(element)).toEqual([ { attributes: { keyId, schemeIdUri: "foo", value: "bar" }, children: { cencPssh: [] }, }, [], ]); }); it("should correctly parse a ContentProtection with cenc:pssh children", async () => { const parseContentProtection = (await vi.importActual("../ContentProtection")) .default as typeof IParseContentProtection; const element = new DOMParser() .parseFromString( `<?xml version="1.0" encoding="utf-8"?> <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready" xmlns:scte35="urn:scte:scte35:2014:xml+bin"> <ContentProtection> <cenc:pssh>AABBCC</cenc:pssh> <cenc:pssh>AAABAC</cenc:pssh> </ContentProtection> </MPD> `, "text/xml", ) .getElementsByTagName("ContentProtection")[0]; expect(parseContentProtection(element)).toEqual([ { attributes: {}, children: { cencPssh: [new Uint8Array([0, 0, 65, 8]), new Uint8Array([0, 0, 1, 0])], }, }, [], ]); }); it("should correctly parse a ContentProtection with both cenc:pssh children and every attributes", async () => { const keyId = new Uint8Array([0, 1, 2, 3]); const mockHexToBytes = vi.fn().mockImplementation(() => { return keyId; }); vi.doMock("../../../../../../utils/string_parsing", () => ({ hexToBytes: mockHexToBytes, })); const parseContentProtection = (await vi.importActual("../ContentProtection")) .default as typeof IParseContentProtection; const element = new DOMParser() .parseFromString( `<?xml version="1.0" encoding="utf-8"?> <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready" xmlns:scte35="urn:scte:scte35:2014:xml+bin"> <ContentProtection schemeIdUri="foo" value="bar" cenc:default_KID="dead-beef" > <cenc:pssh>AABBCC</cenc:pssh> <cenc:pssh>AAABAC</cenc:pssh> </ContentProtection> </MPD> `, "text/xml", ) .getElementsByTagName("ContentProtection")[0]; expect(parseContentProtection(element)).toEqual([ { attributes: { keyId, schemeIdUri: "foo", value: "bar" }, children: { cencPssh: [new Uint8Array([0, 0, 65, 8]), new Uint8Array([0, 0, 1, 0])], }, }, [], ]); }); it("should return a warning if one of the cenc:pssh is invalid base64", async () => { const parseContentProtection = (await vi.importActual("../ContentProtection")) .default as typeof IParseContentProtection; const element = new DOMParser() .parseFromString( `<?xml version="1.0" encoding="utf-8"?> <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:mpeg:dash:schema:mpd:2011" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" xmlns:mspr="urn:microsoft:playready" xmlns:scte35="urn:scte:scte35:2014:xml+bin"> <ContentProtection> <cenc:pssh>AA!BCC</cenc:pssh> <cenc:pssh>AAABAC</cenc:pssh> </ContentProtection> </MPD> `, "text/xml", ) .getElementsByTagName("ContentProtection")[0]; const parsed = parseContentProtection(element); expect(parsed[0]).toEqual({ attributes: {}, children: { cencPssh: [new Uint8Array([0, 0, 1, 0])] }, }); expect(parsed[1]).not.toBe(null); expect(parsed[1]).toHaveLength(1); expect(parsed[1][0]).toBeInstanceOf(Error); expect(parsed[1][0].message).toEqual( '`cenc:pssh` is not a valid base64 string: "AA!BCC"', ); }); });