From 47283cb62c8abee61abe7df2669ffcc4eae570ce Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Fri, 14 Mar 2025 14:04:47 +0530 Subject: [PATCH 1/2] fix: show correct read status on the message status component for a message --- .../Message/MessageSimple/MessageStatus.tsx | 25 ++- .../__tests__/MessageStatus.test.js | 80 ++++++-- .../__snapshots__/MessageStatus.test.js.snap | 192 ++++++++++-------- 3 files changed, 185 insertions(+), 112 deletions(-) diff --git a/package/src/components/Message/MessageSimple/MessageStatus.tsx b/package/src/components/Message/MessageSimple/MessageStatus.tsx index f104a0986e..b59a07d6a3 100644 --- a/package/src/components/Message/MessageSimple/MessageStatus.tsx +++ b/package/src/components/Message/MessageSimple/MessageStatus.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { StyleSheet, Text, View } from 'react-native'; +import { useChannelContext } from '../../../contexts/channelContext/ChannelContext'; import { MessageContextValue, useMessageContext, @@ -23,6 +24,7 @@ const MessageStatusWithContext = < >( props: MessageStatusPropsWithContext, ) => { + const { channel } = useChannelContext(); const { message, threadList } = props; const { @@ -47,18 +49,35 @@ const MessageStatusWithContext = < } if (isMessageWithStylesReadByAndDateSeparator(message)) { + const members = channel?.state.members; + const otherMembers = Object.values(members).filter( + (member) => member.user_id !== message.user?.id, + ); + const hasOtherMembersGreaterThanOne = otherMembers.length > 1; + const hasReadByGreaterThanOne = typeof message.readBy === 'number' && message.readBy > 1; + const shouldDisplayReadByCount = hasOtherMembersGreaterThanOne && hasReadByGreaterThanOne; + const countOfReadBy = + typeof message.readBy === 'number' && hasOtherMembersGreaterThanOne ? message.readBy - 1 : 0; + const showDoubleCheck = hasReadByGreaterThanOne || message.readBy === true; + + console.log({ + shouldDisplayReadByCount, + hasOtherMembersGreaterThanOne, + hasReadByGreaterThanOne, + }); + return ( - {typeof message.readBy === 'number' ? ( + {shouldDisplayReadByCount ? ( - {message.readBy} + {countOfReadBy} ) : null} {message.type !== 'error' ? ( - typeof message.readBy === 'number' || message.readBy === true ? ( + showDoubleCheck ? ( ) : ( diff --git a/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js b/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js index 9049de8d4f..876530395f 100644 --- a/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js +++ b/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js @@ -8,28 +8,63 @@ import { getTestClientWithUser } from '../../../../mock-builders/mock'; import { Streami18n } from '../../../../utils/i18n/Streami18n'; import { Chat } from '../../../Chat/Chat'; import { MessageStatus } from '../MessageStatus'; +import { ChannelsStateProvider } from '../../../../contexts/channelsStateContext/ChannelsStateContext'; +import { Channel } from '../../..'; +import { generateChannelResponse } from '../../../../mock-builders/generator/channel'; +import { generateMember } from '../../../../mock-builders/generator/member'; +import { useMockedApis } from '../../../../mock-builders/api/useMockedApis'; +import { getOrCreateChannelApi } from '../../../../mock-builders/api/getOrCreateChannel'; let chatClient; let id; let i18nInstance; - +let channel; describe('MessageStatus', () => { + const user1 = generateUser({ id: 'id1', name: 'name1' }); + const user2 = generateUser({ id: 'id2', name: 'name2' }); + const user3 = generateUser({ id: 'id3', name: 'name3' }); + const messages = [generateMessage({ user: user1 })]; + const members = [ + generateMember({ user: user1 }), + generateMember({ user: user2 }), + generateMember({ user: user3 }), + ]; beforeAll(async () => { id = 'testID'; - chatClient = await getTestClientWithUser({ id }); i18nInstance = new Streami18n(); }); + beforeEach(async () => { + jest.clearAllMocks(); + const mockedChannel = generateChannelResponse({ + members, + messages, + }); + + chatClient = await getTestClientWithUser(user1); + useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]); + channel = chatClient.channel('messaging', mockedChannel.id); + }); afterEach(cleanup); + renderMessageStatus = (options, channelProps) => + render( + + + + + + + , + ); + it('should render message status with delivered container', async () => { const user = generateUser(); const message = generateMessage({ user }); - const { getByTestId } = render( - - - , - ); + const { getByTestId } = renderMessageStatus({ + lastReceivedId: message.id, + message: { ...message, status: 'received' }, + }); await waitFor(() => { expect(getByTestId('delivered-container')).toBeTruthy(); @@ -40,30 +75,33 @@ describe('MessageStatus', () => { const user = generateUser(); const message = generateMessage({ readBy: 2, user }); - const { getByTestId, getByText, rerender, toJSON } = render( - - - , - ); + const { getByTestId, getByText, rerender, toJSON } = renderMessageStatus({ + lastReceivedId: message.id, + message, + }); await waitFor(() => { expect(getByTestId('read-by-container')).toBeTruthy(); - expect(getByText(message.readBy.toString())).toBeTruthy(); + expect(getByText((message.readBy - 1).toString())).toBeTruthy(); }); const staticUser = generateStaticUser(0); const staticMessage = generateMessage({ readBy: 2, staticUser }); rerender( - - - , + + + + + + + , ); await waitFor(() => { expect(toJSON()).toMatchSnapshot(); expect(getByTestId('read-by-container')).toBeTruthy(); - expect(getByText(staticMessage.readBy.toString())).toBeTruthy(); + expect(getByText((staticMessage.readBy - 1).toString())).toBeTruthy(); }); }); @@ -71,11 +109,9 @@ describe('MessageStatus', () => { const user = generateUser(); const message = generateMessage({ user }); - const { getByTestId } = render( - - - , - ); + const { getByTestId } = renderMessageStatus({ + message: { ...message, status: 'sending' }, + }); await waitFor(() => { expect(getByTestId('sending-container')).toBeTruthy(); diff --git a/package/src/components/Message/MessageSimple/__tests__/__snapshots__/MessageStatus.test.js.snap b/package/src/components/Message/MessageSimple/__tests__/__snapshots__/MessageStatus.test.js.snap index cf8b4cd57a..6224aeaefb 100644 --- a/package/src/components/Message/MessageSimple/__tests__/__snapshots__/MessageStatus.test.js.snap +++ b/package/src/components/Message/MessageSimple/__tests__/__snapshots__/MessageStatus.test.js.snap @@ -2,106 +2,124 @@ exports[`MessageStatus should render message status with read by container 1`] = ` - - 2 - - - - - + 1 + + - - + vbHeight={24} + vbWidth={24} + width={16} + > + + + + + + + `; From 89572b993a878451466a65dd04e56b32a62fb579 Mon Sep 17 00:00:00 2001 From: Khushal Agarwal Date: Fri, 14 Mar 2025 14:15:06 +0530 Subject: [PATCH 2/2] fix: lint issues --- .../Message/MessageSimple/MessageStatus.tsx | 6 ------ .../MessageSimple/__tests__/MessageStatus.test.js | 15 +++++++-------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/package/src/components/Message/MessageSimple/MessageStatus.tsx b/package/src/components/Message/MessageSimple/MessageStatus.tsx index b59a07d6a3..a9c043ac7a 100644 --- a/package/src/components/Message/MessageSimple/MessageStatus.tsx +++ b/package/src/components/Message/MessageSimple/MessageStatus.tsx @@ -60,12 +60,6 @@ const MessageStatusWithContext = < typeof message.readBy === 'number' && hasOtherMembersGreaterThanOne ? message.readBy - 1 : 0; const showDoubleCheck = hasReadByGreaterThanOne || message.readBy === true; - console.log({ - shouldDisplayReadByCount, - hasOtherMembersGreaterThanOne, - hasReadByGreaterThanOne, - }); - return ( {shouldDisplayReadByCount ? ( diff --git a/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js b/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js index 876530395f..400ed93719 100644 --- a/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js +++ b/package/src/components/Message/MessageSimple/__tests__/MessageStatus.test.js @@ -2,21 +2,20 @@ import React from 'react'; import { cleanup, render, waitFor } from '@testing-library/react-native'; +import { Channel } from '../../..'; +import { ChannelsStateProvider } from '../../../../contexts/channelsStateContext/ChannelsStateContext'; +import { getOrCreateChannelApi } from '../../../../mock-builders/api/getOrCreateChannel'; +import { useMockedApis } from '../../../../mock-builders/api/useMockedApis'; +import { generateChannelResponse } from '../../../../mock-builders/generator/channel'; +import { generateMember } from '../../../../mock-builders/generator/member'; import { generateMessage } from '../../../../mock-builders/generator/message'; import { generateStaticUser, generateUser } from '../../../../mock-builders/generator/user'; import { getTestClientWithUser } from '../../../../mock-builders/mock'; import { Streami18n } from '../../../../utils/i18n/Streami18n'; import { Chat } from '../../../Chat/Chat'; import { MessageStatus } from '../MessageStatus'; -import { ChannelsStateProvider } from '../../../../contexts/channelsStateContext/ChannelsStateContext'; -import { Channel } from '../../..'; -import { generateChannelResponse } from '../../../../mock-builders/generator/channel'; -import { generateMember } from '../../../../mock-builders/generator/member'; -import { useMockedApis } from '../../../../mock-builders/api/useMockedApis'; -import { getOrCreateChannelApi } from '../../../../mock-builders/api/getOrCreateChannel'; let chatClient; -let id; let i18nInstance; let channel; describe('MessageStatus', () => { @@ -29,7 +28,7 @@ describe('MessageStatus', () => { generateMember({ user: user2 }), generateMember({ user: user3 }), ]; - beforeAll(async () => { + beforeAll(() => { id = 'testID'; i18nInstance = new Streami18n(); });