From b9f3ce143d2c4b15c9b694804e6bb423de481d1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81d=C3=A1m=20Hassan?= Date: Fri, 24 Nov 2023 13:53:54 +0100 Subject: [PATCH] unit test --- .../components/field-controls/html-editor.tsx | 93 +--------------- .../src/fieldcontrols/html-editor.tsx | 103 ++++++++++++++++++ .../src/fieldcontrols/index.ts | 1 + .../test/html-editor.test.tsx | 43 ++++++++ packages/sn-controls-react/tsconfig.json | 2 +- 5 files changed, 153 insertions(+), 89 deletions(-) create mode 100644 packages/sn-controls-react/src/fieldcontrols/html-editor.tsx create mode 100644 packages/sn-controls-react/test/html-editor.test.tsx diff --git a/apps/sensenet/src/components/field-controls/html-editor.tsx b/apps/sensenet/src/components/field-controls/html-editor.tsx index 3e8243b28..87a51bdf6 100644 --- a/apps/sensenet/src/components/field-controls/html-editor.tsx +++ b/apps/sensenet/src/components/field-controls/html-editor.tsx @@ -1,99 +1,16 @@ /** * @module FieldControls */ -import { Box, InputLabel, Typography, useTheme } from '@material-ui/core' -import { changeTemplatedValue, ReactClientFieldSetting } from '@sensenet/controls-react' -import React, { useEffect, useRef, useState } from 'react' -import MonacoEditor from 'react-monaco-editor' + +import { useTheme } from '@material-ui/core' +import { ReactClientFieldSetting, HtmlEditor as SnHtmlEditor } from '@sensenet/controls-react' +import React from 'react' /** * Field control that represents a LongText field with Html highlights. Available values will be populated from the FieldSettings. */ export const HtmlEditor: React.FC = (props) => { - // const localization = useLocalization() - const initialState = - props.fieldValue || (props.actionName === 'new' && changeTemplatedValue(props.settings.DefaultValue)) || '' - const [value, setValue] = useState(initialState) const theme = useTheme() - const readonly = props.actionName === 'browse' || props.settings.ReadOnly - - const editorRef = useRef(null) - const containerRef = useRef(null) - - useEffect(() => { - console.log({ editorRef, containerRef }) - - if (!editorRef.current) { - return - } - editorRef.current.editor!.onDidContentSizeChange(() => { - const contentHeight = editorRef?.current?.editor?.getContentHeight() - - console.log('contentHeight', contentHeight) - - containerRef.current!.style.height = `${contentHeight}px` - }) - }, [editorRef, containerRef, value]) - - return ( - <> - {props.settings.DisplayName} - -
- { - setValue(v) - props.fieldOnChange?.(props.settings.Name, v) - }} - options={{ - automaticLayout: true, - contextmenu: true, - hideCursorInOverviewRuler: true, - lineNumbers: 'on', - selectOnLineNumbers: true, - scrollBeyondLastLine: false, - minimap: { - enabled: true, - }, - roundedSelection: false, - readOnly: readonly, - cursorStyle: 'line', - scrollbar: { - horizontalSliderSize: 4, - verticalScrollbarSize: 6, - // vertical: 'hidden', - }, - - wordWrap: 'on', - autoIndent: 'advanced', - matchBrackets: 'always', - language: 'html', - suggest: { - snippetsPreventQuickSuggestions: false, - showProperties: true, - showKeywords: true, - showWords: true, - }, - }} - theme={theme.palette.type === 'dark' ? 'admin-ui-dark' : 'vs-light'} - editorWillMount={(monaco) => { - monaco.editor.defineTheme('admin-ui-dark', { - base: 'vs-dark', - inherit: true, - rules: [], - colors: { - 'editor.background': '#121212', - }, - }) - }} - /> -
- - ) + return } diff --git a/packages/sn-controls-react/src/fieldcontrols/html-editor.tsx b/packages/sn-controls-react/src/fieldcontrols/html-editor.tsx new file mode 100644 index 000000000..60309ee1c --- /dev/null +++ b/packages/sn-controls-react/src/fieldcontrols/html-editor.tsx @@ -0,0 +1,103 @@ +/** + * @module FieldControls + */ +import { InputLabel, Theme } from '@material-ui/core' +import React, { useEffect, useRef, useState } from 'react' +import MonacoEditor from 'react-monaco-editor' + +import { changeTemplatedValue } from '../helpers' +import { ReactClientFieldSetting } from './client-field-setting' + +/** + * Field control that represents a LongText field. Available values will be populated from the FieldSettings. + */ +export const HtmlEditor: React.FC< + ReactClientFieldSetting & { + theme?: Theme + test?: boolean + } +> = (props) => { + const initialState = + props.fieldValue || (props.actionName === 'new' && changeTemplatedValue(props.settings.DefaultValue)) || '' + const [value, setValue] = useState(initialState) + + const editorRef = useRef(null) + const containerRef = useRef(null) + + useEffect(() => { + if (!editorRef.current) { + return + } + editorRef.current.editor!.onDidContentSizeChange(() => { + const contentHeight = editorRef?.current?.editor?.getContentHeight() + + containerRef.current!.style.height = `${contentHeight}px` + }) + }, [editorRef]) + const readonly = props.actionName === 'browse' || props.settings.ReadOnly + + if (props.test) { + return
{value}
+ } + + return ( + <> + {props.settings.DisplayName} + +
+ { + setValue(v) + props.fieldOnChange?.(props.settings.Name, v) + }} + options={{ + automaticLayout: true, + contextmenu: true, + hideCursorInOverviewRuler: true, + lineNumbers: 'on', + selectOnLineNumbers: true, + scrollBeyondLastLine: false, + minimap: { + enabled: true, + }, + roundedSelection: false, + readOnly: readonly, + cursorStyle: 'line', + scrollbar: { + horizontalSliderSize: 4, + verticalScrollbarSize: 6, + // vertical: 'hidden', + }, + + wordWrap: 'on', + autoIndent: 'advanced', + matchBrackets: 'always', + language: 'html', + suggest: { + snippetsPreventQuickSuggestions: false, + showProperties: true, + showKeywords: true, + showWords: true, + }, + }} + theme={props.theme?.palette.type === 'dark' ? 'admin-ui-dark' : 'vs-light'} + editorWillMount={(monaco) => { + monaco.editor.defineTheme('admin-ui-dark', { + base: 'vs-dark', + inherit: true, + rules: [], + colors: { + 'editor.background': '#121212', + }, + }) + }} + /> +
+ + ) +} diff --git a/packages/sn-controls-react/src/fieldcontrols/index.ts b/packages/sn-controls-react/src/fieldcontrols/index.ts index 4209c1ce0..f0c015d79 100644 --- a/packages/sn-controls-react/src/fieldcontrols/index.ts +++ b/packages/sn-controls-react/src/fieldcontrols/index.ts @@ -32,3 +32,4 @@ export * from './icon' export * from './localization' export * from './file-size' export * from './page-count' +export * from './html-editor' diff --git a/packages/sn-controls-react/test/html-editor.test.tsx b/packages/sn-controls-react/test/html-editor.test.tsx new file mode 100644 index 000000000..45a7653b7 --- /dev/null +++ b/packages/sn-controls-react/test/html-editor.test.tsx @@ -0,0 +1,43 @@ +import { ActionName } from '@sensenet/control-mapper' +import { mount, ReactWrapper } from 'enzyme' +import React from 'react' +import { act } from 'react-dom/test-utils' +import { defaultLocalization, HtmlEditor } from '../src/fieldcontrols' + +jest.mock('react-monaco-editor', () => + jest.fn((props) => { + return
{props.value}
+ }), +) + +describe('Html Editor', () => { + it('should display the content', async () => { + const props = { + actionName: 'edit' as ActionName, + settings: { + Name: 'test', + DisplayName: 'Test', + Description: 'Test', + Compulsory: false, + ReadOnly: false, + DefaultValue: 'Test', + Type: 'LongTextField', + FieldClassName: 'SenseNet.ContentRepository.Fields.LongTextField', + }, + localization: defaultLocalization, + fieldValue: '

Test

', + fieldOnChange: jest.fn(), + } + + let wrapper: ReactWrapper, React.Component<{}, {}, any>> + + await act(async () => { + wrapper = mount() + }) + wrapper!.update() + + const htmlEditorContainer = wrapper!.find('[data-test="html-editor-container"]') + + expect(htmlEditorContainer.text()).toBe('

Test

') + }) +}) diff --git a/packages/sn-controls-react/tsconfig.json b/packages/sn-controls-react/tsconfig.json index 32cd0d60a..cb6bf593f 100644 --- a/packages/sn-controls-react/tsconfig.json +++ b/packages/sn-controls-react/tsconfig.json @@ -14,7 +14,7 @@ { "path": "../sn-editor-react" }, { "path": "../sn-hooks-react" }, { "path": "../sn-pickers-react" }, - { "path": "../sn-query"}, + { "path": "../sn-query" }, { "path": "../sn-search-react" } ] }