From 2ddf79667069ce71260e7f89293b5d3090ac4114 Mon Sep 17 00:00:00 2001
From: igor <igor.markin@vereign.com>
Date: Fri, 27 Nov 2020 16:40:44 +0300
Subject: [PATCH] Implement plain part normalisation

---
 ...k.test.ts => html-outlook-outlook.test.ts} | 13 ++--
 __tests__/plain-outlook-outlook.test.ts       | 69 +++++++++++++++++++
 src/PlainNormalizer/PlainNormalizer.ts        | 12 ++++
 src/PlainNormalizer/index.ts                  |  5 ++
 src/index.ts                                  |  1 +
 5 files changed, 93 insertions(+), 7 deletions(-)
 rename __tests__/{outlook-outlook.test.ts => html-outlook-outlook.test.ts} (86%)
 create mode 100644 __tests__/plain-outlook-outlook.test.ts
 create mode 100644 src/PlainNormalizer/PlainNormalizer.ts
 create mode 100644 src/PlainNormalizer/index.ts

diff --git a/__tests__/outlook-outlook.test.ts b/__tests__/html-outlook-outlook.test.ts
similarity index 86%
rename from __tests__/outlook-outlook.test.ts
rename to __tests__/html-outlook-outlook.test.ts
index 42268f6..9f73a81 100644
--- a/__tests__/outlook-outlook.test.ts
+++ b/__tests__/html-outlook-outlook.test.ts
@@ -4,7 +4,6 @@ import HTMLNormalizer from "../src/HTMLNormalizer";
 import { EMAIL_VENDORS } from "../src/constants";
 const fs = require("fs");
 const path = require("path");
-const util = require("util");
 
 // Test cases from https://code.vereign.com/alexey.lunin/outlook-files-upload
 
@@ -18,7 +17,7 @@ const getTestCasesDirs = (testCasesPath: string) => {
     return fs.statSync(testCasesPath + "/" + file).isDirectory();
   });
 };
-console.debug = () => {}
+
 const getNormalizedHtml = (
   testCasePath: string
 ): {
@@ -73,9 +72,9 @@ describe("Outlook emails HTML normalization", () => {
     });
   };
 
-   describe("Emails Chrome", describeTestCases("chrome"));
-   describe("Emails Edge", describeTestCases("edge"));
-   describe("Emails Safari", describeTestCases("safari"));
-  //describe("Emails MacOS", describeTestCases("macos"));
-  // describe("Emails Windows", describeTestCases("windows"));
+  describe("Emails Chrome", describeTestCases("chrome"));
+  describe("Emails Edge", describeTestCases("edge"));
+  describe("Emails Safari", describeTestCases("safari"));
+  describe("Emails MacOS", describeTestCases("macos"));
+  describe("Emails Windows", describeTestCases("windows"));
 });
diff --git a/__tests__/plain-outlook-outlook.test.ts b/__tests__/plain-outlook-outlook.test.ts
new file mode 100644
index 0000000..4d22eed
--- /dev/null
+++ b/__tests__/plain-outlook-outlook.test.ts
@@ -0,0 +1,69 @@
+import { describe, test, expect } from "@jest/globals";
+import { PlainNormalizer } from "../src";
+const fs = require("fs");
+const path = require("path");
+
+// Test cases from https://code.vereign.com/alexey.lunin/outlook-files-upload
+
+const TESTS_GLOBAL_PATH = "/outlook-files-upload/uploads";
+const SENT_HTML_NAME = "s_initialPlainContent.data";
+const RECEIVED_HTML_NAME = "r_plainContent.data";
+
+const testsPath = path.resolve(__dirname, `..${TESTS_GLOBAL_PATH}`);
+const getTestCasesDirs = (testCasesPath: string) => {
+  return fs.readdirSync(testCasesPath).filter(function (file) {
+    return fs.statSync(testCasesPath + "/" + file).isDirectory();
+  });
+};
+
+const getNormalizedHtml = (
+  testCasePath: string
+): {
+  sentPlain: string;
+  receivedPlain: string;
+} => {
+  const sentPlain = fs
+    .readFileSync(`${testCasePath}/${SENT_HTML_NAME}`)
+    .toString();
+  const receivedPlain = fs
+    .readFileSync(`${testCasePath}/${RECEIVED_HTML_NAME}`)
+    .toString();
+
+  const sentNormalizedPlain = PlainNormalizer.normalizePlain(sentPlain);
+  const receivedNormalizedPlain = PlainNormalizer.normalizePlain(receivedPlain);
+
+  return {
+    sentPlain: sentNormalizedPlain,
+    receivedPlain: receivedNormalizedPlain,
+  };
+};
+
+describe("Outlook emails Plain normalization", () => {
+  const describeTestCases = (casesName: string) => () => {
+    const testsCasesPath = testsPath + "/" + casesName;
+    const testCasesDirs = getTestCasesDirs(testsCasesPath);
+
+    test.each(testCasesDirs)("Case %s", (dirName: string) => {
+      const testCasePath = testsCasesPath + "/" + dirName;
+      let normalizedHtmls;
+      try {
+        normalizedHtmls = getNormalizedHtml(testCasePath);
+      } catch (e) {
+        console.log(`Invalid test case: ${casesName}/${dirName}`);
+        return;
+      }
+
+      const { sentPlain, receivedPlain } = normalizedHtmls;
+
+      expect(sentPlain.length).toBeGreaterThan(0);
+      expect(receivedPlain.length).toBeGreaterThan(0);
+      expect(receivedPlain).toContain(sentPlain);
+    });
+  };
+
+  describe("Emails Chrome", describeTestCases("chrome"));
+  describe("Emails Edge", describeTestCases("edge"));
+  describe("Emails Safari", describeTestCases("safari"));
+  describe("Emails MacOS", describeTestCases("macos"));
+  describe("Emails Windows", describeTestCases("windows"));
+});
diff --git a/src/PlainNormalizer/PlainNormalizer.ts b/src/PlainNormalizer/PlainNormalizer.ts
new file mode 100644
index 0000000..dc4cd68
--- /dev/null
+++ b/src/PlainNormalizer/PlainNormalizer.ts
@@ -0,0 +1,12 @@
+import { removeSpacesAndLinebreaks } from "../utils";
+
+export const normalizePlainPart = (text: string): string => {
+  text = removeSpacesAndLinebreaks(text);
+  return removeQRCodes(text);
+};
+
+const removeQRCodes = (s: string): string => {
+  return s
+    .replace(/\[qrcode.png]\s*<https:\/\/[\w./?=\-&]+>/g, "")
+    .replace(/<https:\/\/[\w./?=\-&]+>\s*\[qrcode.png]/g, "");
+};
diff --git a/src/PlainNormalizer/index.ts b/src/PlainNormalizer/index.ts
new file mode 100644
index 0000000..0822822
--- /dev/null
+++ b/src/PlainNormalizer/index.ts
@@ -0,0 +1,5 @@
+import { normalizePlainPart } from "./PlainNormalizer";
+
+export default {
+  normalizePlain: normalizePlainPart,
+};
diff --git a/src/index.ts b/src/index.ts
index 791915c..32d700f 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1 +1,2 @@
 export { default as HTMLNormalizer } from "./HTMLNormalizer";
+export { default as PlainNormalizer } from "./PlainNormalizer";
-- 
GitLab