/* * SPDX-FileCopyrightText: 2020 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ import { renderToStaticMarkup } from 'react-dom/server' import { convertHtmlToReact, ParserOptions } from './convertHtmlToReact.js' import { convertNodeToReactElement } from './convertNodeToReactElement.js' import { Document, isTag, isText } from 'domhandler' import { NodeToReactElementTransformer } from './NodeToReactElementTransformer.js' import React, { ReactElement } from 'react' import { beforeEach, describe, expect, it, vitest, beforeAll, afterAll } from 'vitest' import { ElementType } from 'htmlparser2' function parseHtmlToReactHtml(html: string, options: ParserOptions = {}) { return renderToStaticMarkup(
test
')).toBe( expectedHtml('test
') ) }) it('should convert boolean attribute values', () => { expect(parseHtmlToReactHtml('')).toBe( expectedHtml('') ) expect(parseHtmlToReactHtml('')).toBe( expectedHtml('') ) expect(parseHtmlToReactHtml('')).toBe( expectedHtml('') ) }) ;[ ['CONTENTEDITABLE', 'contentEditable'], ['LABEL', 'label'], ['iTemREF', 'itemRef'] ].forEach(([attr, prop]) => { it(`should convert attribute ${attr} to prop ${prop}`, () => { const nodes = convertHtmlToReact(``, {}) expect(nodes).toHaveLength(1) expect((nodes[0] as ReactElement).props).toHaveProperty(prop) }) }) it('should decode html entities by default', () => { expect(parseHtmlToReactHtml('!')).toBe( expectedHtml('!') ) }) it('should not decode html entities when the option is disabled', () => { expect( parseHtmlToReactHtml('!', { decodeEntities: false }) ).toBe(expectedHtml('!')) }) describe('transform function', () => { it('should use the response when it is not undefined', () => { expect( parseHtmlToReactHtml('testtransformed
} }) ).toBe(expectedHtml('transformed
transformed
')) }) it('should not render elements and children when returning null', () => { expect( parseHtmlToReactHtml( 'testinner testbold child
', { transform(node) { if ( isTag(node) && ElementType.isTag(node) && node.name === 'span' ) { return null } } } ) ).toBe(expectedHtml('test
')) }) it('should allow modifying nodes', () => { expect( parseHtmlToReactHtml('test link', { transform(node, index) { if (isTag(node)) { node.attribs.href = '/changed' } return convertNodeToReactElement(node, index) } }) ).toBe(expectedHtml('test link')) }) it('should allow passing the transform function down to children', () => { const transform: NodeToReactElementTransformer = (node, index) => { if (isTag(node)) { if (node.name === 'ul') { node.attribs.class = 'test' return convertNodeToReactElement(node, index, transform) } } else if (isText(node)) { return node.data.replace(/list/, 'changed') } else { return null } } expect( parseHtmlToReactHtml('