PSA/shared/lib/email/replyParser.test.ts
Hermes 284313f908
Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Initial import of AlgaPSA codebase from PSA server
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz

Source: /opt/alga-psa on psa.joliet.tech
2026-06-22 16:12:17 -05:00

108 lines
3.9 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import { describe, expect, it } from 'vitest';
import { getDefaultReplyParserConfig, parseEmailReply } from './replyParser';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
function readFixture(file: string): string {
return fs.readFileSync(path.join(__dirname, '__fixtures__', file), 'utf8');
}
describe('replyParser', () => {
it('honours explicit reply boundaries and extracts hidden tokens', () => {
const text = readFixture('gmail-top-post.txt');
const html = readFixture('gmail-top-post.html');
const result = parseEmailReply({ text, html });
expect(result.confidence).toBe('high');
expect(result.strategy).toBe('custom-boundary');
expect(result.tokens).toEqual({
conversationToken: 'GHFTK-123',
ticketId: '8f4e9f72-1d7d-4b3c-94fb-2f8f9ccce901',
commentId: '6e5874a5-22a9-479d-a20e-052b43165c0d',
});
expect(result.appliedHeuristics).toContain('explicit-boundary');
expect(result.sanitizedText).toMatchInlineSnapshot(`
"Hi support team,\n\nHappy to confirm the restart worked fine."
`);
expect(result.sanitizedHtml).toMatchInlineSnapshot(`
"<p>Hi support team,</p>\n<p>Happy to confirm the restart worked fine.</p>\n<p>Thanks,<br/>Jane Doe<br/><em>Sent from my iPhone</em></p>"
`);
});
it('removes inline quoted sections but preserves responder notes for Outlook style replies', () => {
const text = readFixture('outlook-inline.txt');
const result = parseEmailReply({ text });
expect(result.confidence).toBe('medium');
expect(result.appliedHeuristics).toContain('quote-prefix');
expect(result.sanitizedText).toMatchInlineSnapshot(`
"Hi Alex,\n\nSee inline below.\n\nSerial: SN-998877."
`);
});
it('keeps user preface while discarding forwarded chains', () => {
const text = readFixture('forwarded-thread.txt');
const result = parseEmailReply({ text });
expect(result.strategy).toMatch(/provider-header|custom-boundary|quoted-block/);
expect(result.sanitizedText).toMatchInlineSnapshot(`
"Please see the forwarded ticket below looks like the customer escalated again."
`);
});
it('strips signatures and confidentiality footers', () => {
const text = readFixture('signature-heavy.txt');
const result = parseEmailReply({ text });
expect(result.sanitizedText).not.toMatch(/Confidentiality Notice/);
expect(result.appliedHeuristics).toContain('signature-trim');
expect(result.sanitizedText).toMatchInlineSnapshot(`
"Hello,\n\nHere is the update you requested. The service has been restored as of 16:45 UTC."
`);
});
it('falls back gracefully when no heuristics match', () => {
const text = 'Quick confirmation that everything works as expected.';
const result = parseEmailReply({ text }, getDefaultReplyParserConfig());
expect(result.strategy).toBe('fallback');
expect(result.sanitizedText).toMatchInlineSnapshot('"Quick confirmation that everything works as expected."');
});
it('recovers tokens wrapped/quoted by Gmail', () => {
const text = `let's see if replies work now
*Robert Isaacs* | *CEO*
2963 Gulf to Bay Blvd. Clearwater, FL | 727-591-7436
On Thu, Nov 20, 2025 at 7:58AM Software <support@nineminds.com> wrote:
> [ALGA-REPLY-TOKEN a83113b5-d30f-4ec9-85ce-0d0ce95fa49a
> ticketId=a5ea2cf5-f572-436c-b485-9b5ca07a9e17
> commentId=3de1cc6a-8d4a-4b3c-9a27-72990ab84226]
> --- Please reply above this line ---
>
> --- Please reply above this line ---
> New Comment Added
`;
const result = parseEmailReply({ text });
expect(result.tokens).toEqual({
conversationToken: 'a83113b5-d30f-4ec9-85ce-0d0ce95fa49a',
ticketId: 'a5ea2cf5-f572-436c-b485-9b5ca07a9e17',
commentId: '3de1cc6a-8d4a-4b3c-9a27-72990ab84226',
});
});
});