<commit_before>import { expect } from "chai";
import RxPlayer from "../../../src";
import sleep from "../../utils/sleep.js";
import { waitForLoadedStateAfterLoadVideo } from "../../utils/waitForPlayerState";
import XHRMock from "../../utils/request_mock";

/**
 * Performs a serie of basic tests on a content.
 *
 * @param {Object} manifestInfos - information about what should be found in the
 * manifest.
 * Structure of manifestInfos:
 * ```
 * url {string}
 * transport {string}
 * duration {number}
 * isDynamic {boolean}
 * isLive {boolean}
 * maximumPosition? {number}
 * minimumPosition? {number}
 * availabilityStartTime? {number}
 * periods[]
 *          .adaptations.{
 *            audio,
 *            video,
 *            text,
 *            image
 *          }[]
 *             .isClosedCaption? {boolean}
 *             .isAudioDescription? {boolean}
 *             .normalizedLanguage? {string}
 *             .language? {string}
 *             .representations[]
 *                               .bitrate {number}
 *                               .codec {string}
 *                               .mimeType {string}
 *                               .height? {number}
 *                               .width? {number}
 *                               .index
 *                                     .init
 *                                          .mediaURLs {string}
 *                                     .segments[]
 *                                                .time {number}
 *                                                .timescale {number}
 *                                                .duration {number}
 *                                                .mediaURLs {string}
 * ```
 */
