diff --git a/cypress/components/markdownUtils.cy.tsx b/cypress/components/markdownUtils.cy.tsx new file mode 100644 index 000000000..3c5d1346a --- /dev/null +++ b/cypress/components/markdownUtils.cy.tsx @@ -0,0 +1,54 @@ +import React from 'react'; +import { checkHasContent } from '~/lib/markdownUtils'; + +describe('checkHasContent', () => { + it('returns false for null or undefined', () => { + expect(checkHasContent(null as any)).to.be.false; + expect(checkHasContent(undefined as any)).to.be.false; + }); + + it('returns true for strings and numbers', () => { + expect(checkHasContent('text')).to.be.true; + expect(checkHasContent(123)).to.be.true; + }); + + it('handles empty elements', () => { + const empty = ; + expect(checkHasContent(empty)).to.be.false; + }); + + it('handles single child elements without crashing', () => { + const single = Single; + expect(checkHasContent(single)).to.be.true; + }); + + it('handles arrays of children', () => { + const multiple = ( + + One + Two + + ); + expect(checkHasContent(multiple)).to.be.true; + }); + + it('handles deeply nested content', () => { + const nested = ( +
+ + Deep + +
+ ); + expect(checkHasContent(nested)).to.be.true; + }); + + it('handles deeply nested empty elements', () => { + const nestedEmpty = ( +
+ +
+ ); + expect(checkHasContent(nestedEmpty)).to.be.false; + }); +}); diff --git a/lib/markdownUtils.ts b/lib/markdownUtils.ts index b0d89691e..6a32475a7 100644 --- a/lib/markdownUtils.ts +++ b/lib/markdownUtils.ts @@ -1,3 +1,4 @@ +import React from 'react'; import getFindResultsByGlobalRegExp from '~/lib/getFindResultsByGlobalRegExp'; export const REGEX_TAB_GROUPS = @@ -45,18 +46,16 @@ export const hiddenElements = (...elements: string[]) => { }, {}); }; -export const checkHasContent = (reactNode: React.ReactChild) => { +export const checkHasContent = (reactNode: React.ReactChild): boolean => { if (!reactNode) return false; if (typeof reactNode === 'string' || typeof reactNode === 'number') return true; - if ((reactNode?.props?.children || []).length === 0) return false; - return reactNode.props.children.reduce( - (acc: boolean, reactNode: React.ReactChild) => { - if (acc) return acc; - return checkHasContent(reactNode); - }, - false, - ); + const children = React.Children.toArray(reactNode?.props?.children ?? []); + if (children.length === 0) return false; + return children.reduce((acc: boolean, child: React.ReactNode) => { + if (acc) return acc; + return checkHasContent(child as React.ReactChild); + }, false); }; export function parseTabsFromMarkdown(markdown: string) {