Skip to content

Commit 9ec3605

Browse files
authored
fix: prevent white space only text sending (#538)
Resolves https://sendbird.atlassian.net/browse/UIKIT-3869 Fixes empty spaces(lines) message sending by Enter btn and added more unit tests.
1 parent 9458739 commit 9ec3605

File tree

4 files changed

+85
-25
lines changed

4 files changed

+85
-25
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"@svgr/webpack": "^5.1.0",
103103
"@testing-library/jest-dom": "^5.16.5",
104104
"@testing-library/react": "^13.4.0",
105+
"@testing-library/user-event": "^14.4.3",
105106
"@typescript-eslint/eslint-plugin": "^5.59.2",
106107
"@typescript-eslint/parser": "^5.59.2",
107108
"autoprefixer": "^9.7.4",

src/ui/MessageInput/__tests__/MessageInput.spec.js

Lines changed: 67 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React, { useRef } from 'react';
2-
import { render, screen } from '@testing-library/react';
2+
import { render, screen,fireEvent, waitFor } from '@testing-library/react';
3+
import userEvent from '@testing-library/user-event';
34

45
import MessageInput from "../index";
56

@@ -45,28 +46,75 @@ describe('ui/MessageInput', () => {
4546
).toBe(0);
4647
});
4748

48-
it.skip('should render send icon if text is present', () => {
49-
const component = shallow(
50-
<MessageInput
51-
onSendMessage={noop}
52-
message={{
53-
message: 'hello',
54-
mentionedMessageTempalte: 'hello'
55-
}}
56-
/>
57-
);
49+
it('should call sendMessage with valid string', async () => {
50+
const onSendMessage = jest.fn();
51+
const textRef = { current: { innerText: null } };
52+
const mockText = 'Test Value';
53+
54+
render(<MessageInput onSendMessage={onSendMessage} ref={textRef} />);
55+
56+
const input = screen.getByRole('textbox');
57+
await userEvent.clear(input);
58+
await userEvent.type(input, mockText);
59+
expect(input.textContent).toBe(mockText);
60+
61+
fireEvent.keyDown(input, { key: 'Enter' });
62+
expect(onSendMessage).toHaveBeenCalledWith({ mentionTemplate: mockText, message: mockText });
63+
});
64+
65+
it('should call sendMessage with valid string; new lines included', async () => {
66+
const onSendMessage = jest.fn();
67+
const textRef = { current: { innerText: null } };
68+
const mockText = ' \nTest Value \n';
69+
70+
render(<MessageInput onSendMessage={onSendMessage} ref={textRef} />);
71+
72+
const input = screen.getByRole('textbox');
73+
await userEvent.type(input, mockText);
74+
expect(input.textContent).toBe(mockText);
75+
76+
fireEvent.keyDown(input, { key: 'Enter' });
77+
expect(onSendMessage).toHaveBeenCalledWith({ mentionTemplate: mockText, message: mockText });
78+
});
79+
80+
it('should not call sendMessage with invalid string; only white spaces', async() => {
81+
const onSendMessage = jest.fn();
82+
const textRef = { current: { innerText: null } };
83+
const mockText = ' ';
84+
85+
render(<MessageInput onSendMessage={onSendMessage} ref={textRef} />);
86+
87+
const input = screen.getByRole('textbox');
88+
await userEvent.type(input, mockText);
89+
expect(input.textContent).toBe(mockText);
90+
91+
fireEvent.keyDown(input, { key: 'Enter' });
92+
expect(onSendMessage).not.toHaveBeenCalledWith({ mentionTemplate: mockText, message: mockText });
93+
});
94+
95+
it('should render send icon if text is present', async() => {
96+
const onSendMessage = jest.fn();
97+
const textRef = { current: { innerText: null } };
98+
const mockText = 'hello';
99+
100+
const { container } = render(<MessageInput onSendMessage={onSendMessage} ref={textRef} />);
101+
102+
const input = screen.getByRole('textbox');
103+
await userEvent.type(input, mockText);
104+
expect(input.textContent).toBe(mockText);
105+
58106
expect(
59-
component.find('#sendbird-message-input-text-field').exists()
60-
).toBe(true);
107+
container.getElementsByClassName('sendbird-message-input-text-field').length
108+
).toBe(1);
61109
expect(
62-
component.find('.sendbird-message-input--send').exists()
63-
).toBe(true);
110+
container.getElementsByClassName('sendbird-message-input--send').length
111+
).toBe(1);
64112
expect(
65-
component.find('.sendbird-message-input--attach').exists()
66-
).toBe(false);
113+
container.getElementsByClassName('sendbird-message-input--attach').length
114+
).toBe(0);
67115
expect(
68-
component.find('.sendbird-message-input--edit-action').exists()
69-
).toBe(false);
116+
container.getElementsByClassName('sendbird-message-input--edit-action').length
117+
).toBe(0);
70118
});
71119

