Skip to content
Snippets Groups Projects
utils.ts 6.88 KiB
import { JSDOM } from "jsdom";
const fs = require("fs");
import MIMEParser from "@vereign/mime-parser";

const SENT_EML_NAME = "sent.eml";
const RECEIVED_EML_NAME = "received.eml";
import { PlainNormalizer, HTMLNormalizer } from "../src";
import { expect, test } from "@jest/globals";
import { DOM } from "@vereign/dom";
import { diffStringsUnified } from "jest-diff";

expect.extend({
  toContainWithDiff(target, source) {
    let pass = true;
    try {
      expect(target).toEqual(source);
    } catch (e) {
      pass = false;
    }

    return {
      pass,
      message: pass ? () => "Pass" : () => diffStringsUnified(source, target),
    };
  },
});

const mimeCache: { [key: string]: MIMEParser } = {};
const getMime = (path: string): MIMEParser => {
  if (!mimeCache[path]) {
    const mimeString = fs.readFileSync(path).toString();
    mimeCache[path] = new MIMEParser(mimeString);
  }

  return mimeCache[path];
};

export const getNormalizedPlain = (
  testCasePath: string
): {
  sentPlain: string;
  receivedPlain: string;
} => {
  const sentMime = getMime(`${testCasePath}/${SENT_EML_NAME}`);
  const receivedMime = getMime(`${testCasePath}/${RECEIVED_EML_NAME}`);

  const sentNormalizedPlain = PlainNormalizer.normalizePlain(
    sentMime.getPlain()
  );
  const receivedNormalizedPlain = PlainNormalizer.normalizePlain(
    receivedMime.getPlain()
  );

  return {
    sentPlain: sentNormalizedPlain,
    receivedPlain: receivedNormalizedPlain,
  };
};

export const getTestCasesDirs = (testCasesPath: string): Array<string> => {
  return fs.readdirSync(testCasesPath).filter(function (file) {
    return fs.statSync(testCasesPath + "/" + file).isDirectory();
  });
};

export const getNormalizedHtml = (
  testCasePath: string,
  vendor: string
): {
  sentHtml: string;
  receivedHtml: string;
} => {
  const sentMime = getMime(`${testCasePath}/${SENT_EML_NAME}`);
  const receivedMime = getMime(`${testCasePath}/${RECEIVED_EML_NAME}`);

  const sentHtml = sentMime.getHTML();
  const receivedHtml = receivedMime.getHTML();

  const sentDOM = new DOM(sentHtml);
  const receivedDOM = new JSDOM(receivedHtml);

  const sentNormalizedHtml = HTMLNormalizer.normalizeVendorHtml(
    sentDOM.window.document,
    vendor
  );
  const receivedNormalizedHtml = HTMLNormalizer.normalizeVendorHtml(
    receivedDOM.window.document,
    vendor
  );

  return {
    sentHtml: sentNormalizedHtml,
    receivedHtml: receivedNormalizedHtml,
  };
};

export const createDescribeHtmlTestCases = (
  testsPath: string,
  vendor: string
) =>
  /**
   * @param casesGroupName - name of the folder with cases
   * @param failingCases - a list of cases that are failing and ignored. Pending to be fixed
   * @param casesToCheckOnly - a filter to use if you want to check specific cases
   */
  (
    casesGroupName: string,
    failingCases?: Array<string>,
    casesToCheckOnly?: Array<string>
  ) => (): void => {
    const testsCasesPath = testsPath + "/" + casesGroupName;
    let testCasesDirs = getTestCasesDirs(testsCasesPath);

    if (casesToCheckOnly && casesToCheckOnly.length) {
      testCasesDirs = testCasesDirs.filter((dir) =>
        casesToCheckOnly.includes(dir)
      );
    }

    if (failingCases && failingCases.length) {
      testCasesDirs = testCasesDirs.filter(
        (dir) => !failingCases.includes(dir)
      );
    }

    test.each(testCasesDirs)("Case %s", (dirName: string) => {
      const testCasePath = testsCasesPath + "/" + dirName;
      const normalizedHtmls = getNormalizedHtml(testCasePath, vendor);
      const { sentHtml, receivedHtml } = normalizedHtmls;

      // expect(receivedHtml.length).toBeGreaterThan(0);
      // expect(sentHtml.length).toBeGreaterThan(0);

      // eslint-disable-next-line
      // @ts-ignore
      // console.log(receivedHtml);
      expect(receivedHtml).toContainWithDiff(sentHtml);
    });
  };
