Skip to content

Commit 0df06df

Browse files
committed
fix: prevent including own user in read count displayed in MessageStatus
1 parent 877ff53 commit 0df06df

File tree

3 files changed

+106
-5
lines changed

3 files changed

+106
-5
lines changed

src/components/Message/MessageStatus.tsx

+4-3
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,10 @@ const UnMemoizedMessageStatus = <
7070
const delivered = message.status === 'received' && message.id === lastReceivedId && !threadList;
7171
const deliveredAndRead = !!(readBy?.length && !threadList && !justReadByMe);
7272

73-
const [lastReadUser] = deliveredAndRead
73+
const readersWithoutOwnUser = deliveredAndRead
7474
? readBy.filter((item) => item.id !== client.user?.id)
7575
: [];
76+
const [lastReadUser] = readersWithoutOwnUser;
7677

7778
return (
7879
<span
@@ -149,12 +150,12 @@ const UnMemoizedMessageStatus = <
149150
user={lastReadUser}
150151
/>
151152

152-
{readBy.length > 2 && (
153+
{readersWithoutOwnUser.length > 1 && (
153154
<span
154155
className={`str-chat__message-${messageType}-status-number`}
155156
data-testid='message-status-read-by-many'
156157
>
157-
{readBy.length - 1}
158+
{readersWithoutOwnUser.length}
158159
</span>
159160
)}
160161
</>

src/components/Message/__tests__/MessageStatus.test.js

+31-1
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@ import {
99
TranslationProvider,
1010
} from '../../../context';
1111
import { MessageStatus } from '../MessageStatus';
12-
import { getTestClientWithUser } from '../../../mock-builders';
12+
import { generateMessage, generateUser, getTestClientWithUser } from '../../../mock-builders';
1313

1414
const MESSAGE_STATUS_SENDING_TEST_ID = 'message-status-sending';
1515
const MESSAGE_STATUS_DELIVERED_TEST_ID = 'message-status-received';
1616
const MESSAGE_STATUS_READ_TEST_ID = 'message-status-read-by';
17+
const MESSAGE_STATUS_READ_COUNT_TEST_ID = 'message-status-read-by-many';
1718

1819
const rootClassName = `str-chat__message-simple-status str-chat__message-status`;
1920

@@ -32,6 +33,8 @@ const foreignMsg = {
3233
updated_at: '2024-05-28T15:13:20.900Z',
3334
user: null,
3435
};
36+
37+
const ownMessage = generateMessage({ user });
3538
const errorMsg = { ...foreignMsg, type: 'error', user };
3639
const sendingMsg = { ...foreignMsg, status: 'sending', user };
3740
const deliveredMsg = { ...foreignMsg, user };
@@ -236,4 +239,31 @@ describe('MessageStatus', () => {
236239
expect(container.children[0]).toHaveClass('str-chat__message-XXX-status');
237240
});
238241
});
242+
243+
it('does not render count if read by own user only', async () => {
244+
const client = await getTestClientWithUser(user);
245+
renderComponent({
246+
chatCtx: { client },
247+
messageCtx: { message: ownMessage, readBy: [user] },
248+
});
249+
expect(screen.queryByTestId(MESSAGE_STATUS_READ_COUNT_TEST_ID)).not.toBeInTheDocument();
250+
});
251+
252+
it('does not render count if read by 1 other user', async () => {
253+
const client = await getTestClientWithUser(user);
254+
renderComponent({
255+
chatCtx: { client },
256+
messageCtx: { message: ownMessage, readBy: [generateUser()] },
257+
});
258+
expect(screen.queryByTestId(MESSAGE_STATUS_READ_COUNT_TEST_ID)).not.toBeInTheDocument();
259+
});
260+
261+
it('renders count if read by 2 other users', async () => {
262+
const client = await getTestClientWithUser(user);
263+
renderComponent({
264+
chatCtx: { client },
265+
messageCtx: { message: ownMessage, readBy: [generateUser(), generateUser()] },
266+
});
267+
expect(screen.getByTestId(MESSAGE_STATUS_READ_COUNT_TEST_ID)).toHaveTextContent('2');
268+
});
239269
});

