Skip to content

Commit 316b8c0

Browse files
committed
refactor(tests): annotate attachment, message-input, and remaining tests
Type annotations for ~32 remaining test files across attachment, message-input, message-menu, channel-preview, image-gallery, hooks, and context folders. No behavior changes. Patterns applied (same as the previous commit): - `let client: StreamChat; let channel: Channel;` at describe scope. - `{...} as unknown as XContextValue` for partial context mocks. - `renderComponent` helpers typed with `ComponentProps<typeof X>`. - `MessageResponse` → `LocalMessage` via local wrapper casts. - Replace bogus `as unknown as FileUpload` (never imported — leftover silent bug from .js) with the real component prop type: `LocalAudioAttachment` / `LocalVoiceRecordingAttachment` from `stream-chat` (see `AudioAttachmentUploadPreview.tsx:5`). - Attachment mocks with `localMetadata` typed as `LocalAttachment` (from `stream-chat`) rather than `Partial<Attachment>`. Notable: `AudioAttachmentUploadPreviewNative.test.tsx` and `*Expo.test.tsx` already used `describe.skip` at the top (pre-migration behavior: their mock props don't match the current component API). Kept the skip and loosened helper-arg types to `unknown` so the (unreachable) test bodies type-check. Filing these as follow-up to properly un-skip and update. Takes test:typecheck 227 → 69 (−158). All 69 remaining errors are in the two offline-support helpers (`offline-feature.tsx`, `optimistic-update.tsx`) — handled in the next commit. Full test suite: 752 passed, 14 skipped; only the pre-existing SQLite-isolation flake in `offline-support/index.test.ts` fails. No regressions.
1 parent f964523 commit 316b8c0

34 files changed

Lines changed: 425 additions & 200 deletions

package/src/components/Attachment/__tests__/Attachment.test.tsx

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import React from 'react';
1+
import React, { ComponentProps } from 'react';
22

33
import { render, waitFor } from '@testing-library/react-native';
4+
import type { LocalMessage } from 'stream-chat';
45
import { v4 as uuidv4 } from 'uuid';
56

7+
import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext';
68
import { MessageProvider } from '../../../contexts/messageContext/MessageContext';
9+
import type { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext';
710
import { MessagesProvider } from '../../../contexts/messagesContext/MessagesContext';
811
import { ThemeProvider } from '../../../contexts/themeContext/ThemeContext';
912
import {
@@ -24,18 +27,20 @@ jest.mock('../../../native.ts', () => ({
2427
isSoundPackageAvailable: jest.fn(() => false),
2528
}));
2629

27-
const getAttachmentComponent = (props) => {
28-
const message = generateMessage();
30+
const getAttachmentComponent = (props: ComponentProps<typeof Attachment>) => {
31+
const message = generateMessage() as unknown as LocalMessage;
2932
return (
3033
<ThemeProvider>
3134
<MessagesProvider
32-
value={{
33-
ImageLoadingFailedIndicator,
34-
ImageLoadingIndicator,
35-
FilePreview: FilePreviewDefault,
36-
}}
35+
value={
36+
{
37+
ImageLoadingFailedIndicator,
38+
ImageLoadingIndicator,
39+
FilePreview: FilePreviewDefault,
40+
} as unknown as MessagesContextValue
41+
}
3742
>
38-
<MessageProvider value={{ message }}>
43+
<MessageProvider value={{ message } as unknown as MessageContextValue}>
3944
<Attachment {...props} />
4045
</MessageProvider>
4146
</MessagesProvider>

package/src/components/Attachment/__tests__/Gallery.test.tsx

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
import React from 'react';
1+
import React, { ComponentProps } from 'react';
22

33
import { fireEvent, render, screen, waitFor } from '@testing-library/react-native';
4+
import type { Attachment, ChannelResponse } from 'stream-chat';
45

56
import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvider';
67

@@ -31,15 +32,21 @@ describe('Gallery', () => {
3132

3233
const user1 = generateUser();
3334

34-
const getComponent = async (attachments = [], channelProps = {}) => {
35+
const getComponent = async (
36+
attachments: Attachment[] = [],
37+
channelProps: Partial<ComponentProps<typeof Channel>> = {},
38+
) => {
3539
const chatClient = await getTestClientWithUser({ id: 'testID' });
3640

3741
const mockedChannel = generateChannelResponse({
3842
members: [generateMember({ user: user1 })],
3943
messages: [generateMessage({ attachments, user: user1 })],
4044
});
4145
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
42-
const channel = chatClient.channel('messaging', mockedChannel.id);
46+
const channel = chatClient.channel(
47+
'messaging',
48+
(mockedChannel.channel as unknown as ChannelResponse).id,
49+
);
4350
await channel.watch();
4451

4552
return (

package/src/components/Attachment/__tests__/Giphy.test.tsx

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { ComponentProps } from 'react';
22

33
import {
44
act,
@@ -9,8 +9,16 @@ import {
99
userEvent,
1010
waitFor,
1111
} from '@testing-library/react-native';
12-
12+
import type {
13+
Channel as ChannelType,
14+
ChannelResponse,
15+
LocalMessage,
16+
StreamChat,
17+
} from 'stream-chat';
18+
19+
import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext';
1320
import { MessageProvider } from '../../../contexts/messageContext/MessageContext';
21+
import type { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext';
1422
import { MessagesProvider } from '../../../contexts/messagesContext/MessagesContext';
1523
import { OverlayProvider } from '../../../contexts/overlayContext/OverlayProvider';
1624

@@ -38,21 +46,34 @@ const streami18n = new Streami18n({
3846
describe('Giphy', () => {
3947
const lightTheme = mergeThemes({ scheme: 'light' });
4048

41-
const getAttachmentComponent = (props, messageContextValue = {}) => {
42-
const message = generateMessage();
49+
const getAttachmentComponent = (
50+
props: Record<string, unknown>,
51+
messageContextValue: Partial<MessageContextValue> = {},
52+
) => {
53+
const message = generateMessage() as unknown as LocalMessage;
4354
return (
4455
<ThemeProvider>
45-
<MessagesProvider value={{ ImageLoadingFailedIndicator, ImageLoadingIndicator }}>
46-
<MessageProvider value={{ message, ...messageContextValue }}>
47-
<Giphy {...props} />
56+
<MessagesProvider
57+
value={
58+
{
59+
ImageLoadingFailedIndicator,
60+
ImageLoadingIndicator,
61+
} as unknown as MessagesContextValue
62+
}
63+
>
64+
<MessageProvider
65+
value={{ message, ...messageContextValue } as unknown as MessageContextValue}
66+
>
67+
<Giphy {...(props as unknown as ComponentProps<typeof Giphy>)} />
4868
</MessageProvider>
4969
</MessagesProvider>
5070
</ThemeProvider>
5171
);
5272
};
53-
let chatClient;
54-
let channel;
55-
let attachment;
73+
let chatClient: StreamChat;
74+
let channel: ChannelType;
75+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
76+
let attachment: any;
5677

5778
const actions = [
5879
{ name: 'image_action', text: 'Send', value: 'send' },
@@ -91,7 +112,10 @@ describe('Giphy', () => {
91112

92113
chatClient = await getTestClientWithUser({ id: 'testID' });
93114
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
94-
channel = chatClient.channel('messaging', mockedChannel.id);
115+
channel = chatClient.channel(
116+
'messaging',
117+
(mockedChannel.channel as unknown as ChannelResponse).id,
118+
);
95119
await channel.watch();
96120
};
97121

@@ -321,7 +345,10 @@ describe('Giphy', () => {
321345

322346
const chatClient = await getTestClientWithUser({ id: 'testID' });
323347
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
324-
const channel = chatClient.channel('messaging', mockedChannel.id);
348+
const channel = chatClient.channel(
349+
'messaging',
350+
(mockedChannel.channel as unknown as ChannelResponse).id,
351+
);
325352
await channel.watch();
326353

327354
render(

package/src/components/Attachment/__tests__/buildGallery.test.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { Attachment } from 'stream-chat';
2+
13
import { generateImageAttachment } from '../../../mock-builders/generator/attachment';
24
import { buildGallery } from '../utils/buildGallery/buildGallery';
35

@@ -20,7 +22,7 @@ describe('buildGallery', () => {
2022
];
2123

2224
imageSizeTestCases.forEach((size) => {
23-
const attachments = [];
25+
const attachments: Attachment[] = [];
2426
for (let numOfImages = 0; numOfImages < 4; numOfImages++) {
2527
const a1 = generateImageAttachment({
2628
...size,
@@ -77,7 +79,7 @@ describe('buildGallery', () => {
7779
});
7880

7981
it('gallery size should default to gridHeight and gridWidth if original image size is unavailable', () => {
80-
const attachments = [];
82+
const attachments: Attachment[] = [];
8183
for (let numOfImages = 0; numOfImages < 4; numOfImages++) {
8284
// During each iteration, size of attachments goes up.
8385
attachments.push(generateImageAttachment());

package/src/components/AutoCompleteInput/__tests__/AutoCompleteInput.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ describe('AutoCompleteInput', () => {
4343

4444
const { queryByTestId } = screen;
4545

46-
const input = queryByTestId('auto-complete-text-input');
46+
const input = queryByTestId('auto-complete-text-input')!;
4747

4848
await waitFor(() => {
4949
expect(input).toBeTruthy();
@@ -60,7 +60,7 @@ describe('AutoCompleteInput', () => {
6060

6161
const { queryByTestId } = screen;
6262

63-
const input = queryByTestId('auto-complete-text-input');
63+
const input = queryByTestId('auto-complete-text-input')!;
6464

6565
await waitFor(() => {
6666
expect(input.props.editable).toBeFalsy();
@@ -78,7 +78,7 @@ describe('AutoCompleteInput', () => {
7878

7979
const { queryByTestId } = screen;
8080

81-
const input = queryByTestId('auto-complete-text-input');
81+
const input = queryByTestId('auto-complete-text-input')!;
8282

8383
await waitFor(() => {
8484
expect(input.props.maxLength).toBe(10);
@@ -97,7 +97,7 @@ describe('AutoCompleteInput', () => {
9797

9898
const { queryByTestId } = screen;
9999

100-
const input = queryByTestId('auto-complete-text-input');
100+
const input = queryByTestId('auto-complete-text-input')!;
101101

102102
act(() => {
103103
fireEvent.changeText(input, 'hello');
@@ -125,7 +125,7 @@ describe('AutoCompleteInput', () => {
125125

126126
const { queryByTestId } = screen;
127127

128-
const input = queryByTestId('auto-complete-text-input');
128+
const input = queryByTestId('auto-complete-text-input')!;
129129

130130
act(() => {
131131
fireEvent(input, 'selectionChange', {
@@ -155,7 +155,7 @@ describe('AutoCompleteInput', () => {
155155

156156
const { queryByTestId } = screen;
157157

158-
const input = queryByTestId('auto-complete-text-input');
158+
const input = queryByTestId('auto-complete-text-input')!;
159159

160160
await waitFor(() => {
161161
expect(input.props.placeholder).toBe(data.result);

package/src/components/ChannelList/hooks/__tests__/useChannelActionItems.test.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ describe('getChannelActionItems', () => {
149149
isDirectChat: false,
150150
isPinned: false,
151151
muteActive: false,
152-
t: (value) => value,
152+
t: ((value: string) => value) as TranslationContextValue['t'],
153153
});
154154
const actionItems = getChannelActionItems({
155155
context: {
@@ -159,7 +159,7 @@ describe('getChannelActionItems', () => {
159159
isDirectChat: false,
160160
isPinned: false,
161161
muteActive: false,
162-
t: (value) => value,
162+
t: ((value: string) => value) as TranslationContextValue['t'],
163163
},
164164
defaultItems,
165165
});
@@ -186,7 +186,7 @@ describe('getChannelActionItems', () => {
186186
isDirectChat: true,
187187
isPinned: false,
188188
muteActive: true,
189-
t: (value) => value,
189+
t: ((value: string) => value) as TranslationContextValue['t'],
190190
});
191191

192192
expect(actionItems.map((item) => item.id)).toEqual(['mute', 'block', 'leave', 'deleteChannel']);
@@ -213,7 +213,7 @@ describe('getChannelActionItems', () => {
213213
isDirectChat: false,
214214
isPinned: false,
215215
muteActive: false,
216-
t: (value) => value,
216+
t: ((value: string) => value) as TranslationContextValue['t'],
217217
});
218218

219219
expect(actionItems.map((item) => item.id)).toEqual(['mute', 'leave']);
@@ -228,7 +228,7 @@ describe('getChannelActionItems', () => {
228228
isDirectChat: false,
229229
isPinned: false,
230230
muteActive: true,
231-
t: (value) => value,
231+
t: ((value: string) => value) as TranslationContextValue['t'],
232232
});
233233

234234
expect(actionItems[0].action).toBe(channelActions.unmuteChannel);
@@ -251,7 +251,7 @@ describe('getChannelActionItems', () => {
251251
isDirectChat: false,
252252
isPinned: false,
253253
muteActive: false,
254-
t: (value) => value,
254+
t: ((value: string) => value) as TranslationContextValue['t'],
255255
});
256256

257257
const deleteItem = actionItems.find((item) => item.id === 'deleteChannel');

package/src/components/ChannelList/hooks/__tests__/useChannelActionItemsById.test.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ describe('useChannelActionItemsById', () => {
2121
const channelActionItems: useChannelActionItemsModule.ChannelActionItem[] = [
2222
{
2323
action: jest.fn(),
24-
Icon: <></>,
24+
Icon: () => <></>,
2525
id: 'pin',
2626
label: '',
2727
placement: 'both',
2828
type: 'standard',
2929
},
3030
{
3131
action: jest.fn(),
32-
Icon: <></>,
32+
Icon: () => <></>,
3333
id: 'deleteChannel',
3434
label: '',
3535
placement: 'both',

package/src/components/ChannelList/hooks/listeners/__tests__/useChannelUpdated.test.tsx

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { Image, Text } from 'react-native';
44
import { act, render, waitFor } from '@testing-library/react-native';
55
import type { Channel, ChannelResponse, Event, StreamChat } from 'stream-chat';
66

7+
import type { ChatContextValue } from '../../../../../contexts/chatContext/ChatContext';
78
import { ChatContext, useChannelUpdated } from '../../../../../index';
89

910
describe('useChannelUpdated', () => {
@@ -33,16 +34,16 @@ describe('useChannelUpdated', () => {
3334
} as unknown as StreamChat;
3435

3536
const TestComponent = () => {
36-
const [channels, setChannels] = useState<Channel[] | null>([mockChannel]);
37+
const [channels, setChannels] = useState<Channel[]>([mockChannel]);
3738

3839
useChannelUpdated({ setChannels });
3940

4041
if (
4142
channels &&
4243
channels[0].data?.own_capabilities &&
43-
Object.keys(channels[0].data?.own_capabilities as { [key: string]: boolean }).includes(
44-
'send_messages',
45-
)
44+
Object.keys(
45+
channels[0].data?.own_capabilities as unknown as { [key: string]: boolean },
46+
).includes('send_messages')
4647
) {
4748
return <Text>Send messages enabled</Text>;
4849
}
@@ -53,16 +54,18 @@ describe('useChannelUpdated', () => {
5354
const { getByText } = await waitFor(() =>
5455
render(
5556
<ChatContext.Provider
56-
value={{
57-
appSettings: null,
58-
client: mockClient,
59-
connectionRecovering: false,
60-
enableOfflineSupport: false,
61-
ImageComponent: Image,
62-
isOnline: true,
63-
mutedUsers: [],
64-
setActiveChannel: () => null,
65-
}}
57+
value={
58+
{
59+
appSettings: null,
60+
client: mockClient,
61+
connectionRecovering: false,
62+
enableOfflineSupport: false,
63+
ImageComponent: Image,
64+
isOnline: true,
65+
mutedUsers: [],
66+
setActiveChannel: () => null,
67+
} as unknown as ChatContextValue
68+
}
6669
>
6770
<TestComponent />
6871
</ChatContext.Provider>,

0 commit comments

Comments
 (0)