export const createDescribePlainTestCases = (testsPath: string) => (
  casesName: string,
  failingCases: Array<string> = [],
  casesToCheckOnly?: Array<string>
) => (): void => {
  const testsCasesPath = testsPath + "/" + casesName;
  let testCasesDirs = getTestCasesDirs(testsCasesPath);

  if (casesToCheckOnly && casesToCheckOnly.length) {
    testCasesDirs = testCasesDirs.filter((dir) =>
      casesToCheckOnly.includes(dir)
    );
  }

  if (failingCases && failingCases.length) {
    testCasesDirs = testCasesDirs.filter((dir) => !failingCases.includes(dir));
  }

  test.each(testCasesDirs)("Case %s", (dirName: string) => {
    const testCasePath = testsCasesPath + "/" + dirName;
    const normalizedPlain = getNormalizedPlain(testCasePath);

    const { sentPlain, receivedPlain } = normalizedPlain;
    // expect(sentPlain.length).toBeGreaterThan(0);
    // expect(receivedPlain.length).toBeGreaterThan(0);

    // eslint-disable-next-line
    // @ts-ignore
    expect(receivedPlain).toContainWithDiff(sentPlain);
  });
};

export const createDescribePseudoPlainTestCases = (
  testsPath: string,
  vendor: string
) =>
  /**
   * @param casesGroupName - name of the folder with cases
   * @param failingCases - a list of cases that are failing and ignored. Pending to be fixed
   * @param casesToCheckOnly - a filter to use if you want to check specific cases
   */
  (
    casesGroupName: string,
    failingCases?: Array<string>,
    casesToCheckOnly?: Array<string>
  ) => (): void => {
    const testsCasesPath = testsPath + "/" + casesGroupName;
    let testCasesDirs = getTestCasesDirs(testsCasesPath);

    if (casesToCheckOnly && casesToCheckOnly.length) {
      testCasesDirs = testCasesDirs.filter((dir) =>
        casesToCheckOnly.includes(dir)
      );
    }

    if (failingCases && failingCases.length) {
      testCasesDirs = testCasesDirs.filter(
        (dir) => !failingCases.includes(dir)
      );
    }

    test.each(testCasesDirs)("Case %s", (dirName: string) => {
      const testCasePath = testsCasesPath + "/" + dirName;
      const { sentHtmlDocument, receivedHtmlDocument } = getDOMDocuments(
        testCasePath
      );

      HTMLNormalizer.normalizeVendorHtml(receivedHtmlDocument, vendor);
      HTMLNormalizer.normalizeVendorHtml(sentHtmlDocument, vendor);
      const normalizedReceivedPseudoPlainText = HTMLNormalizer.extractPseudoPlainPart(
        receivedHtmlDocument
      );

      const normalizedSentPseudoPlainText = HTMLNormalizer.extractPseudoPlainPart(
        sentHtmlDocument
      );

      expect(normalizedReceivedPseudoPlainText).toEqual(
        normalizedSentPseudoPlainText
      );
    });
  };

export const getDOMDocuments = (
  testCasePath: string
): {
  sentHtmlDocument: HTMLDocument;
  receivedHtmlDocument: HTMLDocument;
} => {
  const sentMime = getMime(`${testCasePath}/${SENT_EML_NAME}`);
  const receivedMime = getMime(`${testCasePath}/${RECEIVED_EML_NAME}`);

  const sentDOM = new DOM(sentMime.getHTML());
  const receivedDOM = new JSDOM(receivedMime.getHTML());

  return {
    sentHtmlDocument: sentDOM.window.document,
    receivedHtmlDocument: receivedDOM.window.document,
  };
};