checkFolder = (videoFormat, name, { directories, files }) =>
  describe(name, () => {
    for (const [folderName, subDirectory] of Object.entries(directories)) {
      checkFolder(videoFormat, folderName, subDirectory);
    }

    it("index.md is valid", () => {
      expect(files["index.md"]).not.toBeUndefined();

      // faq exception for series format requirement
      if (name === "_more/faq") {
        assertPropTypes(formatDefinitions.faq, files["index.md"].content, "YAML", "index.md");
        return;
      }

      assertPropTypes(formatDefinitions.series, files["index.md"].content, "YAML", "index.md");
    });

    it("files are uniquely numbered", () => {
      let numbers = Object.keys(files).map((fileName) => fileName.split("-")[0]);
      let numberSet = new Set(numbers);
      expect(numbers).toHaveLength(numberSet.size);
    });

    for (const [fileName, file] of Object.entries(files)) {
      if (fileName === "index.md") {
        // We handled that already.
        continue;
      }

      describe(fileName, () => {
        try {
          file.load();
        } catch (e) {}

        const valid = file.isValid();

        // Set up global state needed for all tests, these get run before any tests.
        if (valid) {
          const { video_id, web_editor, repository } = file.content;
          const resolvedRepository = repository ? resolveLocalUrl(repository, path.dirname(markdownFilenameToUrl(file.path))) : repository;

          if (video_id) {
            knownVideos[video_id] = knownVideos[video_id] || [];
            knownVideos[video_id].push(file);
          }

          if (repository) {
            const repoToEditor = (repositoryToWebEditorMapping[resolvedRepository] = repositoryToWebEditorMapping[resolvedRepository] || {});
            const editorSources = (repoToEditor[web_editor] = repoToEditor[web_editor] || []);
            editorSources.push(file);
          }

          if (web_editor) {
            const editorToRepo = (webEditorToRepositoryMapping[web_editor] = webEditorToRepositoryMapping[web_editor] || {});
            const repoSources = (editorToRepo[resolvedRepository] = editorToRepo[resolvedRepository] || []);
            repoSources.push(file);
          }
          // Unload for the first pass, will be reloaded when required
          file.unload();
        }

        afterAll(() => file.unload());

        it("is formatted correctly", () => {
          file.load();
        });

        itIf(valid)("has valid YAML layout and types", () => {
          assertPropTypes(videoFormat, file.content, "YAML", fileName);
        });

        itIf(valid)("title matches internal numbering", () => {
          // Get file name with leading zeros stripped
          let fileNumber = fileName.split("-")[0];
          fileNumber = fileNumber.replace(/^0+/, "");

          // Gets internal representation as a string
          let videoString = file.content.video_number.toString();
          // If we're in a standalone
          if (videoString === fileNumber) return;
          // If the video has parts, check we match the last one only.
          let parts = fileNumber.split(".");
          if (videoString === parts[parts.length - 1] || file.content.ignore_filename) return;
          throw new Error("Expected file numbering to match internal numbering");
        });

        itIf(valid && file.content.video_id)("Has a unique video_id", () => {
          const fileList = knownVideos[file.content.video_id];
          if (fileList.length !== 1) {
            throw new Error(
              `video_id is shared with: ${fileList
                .filter((f) => f !== file)
                .map((f) => f.path)
                .join(", ")}`,
            );
          }
        });

        describeIf(valid)("YouTube links", () => {
          function findVideos(obj) {
            if (typeof obj === "string") {
              return;
            }
            for (let [k, videoId] of Object.entries(obj)) {
              if (k === "video_id") {
                it(`linked video ID: ${videoId} is not a local link`, () => {
                  if (videoId in knownVideos) {
                    throw new Error(`Video ${videoId} linked in ${file.path} should point to ${markdownFilenameToUrl(knownVideos[videoId][0].path)}`);
                  }
                });
              }
              findVideos(obj[k]);
            }
          }
          const { video_id, ...remainingEntries } = file.content;
          findVideos(remainingEntries);
        });

        itIf(valid)("has a valid repository to web_editor mapping", () => {
          // This only checks that for an unset web_editor that should be set
          const { repository, web_editor } = file.content;
          if (repository && !web_editor) {
            let resolvedRepository = resolveLocalUrl(repository, path.dirname(markdownFilenameToUrl(file.path)));
            const webEditors = repositoryToWebEditorMapping[resolvedRepository];
            const webEditorList = Object.keys(webEditors);
            if (webEditorList.length === 2) {
              const correct = webEditorList[0] === "undefined" ? webEditorList[1] : webEditorList[0];
              throw new Error(`should have web_editor = ${correct}\n - The relationship of ${resolvedRepository} <-> ${correct} is defined in ${webEditors[correct].map((f) => f.path).join(", ")}`);
            }
          }
        });

        itIf(valid)("has a valid web_editor to repository mapping", () => {
          // This only checks that for an unset repository that should be set
          const { repository, web_editor } = file.content;
          if (web_editor && !repository) {
            const repositories = webEditorToRepositoryMapping[web_editor];
            const repositoryList = Object.keys(repositories);
            if (repositoryList.length === 2) {
              const correct = repositoryList[0] === "undefined" ? repositoryList[1] : repositoryList[0];
              throw new Error(`should have repository = ${correct}\n - The relationship of ${correct} <-> ${web_editor} is defined in ${repositories[correct].map((f) => f.path).join(", ")}`);
            }
          }
        });
      });
    }
  })
************************************************
This file was created by Billy Timimi.
Other contributors include: *add you your name here if you were kind enough to help.*

The purpose of this file is to do unit testing of all the files in the
_CodingChallenges directory, in order to insure they are all valid.

If you are trying to read the source of the website and are unsure as to what
this file does/what unit testing is, I reccomend you check out the coding train's
video on it: https://www.youtube.com/watch?v=S3QwafQEvSs, it's where I learn't
everything needed to create this script.
*************************************************