72120
it('should display save/cancel button on edit mode', () => {

src/ui/MessageInput/index.jsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ const MessageInput = React.forwardRef((props, ref) => {
137137
//
138138
}
139139
setMentionedUserIds([]);
140-
setIsInput(textField?.innerText?.trim().length > 0);
140+
setIsInput(textField?.textContent?.trim().length > 0);
141141
setHeight();
142142
}, [initialValue]);
143143

@@ -184,7 +184,7 @@ const MessageInput = React.forwardRef((props, ref) => {
184184
}
185185
setMentionedUserIds([]);
186186
}
187-
setIsInput(textField?.innerText?.trim().length > 0);
187+
setIsInput(textField?.textContent?.trim().length > 0);
188188
setHeight();
189189
}
190190
}, [isEdit, message]);
@@ -199,7 +199,7 @@ const MessageInput = React.forwardRef((props, ref) => {
199199
setMentionedUserIds(newMentionedUserIds);
200200
}
201201
}
202-
setIsInput(textField.innerText.trim().length > 0);
202+
setIsInput(textField.textContent?.trim().length > 0);
203203
}, [targetStringInfo, isMentionEnabled]);
204204

205205
// #Mention | Replace selected user nickname to the MentionedUserLabel
@@ -325,7 +325,7 @@ const MessageInput = React.forwardRef((props, ref) => {
325325

326326
const sendMessage = () => {
327327
const textField = ref?.current;
328-
if (!isEdit && textField?.innerText) {
328+
if (!isEdit && textField?.textContent) {
329329
let messageText = '';
330330
let mentionTemplate = '';
331331
textField.childNodes.forEach((node) => {
@@ -355,7 +355,7 @@ const MessageInput = React.forwardRef((props, ref) => {
355355
setHeight();
356356
}
357357
};
358-
const isEditDisabled = !(ref?.current?.innerText?.trim());
358+
const isEditDisabled = !(ref?.current?.textContent?.trim());
359359
const editMessage = () => {
360360
const textField = ref?.current;
361361
const messageId = message?.messageId;
@@ -420,6 +420,7 @@ const MessageInput = React.forwardRef((props, ref) => {
420420
e.preventDefault();
421421
} else {
422422
if (!e.shiftKey && e.key === MessageInputKeys.Enter
423+
&& textField?.textContent?.trim().length > 0
423424
&& e?.nativeEvent?.isComposing !== true
424425
) {
425426
e.preventDefault();
@@ -448,7 +449,7 @@ const MessageInput = React.forwardRef((props, ref) => {
448449
onInput={() => {
449450
setHeight();
450451
onStartTyping();
451-
setIsInput(textField.innerText?.trim().length > 0);
452+
setIsInput(textField?.textContent?.trim().length > 0);
452453
useMentionedLabelDetection();
453454
}}
454455
onPaste={onPaste}

yarn.lock

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2471,6 +2471,7 @@ __metadata:
24712471
"@svgr/webpack": ^5.1.0
24722472
"@testing-library/jest-dom": ^5.16.5
24732473
"@testing-library/react": ^13.4.0
2474+
"@testing-library/user-event": ^14.4.3
24742475
"@typescript-eslint/eslint-plugin": ^5.59.2
24752476
"@typescript-eslint/parser": ^5.59.2
24762477
autoprefixer: ^9.7.4
@@ -3733,6 +3734,15 @@ __metadata:
37333734
languageName: node
37343735
linkType: hard
37353736

3737+
"@testing-library/user-event@npm:^14.4.3":
3738+
version: 14.4.3
3739+
resolution: "@testing-library/user-event@npm:14.4.3"
3740+
peerDependencies:
3741+
"@testing-library/dom": ">=7.21.4"
3742+
checksum: 852c48ea6db1c9471b18276617c84fec4320771e466cd58339a732ca3fd73ad35e5a43ae14f51af51a8d0a150dcf60fcaab049ef367871207bea8f92c4b8195e
3743+
languageName: node
3744+
linkType: hard
3745+
37363746
"@tootallnate/once@npm:2":
37373747
version: 2.0.0
37383748
resolution: "@tootallnate/once@npm:2.0.0"

0 commit comments

Comments
 (0)