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:
Ashish Gupta 2025-01-31 22:17:59 +05:30 committed by GitHub
parent 647bab6019
commit a39ee72b6b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 3 deletions

View File

@ -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('');
});
});

View File

@ -15,7 +15,10 @@
import classNames from 'classnames';
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
import { formatContent } from '../../../utils/BlockEditorUtils';
import {
formatContent,
formatValueBasedOnContent,
} from '../../../utils/BlockEditorUtils';
import BlockEditor from '../../BlockEditor/BlockEditor';
import { BlockEditorRef } from '../../BlockEditor/BlockEditor.interface';
import {
@ -39,7 +42,8 @@ const RichTextEditor = forwardRef<EditorContentRef, RichTextEditorProp>(
const editorRef = useRef<BlockEditorRef>({} as BlockEditorRef);
const onChangeHandler = (backendFormatHtmlContent: string) => {
onTextChange && onTextChange(backendFormatHtmlContent);
onTextChange &&
onTextChange(formatValueBasedOnContent(backendFormatHtmlContent));
};
useImperativeHandle(ref, () => ({
@ -47,7 +51,7 @@ const RichTextEditor = forwardRef<EditorContentRef, RichTextEditorProp>(
const htmlContent = editorRef.current?.editor?.getHTML() ?? '';
const backendFormat = formatContent(htmlContent, 'server');
return backendFormat === '<p></p>' ? '' : backendFormat;
return formatValueBasedOnContent(backendFormat);
},
}));

View File

@ -11,6 +11,7 @@
* limitations under the License.
*/
import {
formatValueBasedOnContent,
getHtmlStringFromMarkdownString,
getTextFromHtmlString,
} 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('');
});
});

View File

@ -118,6 +118,9 @@ export const formatContent = (
return modifiedHtmlString;
};
export const formatValueBasedOnContent = (value: string) =>
value === '<p></p>' ? '' : value;
export const isHTMLString = (content: string) => {
try {
const parser = new DOMParser();