62 lines · 2.6 KB
import { describe, expect, test } from "bun:test";
import { extractReplyText, htmlToReplyText } from "./email-reply-text";

describe("extractReplyText", () => {
  test("keeps the reply and drops a Gmail-style quote", () => {
    const text = [
      "Thanks, that fixed it.",
      "",
      "Will close once CI is green.",
      "",
      "On Mon, Oct 12, 2026 at 9:14 AM gitfor <noreply@mail.gitfor.dev> wrote:",
      "> [gitfor] acme/web#12: Crash on save",
      "> View on the forge: https://gitfor.dev/acme/web/issues/12",
    ].join("\n");
    expect(extractReplyText(text, null)).toBe("Thanks, that fixed it.\n\nWill close once CI is green.");
  });

  test("handles an attribution line wrapped onto two lines", () => {
    const text = "Looks good\n\nOn Mon, Oct 12, 2026 at 9:14 AM gitfor <noreply@mail.gitfor.dev>\nwrote:\n> quoted";
    expect(extractReplyText(text, null)).toBe("Looks good");
  });

  test("stops at Outlook header blocks and original-message rules", () => {
    expect(extractReplyText("Yes\n\nFrom: gitfor <noreply@mail.gitfor.dev>\nSent: Monday\nSubject: x", null)).toBe(
      "Yes",
    );
    expect(extractReplyText("Agreed\n-----Original Message-----\nFrom: someone", null)).toBe("Agreed");
    expect(extractReplyText("Done\n________________________________\nFrom: gitfor", null)).toBe("Done");
  });

  test("drops signatures, mobile footers and stray quoted lines", () => {
    expect(extractReplyText("Ship it\n-- \nAlice\nACME Corp", null)).toBe("Ship it");
    expect(extractReplyText("On it\n\nSent from my iPhone", null)).toBe("On it");
    expect(extractReplyText("> earlier text\nMy answer\n> more quote", null)).toBe("My answer");
  });

  test("keeps markdown and inline code intact", () => {
    const text = "Try:\n\n```sh\nbun test --isolate\n```\n\n- one\n- two";
    expect(extractReplyText(text, null)).toBe(text);
  });