diff --git a/plugins/techdocs/src/reader/transformers/html/transformer.sanitizer.test.tsx b/plugins/techdocs/src/reader/transformers/html/transformer.sanitizer.test.tsx index 39d3d229aa..ed02f86060 100644 --- a/plugins/techdocs/src/reader/transformers/html/transformer.sanitizer.test.tsx +++ b/plugins/techdocs/src/reader/transformers/html/transformer.sanitizer.test.tsx @@ -143,4 +143,35 @@ describe('Transformers > Html > Sanitizer Custom Elements', () => { expect(elements).toHaveLength(1); expect(elements[0].hasAttribute('dominant-baseline')).toBe(true); }); + + it('removes javascript: hrefs while preserving link text', async () => { + const { result } = renderHook(() => useSanitizerTransformer(), { wrapper }); + const dirtyDom = document.createElement('html'); + const dirtyHTML = ` + + + JS 1 + JS 2 (leading space) + JS 3 (whitespace) + + JS 4 (mixed case) + JS 5 (entity-encoded colon) + `; + dirtyDom.innerHTML = dirtyHTML; + const clearDom = await result.current(dirtyDom); // calling html transformer + const elements = Array.from( + clearDom.querySelectorAll('body > a'), + ); + expect(elements).toHaveLength(5); + for (const el of elements) { + // DOMPurify strips the dangerous href attribute + expect(el.getAttribute('href')).toBeNull(); + } + // link text remains + expect(clearDom.textContent).toContain('JS 1'); + expect(clearDom.textContent).toContain('JS 2 (leading space)'); + expect(clearDom.textContent).toContain('JS 3 (whitespace)'); + expect(clearDom.textContent).toContain('JS 4 (mixed case)'); + expect(clearDom.textContent).toContain('JS 5 (entity-encoded colon)'); + }); });