import React from 'react' import { render, waitFor } from '@toptal/picasso-test-utils' import type { OmitInternalProps } from '@toptal/picasso-shared' import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin' import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin' import type { LexicalComposerContextWithEditor } from '@lexical/react/LexicalComposerContext' import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' import LexicalEditor from './LexicalEditor' import type { Props } from './LexicalEditor' import { TextLengthPlugin, HeadingsReplacementPlugin, ListPlugin, LinkPlugin, } from '../plugins' import ToolbarPlugin from '../LexicalEditorToolbarPlugin' jest.mock('../LexicalEditorToolbarPlugin', () => ({ __esModule: true, default: jest.fn(() =>
LexicalEditorToolbarPlugin
), })) jest.mock('@lexical/react/LexicalComposerContext', () => ({ __esModule: true, useLexicalComposerContext: jest.fn(() => [{}]), })) jest.mock('../plugins', () => ({ __esModule: true, ListPlugin: jest.fn(), EmojiPlugin: jest.fn(), TextLengthPlugin: jest.fn(), HeadingsReplacementPlugin: jest.fn(), LinkPlugin: jest.fn(), ImagePlugin: jest.fn(), })) jest.mock('@lexical/react/LexicalHistoryPlugin', () => ({ __esModule: true, HistoryPlugin: jest.fn(() => [{}]), })) jest.mock('@lexical/react/LexicalRichTextPlugin', () => ({ __esModule: true, RichTextPlugin: () =>
RichTextPlugin
, })) jest.mock('@lexical/react/LexicalComposer', () => ({ __esModule: true, LexicalComposer: ({ children }: any) =>
{children}
, })) jest.mock('@lexical/react/LexicalOnChangePlugin', () => ({ __esModule: true, OnChangePlugin: jest.fn(() =>
OnChangePlugin
), })) const mockedUseLexicalComposerContext = useLexicalComposerContext as jest.MockedFunction< typeof useLexicalComposerContext > const mockedLexicalTextLengthPlugin = TextLengthPlugin as jest.MockedFunction< typeof TextLengthPlugin > const mockedHistoryPlugin = HistoryPlugin as jest.MockedFunction< typeof HistoryPlugin > const mockedLexicalHeadingsReplacementPlugin = HeadingsReplacementPlugin as jest.MockedFunction< typeof HeadingsReplacementPlugin > const mockedLexicalLinkPlugin = LinkPlugin as jest.MockedFunction< typeof LinkPlugin > const mockedToolbarPlugin = ToolbarPlugin as jest.MockedFunction< typeof ToolbarPlugin > const mockedLexicalListPlugin = ListPlugin as jest.MockedFunction< typeof ListPlugin > const mockedOnChangePlugin = OnChangePlugin as jest.MockedFunction< typeof OnChangePlugin > const onTextLengthChange = jest.fn() const renderLexicalEditor = (props: Partial> = {}) => { return render( ) } describe('LexicalEditor', () => { beforeEach(() => { mockedLexicalTextLengthPlugin.mockImplementation(() => null) mockedLexicalHeadingsReplacementPlugin.mockImplementation(() => null) mockedToolbarPlugin.mockImplementation(() => (
LexicalEditorToolbarPlugin
)) mockedOnChangePlugin.mockImplementation(() => null) mockedLexicalListPlugin.mockImplementation(() =>
) mockedLexicalLinkPlugin.mockImplementation(() =>
) mockedUseLexicalComposerContext.mockImplementation( () => [ { registerUpdateListener: jest.fn(() => () => {}), registerCommand: jest.fn(() => () => {}), }, ] as unknown as LexicalComposerContextWithEditor ) }) afterEach(() => { jest.clearAllMocks() }) describe('when LexicalEditor is rendered', () => { it('displays Editor core parts', async () => { const { getByText } = renderLexicalEditor() expect(getByText('RichTextPlugin')).toBeInTheDocument() }) it('renders LexicalTextLengthPlugin with correct props', async () => { renderLexicalEditor() await waitFor(() => expect(mockedLexicalTextLengthPlugin).toHaveBeenCalledWith( { onTextLengthChange, }, {} ) ) }) it('renders LexicalHeadingsReplacementPlugin', async () => { renderLexicalEditor() await waitFor(() => expect(mockedLexicalHeadingsReplacementPlugin).toHaveBeenCalled() ) }) it('renders HistoryPlugin', async () => { renderLexicalEditor() await waitFor(() => expect(mockedHistoryPlugin).toHaveBeenCalled()) }) it('renders OnChangePlugin with correct props', () => { renderLexicalEditor() expect(mockedOnChangePlugin).toHaveBeenCalledWith( { ignoreSelectionChange: true, onChange: expect.any(Function), }, {} ) }) it('renders ToolbarPlugin with correct props', () => { renderLexicalEditor() expect(mockedToolbarPlugin).toHaveBeenCalledWith( { id: 'id', toolbarRef: { current: null, }, }, {} ) }) }) describe('when customEmojis and plugins prop is passed', () => { it('renders ToolbarPlugin with correct props', () => { renderLexicalEditor({ customEmojis: ['foo' as any], plugins: ['link'], }) expect(mockedToolbarPlugin).toHaveBeenCalledWith( { id: 'id', toolbarRef: { current: null, }, }, {} ) }) }) })