diff --git a/apps/api/src/services/EmailService.ts b/apps/api/src/services/EmailService.ts index 85ce5cd..890701d 100644 --- a/apps/api/src/services/EmailService.ts +++ b/apps/api/src/services/EmailService.ts @@ -659,12 +659,16 @@ export class EmailService { /** * Detects if HTML contains custom patterns that indicate it was written in the HTML editor * rather than the visual editor. Mirrors the same logic in apps/web/src/lib/emailStyles.ts. + * + * The TipTap editor loads StarterKit + TextAlign + Color + TextStyle + Link + + * ResizableImage + VariableMention. TextStyle/Color/Link round-trip and + * markup. This detection therefore PERMITS span + inline styles and only + * REJECTS markup TipTap cannot represent (tables, divs, forms, embeds, custom attrs, + * ')).toBe(true); + }); + + it('returns true for @media query inside a style block', () => { + expect(detectCustomHtmlPatterns('@media (max-width: 600px) { ... }')).toBe(true); + }); + + it('returns true for custom data-* attribute', () => { + expect(detectCustomHtmlPatterns('

x

')).toBe(true); + }); + + it('returns true for aria-* attribute', () => { + expect(detectCustomHtmlPatterns('

y

')).toBe(true); + }); + + it('returns true for role= attribute', () => { + expect(detectCustomHtmlPatterns('

x

')).toBe(true); + }); + + it('returns true for id= attribute on an element', () => { + expect(detectCustomHtmlPatterns('

x

')).toBe(true); + }); + + it('returns true for a disallowed CSS class', () => { + expect(detectCustomHtmlPatterns('

x

')).toBe(true); + }); + + it('returns true for
,
,
,