Skip to content

Commit 32859c9

Browse files
committed
test: adjust poll tests
1 parent 6386293 commit 32859c9

File tree

2 files changed

+99
-103
lines changed

2 files changed

+99
-103
lines changed

src/components/Poll/PollCreationDialog/PollCreationDialogControls.tsx

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
11
import React from 'react';
2-
import { useMessageComposer } from '../../MessageInput';
2+
import { useCanCreatePoll, useMessageComposer } from '../../MessageInput';
33
import { useMessageInputContext, useTranslationContext } from '../../../context';
4-
import { useStateStore } from '../../../store';
5-
import type { PollComposerState } from 'stream-chat';
6-
7-
const pollComposerStateSelector = (state: PollComposerState) => ({
8-
errors: Object.values(state.errors).filter((e) => e),
9-
});
104

115
export type PollCreationDialogControlsProps = {
126
close: () => void;
@@ -18,10 +12,7 @@ export const PollCreationDialogControls = ({
1812
const { t } = useTranslationContext('PollCreationDialogControls');
1913
const { handleSubmit: handleSubmitMessage } = useMessageInputContext();
2014
const messageComposer = useMessageComposer();
21-
const { errors } = useStateStore(
22-
messageComposer.pollComposer.state,
23-
pollComposerStateSelector,
24-
);
15+
const canCreatePoll = useCanCreatePoll();
2516

2617
return (
2718
<div className='str-chat__dialog__controls'>
@@ -36,7 +27,7 @@ export const PollCreationDialogControls = ({
3627
</button>
3728
<button
3829
className='str-chat__dialog__controls-button str-chat__dialog__controls-button--submit'
39-
disabled={!messageComposer.pollComposer.canCreatePoll || errors.length > 0}
30+
disabled={!canCreatePoll}
4031
onClick={() => {
4132
messageComposer
4233
.createPoll()

src/components/Poll/__tests__/PollCreationDialog.test.js

Lines changed: 96 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ import React from 'react';
22
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
33
import '@testing-library/jest-dom';
44
import { PollCreationDialog } from '../PollCreationDialog';
5-
import {
6-
ChatProvider,
7-
MessageInputContextProvider,
8-
TranslationProvider,
9-
} from '../../../context';
10-
import { generateUser, getTestClientWithUser } from '../../../mock-builders';
5+
import { MessageInputContextProvider } from '../../../context';
6+
import { generateUser, initClientWithChannels } from '../../../mock-builders';
7+
import { Chat } from '../../Chat';
8+
import { Channel } from '../../Channel';
119

1210
const NAME_FIELD_PLACEHOLDER = 'Ask a question';
1311
const OPTION_FIELD_PLACEHOLDER = 'Add an option';
@@ -22,7 +20,6 @@ const NAME_INPUT_FIELD_ERROR_TEST_ID = 'poll-name-input-field-error';
2220
const OPTION_INPUT_FIELD_ERROR_TEST_ID = 'poll-option-input-field-error';
2321
const MAX_VOTE_COUT_INPUT_FIELD_ERROR_TEST_ID =
2422
'poll-max-votes-allowed-input-field-error';
25-
const REQUIRED_FIELD_ERROR_TEXT = 'The field is required';
2623
const DUPLICATE_OPTION_FIELD_ERROR_TEXT = 'Option already exists';
2724
const MAX_VOTE_COUNT_FIELD_ERROR_TEXT = 'Type a number from 2 to 10';
2825

@@ -31,22 +28,29 @@ const getOptionInput = () => screen.getByPlaceholderText(OPTION_FIELD_PLACEHOLDE
3128

3229
const close = jest.fn();
3330
const handleSubmit = jest.fn();
34-
const t = (v) => v;
35-
3631
const user = generateUser();
3732

38-
const renderComponent = async ({ client: customClient } = {}) => {
39-
const client = customClient ?? (await getTestClientWithUser(user));
40-
41-
return render(
42-
<ChatProvider value={{ client }}>
43-
<TranslationProvider value={{ t }}>
44-
<MessageInputContextProvider value={{ handleSubmit }}>
45-
<PollCreationDialog close={close} />
46-
</MessageInputContextProvider>
47-
</TranslationProvider>
48-
</ChatProvider>,
49-
);
33+
const renderComponent = async ({ channel: customChannel, client: customClient } = {}) => {
34+
let channel = customChannel;
35+
let client = customClient;
36+
if (!(channel && client)) {
37+
const initiated = await initClientWithChannels();
38+
channel = initiated.channels[0];
39+
client = initiated.client;
40+
}
41+
let result;
42+
await act(() => {
43+
result = render(
44+
<Chat client={client}>
45+
<Channel channel={channel}>
46+
<MessageInputContextProvider value={{ handleSubmit }}>
47+
<PollCreationDialog close={close} />
48+
</MessageInputContextProvider>
49+
</Channel>
50+
</Chat>,
51+
);
52+
});
53+
return { channel, client, ...result };
5054
};
5155

5256
describe('PollCreationDialog', () => {
@@ -77,8 +81,8 @@ describe('PollCreationDialog', () => {
7781
const text = 'Abc';
7882
await renderComponent();
7983
const nameInput = getNameInput();
80-
act(() => {
81-
fireEvent.change(nameInput, { target: { value: text } });
84+
await act(async () => {
85+
await fireEvent.change(nameInput, { target: { value: text } });
8286
});
8387
expect(nameInput).toHaveValue(text);
8488
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
@@ -89,14 +93,14 @@ describe('PollCreationDialog', () => {
8993
await renderComponent();
9094
const nameInput = getNameInput();
9195
expect(screen.getByTestId(NAME_INPUT_FIELD_ERROR_TEST_ID)).not.toHaveTextContent();
92-
act(() => {
93-
fireEvent.focus(nameInput);
96+
await act(async () => {
97+
await fireEvent.focus(nameInput);
9498
});
95-
act(() => {
96-
fireEvent.blur(nameInput);
99+
await act(async () => {
100+
await fireEvent.blur(nameInput);
97101
});
98102
expect(screen.getByTestId(NAME_INPUT_FIELD_ERROR_TEST_ID)).toHaveTextContent(
99-
REQUIRED_FIELD_ERROR_TEXT,
103+
'Name is required',
100104
);
101105
expect(nameInput).toHaveValue('');
102106
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
@@ -108,17 +112,17 @@ describe('PollCreationDialog', () => {
108112
await renderComponent();
109113
const nameInput = getNameInput();
110114
expect(screen.getByTestId(NAME_INPUT_FIELD_ERROR_TEST_ID)).not.toHaveTextContent();
111-
act(() => {
112-
fireEvent.focus(nameInput);
115+
await act(async () => {
116+
await fireEvent.focus(nameInput);
113117
});
114-
act(() => {
115-
fireEvent.blur(nameInput);
118+
await act(async () => {
119+
await fireEvent.blur(nameInput);
116120
});
117-
act(() => {
118-
fireEvent.change(nameInput, { target: { value: text } });
121+
await act(async () => {
122+
await fireEvent.change(nameInput, { target: { value: text } });
119123
});
120-
act(() => {
121-
fireEvent.blur(nameInput);
124+
await act(async () => {
125+
await fireEvent.blur(nameInput);
122126
});
123127
expect(screen.getByTestId(NAME_INPUT_FIELD_ERROR_TEST_ID)).not.toHaveTextContent();
124128
expect(nameInput).toHaveValue(text);
@@ -143,12 +147,12 @@ describe('PollCreationDialog', () => {
143147
const text = 'Abc';
144148
await renderComponent();
145149
const nameInput = getNameInput();
146-
act(() => {
147-
fireEvent.change(nameInput, { target: { value: text } });
150+
await act(async () => {
151+
await fireEvent.change(nameInput, { target: { value: text } });
148152
});
149153
const optionInput = getOptionInput();
150-
act(() => {
151-
fireEvent.change(optionInput, { target: { value: text } });
154+
await act(async () => {
155+
await fireEvent.change(optionInput, { target: { value: text } });
152156
});
153157
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
154158
expect(screen.getByText(CREATE_BUTTON_TEXT)).toBeEnabled();
@@ -239,8 +243,8 @@ describe('PollCreationDialog', () => {
239243
it('shows max vote count input on max vote count enabling', async () => {
240244
await renderComponent();
241245
const enforceUniqueToggle = screen.getByLabelText(MULTIPLE_ANSWERS_FIELD_LABEL);
242-
act(() => {
243-
fireEvent.click(enforceUniqueToggle);
246+
await act(async () => {
247+
await fireEvent.click(enforceUniqueToggle);
244248
});
245249
expect(enforceUniqueToggle).toBeChecked();
246250
expect(screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER).value).toBe('');
@@ -252,20 +256,20 @@ describe('PollCreationDialog', () => {
252256
const text = 'Abc';
253257
await renderComponent();
254258
const nameInput = getNameInput();
255-
act(() => {
256-
fireEvent.change(nameInput, { target: { value: text } });
259+
await act(async () => {
260+
await fireEvent.change(nameInput, { target: { value: text } });
257261
});
258262
const optionInput = getOptionInput();
259-
act(() => {
260-
fireEvent.change(optionInput, { target: { value: text } });
263+
await act(async () => {
264+
await fireEvent.change(optionInput, { target: { value: text } });
261265
});
262266
const enforceUniqueToggle = screen.getByLabelText(MULTIPLE_ANSWERS_FIELD_LABEL);
263-
act(() => {
264-
fireEvent.click(enforceUniqueToggle);
267+
await act(async () => {
268+
await fireEvent.click(enforceUniqueToggle);
265269
});
266270
const maxVoteCountInput = screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER);
267-
act(() => {
268-
fireEvent.change(maxVoteCountInput, { target: { value: '2' } });
271+
await act(async () => {
272+
await fireEvent.change(maxVoteCountInput, { target: { value: '2' } });
269273
});
270274
expect(screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER).value).toBe('2');
271275
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
@@ -276,20 +280,20 @@ describe('PollCreationDialog', () => {
276280
const text = 'Abc';
277281
await renderComponent();
278282
const nameInput = getNameInput();
279-
act(() => {
280-
fireEvent.change(nameInput, { target: { value: text } });
283+
await act(async () => {
284+
await fireEvent.change(nameInput, { target: { value: text } });
281285
});
282286
const optionInput = getOptionInput();
283-
act(() => {
284-
fireEvent.change(optionInput, { target: { value: text } });
287+
await act(async () => {
288+
await fireEvent.change(optionInput, { target: { value: text } });
285289
});
286290
const enforceUniqueToggle = screen.getByLabelText(MULTIPLE_ANSWERS_FIELD_LABEL);
287-
act(() => {
288-
fireEvent.click(enforceUniqueToggle);
291+
await act(async () => {
292+
await fireEvent.click(enforceUniqueToggle);
289293
});
290294
const maxVoteCountInput = screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER);
291-
act(() => {
292-
fireEvent.change(maxVoteCountInput, { target: { value: '1' } });
295+
await act(async () => {
296+
await fireEvent.change(maxVoteCountInput, { target: { value: '11' } });
293297
});
294298

295299
const maxVoteCountErrors = screen.getAllByTestId(
@@ -298,16 +302,16 @@ describe('PollCreationDialog', () => {
298302

299303
expect(maxVoteCountErrors).toHaveLength(1);
300304
expect(maxVoteCountErrors[0]).toHaveTextContent(MAX_VOTE_COUNT_FIELD_ERROR_TEXT);
301-
expect(screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER).value).toBe('1');
305+
expect(screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER).value).toBe('11');
302306
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
303307
expect(screen.getByText(CREATE_BUTTON_TEXT)).toBeDisabled();
304308
});
305309

306310
it('toggles voting visibility', async () => {
307311
await renderComponent();
308312
const votingVisibilityToggle = screen.getByLabelText(VOTING_VISIBILITY_FIELD_LABEL);
309-
act(() => {
310-
fireEvent.click(votingVisibilityToggle);
313+
await act(async () => {
314+
await fireEvent.click(votingVisibilityToggle);
311315
});
312316
expect(votingVisibilityToggle).toBeChecked();
313317
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
@@ -317,8 +321,8 @@ describe('PollCreationDialog', () => {
317321
it('toggles allowing user suggested options', async () => {
318322
await renderComponent();
319323
const suggestOptionToggle = screen.getByLabelText(OPTION_SUGGESTION_FIELD_LABEL);
320-
act(() => {
321-
fireEvent.click(suggestOptionToggle);
324+
await act(async () => {
325+
await fireEvent.click(suggestOptionToggle);
322326
});
323327
expect(suggestOptionToggle).toBeChecked();
324328
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
@@ -328,8 +332,8 @@ describe('PollCreationDialog', () => {
328332
it('toggles allowing user comments', async () => {
329333
await renderComponent();
330334
const allowCommentsToggle = screen.getByLabelText(ALLOW_COMMENTS_FIELD_LABEL);
331-
act(() => {
332-
fireEvent.click(allowCommentsToggle);
335+
await act(async () => {
336+
await fireEvent.click(allowCommentsToggle);
333337
});
334338
expect(allowCommentsToggle).toBeChecked();
335339
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
@@ -350,58 +354,59 @@ describe('PollCreationDialog', () => {
350354
};
351355
const expectedPollPayload = { ...formState, max_votes_allowed: 10 };
352356

353-
const client = await getTestClientWithUser(user);
354-
let pollId;
357+
const poll = { id: 'pollId' };
358+
const {
359+
channels: [channel],
360+
client,
361+
} = await initClientWithChannels({ customUser: user });
362+
await renderComponent({ channel, client });
355363
const createPollSpy = jest
356364
.spyOn(client, 'createPoll')
357-
.mockImplementationOnce((poll) => {
358-
pollId = poll.id;
359-
return Promise.resolve({ poll });
360-
});
365+
.mockImplementationOnce(() => Promise.resolve({ poll }));
361366

362-
await renderComponent({ client });
363-
act(() => {
364-
fireEvent.change(getNameInput(), { target: { value: formState.name } });
367+
await act(async () => {
368+
await fireEvent.change(getNameInput(), { target: { value: formState.name } });
365369
});
366-
act(() => {
367-
fireEvent.change(getOptionInput(), {
370+
await act(async () => {
371+
await fireEvent.change(getOptionInput(), {
368372
target: { value: formState.options[0].text },
369373
});
370374
});
371375
const optionFields = screen.getAllByPlaceholderText(OPTION_FIELD_PLACEHOLDER);
372-
act(() => {
373-
fireEvent.change(optionFields[1], { target: { value: formState.options[1].text } });
376+
await act(async () => {
377+
await fireEvent.change(optionFields[1], {
378+
target: { value: formState.options[1].text },
379+
});
374380
});
375-
act(() => {
376-
fireEvent.click(screen.getByLabelText(MULTIPLE_ANSWERS_FIELD_LABEL));
381+
await act(async () => {
382+
await fireEvent.click(screen.getByLabelText(MULTIPLE_ANSWERS_FIELD_LABEL));
377383
});
378-
act(() => {
379-
fireEvent.change(screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER), {
384+
await act(async () => {
385+
await fireEvent.change(screen.getByPlaceholderText(MAX_VOTES_FIELD_PLACEHOLDER), {
380386
target: { value: formState.max_votes_allowed },
381387
});
382388
});
383-
act(() => {
384-
fireEvent.click(screen.getByLabelText(VOTING_VISIBILITY_FIELD_LABEL));
389+
await act(async () => {
390+
await fireEvent.click(screen.getByLabelText(VOTING_VISIBILITY_FIELD_LABEL));
385391
});
386-
act(() => {
387-
fireEvent.click(screen.getByLabelText(OPTION_SUGGESTION_FIELD_LABEL));
392+
await act(async () => {
393+
await fireEvent.click(screen.getByLabelText(OPTION_SUGGESTION_FIELD_LABEL));
388394
});
389-
act(() => {
390-
fireEvent.click(screen.getByLabelText(ALLOW_COMMENTS_FIELD_LABEL));
395+
await act(async () => {
396+
await fireEvent.click(screen.getByLabelText(ALLOW_COMMENTS_FIELD_LABEL));
391397
});
392398
expect(screen.getByText(CANCEL_BUTTON_TEXT)).toBeEnabled();
393399
const submitButton = screen.getByText(CREATE_BUTTON_TEXT);
394400
expect(submitButton).toBeEnabled();
395-
act(() => {
396-
fireEvent.click(submitButton);
401+
await act(async () => {
402+
await fireEvent.click(submitButton);
397403
});
398404

399405
await waitFor(() => {
400406
expect(createPollSpy).toHaveBeenCalledWith(
401407
expect.objectContaining(expectedPollPayload),
402408
);
403409
expect(close).toHaveBeenCalledTimes(1);
404-
expect(handleSubmit).toHaveBeenCalledWith(expect.any(Object), { poll_id: pollId });
405410
});
406411
});
407412

0 commit comments

Comments
 (0)