Skip to content

Commit a1f80eb

Browse files
authored
fix(studio-assistant): always disable send button when textarea is empty (#18907)
1 parent 684a8f9 commit a1f80eb

2 files changed

Lines changed: 45 additions & 39 deletions

File tree

src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/UserInput/UserInput.test.tsx

Lines changed: 43 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,12 @@ describe('UserInput', () => {
1414

1515
it('should render textarea with placeholder', () => {
1616
renderUserInput();
17-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
18-
19-
expect(textarea).toBeInTheDocument();
17+
expect(getTextarea()).toBeInTheDocument();
2018
});
2119

2220
it('should render send button', () => {
2321
renderUserInput();
24-
const sendButton = screen.getByRole('button', { name: mockTexts.send });
25-
26-
expect(sendButton).toBeInTheDocument();
22+
expect(getSendButton()).toBeInTheDocument();
2723
});
2824

2925
it('should render attachment button when enableCompactInterface is false', () => {
@@ -56,30 +52,44 @@ describe('UserInput', () => {
5652

5753
it('should disable send button when textarea is empty', () => {
5854
renderUserInput();
59-
const sendButton = screen.getByRole('button', { name: mockTexts.send });
55+
expect(getSendButton()).toBeDisabled();
56+
});
57+
58+
it('should disable send button when textarea is empty, even when there is an attachment', async () => {
59+
const user = userEvent.setup();
60+
renderUserInput();
61+
const fileInput = screen.getByLabelText(mockTexts.addAttachment, { selector: 'input' });
62+
const attachment = new File(['file content'], 'attachment.txt', { type: 'text/plain' });
6063

61-
expect(sendButton).toBeDisabled();
64+
await user.upload(fileInput, attachment);
65+
66+
expect(getSendButton()).toBeDisabled();
67+
});
68+
69+
it('should disable send button when entering empty or white-space only message', async () => {
70+
const user = userEvent.setup();
71+
renderUserInput();
72+
73+
await user.type(getTextarea(), ' ');
74+
75+
expect(getSendButton()).toBeDisabled();
6276
});
6377

6478
it('should enable send button when textarea has content', async () => {
6579
const user = userEvent.setup();
6680
renderUserInput();
67-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
68-
const sendButton = screen.getByRole('button', { name: mockTexts.send });
6981

70-
await user.type(textarea, 'Test message');
82+
await user.type(getTextarea(), 'Test message');
7183

72-
expect(sendButton).toBeEnabled();
84+
expect(getSendButton()).toBeEnabled();
7385
});
7486

7587
it('should call onSubmitMessage when send button is clicked', async () => {
7688
const user = userEvent.setup();
7789
renderUserInput();
78-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
79-
const sendButton = screen.getByRole('button', { name: mockTexts.send });
8090

81-
await user.type(textarea, 'Test message');
82-
await user.click(sendButton);
91+
await user.type(getTextarea(), 'Test message');
92+
await user.click(getSendButton());
8393

8494
expect(onSubmitMessage).toHaveBeenCalledTimes(1);
8595
expect(onSubmitMessage).toHaveBeenCalledWith(
@@ -92,22 +102,20 @@ describe('UserInput', () => {
92102
it('should submit allowAppChanges value according to switch state', async () => {
93103
const user = userEvent.setup();
94104
renderUserInput();
95-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
96-
const sendButton = screen.getByRole('button', { name: mockTexts.send });
97105
const allowAppChangesSwitch = screen.getByRole('switch', {
98106
name: mockTexts.allowAppChangesSwitch,
99107
});
100108

101-
await user.type(textarea, 'Test message');
102-
await user.click(sendButton);
109+
await user.type(getTextarea(), 'Test message');
110+
await user.click(getSendButton());
103111

104112
expect(onSubmitMessage).toHaveBeenLastCalledWith(
105113
expect.objectContaining({ allowAppChanges: false }),
106114
);
107115

108116
await user.click(allowAppChangesSwitch);
109-
await user.type(textarea, 'Another message');
110-
await user.click(sendButton);
117+
await user.type(getTextarea(), 'Another message');
118+
await user.click(getSendButton());
111119

112120
expect(onSubmitMessage).toHaveBeenLastCalledWith(
113121
expect.objectContaining({ allowAppChanges: true }),
@@ -118,44 +126,40 @@ describe('UserInput', () => {
118126
it('should clear textarea after submitting message', async () => {
119127
const user = userEvent.setup();
120128
renderUserInput();
121-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
122-
const sendButton = screen.getByRole('button', { name: mockTexts.send });
129+
const textarea = getTextarea();
123130

124131
await user.type(textarea, 'Test message');
125-
await user.click(sendButton);
132+
await user.click(getSendButton());
126133

127134
expect(textarea).toHaveValue('');
128135
});
129136

130137
it('should submit message on Enter key press', async () => {
131138
const user = userEvent.setup();
132139
renderUserInput();
133-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
134140

135-
await user.type(textarea, 'Test message{Enter}');
141+
await user.type(getTextarea(), 'Test message{Enter}');
136142

137143
expect(onSubmitMessage).toHaveBeenCalledTimes(1);
138144
});
139145

140-
it('should not submit message on Shift+Enter key press', async () => {
146+
it('should not submit message on Enter key press when textarea is empty', async () => {
141147
const user = userEvent.setup();
142148
renderUserInput();
143-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
144149

145-
await user.type(textarea, 'Test message{Shift>}{Enter}');
150+
await user.click(getTextarea());
151+
await user.keyboard('{Enter}');
146152

147153
expect(onSubmitMessage).not.toHaveBeenCalled();
148154
});
149155

150-
it('should disable the send button when entering empty or white-space only message', async () => {
156+
it('should not submit message on Shift+Enter key press', async () => {
151157
const user = userEvent.setup();
152158
renderUserInput();
153-
const textarea = screen.getByPlaceholderText(mockTexts.textarea.placeholder);
154159

155-
await user.type(textarea, ' ');
160+
await user.type(getTextarea(), 'Test message{Shift>}{Enter}');
156161

157-
const sendButton = screen.getByRole('button', { name: mockTexts.send });
158-
expect(sendButton).toBeDisabled();
162+
expect(onSubmitMessage).not.toHaveBeenCalled();
159163
});
160164
});
161165

@@ -168,3 +172,7 @@ const defaultProps: UserInputProps = {
168172
const renderUserInput = (props?: Partial<UserInputProps>): void => {
169173
render(<UserInput {...defaultProps} {...props} />);
170174
};
175+
176+
const getSendButton = (): HTMLElement => screen.getByRole('button', { name: mockTexts.send });
177+
178+
const getTextarea = (): HTMLElement => screen.getByPlaceholderText(mockTexts.textarea.placeholder);

src/Designer/frontend/libs/studio-assistant/src/components/ChatColumn/UserInput/UserInput.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export function UserInput({
3939
}, [cancelledMessageContent, onCancelledMessageConsumed]);
4040

4141
const hasTextContent = messageContent.trim().length > 0;
42-
const canSubmit = hasTextContent || attachments.length > 0;
4342

4443
const resetInputs = useCallback((): void => {
4544
setMessageContent('');
@@ -89,7 +88,7 @@ export function UserInput({
8988
}, []);
9089

9190
const handleSubmit = (): void => {
92-
if (!canSubmit) return;
91+
if (!hasTextContent) return;
9392
const message: UserMessage = createUserMessage(messageContent, allowAppChanges, attachments);
9493
onSubmitMessage(message);
9594
resetInputs();
@@ -121,7 +120,6 @@ export function UserInput({
121120
ref={fileInputRef}
122121
type='file'
123122
className={classes.hiddenFileInput}
124-
data-testid='user-input-file'
125123
aria-label={texts.addAttachment}
126124
/>
127125
<StudioButton
@@ -148,7 +146,7 @@ export function UserInput({
148146
{texts.cancel} <XMarkIcon />
149147
</StudioButton>
150148
) : (
151-
<StudioButton onClick={handleSubmit} disabled={!canSubmit}>
149+
<StudioButton onClick={handleSubmit} disabled={!hasTextContent}>
152150
{texts.send} <PaperplaneFillIcon />
153151
</StudioButton>
154152
)}

0 commit comments

Comments
 (0)