src/components/MessageList/__tests__/utils.test.js

+71-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { generateFileAttachment, generateMessage, generateUser } from '../../../mock-builders';
22

3-
import { getGroupStyles, makeDateMessageId, processMessages } from '../utils';
3+
import { getGroupStyles, getReadStates, makeDateMessageId, processMessages } from '../utils';
44
import { CUSTOM_MESSAGE_TYPE } from '../../../constants/messageTypes';
55

66
const mockedNanoId = 'V1StGXR8_Z5jdHi6B-myT';
@@ -622,3 +622,73 @@ describe('getGroupStyles', () => {
622622
expect(getGroupStyles(message, previousMessage, nextMessage, noGroupByUser)).toBe('single');
623623
});
624624
});
625+
626+
describe('getReadStates', () => {
627+
const messages = [
628+
generateMessage({
629+
created_at: new Date('2024-05-21T17:57:31.9876Z'),
630+
id: 'u49866124-uJx-xdCYq0zQ9r5VTuJFH',
631+
}),
632+
generateMessage({
633+
created_at: new Date('2024-05-21T17:57:32.9876Z'),
634+
id: 'u49866124-uJx-xdCYq0zQ9r5VTuJFV',
635+
}),
636+
generateMessage({
637+
created_at: new Date('2024-07-24T22:49:35.527Z'),
638+
id: 'u49866124-uJx-xdCYq0zQ9r5VTuJFY',
639+
}),
640+
];
641+
const read = {
642+
user1: {
643+
last_read: new Date('2024-05-21T17:20:29.402Z'),
644+
last_read_message_id: undefined,
645+
user: { id: 'user1' },
646+
},
647+
user2: {
648+
last_read: new Date('2024-07-24T22:49:36.527Z'),
649+
last_read_message_id: 'u96661092-14eb8ca1-a04c-4098-1d96-b1313d0b794b',
650+
user: { id: 'user2' },
651+
},
652+
user3: {
653+
last_read: '2024-05-21T17:40:57.794Z',
654+
last_read_message_id: 'user7-dcad8dbd-f234-469e-2a46-bd8405beabb7',
655+
user: { id: 'user3' },
656+
},
657+
user5: {
658+
last_read: undefined,
659+
last_read_message_id: undefined,
660+
user: { id: 'user5' },
661+
},
662+
user6: {
663+
last_read: undefined,
664+
last_read_message_id: 'u49866124-uJx-xdCYq0zQ9r5VTuJFH',
665+
user: { id: 'user6' },
666+
},
667+
user7: {
668+
last_read: new Date('2024-05-21T17:59:04.911Z'),
669+
last_read_message_id: 'u49866124-uJx-xdCYq0zQ9r5VTuJFH',
670+
user: { id: 'user7' },
671+
},
672+
user8: {
673+
last_read: new Date('2024-06-24T23:00:12.391Z'),
674+
last_read_message_id: 'u49866124-73190b61-adf7-4e99-0779-565f22239e36',
675+
user: undefined,
676+
},
677+
};
678+
679+
it('returns the list of message readers based on last_read timestamp only for the last read message by user', () => {
680+
expect(getReadStates(messages, read)).toStrictEqual({
681+
'u49866124-uJx-xdCYq0zQ9r5VTuJFV': [{ id: 'user7' }, undefined],
682+
'u49866124-uJx-xdCYq0zQ9r5VTuJFY': [{ id: 'user2' }],
683+
});
684+
});
685+
686+
it("lists the user for each message that was created before the user's last_read timestamp", () => {
687+
const returnAllReadData = true;
688+
expect(getReadStates(messages, read, returnAllReadData)).toStrictEqual({
689+
'u49866124-uJx-xdCYq0zQ9r5VTuJFH': [{ id: 'user2' }, { id: 'user7' }, undefined],
690+
'u49866124-uJx-xdCYq0zQ9r5VTuJFV': [{ id: 'user2' }, { id: 'user7' }, undefined],
691+
'u49866124-uJx-xdCYq0zQ9r5VTuJFY': [{ id: 'user2' }],
692+
});
693+
});
694+
});

0 commit comments

Comments
 (0)