Skip to content

Commit a063caf

Browse files
committed
tests: add tests for the mark as unread feature
1 parent c032297 commit a063caf

File tree

4 files changed

+363
-97
lines changed

4 files changed

+363
-97
lines changed

package/src/components/Channel/__tests__/Channel.test.js

Lines changed: 109 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import {
2929
useChannelDataState,
3030
useChannelMessageDataState,
3131
} from '../hooks/useChannelDataState';
32+
import * as MessageListPaginationHooks from '../hooks/useMessageListPagination';
3233

3334
// This component is used for performing effects in a component that consumes ChannelContext,
3435
// i.e. making use of the callbacks & values provided by the Channel component.
@@ -87,6 +88,7 @@ describe('Channel', () => {
8788
const nullChannel = {
8889
...channel,
8990
cid: null,
91+
countUnread: () => 0,
9092
off: () => {},
9193
on: () => ({
9294
unsubscribe: () => null,
@@ -464,79 +466,128 @@ describe('Channel initial load useEffect', () => {
464466
);
465467
});
466468

467-
it("should not call loadChannelAtFirstUnreadMessage if channel's unread count is 0", async () => {
468-
const mockedChannel = generateChannelResponse({
469-
messages: Array.from({ length: 10 }, (_, i) => generateMessage({ text: `message-${i}` })),
469+
describe('initialScrollToFirstUnreadMessage', () => {
470+
afterEach(() => {
471+
// Clear all mocks after each test
472+
jest.clearAllMocks();
473+
// Restore all mocks to their original implementation
474+
jest.restoreAllMocks();
475+
cleanup();
470476
});
477+
const mockedHook = (values) =>
478+
jest.spyOn(MessageListPaginationHooks, 'useMessageListPagination').mockImplementation(() => ({
479+
copyMessagesStateFromChannel: jest.fn(),
480+
loadChannelAroundMessage: jest.fn(),
481+
loadChannelAtFirstUnreadMessage: jest.fn(),
482+
loadInitialMessagesStateFromChannel: jest.fn(),
483+
loadLatestMessages: jest.fn(),
484+
loadMore: jest.fn(),
485+
loadMoreRecent: jest.fn(),
486+
state: { ...channelInitialState },
487+
...values,
488+
}));
489+
it("should not call loadChannelAtFirstUnreadMessage if channel's unread count is 0", async () => {
490+
const mockedChannel = generateChannelResponse({
491+
messages: Array.from({ length: 10 }, (_, i) => generateMessage({ text: `message-${i}` })),
492+
});
471493

472-
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
473-
const channel = chatClient.channel('messaging', mockedChannel.id);
474-
await channel.watch();
475-
const messages = Array.from({ length: 100 }, (_, i) => generateMessage({ id: i }));
494+
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
495+
const channel = chatClient.channel('messaging', mockedChannel.id);
496+
await channel.watch();
497+
const user = generateUser();
498+
const read_data = {};
476499

477-
const loadMessageIntoState = jest.fn();
478-
channel.state = {
479-
...channelInitialState,
480-
loadMessageIntoState,
481-
messagePagination: {
482-
hasNext: true,
483-
hasPrev: true,
484-
},
485-
messages,
486-
};
487-
channel.countUnread = jest.fn(() => 0);
500+
read_data[chatClient.user.id] = {
501+
user: user,
502+
last_read: new Date(),
503+
};
488504

489-
renderComponent({ channel, initialScrollToFirstUnreadMessage: true });
505+
channel.state = {
506+
...channelInitialState,
507+
read: read_data,
508+
};
509+
channel.countUnread = jest.fn(() => 0);
490510

491-
await waitFor(() => {
492-
expect(loadMessageIntoState).not.toHaveBeenCalled();
493-
});
494-
});
511+
const loadChannelAtFirstUnreadMessageFn = jest.fn();
495512

496-
it("should call loadChannelAtFirstUnreadMessage if channel's unread count is greater than 0", async () => {
497-
const mockedChannel = generateChannelResponse({
498-
messages: Array.from({ length: 10 }, (_, i) => generateMessage({ text: `message-${i}` })),
499-
});
513+
mockedHook({ loadChannelAtFirstUnreadMessage: loadChannelAtFirstUnreadMessageFn });
500514

501-
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
502-
const channel = chatClient.channel('messaging', mockedChannel.id);
503-
await channel.watch();
504-
const messages = Array.from({ length: 100 }, (_, i) => generateMessage({ id: i }));
515+
renderComponent({ channel, initialScrollToFirstUnreadMessage: true });
505516

506-
let targetedMessageId = 0;
507-
const loadMessageIntoState = jest.fn((id) => {
508-
targetedMessageId = id;
509-
const newMessages = getElementsAround(messages, 'id', id);
510-
channel.state.messages = newMessages;
517+
await waitFor(() => {
518+
expect(loadChannelAtFirstUnreadMessageFn).not.toHaveBeenCalled();
519+
});
511520
});
512521

513-
channel.state = {
514-
...channelInitialState,
515-
loadMessageIntoState,
516-
messagePagination: {
517-
hasNext: true,
518-
hasPrev: true,
519-
},
520-
messages,
521-
messageSets: [{ isCurrent: true, isLatest: true }],
522-
};
522+
it("should call loadChannelAtFirstUnreadMessage if channel's unread count is greater than 0", async () => {
523+
const mockedChannel = generateChannelResponse({
524+
messages: Array.from({ length: 10 }, (_, i) => generateMessage({ text: `message-${i}` })),
525+
});
523526

524-
channel.countUnread = jest.fn(() => 15);
527+
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
528+
const channel = chatClient.channel('messaging', mockedChannel.id);
529+
await channel.watch();
525530

526-
renderComponent({ channel, initialScrollToFirstUnreadMessage: true });
531+
const user = generateUser();
532+
const numberOfUnreadMessages = 15;
533+
const read_data = {};
527534

528-
await waitFor(() => {
529-
expect(loadMessageIntoState).toHaveBeenCalledTimes(1);
535+
read_data[chatClient.user.id] = {
536+
user: user,
537+
last_read: new Date(),
538+
unread_messages: numberOfUnreadMessages,
539+
};
540+
channel.state = {
541+
...channelInitialState,
542+
read: read_data,
543+
};
544+
545+
channel.countUnread = jest.fn(() => numberOfUnreadMessages);
546+
const loadChannelAtFirstUnreadMessageFn = jest.fn();
547+
548+
mockedHook({ loadChannelAtFirstUnreadMessage: loadChannelAtFirstUnreadMessageFn });
549+
550+
renderComponent({ channel, initialScrollToFirstUnreadMessage: true });
551+
552+
await waitFor(() => {
553+
expect(loadChannelAtFirstUnreadMessageFn).toHaveBeenCalled();
554+
});
530555
});
531556

532-
const { result: channelMessageState } = renderHook(() => useChannelMessageDataState(channel));
533-
await waitFor(() =>
534-
expect(
535-
channelMessageState.current.state.messages.find(
536-
(message) => message.id === targetedMessageId,
537-
),
538-
).toBeDefined(),
539-
);
557+
it("should not call loadChannelAtFirstUnreadMessage if channel's unread count is greater than 0 lesser than scrollToFirstUnreadThreshold", async () => {
558+
const mockedChannel = generateChannelResponse({
559+
messages: Array.from({ length: 10 }, (_, i) => generateMessage({ text: `message-${i}` })),
560+
});
561+
562+
useMockedApis(chatClient, [getOrCreateChannelApi(mockedChannel)]);
563+
const channel = chatClient.channel('messaging', mockedChannel.id);
564+
await channel.watch();
565+
566+
const user = generateUser();
567+
const numberOfUnreadMessages = 2;
568+
const read_data = {};
569+
570+
read_data[chatClient.user.id] = {
571+
user: user,
572+
last_read: new Date(),
573+
unread_messages: numberOfUnreadMessages,
574+
};
575+
channel.state = {
576+
...channelInitialState,
577+
read: read_data,
578+
};
579+
580+
channel.countUnread = jest.fn(() => numberOfUnreadMessages);
581+
const loadChannelAtFirstUnreadMessageFn = jest.fn();
582+
583+
mockedHook({ loadChannelAtFirstUnreadMessage: loadChannelAtFirstUnreadMessageFn });
584+
585+
renderComponent({ channel, initialScrollToFirstUnreadMessage: true });
586+
587+
await waitFor(() => {
588+
expect(loadChannelAtFirstUnreadMessageFn).not.toHaveBeenCalled();
589+
});
590+
});
540591
});
541592

542593
it('should call resyncChannel when connection changed event is triggered', async () => {

0 commit comments

Comments
 (0)