export default function launchTestsForContent(manifestInfos) {
  let player;
  let xhrMock;

  const { availabilityStartTime,
          isDynamic,
          isLive,
          maximumPosition,
          minimumPosition,
          periods: periodsInfos,
          transport } = manifestInfos;

  const firstPeriodIndex = isLive ? periodsInfos.length - 1 : 0;
  const videoRepresentationsForFirstPeriod =
    periodsInfos[firstPeriodIndex].adaptations.video &&
    periodsInfos[firstPeriodIndex].adaptations.video.length ?
      periodsInfos[firstPeriodIndex].adaptations.video[0].representations : [];
  const videoBitrates = videoRepresentationsForFirstPeriod
    .map(representation => representation.bitrate);

  const audioRepresentationsForFirstPeriod =
    periodsInfos[firstPeriodIndex].adaptations.audio &&
    periodsInfos[firstPeriodIndex].adaptations.audio.length ?
      periodsInfos[firstPeriodIndex].adaptations.audio[0].representations : [];
  const audioBitrates = audioRepresentationsForFirstPeriod
    .map(representation => representation.bitrate);

  describe("API tests", () => {
    beforeEach(() => {
      player = new RxPlayer();
      xhrMock = new XHRMock();
    });

    afterEach(() => {
      player.dispose();
      xhrMock.restore();
    });

    describe("loadVideo", () => {
      it("should fetch the manifest then the init segments", async function () {
        xhrMock.lock();

        // set the lowest bitrate to facilitate the test
        player.setVideoBitrate(0);
        player.setAudioBitrate(0);

        player.loadVideo({ url: manifestInfos.url, transport });

        // should only have the manifest for now
        await sleep(1);
        expect(xhrMock.getLockedXHR().length).to.equal(1);
        expect(xhrMock.getLockedXHR()[0].url).to.equal(manifestInfos.url);

        await xhrMock.flush(); // only wait for the manifest request
        await sleep(1);

        expect(player.getPlayerState()).to.equal("LOADING");

        const firstPeriodAdaptationsInfos = periodsInfos[firstPeriodIndex]
          .adaptations;
        const audioRepresentationInfos =
          firstPeriodAdaptationsInfos.audio &&
          firstPeriodAdaptationsInfos.audio[0] &&
          firstPeriodAdaptationsInfos.audio[0].representations[0];
        const videoRepresentationInfos =
          firstPeriodAdaptationsInfos.video &&
          firstPeriodAdaptationsInfos.video[0] &&
          firstPeriodAdaptationsInfos.video[0].representations[0];

        if (
          (audioRepresentationInfos && audioRepresentationInfos.index.init) ||
          (videoRepresentationInfos && videoRepresentationInfos.index.init)
        ) {
          if (
            (audioRepresentationInfos && audioRepresentationInfos.index.init) &&
            (videoRepresentationInfos && videoRepresentationInfos.index.init)
          ) {
            expect(xhrMock.getLockedXHR().length)
              .to.be.at.least(2, "should request two init segments");
            const requestsDone = xhrMock.getLockedXHR().map(({ url }) => url);
            expect(requestsDone)
              .to.include(videoRepresentationInfos.index.init.mediaURLs[0]);
            expect(requestsDone)
              .to.include(audioRepresentationInfos.index.init.mediaURLs[0]);
          } else if (!(
            audioRepresentationInfos && audioRepresentationInfos.index.init)
          ) {
            expect(xhrMock.getLockedXHR().length).to.equal(1);
            expect(xhrMock.getLockedXHR()[0].url).to
              .equal(videoRepresentationInfos.index.init.mediaURLs[0]);
          } else {
            expect(xhrMock.getLockedXHR().length).to.equal(1);
            expect(xhrMock.getLockedXHR()[0].url).to
              .equal(audioRepresentationInfos.index.init.mediaURLs[0]);
          }
        }
      });

      if (transport === "dash" || transport === "smooth") {
        it("should not do the initial manifest request if an `initialManifest` option is set as a string", async function () {
          const initialManifest = await (
            (await fetch(manifestInfos.url))
              .text());
          xhrMock.lock();
          player.loadVideo({ url: manifestInfos.url,
                             transport,
                             transportOptions: { initialManifest } });

          await sleep(100);
          expect(xhrMock.getLockedXHR().length).to.be.at.least(1);
          expect(xhrMock.getLockedXHR()[0].url).not.to.equal(manifestInfos.url);
        });
        it("should not do the initial manifest request if an `initialManifest` option is set as a document", async function () {
          const initialManifestStr = await (
            (await fetch(manifestInfos.url))
              .text());
          const initialManifest = new DOMParser().parseFromString(initialManifestStr, "text/xml");
          xhrMock.lock();
          player.loadVideo({ url: manifestInfos.url,
                             transport,
                             transportOptions: { initialManifest } });

          await sleep(100);
          expect(xhrMock.getLockedXHR().length).to.be.at.least(1);
          expect(xhrMock.getLockedXHR()[0].url).not.to.equal(manifestInfos.url);
        });
      }
    });

    describe("getError", () => {
      it("should return null if no fatal error has happened", async function() {
        player.loadVideo({
          url: manifestInfos.url,
          transport,
          autoPlay: false,
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getError()).to.equal(null);
      });
    });

    describe("getManifest", () => {
      it("should return the manifest correctly parsed", async function () {
        xhrMock.lock();
        player.loadVideo({ url: manifestInfos.url, transport });

        await sleep(10);
        await xhrMock.flush(); // only wait for the manifest request
        await sleep(10);

        const manifest = player.getManifest();
        expect(manifest).not.to.equal(null);
        expect(typeof manifest).to.equal("object");
        expect(manifest.transport).to.equal(transport);
        expect(typeof manifest.id).to.equal("string");
        expect(manifest.isDynamic).to.equal(isDynamic);
        expect(manifest.isLive).to.equal(isLive);
        expect(manifest.getUrl()).to.equal(manifestInfos.url);

        expect(manifest.getMaximumSafePosition()).to.equal(maximumPosition);
        expect(manifest.getMinimumSafePosition()).to.equal(minimumPosition);
        expect(manifest.availabilityStartTime).to.equal(availabilityStartTime);

        expect(manifest.periods.length).to.equal(periodsInfos.length);
        for (
          let periodIndex = 0;
          periodIndex < periodsInfos.length;
          periodIndex++<commit_msg>Raise timer in getManifest check to avoid false negatives<commit_after>import { expect } from "chai";
import RxPlayer from "../../../src";
import sleep from "../../utils/sleep.js";
import { waitForLoadedStateAfterLoadVideo } from "../../utils/waitForPlayerState";
import XHRMock from "../../utils/request_mock";

/**
 * Performs a serie of basic tests on a content.
 *
 * @param {Object} manifestInfos - information about what should be found in the
 * manifest.
 * Structure of manifestInfos:
 * ```
 * url {string}
 * transport {string}
 * duration {number}
 * isDynamic {boolean}
 * isLive {boolean}
 * maximumPosition? {number}
 * minimumPosition? {number}
 * availabilityStartTime? {number}
 * periods[]
 *          .adaptations.{
 *            audio,
 *            video,
 *            text,
 *            image
 *          }[]
 *             .isClosedCaption? {boolean}
 *             .isAudioDescription? {boolean}
 *             .normalizedLanguage? {string}
 *             .language? {string}
 *             .representations[]
 *                               .bitrate {number}
 *                               .codec {string}
 *                               .mimeType {string}
 *                               .height? {number}
 *                               .width? {number}
 *                               .index
 *                                     .init
 *                                          .mediaURLs {string}
 *                                     .segments[]
 *                                                .time {number}
 *                                                .timescale {number}
 *                                                .duration {number}
 *                                                .mediaURLs {string}
 * ```
 */
export default function launchTestsForContent(manifestInfos) {
  let player;
  let xhrMock;

  const { availabilityStartTime,
          isDynamic,
          isLive,
          maximumPosition,
          minimumPosition,
          periods: periodsInfos,
          transport } = manifestInfos;

  const firstPeriodIndex = isLive ? periodsInfos.length - 1 : 0;
  const videoRepresentationsForFirstPeriod =
    periodsInfos[firstPeriodIndex].adaptations.video &&
    periodsInfos[firstPeriodIndex].adaptations.video.length ?
      periodsInfos[firstPeriodIndex].adaptations.video[0].representations : [];
  const videoBitrates = videoRepresentationsForFirstPeriod
    .map(representation => representation.bitrate);

  const audioRepresentationsForFirstPeriod =
    periodsInfos[firstPeriodIndex].adaptations.audio &&
    periodsInfos[firstPeriodIndex].adaptations.audio.length ?
      periodsInfos[firstPeriodIndex].adaptations.audio[0].representations : [];
  const audioBitrates = audioRepresentationsForFirstPeriod
    .map(representation => representation.bitrate);

  describe("API tests", () => {
    beforeEach(() => {
      player = new RxPlayer();
      xhrMock = new XHRMock();
    });

    afterEach(() => {
      player.dispose();
      xhrMock.restore();
    });

    describe("loadVideo", () => {
      it("should fetch the manifest then the init segments", async function () {
        xhrMock.lock();

        // set the lowest bitrate to facilitate the test
        player.setVideoBitrate(0);
        player.setAudioBitrate(0);

        player.loadVideo({ url: manifestInfos.url, transport });

        // should only have the manifest for now
        await sleep(1);
        expect(xhrMock.getLockedXHR().length).to.equal(1);
        expect(xhrMock.getLockedXHR()[0].url).to.equal(manifestInfos.url);

        await xhrMock.flush(); // only wait for the manifest request
        await sleep(1);

        expect(player.getPlayerState()).to.equal("LOADING");

        const firstPeriodAdaptationsInfos = periodsInfos[firstPeriodIndex]
          .adaptations;
        const audioRepresentationInfos =
          firstPeriodAdaptationsInfos.audio &&
          firstPeriodAdaptationsInfos.audio[0] &&
          firstPeriodAdaptationsInfos.audio[0].representations[0];
        const videoRepresentationInfos =
          firstPeriodAdaptationsInfos.video &&
          firstPeriodAdaptationsInfos.video[0] &&
          firstPeriodAdaptationsInfos.video[0].representations[0];

        if (
          (audioRepresentationInfos && audioRepresentationInfos.index.init) ||
          (videoRepresentationInfos && videoRepresentationInfos.index.init)
        ) {
          if (
            (audioRepresentationInfos && audioRepresentationInfos.index.init) &&
            (videoRepresentationInfos && videoRepresentationInfos.index.init)
          ) {
            expect(xhrMock.getLockedXHR().length)
              .to.be.at.least(2, "should request two init segments");
            const requestsDone = xhrMock.getLockedXHR().map(({ url }) => url);
            expect(requestsDone)
              .to.include(videoRepresentationInfos.index.init.mediaURLs[0]);
            expect(requestsDone)
              .to.include(audioRepresentationInfos.index.init.mediaURLs[0]);
          } else if (!(
            audioRepresentationInfos && audioRepresentationInfos.index.init)
          ) {
            expect(xhrMock.getLockedXHR().length).to.equal(1);
            expect(xhrMock.getLockedXHR()[0].url).to
              .equal(videoRepresentationInfos.index.init.mediaURLs[0]);
          } else {
            expect(xhrMock.getLockedXHR().length).to.equal(1);
            expect(xhrMock.getLockedXHR()[0].url).to
              .equal(audioRepresentationInfos.index.init.mediaURLs[0]);
          }
        }
      });

      if (transport === "dash" || transport === "smooth") {
        it("should not do the initial manifest request if an `initialManifest` option is set as a string", async function () {
          const initialManifest = await (
            (await fetch(manifestInfos.url))
              .text());
          xhrMock.lock();
          player.loadVideo({ url: manifestInfos.url,
                             transport,
                             transportOptions: { initialManifest } });

          await sleep(100);
          expect(xhrMock.getLockedXHR().length).to.be.at.least(1);
          expect(xhrMock.getLockedXHR()[0].url).not.to.equal(manifestInfos.url);
        });
        it("should not do the initial manifest request if an `initialManifest` option is set as a document", async function () {
          const initialManifestStr = await (
            (await fetch(manifestInfos.url))
              .text());
          const initialManifest = new DOMParser().parseFromString(initialManifestStr, "text/xml");
          xhrMock.lock();
          player.loadVideo({ url: manifestInfos.url,
                             transport,
                             transportOptions: { initialManifest } });

          await sleep(100);
          expect(xhrMock.getLockedXHR().length).to.be.at.least(1);
          expect(xhrMock.getLockedXHR()[0].url).not.to.equal(manifestInfos.url);
        });
      }
    });

    describe("getError", () => {
      it("should return null if no fatal error has happened", async function() {
        player.loadVideo({
          url: manifestInfos.url,
          transport,
          autoPlay: false,
        });
        await waitForLoadedStateAfterLoadVideo(player);
        expect(player.getError()).to.equal(null);
      });
    });

    describe("getManifest", () => {
      it("should return the manifest correctly parsed", async function () {
        xhrMock.lock();
        player.loadVideo({ url: manifestInfos.url, transport });

        await sleep(100);
        await xhrMock.flush(); // only wait for the manifest request
        await sleep(100);

        const manifest = player.getManifest();
        expect(manifest).not.to.equal(null);
        expect(typeof manifest).to.equal("object");
        expect(manifest.transport).to.equal(transport);
        expect(typeof manifest.id).to.equal("string");
        expect(manifest.isDynamic).to.equal(isDynamic);
        expect(manifest.isLive).to.equal(isLive);
        expect(manifest.getUrl()).to.equal(manifestInfos.url);

        expect(manifest.getMaximumSafePosition()).to.equal(maximumPosition);
        expect(manifest.getMinimumSafePosition()).to.equal(minimumPosition);
        expect(manifest.availabilityStartTime).to.equal(availabilityStartTime);

        expect(manifest.periods.length).to.equal(periodsInfos.length);
        for (
          let periodIndex = 0;
          periodIndex < periodsInfos.length;
          periodIndex++
{'fraction_non_alphanumeric': 0.11662355984011286, 'fraction_numerical': 0.004820126969198213, 'mean_word_length': 2.0781617514022073, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 36, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6032377', 'n_tokens_mistral': 4514, 'n_tokens_neox': 4428, 'n_words': 813}