mirror of
https://github.com/open-metadata/OpenMetadata.git
synced 2025-07-21 08:21:40 +00:00
MINOR: fix the required description field saving issue without content (#19624)
* fix the required description field saving issue without content * remove the commented code
This commit is contained in:
parent
647bab6019
commit
a39ee72b6b
@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2025 Collate.
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
import { fireEvent, render, screen } from '@testing-library/react';
|
||||||
|
import React from 'react';
|
||||||
|
import { EditorContentRef } from '../../Modals/ModalWithMarkdownEditor/ModalWithMarkdownEditor.interface';
|
||||||
|
import RichTextEditor from './RichTextEditor';
|
||||||
|
|
||||||
|
jest.mock('../../BlockEditor/BlockEditor', () => {
|
||||||
|
return jest.fn().mockImplementation(({ content, onChange, ref }: any) => {
|
||||||
|
if (ref && ref.current) {
|
||||||
|
ref.current = { editor: { getHTML: jest.fn().mockReturnValue(content) } }; // mock the editor object
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<textarea
|
||||||
|
data-testid="editor-textarea"
|
||||||
|
ref={ref as React.Ref<HTMLTextAreaElement>}
|
||||||
|
value={content}
|
||||||
|
onChange={(e) => {
|
||||||
|
onChange(e.target.value);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const onTextChangeMock = jest.fn();
|
||||||
|
|
||||||
|
describe('RichTextEditor', () => {
|
||||||
|
it('renders without crashing', () => {
|
||||||
|
render(<RichTextEditor onTextChange={onTextChangeMock} />);
|
||||||
|
const editorElement = screen.getByTestId('editor');
|
||||||
|
|
||||||
|
expect(editorElement).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Passes initialValue prop correctly to BlockEditor', () => {
|
||||||
|
const initialValue = 'Initial content';
|
||||||
|
render(
|
||||||
|
<RichTextEditor
|
||||||
|
initialValue={initialValue}
|
||||||
|
onTextChange={onTextChangeMock}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const textarea = screen.getByTestId('editor-textarea');
|
||||||
|
|
||||||
|
expect(textarea).toHaveValue(initialValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trigger onTextChange when content changes', () => {
|
||||||
|
render(<RichTextEditor onTextChange={onTextChangeMock} />);
|
||||||
|
|
||||||
|
fireEvent.change(screen.getByTestId('editor-textarea'), {
|
||||||
|
target: { value: 'New content' },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(onTextChangeMock).toHaveBeenCalledWith('New content');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should trigger onTextChange with empty content in case of value is <p></p> tags)', () => {
|
||||||
|
render(<RichTextEditor onTextChange={onTextChangeMock} />);
|
||||||
|
|
||||||
|
fireEvent.change(screen.getByTestId('editor-textarea'), {
|
||||||
|
target: { value: '<p></p>' },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(onTextChangeMock).toHaveBeenCalledWith('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return empty string when value is <p></p> format content is empty', () => {
|
||||||
|
const editorRef: React.RefObject<EditorContentRef> = React.createRef();
|
||||||
|
const initialValue = '<p></p>';
|
||||||
|
|
||||||
|
render(<RichTextEditor initialValue={initialValue} ref={editorRef} />);
|
||||||
|
|
||||||
|
const getEditorContent = editorRef.current?.getEditorContent();
|
||||||
|
|
||||||
|
expect(getEditorContent).toBe('');
|
||||||
|
});
|
||||||
|
});
|
@ -15,7 +15,10 @@
|
|||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
||||||
import { formatContent } from '../../../utils/BlockEditorUtils';
|
import {
|
||||||
|
formatContent,
|
||||||
|
formatValueBasedOnContent,
|
||||||
|
} from '../../../utils/BlockEditorUtils';
|
||||||
import BlockEditor from '../../BlockEditor/BlockEditor';
|
import BlockEditor from '../../BlockEditor/BlockEditor';
|
||||||
import { BlockEditorRef } from '../../BlockEditor/BlockEditor.interface';
|
import { BlockEditorRef } from '../../BlockEditor/BlockEditor.interface';
|
||||||
import {
|
import {
|
||||||
@ -39,7 +42,8 @@ const RichTextEditor = forwardRef<EditorContentRef, RichTextEditorProp>(
|
|||||||
const editorRef = useRef<BlockEditorRef>({} as BlockEditorRef);
|
const editorRef = useRef<BlockEditorRef>({} as BlockEditorRef);
|
||||||
|
|
||||||
const onChangeHandler = (backendFormatHtmlContent: string) => {
|
const onChangeHandler = (backendFormatHtmlContent: string) => {
|
||||||
onTextChange && onTextChange(backendFormatHtmlContent);
|
onTextChange &&
|
||||||
|
onTextChange(formatValueBasedOnContent(backendFormatHtmlContent));
|
||||||
};
|
};
|
||||||
|
|
||||||
useImperativeHandle(ref, () => ({
|
useImperativeHandle(ref, () => ({
|
||||||
@ -47,7 +51,7 @@ const RichTextEditor = forwardRef<EditorContentRef, RichTextEditorProp>(
|
|||||||
const htmlContent = editorRef.current?.editor?.getHTML() ?? '';
|
const htmlContent = editorRef.current?.editor?.getHTML() ?? '';
|
||||||
const backendFormat = formatContent(htmlContent, 'server');
|
const backendFormat = formatContent(htmlContent, 'server');
|
||||||
|
|
||||||
return backendFormat === '<p></p>' ? '' : backendFormat;
|
return formatValueBasedOnContent(backendFormat);
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import {
|
import {
|
||||||
|
formatValueBasedOnContent,
|
||||||
getHtmlStringFromMarkdownString,
|
getHtmlStringFromMarkdownString,
|
||||||
getTextFromHtmlString,
|
getTextFromHtmlString,
|
||||||
} from './BlockEditorUtils';
|
} from './BlockEditorUtils';
|
||||||
@ -117,3 +118,17 @@ describe('getHtmlStringFromMarkdownString', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('formatValueBasedOnContent', () => {
|
||||||
|
it('should return the same string if input is not empty p tag', () => {
|
||||||
|
const input = '<p>Hello World</p>';
|
||||||
|
|
||||||
|
expect(formatValueBasedOnContent(input)).toBe(input);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return the empty string if input is empty p tag', () => {
|
||||||
|
const input = '<p></p>';
|
||||||
|
|
||||||
|
expect(formatValueBasedOnContent(input)).toBe('');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -118,6 +118,9 @@ export const formatContent = (
|
|||||||
return modifiedHtmlString;
|
return modifiedHtmlString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const formatValueBasedOnContent = (value: string) =>
|
||||||
|
value === '<p></p>' ? '' : value;
|
||||||
|
|
||||||
export const isHTMLString = (content: string) => {
|
export const isHTMLString = (content: string) => {
|
||||||
try {
|
try {
|
||||||
const parser = new DOMParser();
|
const parser = new DOMParser();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user