Skip to content

Commit

Permalink
Merge pull request #278 from weni-ai/tests/texteditor
Browse files Browse the repository at this point in the history
[CEF-437] Tests: add texteditor tests
  • Loading branch information
paulobernardoaf authored Nov 13, 2024
2 parents a7fe963 + 0cb789b commit 6c80e87
Show file tree
Hide file tree
Showing 7 changed files with 2,373 additions and 3 deletions.
79 changes: 79 additions & 0 deletions src/components/form/texteditor/TextEditorActions.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import TextEditorActions, {
TextEditorActionProps,
} from 'components/form/texteditor/TextEditorActions';
import * as React from 'react';
import { render, fireEvent, fireCustomEvent } from 'test/utils';

const baseProps: TextEditorActionProps = {
entry: { value: '' },
maxLength: 100,
onAddEmoji: vi.fn(),
onFormat: vi.fn(),
};

describe(TextEditorActions.name, () => {
it('renders', () => {
const { baseElement } = render(<TextEditorActions {...baseProps} />);
expect(baseElement).toMatchSnapshot();
});

it('should toggle emoji picker', () => {
const { baseElement, getByTestId } = render(
<TextEditorActions {...baseProps} />,
);

const emojiButton = getByTestId('emoji-button');
expect(baseElement).toMatchSnapshot();
fireEvent.click(emojiButton);
expect(baseElement).toMatchSnapshot();
});

it('should emit add emoji', () => {
const { getByTestId } = render(<TextEditorActions {...baseProps} />);

const emojiButton = getByTestId('emoji-button');
fireEvent.click(emojiButton);

expect(baseProps.onAddEmoji).not.toHaveBeenCalled();
const emojiPicker = getByTestId('emoji-picker');

fireCustomEvent(emojiPicker, 'emoji-selected', { emoji: '👍' });
expect(baseProps.onAddEmoji).toHaveBeenCalled();
});

it('should close emoji picker on click outside', () => {
const { baseElement, getByTestId } = render(
<TextEditorActions {...baseProps} />,
);

const emojiButton = getByTestId('emoji-button');
fireEvent.click(emojiButton);
expect(baseElement).toMatchSnapshot();

const emojiPicker = getByTestId('emoji-picker');
fireCustomEvent(emojiPicker, 'click-outside', true);
expect(baseElement).toMatchSnapshot();
});

it('should emit formats', () => {
const { getByTestId } = render(<TextEditorActions {...baseProps} />);

const boldButton = getByTestId('bold-button');
const italicButton = getByTestId('italic-button');
const codeButton = getByTestId('code-button');
const strikeButton = getByTestId('strike-button');

expect(baseProps.onFormat).not.toHaveBeenCalled();
fireEvent.click(boldButton);
expect(baseProps.onFormat).toHaveBeenCalledWith('*');

fireEvent.click(italicButton);
expect(baseProps.onFormat).toHaveBeenCalledWith('_');

fireEvent.click(codeButton);
expect(baseProps.onFormat).toHaveBeenCalledWith('```');

fireEvent.click(strikeButton);
expect(baseProps.onFormat).toHaveBeenCalledWith('~');
});
});
12 changes: 9 additions & 3 deletions src/components/form/texteditor/TextEditorActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import styles from './TextEditorActions.module.scss';
const UnnnicButton = applyVueInReact(Unnnic.unnnicButton);
const UnnnicEmojiPicker = applyVueInReact(Unnnic.unnnicEmojiPicker);

