import type { ReactElement } from 'react' import { renderHook } from '@testing-library/react-hooks' import type { ASTType } from '../../types' import useRichText from './useRichText' describe('useRichText', () => { describe('not allowed tags', () => { it('returns the unmapped tag', () => { const tree = { type: 'root', children: [ { type: 'element', tagName: 'h1', properties: {}, children: [{ type: 'text', value: 'foobar' }], }, ], } as unknown as ASTType const { result } = renderHook(() => useRichText(tree)) const header = result.current as ReactElement expect(header.type).toBe('h1') expect(header.props.children).toEqual(['foobar']) }) }) describe('allowed tags', () => { ;(['p', 'h3', 'strong', 'em', 'ul', 'ol', 'li'] as const).forEach(tag => { it(`maps ${tag} with proper Picasso component`, () => { const tree: ASTType = { type: 'root', children: [ { type: 'element', tagName: tag, properties: {}, children: [{ type: 'text', value: 'foobar' }], }, ], } const { result } = renderHook(() => useRichText(tree)) const element = result.current as ReactElement const componentName = tag.charAt(0).toUpperCase() + tag.slice(1) expect((element.type as Function).name).toEqual(componentName) expect(element.props.children).toEqual(['foobar']) }) }) }) it('handles mulltiple children', () => { const tree: ASTType = { type: 'root', children: [ { type: 'element', tagName: 'h3', properties: {}, children: [{ type: 'text', value: 'foo' }], }, { type: 'element', tagName: 'p', properties: {}, children: [{ type: 'text', value: 'bar' }], }, ], } const { result } = renderHook(() => useRichText(tree)) const [headerElement, paragraphElement] = result.current as [ ReactElement, ReactElement ] expect((headerElement.type as Function).name).toBe('H3') expect(headerElement.props.children).toEqual(['foo']) expect((paragraphElement.type as Function).name).toBe('P') expect(paragraphElement.props.children).toEqual(['bar']) }) it('handles children recursively', () => { const tree: ASTType = { type: 'root', children: [ { type: 'element', tagName: 'ul', properties: {}, children: [ { type: 'element', tagName: 'li', properties: {}, children: [{ type: 'text', value: 'foo' }], }, { type: 'element', tagName: 'li', properties: {}, children: [{ type: 'text', value: 'bar' }], }, ], }, ], } const { result } = renderHook(() => useRichText(tree)) const ulElement = result.current as ReactElement const [liElementFirst, liElementSecond] = ulElement.props.children as [ ReactElement, ReactElement ] expect((ulElement.type as Function).name).toBe('Ul') expect((liElementFirst.type as Function).name).toBe('Li') expect(liElementFirst.props.children).toEqual(['foo']) expect((liElementSecond.type as Function).name).toBe('Li') expect(liElementSecond.props.children).toEqual(['bar']) }) describe('when children are empty', () => { it('returns null', () => { const { result } = renderHook(() => useRichText({ type: 'root', children: [], }) ) expect(result.current).toBeNull() }) }) describe('when children of child are empty', () => { it('returns correct node', () => { const tree: ASTType = { type: 'root', children: [ { type: 'element', tagName: 'h3', properties: {}, children: [{ type: 'text', value: 'foobar' }], }, { type: 'element', tagName: 'br', properties: {}, children: [], }, ], } const { result } = renderHook(() => useRichText(tree)) const [headingElement, brElement] = result.current as [ ReactElement, ReactElement ] expect((headingElement.type as Function).name).toBe('H3') expect(brElement.type).toBe('br') }) }) describe('when children are undefined', () => { it('returns null', () => { const { result } = renderHook(() => useRichText({ type: 'root', }) ) expect(result.current).toBeNull() }) }) })