snapshot of https://github.com/marmelab/atomic-crm.git (main, 2026-09-18; blobs > 131072B omitted)
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
Some checks failed
✅ Check / 🔬 ESLint (push) Failing after 21s
✅ Check / 🏷️ Typecheck (push) Failing after 11s
✅ Check / 🔎 Test (push) Failing after 11s
✅ Check / e2e-test (push) Failing after 11s
✅ Check / 🔨 Build (push) Failing after 11s
🚀 Deploy / 🚀 Deploy (doc) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (demo) (push) Failing after 12s
🚀 Deploy / 🚀 Deploy (supabase) (push) Failing after 18s
This commit is contained in:
321
supabase/functions/postmark/forwardedParser.test.ts
Normal file
321
supabase/functions/postmark/forwardedParser.test.ts
Normal file
@@ -0,0 +1,321 @@
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import {
|
||||
stripForwardingHeaderBlock,
|
||||
stripSubjectForwardingPrefix,
|
||||
stripMailSignature,
|
||||
getForwardedMailContent,
|
||||
} from "./forwardedParser";
|
||||
|
||||
describe("forwardedParser", () => {
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
describe("stripForwardingHeaderBlock", () => {
|
||||
describe("returns original text when no forwarding separator is found", () => {
|
||||
it("returns the original text for plain content", () => {
|
||||
const text = "Hello, this is a regular email body.";
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(text);
|
||||
});
|
||||
|
||||
it("trims whitespace when no separator is found", () => {
|
||||
const text = " Hello world ";
|
||||
expect(stripForwardingHeaderBlock(text)).toBe("Hello world");
|
||||
});
|
||||
|
||||
it("returns original text when separator is not on the first line", () => {
|
||||
const text =
|
||||
"Some intro line\n---------- Forwarded message ----------\nActual content";
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(text.trim());
|
||||
});
|
||||
});
|
||||
|
||||
describe("Gmail forwarded separator", () => {
|
||||
it("strips the Gmail forwarded header block", () => {
|
||||
const text = [
|
||||
"---------- Forwarded message ----------",
|
||||
"From: Alice <alice@example.com>",
|
||||
"Date: Mon, 24 Feb 2026 10:00:00 +0000",
|
||||
"Subject: Meeting notes",
|
||||
"To: Bob <bob@example.com>",
|
||||
"",
|
||||
"Hi Bob,",
|
||||
"",
|
||||
"Here are the meeting notes.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(
|
||||
"Hi Bob,\n\nHere are the meeting notes.",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Apple Mail forwarded separator", () => {
|
||||
it("strips the Apple Mail forwarded header block", () => {
|
||||
const text = [
|
||||
"Begin forwarded message:",
|
||||
"From: Alice <alice@example.com>",
|
||||
"Subject: Hello",
|
||||
"Date: 24 Feb 2026",
|
||||
"To: Bob <bob@example.com>",
|
||||
"",
|
||||
"This is the original message.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(
|
||||
"This is the original message.",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Outlook / Exchange forwarded separator", () => {
|
||||
it("strips the Outlook forwarded header block", () => {
|
||||
const text = [
|
||||
"-----Original Message-----",
|
||||
"From: Alice <alice@example.com>",
|
||||
"Sent: Monday, February 24, 2026 10:00 AM",
|
||||
"To: Bob <bob@example.com>",
|
||||
"Subject: Project update",
|
||||
"",
|
||||
"Please find the update below.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(
|
||||
"Please find the update below.",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("French forwarded separators", () => {
|
||||
it("strips the 'Message transféré' header block", () => {
|
||||
const text = [
|
||||
"---------- Message transféré ----------",
|
||||
"De : Alice <alice@example.com>",
|
||||
"Date : 24 févr. 2026",
|
||||
"Objet : Réunion",
|
||||
"",
|
||||
"Bonjour,",
|
||||
"",
|
||||
"Voici le message.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(
|
||||
"Bonjour,\n\nVoici le message.",
|
||||
);
|
||||
});
|
||||
|
||||
it("strips the 'Transféré' header block", () => {
|
||||
const text = [
|
||||
"----- Transféré -----",
|
||||
"De : Alice <alice@example.com>",
|
||||
"",
|
||||
"Le message transféré.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe("Le message transféré.");
|
||||
});
|
||||
|
||||
it("strips the ASCII-variant 'Message transfere' header block", () => {
|
||||
const text = [
|
||||
"---------- Message transfere ----------",
|
||||
"De : Alice <alice@example.com>",
|
||||
"",
|
||||
"Bonjour.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe("Bonjour.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("German forwarded separator", () => {
|
||||
it("strips the 'Weitergeleitete Nachricht' header block", () => {
|
||||
const text = [
|
||||
"---------- Weitergeleitete Nachricht ----------",
|
||||
"Von: Alice <alice@example.com>",
|
||||
"Datum: 24. Feb. 2026",
|
||||
"Betreff: Projekt",
|
||||
"",
|
||||
"Hallo,",
|
||||
"",
|
||||
"Hier ist die Nachricht.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(
|
||||
"Hallo,\n\nHier ist die Nachricht.",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("edge cases", () => {
|
||||
it("strip everything when there is only one forwarded block and nothing after", () => {
|
||||
const text = [
|
||||
"---------- Forwarded message ----------",
|
||||
"From: Alice <alice@example.com>",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe("");
|
||||
});
|
||||
|
||||
it("preserves multi-paragraph body content", () => {
|
||||
const text = [
|
||||
"---------- Forwarded message ----------",
|
||||
"From: Alice <alice@example.com>",
|
||||
"",
|
||||
"First paragraph.",
|
||||
"",
|
||||
"Second paragraph.",
|
||||
"",
|
||||
"Third paragraph.",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe(
|
||||
"First paragraph.\n\nSecond paragraph.\n\nThird paragraph.",
|
||||
);
|
||||
});
|
||||
|
||||
it("trims leading and trailing whitespace from the result", () => {
|
||||
const text = [
|
||||
"---------- Forwarded message ----------",
|
||||
"From: Alice",
|
||||
"",
|
||||
" ",
|
||||
" Body content ",
|
||||
" ",
|
||||
].join("\n");
|
||||
|
||||
expect(stripForwardingHeaderBlock(text)).toBe("Body content");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("stripSubjectForwardingPrefix", () => {
|
||||
it("strips 'Fwd:' prefix", () => {
|
||||
expect(stripSubjectForwardingPrefix("Fwd: Hello")).toBe("Hello");
|
||||
});
|
||||
|
||||
it("strips 'FW:' prefix", () => {
|
||||
expect(stripSubjectForwardingPrefix("FW: Hello")).toBe("Hello");
|
||||
});
|
||||
|
||||
it("strips 'FWD:' prefix", () => {
|
||||
expect(stripSubjectForwardingPrefix("FWD: Hello")).toBe("Hello");
|
||||
});
|
||||
|
||||
it("strips 'Tr:' prefix (French)", () => {
|
||||
expect(stripSubjectForwardingPrefix("Tr: Bonjour")).toBe("Bonjour");
|
||||
});
|
||||
|
||||
it("strips 'SV:' prefix (Scandinavian)", () => {
|
||||
expect(stripSubjectForwardingPrefix("SV: Hei")).toBe("Hei");
|
||||
});
|
||||
|
||||
it("strips 'VS:' prefix", () => {
|
||||
expect(stripSubjectForwardingPrefix("VS: Hallo")).toBe("Hallo");
|
||||
});
|
||||
|
||||
it("strips 'WG:' prefix (German)", () => {
|
||||
expect(stripSubjectForwardingPrefix("WG: Hallo")).toBe("Hallo");
|
||||
});
|
||||
|
||||
it("is case-insensitive", () => {
|
||||
expect(stripSubjectForwardingPrefix("fwd: lowercase")).toBe("lowercase");
|
||||
expect(stripSubjectForwardingPrefix("FWD - Mixed")).toBe("Mixed");
|
||||
});
|
||||
|
||||
it("returns the subject unchanged when no prefix is present", () => {
|
||||
expect(stripSubjectForwardingPrefix("Meeting notes")).toBe(
|
||||
"Meeting notes",
|
||||
);
|
||||
});
|
||||
|
||||
it("handles dash separator instead of colon", () => {
|
||||
expect(stripSubjectForwardingPrefix("Fwd - My subject")).toBe(
|
||||
"My subject",
|
||||
);
|
||||
});
|
||||
|
||||
it("should return original subject if stripping results in empty string", () => {
|
||||
vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
const subject = "Fwd: ";
|
||||
expect(stripSubjectForwardingPrefix(subject)).toBe(subject);
|
||||
});
|
||||
});
|
||||
|
||||
describe("stripMailSignature", () => {
|
||||
it("strips the mail signature when separator is present", () => {
|
||||
const text = "Hello,\nThis is the email body.\n-- \nSignature here";
|
||||
expect(stripMailSignature(text)).toBe("Hello,\nThis is the email body.");
|
||||
});
|
||||
|
||||
it("returns original text when no signature separator is found", () => {
|
||||
const text = "Hello,\nThis is the email body.\nBest regards.";
|
||||
expect(stripMailSignature(text)).toBe(text);
|
||||
});
|
||||
|
||||
it("handles multiple occurrences of the signature separator", () => {
|
||||
const text =
|
||||
"Hello,\nThis is the email body.\n-- \nFirst signature\n-- \nSecond signature";
|
||||
expect(stripMailSignature(text)).toBe("Hello,\nThis is the email body.");
|
||||
});
|
||||
|
||||
it("trims whitespace from the result", () => {
|
||||
const text = "Hello,\nThis is the email body.\n-- \nSignature here ";
|
||||
expect(stripMailSignature(text)).toBe("Hello,\nThis is the email body.");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getForwardedMailContent", () => {
|
||||
it("strips both the forwarding header block and the mail signature", () => {
|
||||
const text = [
|
||||
"---------- Forwarded message ----------",
|
||||
"From: Alice <alice@wonderland.com>",
|
||||
"",
|
||||
"Hi Bob,",
|
||||
"This is the original message.",
|
||||
"-- \nAlice's signature",
|
||||
].join("\n");
|
||||
|
||||
expect(getForwardedMailContent(text)).toBe(
|
||||
"Hi Bob,\nThis is the original message.",
|
||||
);
|
||||
});
|
||||
|
||||
it("returns original text when stripping results in empty content", () => {
|
||||
vi.spyOn(console, "warn").mockImplementation(() => {});
|
||||
const text = [
|
||||
"---------- Forwarded message ----------",
|
||||
"From: Alice <alice@wonderland.com>",
|
||||
"",
|
||||
"-- \nAlice's signature",
|
||||
].join("\n");
|
||||
|
||||
// Both stripping operations would result in empty content, so original text should be returned.
|
||||
expect(getForwardedMailContent(text)).toBe(text.trim());
|
||||
});
|
||||
|
||||
it("handles text with no forwarding header and no signature", () => {
|
||||
const text = "Hello,\nThis is a simple email body.";
|
||||
expect(getForwardedMailContent(text)).toBe(text);
|
||||
});
|
||||
|
||||
it("handles text with only a forwarding header", () => {
|
||||
const text = [
|
||||
"---------- Forwarded message ----------",
|
||||
"From: Alice <alice@wonderland.com>",
|
||||
"",
|
||||
"This is the original message.",
|
||||
].join("\n");
|
||||
|
||||
expect(getForwardedMailContent(text)).toBe(
|
||||
"This is the original message.",
|
||||
);
|
||||
});
|
||||
|
||||
it("handles text with only a mail signature", () => {
|
||||
const text = "Hello,\nThis is the email body.\n-- \nBest regards.";
|
||||
expect(getForwardedMailContent(text)).toBe(
|
||||
"Hello,\nThis is the email body.",
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user