export interface TextEditorProps {
export interface TextEditorActionProps {
entry: StringEntry;
maxLength: number;
onAddEmoji: (emoji: any) => void;
Expand All @@ -22,10 +22,10 @@ export interface TextEditorState {
}

export default class TextEditorActions extends React.Component<
TextEditorProps,
TextEditorActionProps,
TextEditorState
> {
constructor(props: TextEditorProps) {
constructor(props: TextEditorActionProps) {
super(props);

this.state = {
Expand All @@ -49,6 +49,7 @@ export default class TextEditorActions extends React.Component<
<div className={styles.actions}>
<div className={styles.emoji_picker_wrapper}>
<UnnnicButton
data-testid="emoji-button"
iconCenter="sentiment_satisfied"
size="small"
type="tertiary"
Expand All @@ -57,6 +58,7 @@ export default class TextEditorActions extends React.Component<
{this.state.showEmojiPicker && (
<div className={styles.emoji_picker}>
<UnnnicEmojiPicker
data-testid="emoji-picker"
onEmojiSelected={(e: any) => this.addEmoji(e)}
onClickOutside={() => this.toggleEmojiPicker()}
/>
Expand All @@ -65,27 +67,31 @@ export default class TextEditorActions extends React.Component<
</div>

<UnnnicButton
data-testid="bold-button"
iconCenter="format_bold"
size="small"
type="tertiary"
onClick={() => this.props.onFormat('*')}
/>

<UnnnicButton
data-testid="italic-button"
iconCenter="format_italic"
size="small"
type="tertiary"
onClick={() => this.props.onFormat('_')}
/>

<UnnnicButton
data-testid="code-button"
iconCenter="code"
size="small"
type="tertiary"
onClick={() => this.props.onFormat('```')}
/>

<UnnnicButton
data-testid="strike-button"
iconCenter="format_strikethrough"
size="small"
type="tertiary"
Expand Down
163 changes: 163 additions & 0 deletions src/components/form/texteditor/TextEditorElement.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
import TextEditorElement, {
TextEditorProps,
} from 'components/form/texteditor/TextEditorElement';
import * as React from 'react';
import {
render,
fireEvent,
fireCustomEvent,
fireUnnnicTextAreaChangeText,
} from 'test/utils';

const baseProps: TextEditorProps = {
name: 'Message',
entry: { value: '' },
onChange: vi.fn(),
};

describe(TextEditorElement.name, () => {
beforeEach(() => {
vi.clearAllMocks();
});

it('renders', () => {
const { baseElement } = render(<TextEditorElement {...baseProps} />);
expect(baseElement).toMatchSnapshot();
});

it('renders with initial value', () => {
const { baseElement } = render(
<TextEditorElement {...baseProps} entry={{ value: 'Hello' }} />,
);
expect(baseElement).toMatchSnapshot();
});

it('renders with autocomplete', () => {
const { baseElement } = render(
<TextEditorElement {...baseProps} autocomplete={true} />,
);
expect(baseElement).toMatchSnapshot();
});

it('renders with label', () => {
const { baseElement } = render(
<TextEditorElement {...baseProps} showLabel={true} />,
);
expect(baseElement).toMatchSnapshot();
});

it('renders with autocomplete and label', () => {
const { baseElement } = render(
<TextEditorElement {...baseProps} autocomplete={true} showLabel={true} />,
);
expect(baseElement).toMatchSnapshot();
});

it('renders with error', () => {
const { baseElement } = render(
<TextEditorElement
{...baseProps}
entry={{
value: '',
validationFailures: [
{
message: 'Error',
},
],
}}
/>,
);
expect(baseElement).toMatchSnapshot();
});

it('should call onChange with correct value', () => {
const { getByTestId } = render(
<TextEditorElement {...baseProps} autocomplete={true} />,
);
const input = getByTestId('Message');

fireUnnnicTextAreaChangeText(input, 'Hello');
expect(baseProps.onChange).toHaveBeenCalledWith('Hello', 'Message');
});

it('should not call onChange if undefined', () => {
const { getByTestId } = render(
<TextEditorElement
{...baseProps}
autocomplete={true}
onChange={undefined}
/>,
);
const input = getByTestId('Message');

fireUnnnicTextAreaChangeText(input, 'hello');
expect(baseProps.onChange).not.toHaveBeenCalled();
});

it('should call on change when emoji is added', () => {
const { getByTestId } = render(
<TextEditorElement {...baseProps} autocomplete={true} />,
);

const emojiButton = getByTestId('emoji-button');
fireEvent.click(emojiButton);

expect(baseProps.onChange).not.toHaveBeenCalled();
const emojiPicker = getByTestId('emoji-picker');

fireCustomEvent(emojiPicker, 'emoji-selected', { emoji: '👍' });
expect(baseProps.onChange).toHaveBeenCalledTimes(1);
});

it('should emit on change formatted value', () => {
const { getByTestId, rerender } = render(
<TextEditorElement {...baseProps} autocomplete={true} />,
);

const input = getByTestId('Message');
fireUnnnicTextAreaChangeText(input, 'Hello');
expect(baseProps.onChange).toHaveBeenCalledWith('Hello', 'Message');

rerender(
<TextEditorElement
{...baseProps}
autocomplete={true}
entry={{ value: 'Hello' }}
/>,
);

const boldButton = getByTestId('bold-button');
fireEvent.click(boldButton);
expect(baseProps.onChange).toHaveBeenCalledWith('Hello**', 'Message');

const italicButton = getByTestId('italic-button');
fireEvent.click(italicButton);
expect(baseProps.onChange).toHaveBeenCalledWith('Hello__', 'Message');

const codeButton = getByTestId('code-button');
fireEvent.click(codeButton);
expect(baseProps.onChange).toHaveBeenCalledWith('Hello``````', 'Message');

const strikeButton = getByTestId('strike-button');
fireEvent.click(strikeButton);
expect(baseProps.onChange).toHaveBeenCalledWith('Hello~~', 'Message');
});

it('should not emit formats if disabled', () => {
const { getByTestId } = render(
<TextEditorElement {...baseProps} autocomplete={true} disabled={true} />,
);

const boldButton = getByTestId('bold-button');
const italicButton = getByTestId('italic-button');
const codeButton = getByTestId('code-button');
const strikeButton = getByTestId('strike-button');

expect(baseProps.onChange).not.toHaveBeenCalled();
fireEvent.click(boldButton);
fireEvent.click(italicButton);
fireEvent.click(codeButton);
fireEvent.click(strikeButton);
expect(baseProps.onChange).not.toHaveBeenCalled();
});
});
Loading

0 comments on commit 6c80e87

Please sign in to comment.