Skip to content

Commit 94306e0

Browse files
committed
tests: add tests
1 parent afabb1d commit 94306e0

26 files changed

+1584
-1380
lines changed

package/src/components/AttachmentPicker/AttachmentPicker.tsx

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,27 @@ export type AttachmentPickerProps = Pick<
4040
/**
4141
* Custom UI component to render error component while opening attachment picker.
4242
*
43-
* **Default** [AttachmentPickerError](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/AttachmentPicker/components/AttachmentPickerError.tsx)
43+
* **Default**
44+
* [AttachmentPickerError](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/AttachmentPicker/components/AttachmentPickerError.tsx)
4445
*/
4546
AttachmentPickerError: React.ComponentType<AttachmentPickerErrorProps>;
4647
/**
4748
* Custom UI component to render error image for attachment picker
4849
*
49-
* **Default** [AttachmentPickerErrorImage](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/AttachmentPicker/components/AttachmentPickerErrorImage.tsx)
50+
* **Default**
51+
* [AttachmentPickerErrorImage](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/AttachmentPicker/components/AttachmentPickerErrorImage.tsx)
5052
*/
5153
AttachmentPickerErrorImage: React.ComponentType;
5254
/**
5355
* Custom UI Component to render select more photos for selected gallery access in iOS.
5456
*/
5557
AttachmentPickerIOSSelectMorePhotos: React.ComponentType;
5658
/**
57-
* Custom UI component to render overlay component, that shows up on top of [selected image](https://github.com/GetStream/stream-chat-react-native/blob/main/screenshots/docs/1.png) (with tick mark)
59+
* Custom UI component to render overlay component, that shows up on top of [selected
60+
* image](https://github.com/GetStream/stream-chat-react-native/blob/main/screenshots/docs/1.png) (with tick mark)
5861
*
59-
* **Default** [ImageOverlaySelectedComponent](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/AttachmentPicker/components/ImageOverlaySelectedComponent.tsx)
62+
* **Default**
63+
* [ImageOverlaySelectedComponent](https://github.com/GetStream/stream-chat-react-native/blob/main/package/src/components/AttachmentPicker/components/ImageOverlaySelectedComponent.tsx)
6064
*/
6165
ImageOverlaySelectedComponent: React.ComponentType;
6266
attachmentPickerErrorButtonText?: string;
@@ -157,7 +161,8 @@ export const AttachmentPicker = React.forwardRef(
157161
if (!NativeHandlers.oniOS14GalleryLibrarySelectionChange) {
158162
return;
159163
}
160-
// ios 14 library selection change event is fired when user reselects the images that are permitted to be readable by the app
164+
// ios 14 library selection change event is fired when user reselects the images that are permitted to be
165+
// readable by the app
161166
const { unsubscribe } = NativeHandlers.oniOS14GalleryLibrarySelectionChange(() => {
162167
// we reset the cursor and has next page to true to facilitate fetching of the first page of photos again
163168
hasNextPageRef.current = true;
@@ -232,7 +237,8 @@ export const AttachmentPicker = React.forwardRef(
232237
!loadingPhotos
233238
) {
234239
getMorePhotos();
235-
// we do this only once on open for avoiding to request permissions in rationale dialog again and again on Android
240+
// we do this only once on open for avoiding to request permissions in rationale dialog again and again on
241+
// Android
236242
attemptedToLoadPhotosOnOpenRef.current = true;
237243
}
238244
}, [currentIndex, selectedPicker, getMorePhotos, loadingPhotos]);
@@ -301,6 +307,7 @@ export const AttachmentPicker = React.forwardRef(
301307
numColumns={numberOfAttachmentPickerImageColumns ?? 3}
302308
onEndReached={photoError ? undefined : getMorePhotos}
303309
renderItem={renderAttachmentPickerItem}
310+
testID={'attachment-picker-list'}
304311
/>
305312
</BottomSheet>
306313
{selectedPicker === 'images' && photoError && (

package/src/components/Channel/hooks/useCreateOwnCapabilitiesContext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const useCreateOwnCapabilitiesContext = ({
2222
? JSON.stringify(Object.values(overrideCapabilities))
2323
: null;
2424

25-
// Effect to watch for changes in channel.data?.own_capabilities and update the own_capabilties state accordingly.
25+
// Effect to watch for changes in channel.data?.own_capabilities and update the own_capabilities state accordingly.
2626
useEffect(() => {
2727
setOwnCapabilites(JSON.stringify(channel.data?.own_capabilities as Array<string>));
2828
}, [channel.data?.own_capabilities]);

package/src/components/MessageInput/AttachButton.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ import { Pressable } from 'react-native';
55
import { NativeAttachmentPicker } from './components/NativeAttachmentPicker';
66

77
import { useAttachmentPickerContext } from '../../contexts/attachmentPickerContext/AttachmentPickerContext';
8-
import { ChannelContextValue } from '../../contexts/channelContext/ChannelContext';
98
import { useMessageInputContext } from '../../contexts/messageInputContext/MessageInputContext';
109
import { useTheme } from '../../contexts/themeContext/ThemeContext';
1110
import { Attach } from '../../icons/Attach';
1211

1312
import { isImageMediaLibraryAvailable } from '../../native';
1413

15-
type AttachButtonPropsWithContext = Pick<ChannelContextValue, 'disabled'> & {
14+
type AttachButtonPropsWithContext = {
15+
disabled?: boolean;
1616
/** Function that opens attachment options bottom sheet */
1717
handleOnPress?: ((event: GestureResponderEvent) => void) & (() => void);
1818
selectedPicker?: 'images';
@@ -21,7 +21,7 @@ type AttachButtonPropsWithContext = Pick<ChannelContextValue, 'disabled'> & {
2121
const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => {
2222
const [showAttachButtonPicker, setShowAttachButtonPicker] = useState<boolean>(false);
2323
const [attachButtonLayoutRectangle, setAttachButtonLayoutRectangle] = useState<LayoutRectangle>();
24-
const { disabled, handleOnPress, selectedPicker } = props;
24+
const { disabled = false, handleOnPress, selectedPicker } = props;
2525
const {
2626
theme: {
2727
colors: { accent_blue, grey },
@@ -51,6 +51,9 @@ const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => {
5151
};
5252

5353
const onPressHandler = () => {
54+
if (disabled) {
55+
return;
56+
}
5457
if (handleOnPress) {
5558
handleOnPress();
5659
return;
@@ -71,7 +74,7 @@ const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => {
7174
<Pressable
7275
disabled={disabled}
7376
onLayout={onAttachButtonLayout}
74-
onPress={disabled ? () => null : onPressHandler}
77+
onPress={onPressHandler}
7578
style={[attachButton]}
7679
testID='attach-button'
7780
>

package/src/components/MessageInput/CommandsButton.tsx

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,24 @@
1-
import React, { useCallback, useMemo } from 'react';
1+
import React, { useCallback } from 'react';
22
import type { GestureResponderEvent, PressableProps } from 'react-native';
3-
import { Pressable, View } from 'react-native';
4-
5-
import { SearchSourceState, TextComposerState } from 'stream-chat';
3+
import { Pressable } from 'react-native';
64

75
import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer';
86
import { useTheme } from '../../contexts/themeContext/ThemeContext';
9-
import { useStateStore } from '../../hooks/useStateStore';
107
import { Lightning } from '../../icons/Lightning';
118

129
export type CommandsButtonProps = {
13-
/** Function that opens commands selector */
10+
/** Function that opens commands selector. */
1411
handleOnPress?: PressableProps['onPress'];
1512
/**
16-
* Determins if the text input has text
13+
* Determines if the text input has text
1714
*/
1815
hasText?: boolean;
1916
};
2017

21-
const textComposerStateSelector = (state: TextComposerState) => ({
22-
suggestions: state.suggestions,
23-
text: state.text,
24-
});
25-
26-
const searchSourceStateSelector = (nextValue: SearchSourceState) => ({
27-
items: nextValue.items,
28-
});
29-
3018
export const CommandsButton = (props: CommandsButtonProps) => {
3119
const { handleOnPress, hasText } = props;
3220
const messageComposer = useMessageComposer();
3321
const { textComposer } = messageComposer;
34-
const { suggestions } = useStateStore(textComposer.state, textComposerStateSelector);
35-
const { items } = useStateStore(suggestions?.searchSource.state, searchSourceStateSelector) ?? {};
36-
const trigger = suggestions?.trigger;
37-
38-
const commandsButtonEnabled = useMemo(() => {
39-
return items && items?.length > 0 && trigger === '/';
40-
}, [items, trigger]);
4122

4223
const onPressHandler = useCallback(
4324
async (event: GestureResponderEvent) => {
@@ -59,8 +40,8 @@ export const CommandsButton = (props: CommandsButtonProps) => {
5940

6041
const {
6142
theme: {
62-
colors: { accent_blue, grey },
63-
messageInput: { commandsButton, commandsButtonContainer },
43+
colors: { grey },
44+
messageInput: { commandsButton },
6445
},
6546
} = useTheme();
6647

@@ -69,11 +50,9 @@ export const CommandsButton = (props: CommandsButtonProps) => {
6950
}
7051

7152
return (
72-
<View style={[commandsButtonContainer]}>
73-
<Pressable onPress={onPressHandler} style={[commandsButton]} testID='commands-button'>
74-
<Lightning fill={commandsButtonEnabled ? accent_blue : grey} size={32} />
75-
</Pressable>
76-
</View>
53+
<Pressable onPress={onPressHandler} style={[commandsButton]} testID='commands-button'>
54+
<Lightning fill={grey} size={32} />
55+
</Pressable>
7756
);
7857
};
7958

package/src/components/MessageInput/FileUploadPreview.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const UnMemoizedFileUploadPreview = (props: FileUploadPreviewPropsWithContext) =
6161
return attachments.filter(
6262
(attachment) =>
6363
isLocalFileAttachment(attachment) ||
64-
isLocalFileAttachment(attachment) ||
64+
isLocalAudioAttachment(attachment) ||
6565
isLocalVoiceRecordingAttachment(attachment) ||
6666
isLocalVideoAttachment(attachment),
6767
);
@@ -89,7 +89,8 @@ const UnMemoizedFileUploadPreview = (props: FileUploadPreviewPropsWithContext) =
8989
// eslint-disable-next-line react-hooks/exhaustive-deps
9090
}, [fileUploads]);
9191

92-
// Handler triggered when an audio is loaded in the message input. The initial state is defined for the audio here and the duration is set.
92+
// Handler triggered when an audio is loaded in the message input. The initial state is defined for the audio here
93+
// and the duration is set.
9394
const onLoad = useCallback((index: string, duration: number) => {
9495
setAudioAttachmentsStateMap((prevState) => ({
9596
...prevState,
@@ -100,7 +101,8 @@ const UnMemoizedFileUploadPreview = (props: FileUploadPreviewPropsWithContext) =
100101
}));
101102
}, []);
102103

103-
// The handler which is triggered when the audio progresses/ the thumb is dragged in the progress control. The progressed duration is set here.
104+
// The handler which is triggered when the audio progresses/ the thumb is dragged in the progress control. The
105+
// progressed duration is set here.
104106
const onProgress = useCallback((index: string, progress: number) => {
105107
setAudioAttachmentsStateMap((prevState) => ({
106108
...prevState,
@@ -255,6 +257,7 @@ const UnMemoizedFileUploadPreview = (props: FileUploadPreviewPropsWithContext) =
255257
ref={flatListRef}
256258
renderItem={renderItem}
257259
style={[styles.flatList, flatList]}
260+
testID={'file-upload-preview'}
258261
/>
259262
);
260263
};

package/src/components/MessageInput/ImageUploadPreview.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ const UnmemoizedImageUploadPreview = (props: ImageUploadPreviewPropsWithContext)
3131
const { attachmentManager } = useMessageComposer();
3232
const { attachments } = useAttachmentManagerState();
3333

34-
const imageOrVideoUploads = attachments.filter((attachment) =>
35-
isLocalImageAttachment(attachment),
36-
);
34+
const imageUploads = attachments.filter((attachment) => isLocalImageAttachment(attachment));
3735

3836
const {
3937
theme: {
@@ -60,13 +58,13 @@ const UnmemoizedImageUploadPreview = (props: ImageUploadPreviewPropsWithContext)
6058
],
6159
);
6260

63-
if (!imageOrVideoUploads.length) {
61+
if (!imageUploads.length) {
6462
return null;
6563
}
6664

6765
return (
6866
<FlatList
69-
data={imageOrVideoUploads}
67+
data={imageUploads}
7068
getItemLayout={(_, index) => ({
7169
index,
7270
length: IMAGE_PREVIEW_SIZE + 8,

package/src/components/MessageInput/InputButtons.tsx

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@ import { StyleSheet, View } from 'react-native';
33

44
import { TextComposerState } from 'stream-chat';
55

6-
import { AttachmentPickerContextValue, useAttachmentPickerContext } from '../../contexts';
6+
import {
7+
AttachmentPickerContextValue,
8+
OwnCapabilitiesContextValue,
9+
useAttachmentPickerContext,
10+
} from '../../contexts';
711
import { useAttachmentManagerState } from '../../contexts/messageInputContext/hooks/useAttachmentManagerState';
812
import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer';
913
import {
@@ -27,7 +31,8 @@ export type InputButtonsWithContextProps = Pick<
2731
| 'MoreOptionsButton'
2832
| 'toggleAttachmentPicker'
2933
> &
30-
Pick<AttachmentPickerContextValue, 'selectedPicker'>;
34+
Pick<AttachmentPickerContextValue, 'selectedPicker'> &
35+
Pick<OwnCapabilitiesContextValue, 'uploadFile'>;
3136

3237
const textComposerStateSelector = (state: TextComposerState) => ({
3338
command: state.command,
@@ -43,6 +48,7 @@ export const InputButtonsWithContext = (props: InputButtonsWithContextProps) =>
4348
hasFilePicker,
4449
hasImagePicker,
4550
MoreOptionsButton,
51+
uploadFile: ownCapabilitiesUploadFile,
4652
} = props;
4753
const { textComposer } = useMessageComposer();
4854
const { command, text } = useStateStore(textComposer.state, textComposerStateSelector);
@@ -67,24 +73,29 @@ export const InputButtonsWithContext = (props: InputButtonsWithContextProps) =>
6773
setShowMoreOptions(true);
6874
}, [setShowMoreOptions]);
6975

70-
const ownCapabilities = useOwnCapabilitiesContext();
76+
const hasAttachmentUploadCapabilities =
77+
(hasCameraPicker || hasFilePicker || hasImagePicker) && ownCapabilitiesUploadFile;
7178

7279
if (command) {
7380
return null;
7481
}
7582

76-
return !showMoreOptions && (hasCameraPicker || hasImagePicker || hasFilePicker) && hasCommands ? (
83+
if (!hasAttachmentUploadCapabilities && !hasCommands) {
84+
return null;
85+
}
86+
87+
return !showMoreOptions ? (
7788
<MoreOptionsButton handleOnPress={handleShowMoreOptions} />
7889
) : (
7990
<>
80-
{(hasCameraPicker || hasImagePicker || hasFilePicker) && ownCapabilities.uploadFile && (
91+
{hasAttachmentUploadCapabilities ? (
8192
<View
8293
style={[hasCommands ? styles.attachButtonContainer : undefined, attachButtonContainer]}
8394
>
8495
<AttachButton />
8596
</View>
86-
)}
87-
{hasCommands && <CommandsButton hasText={hasText} />}
97+
) : null}
98+
{hasCommands ? <CommandsButton hasText={hasText} /> : null}
8899
</>
89100
);
90101
};
@@ -149,6 +160,7 @@ export const InputButtons = (props: InputButtonsProps) => {
149160
toggleAttachmentPicker,
150161
} = useMessageInputContext();
151162
const { selectedPicker } = useAttachmentPickerContext();
163+
const { uploadFile } = useOwnCapabilitiesContext();
152164

153165
return (
154166
<MemoizedInputButtonsWithContext
@@ -162,6 +174,7 @@ export const InputButtons = (props: InputButtonsProps) => {
162174
MoreOptionsButton,
163175
selectedPicker,
164176
toggleAttachmentPicker,
177+
uploadFile,
165178
}}
166179
{...props}
167180
/>

0 commit comments

Comments
 (0)