From 5561d3ae8d01ae3c843c53e75cc1878e25876d9f Mon Sep 17 00:00:00 2001
From: Anton Arnautov <arnautov.anton@gmail.com>
Date: Tue, 20 Aug 2024 14:06:38 +0200
Subject: [PATCH] Adjust tests, add generics

---
 .../Message/__tests__/MessageOptions.test.js  | 67 +++++++++----------
 src/components/Message/utils.tsx              |  8 ++-
 .../MessageActions/MessageActions.tsx         |  5 +-
 3 files changed, 39 insertions(+), 41 deletions(-)

diff --git a/src/components/Message/__tests__/MessageOptions.test.js b/src/components/Message/__tests__/MessageOptions.test.js
index 70800a3eb8..fb3ce9b8ad 100644
--- a/src/components/Message/__tests__/MessageOptions.test.js
+++ b/src/components/Message/__tests__/MessageOptions.test.js
@@ -9,7 +9,6 @@ import { MessageSimple } from '../MessageSimple';
 import { ACTIONS_NOT_WORKING_IN_THREAD, MESSAGE_ACTIONS } from '../utils';
 
 import { Attachment } from '../../Attachment';
-import { MessageActions as MessageActionsMock } from '../../MessageActions';
 
 import { ChannelActionProvider } from '../../../context/ChannelActionContext';
 import { ChannelStateProvider } from '../../../context/ChannelStateContext';
@@ -23,9 +22,7 @@ import {
   getTestClientWithUser,
 } from '../../../mock-builders';
 
-jest.mock('../../MessageActions', () => ({
-  MessageActions: jest.fn(() => <div />),
-}));
+const MESSAGE_ACTIONS_TEST_ID = 'message-actions';
 
 const minimumCapabilitiesToRenderMessageActions = { 'delete-any-message': true };
 const alice = generateUser({ name: 'alice' });
@@ -185,43 +182,45 @@ describe('<MessageOptions />', () => {
   });
 
   it('should render message actions', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).toBeInTheDocument();
   });
 
   it('should not show message actions button if actions are disabled', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: { messageActions: [] },
     });
-    expect(MessageActionsMock).;
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).not.toBeInTheDocument();
   });
 
   it('should not show actions box for message in thread if only non-thread actions are available', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: { messageActions: ACTIONS_NOT_WORKING_IN_THREAD, threadList: true },
     });
-    expect(MessageActionsMock).not.toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).not.toBeInTheDocument();
   });
 
   it('should show actions box for message in thread if not only non-thread actions are available', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         messageActions: [...ACTIONS_NOT_WORKING_IN_THREAD, MESSAGE_ACTIONS.delete],
         threadList: true,
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).toBeInTheDocument();
   });
 
   it('should show actions box for a message in thread if custom actions provided are non-thread', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         customMessageActions: ACTIONS_NOT_WORKING_IN_THREAD,
@@ -229,78 +228,76 @@ describe('<MessageOptions />', () => {
         threadList: true,
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).toHaveBeenCalled();
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).toBeInTheDocument();
   });
 
   it('should not show actions box for message outside thread with single action "react"', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         messageActions: [MESSAGE_ACTIONS.react],
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).not.toHaveBeenCalled();
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).not.toBeInTheDocument();
   });
 
   it('should show actions box for message outside thread with single action "react" if custom actions available', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         customMessageActions: [MESSAGE_ACTIONS.react],
         messageActions: [MESSAGE_ACTIONS.react],
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).toBeInTheDocument();
   });
 
   it('should not show actions box for message outside thread with single action "reply"', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         messageActions: [MESSAGE_ACTIONS.reply],
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).not.toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).not.toBeInTheDocument();
   });
 
   it('should show actions box for message outside thread with single action "reply" if custom actions available', async () => {
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         customMessageActions: [MESSAGE_ACTIONS.reply],
         messageActions: [MESSAGE_ACTIONS.reply],
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).toBeInTheDocument();
   });
 
   it('should not show actions box for message outside thread with two actions "react" & "reply"', async () => {
     const actions = [MESSAGE_ACTIONS.react, MESSAGE_ACTIONS.reply];
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         messageActions: actions,
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).not.toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).not.toBeInTheDocument();
   });
 
   it('should show actions box for message outside thread with single actions "react" & "reply" if custom actions available', async () => {
     const actions = [MESSAGE_ACTIONS.react, MESSAGE_ACTIONS.reply];
-    await renderMessageOptions({
+    const { queryByTestId } = await renderMessageOptions({
       channelStateOpts: { channelCapabilities: minimumCapabilitiesToRenderMessageActions },
       customMessageProps: {
         customMessageActions: actions,
         messageActions: actions,
       },
     });
-    // eslint-disable-next-line jest/prefer-called-with
-    expect(MessageActionsMock).toHaveBeenCalled();
+
+    expect(queryByTestId(MESSAGE_ACTIONS_TEST_ID)).toBeInTheDocument();
   });
 });
diff --git a/src/components/Message/utils.tsx b/src/components/Message/utils.tsx
index 1f0e91b16b..31792e333a 100644
--- a/src/components/Message/utils.tsx
+++ b/src/components/Message/utils.tsx
@@ -219,15 +219,17 @@ export const showMessageActionsBox = (
   inThread?: boolean | undefined,
 ) => shouldRenderMessageActions({ inThread, messageActions: actions });
 
-export const shouldRenderMessageActions = ({
+export const shouldRenderMessageActions = <
+  Scg extends DefaultStreamChatGenerics = DefaultStreamChatGenerics
+>({
   customMessageActions,
   CustomMessageActionsList,
   inThread,
   messageActions,
 }: {
   messageActions: MessageActionsArray;
-  customMessageActions?: CustomMessageActions;
-  CustomMessageActionsList?: ComponentContextValue['CustomMessageActionsList'];
+  customMessageActions?: CustomMessageActions<Scg>;
+  CustomMessageActionsList?: ComponentContextValue<Scg>['CustomMessageActionsList'];
   inThread?: boolean;
 }) => {
   if (
diff --git a/src/components/MessageActions/MessageActions.tsx b/src/components/MessageActions/MessageActions.tsx
index 93835274d8..174733beed 100644
--- a/src/components/MessageActions/MessageActions.tsx
+++ b/src/components/MessageActions/MessageActions.tsx
@@ -80,7 +80,7 @@ export const MessageActions = <
     threadList,
   } = useMessageContext<StreamChatGenerics>('MessageActions');
 
-  const { CustomMessageActionsList } = useComponentContext('MessageActions');
+  const { CustomMessageActionsList } = useComponentContext<StreamChatGenerics>('MessageActions');
 
   const { t } = useTranslationContext('MessageActions');
 
@@ -99,8 +99,7 @@ export const MessageActions = <
 
   const messageActions = getMessageActions();
 
-  const renderMessageActions = shouldRenderMessageActions({
-    // @ts-expect-error
+  const renderMessageActions = shouldRenderMessageActions<StreamChatGenerics>({
     customMessageActions,
     CustomMessageActionsList,
     inThread: threadList,