import { describe, it, expect } from 'vitest'; import { EmailQuoteExtractor } from '../emailQuoteExtractor.js'; const SAMPLE_EMAIL_HTML = `

method

On Mon, Sep 29, 2025 at 5:18 PM John shivam@chatwoot.com wrote:

Hi

On Mon, Sep 29, 2025 at 5:17 PM Shivam Mishra shivam@chatwoot.com wrote:

Yes, it is.

On Mon, Sep 29, 2025 at 5:16 PM John from Shaneforwoot < shaneforwoot@gmail.com> wrote:

Hey

On Mon, Sep 29, 2025 at 4:59 PM John shivam@chatwoot.com wrote:

This is another quoted quoted text reply

This is nice

On Mon, Sep 29, 2025 at 4:21 PM John from Shaneforwoot < > shaneforwoot@gmail.com> wrote:

Hey there, this is a reply from Chatwoot, notice the quoted text

Hey there

This is an email text, enjoy reading this

-- Shivam Mishra, Chatwoot

`; const EMAIL_WITH_SIGNATURE = `

Latest reply here.

Thanks,

Jane Doe

On Mon, Sep 22, Someone wrote:

Previous reply content

`; const EMAIL_WITH_FOLLOW_UP_CONTENT = `

Inline quote that should stay

Internal note follows

Regards,

`; describe('EmailQuoteExtractor', () => { it('removes blockquote-based quotes from the email body', () => { const cleanedHtml = EmailQuoteExtractor.extractQuotes(SAMPLE_EMAIL_HTML); const container = document.createElement('div'); container.innerHTML = cleanedHtml; expect(container.querySelectorAll('blockquote').length).toBe(0); expect(container.textContent?.trim()).toBe('method'); expect(container.textContent).not.toContain( 'On Mon, Sep 29, 2025 at 5:18 PM' ); }); it('keeps blockquote fallback when it is not the last top-level element', () => { const cleanedHtml = EmailQuoteExtractor.extractQuotes( EMAIL_WITH_FOLLOW_UP_CONTENT ); const container = document.createElement('div'); container.innerHTML = cleanedHtml; expect(container.querySelector('blockquote')).not.toBeNull(); expect(container.lastElementChild?.tagName).toBe('P'); }); it('detects quote indicators in nested blockquotes', () => { const result = EmailQuoteExtractor.hasQuotes(SAMPLE_EMAIL_HTML); expect(result).toBe(true); }); it('does not flag blockquotes that are followed by other elements', () => { expect(EmailQuoteExtractor.hasQuotes(EMAIL_WITH_FOLLOW_UP_CONTENT)).toBe( false ); }); it('returns false when no quote indicators are present', () => { const html = '

Plain content

'; expect(EmailQuoteExtractor.hasQuotes(html)).toBe(false); }); it('removes trailing blockquotes while preserving trailing signatures', () => { const cleanedHtml = EmailQuoteExtractor.extractQuotes(EMAIL_WITH_SIGNATURE); expect(cleanedHtml).toContain('

Thanks,

'); expect(cleanedHtml).toContain('

Jane Doe

'); expect(cleanedHtml).not.toContain(' { expect(EmailQuoteExtractor.hasQuotes(EMAIL_WITH_SIGNATURE)).toBe(true); }); });