diff --git a/tests/ui/GroupChatNameTests.tsx b/tests/ui/GroupChatNameTests.tsx new file mode 100644 index 000000000000..fc383efe4e28 --- /dev/null +++ b/tests/ui/GroupChatNameTests.tsx @@ -0,0 +1,342 @@ +/* eslint-disable testing-library/no-node-access */ + +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ + +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +import {act, render, screen, waitFor} from '@testing-library/react-native'; +import React from 'react'; +import Onyx from 'react-native-onyx'; +import * as Localize from '@libs/Localize'; +import * as AppActions from '@userActions/App'; +import * as User from '@userActions/User'; +import App from '@src/App'; +import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import type {Participant} from '@src/types/onyx/Report'; +import PusherHelper from '../utils/PusherHelper'; +import * as TestHelper from '../utils/TestHelper'; +import {navigateToSidebarOption} from '../utils/TestHelper'; +import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; +import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'; + +// We need a large timeout here as we are lazy loading React Navigation screens and this test is running against the entire mounted App +jest.setTimeout(50000); + +jest.mock('../../src/components/ConfirmedRoute.tsx'); + +// Needed for: https://stackoverflow.com/questions/76903168/mocking-libraries-in-jest +jest.mock('react-native/Libraries/LogBox/LogBox', () => ({ + /* eslint-disable-next-line @typescript-eslint/naming-convention */ + __esModule: true, + default: { + ignoreLogs: jest.fn(), + ignoreAllLogs: jest.fn(), + }, +})); + +/** + * We need to keep track of the transitionEnd callback so we can trigger it in our tests + */ +let transitionEndCB: () => void; + +jest.mock('@react-navigation/native'); + +TestHelper.setupApp(); + +const REPORT_ID = '1'; +const USER_A_ACCOUNT_ID = 1; +const USER_A_EMAIL = 'user_a@test.com'; +const USER_B_ACCOUNT_ID = 2; +const USER_B_EMAIL = 'user_b@test.com'; +const USER_C_ACCOUNT_ID = 3; +const USER_C_EMAIL = 'user_c@test.com'; +const USER_D_ACCOUNT_ID = 4; +const USER_D_EMAIL = 'user_d@test.com'; +const USER_E_ACCOUNT_ID = 5; +const USER_E_EMAIL = 'user_e@test.com'; +const USER_F_ACCOUNT_ID = 6; +const USER_F_EMAIL = 'user_f@test.com'; +const USER_G_ACCOUNT_ID = 7; +const USER_G_EMAIL = 'user_g@test.com'; +const USER_H_ACCOUNT_ID = 8; +const USER_H_EMAIL = 'user_h@test.com'; + +/** + * Sets up a test with a logged in user. Returns the test instance. + */ +function signInAndGetApp(reportName = '', participantAccountIDs?: number[]): Promise { + // Render the App and sign in as a test user. + render(); + + const participants: Record = {}; + participantAccountIDs?.forEach((id) => { + participants[id] = { + notificationPreference: 'always', + hidden: false, + role: id === 1 ? CONST.REPORT.ROLE.ADMIN : CONST.REPORT.ROLE.MEMBER, + } as Participant; + }); + + return waitForBatchedUpdatesWithAct() + .then(async () => { + await waitForBatchedUpdatesWithAct(); + const hintText = Localize.translateLocal('loginForm.loginForm'); + const loginForm = screen.queryAllByLabelText(hintText); + expect(loginForm).toHaveLength(1); + + await act(async () => { + await TestHelper.signInWithTestUser(USER_A_ACCOUNT_ID, USER_A_EMAIL, undefined, undefined, 'A'); + }); + return waitForBatchedUpdatesWithAct(); + }) + .then(() => { + User.subscribeToUserEvents(); + return waitForBatchedUpdates(); + }) + .then(async () => { + // Simulate setting an unread report and personal details + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${REPORT_ID}`, { + reportID: REPORT_ID, + reportName, + lastMessageText: 'Test', + participants, + lastActorAccountID: USER_B_ACCOUNT_ID, + type: CONST.REPORT.TYPE.CHAT, + chatType: CONST.REPORT.CHAT_TYPE.GROUP, + }); + + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, { + [USER_A_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_A_EMAIL, USER_A_ACCOUNT_ID, 'A'), + [USER_B_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_B_EMAIL, USER_B_ACCOUNT_ID, 'B'), + [USER_C_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_C_EMAIL, USER_C_ACCOUNT_ID, 'C'), + [USER_D_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_D_EMAIL, USER_D_ACCOUNT_ID, 'D'), + [USER_E_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_E_EMAIL, USER_E_ACCOUNT_ID, 'E'), + [USER_F_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_F_EMAIL, USER_F_ACCOUNT_ID, 'F'), + [USER_G_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_G_EMAIL, USER_G_ACCOUNT_ID, 'G'), + [USER_H_ACCOUNT_ID]: TestHelper.buildPersonalDetails(USER_H_EMAIL, USER_H_ACCOUNT_ID, 'H'), + }); + + // We manually setting the sidebar as loaded since the onLayout event does not fire in tests + AppActions.setSidebarLoaded(); + return waitForBatchedUpdatesWithAct(); + }); +} + +/** + * Tests for checking the group chat names at places like LHN, chat header, details page etc. + * Note that limit of 5 names is only for the header. + */ +describe('Tests for group chat name', () => { + beforeEach(() => { + jest.clearAllMocks(); + Onyx.clear(); + + // Unsubscribe to pusher channels + PusherHelper.teardown(); + }); + + const participantAccountIDs4 = [USER_A_ACCOUNT_ID, USER_B_ACCOUNT_ID, USER_C_ACCOUNT_ID, USER_D_ACCOUNT_ID]; + const participantAccountIDs8 = [...participantAccountIDs4, USER_E_ACCOUNT_ID, USER_F_ACCOUNT_ID, USER_G_ACCOUNT_ID, USER_H_ACCOUNT_ID]; + + it('Should show correctly in LHN', () => + signInAndGetApp('A, B, C, D', participantAccountIDs4).then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + return waitFor(() => expect(displayNameText?.props?.children?.[0]).toBe('A, B, C, D')); + })); + + it('Should show correctly in LHN when report name is not present', () => + signInAndGetApp('', participantAccountIDs4).then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + return waitFor(() => expect(displayNameText?.props?.children?.[0]).toBe('A, B, C, D')); + })); + + it('Should show limited names in LHN when 8 participants are present', () => + signInAndGetApp('', participantAccountIDs8).then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + return waitFor(() => expect(displayNameText?.props?.children?.[0]).toBe('A, B, C, D, E')); + })); + + it('Check if group name shows fine for report header', () => + signInAndGetApp('', participantAccountIDs4) + .then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + expect(displayNameText?.props?.children?.[0]).toBe('A, B, C, D'); + + return navigateToSidebarOption(0); + }) + .then(waitForBatchedUpdates) + .then(async () => { + await act(() => transitionEndCB?.()); + const name = 'A, B, C, D'; + const displayNameTexts = screen.queryAllByLabelText(name); + return waitFor(() => expect(displayNameTexts).toHaveLength(1)); + })); + + it('Should show only 5 names when there are 8 participants in the report header', () => + signInAndGetApp('', participantAccountIDs8) + .then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + expect(displayNameText?.props?.children?.[0]).toBe('A, B, C, D, E'); + + return navigateToSidebarOption(0); + }) + .then(waitForBatchedUpdates) + .then(async () => { + await act(() => transitionEndCB?.()); + const name = 'A, B, C, D, E'; + const displayNameTexts = screen.queryAllByLabelText(name); + return waitFor(() => expect(displayNameTexts).toHaveLength(1)); + })); + + it('Should show exact name in header when report name is available with 4 participants', () => + signInAndGetApp('Test chat', participantAccountIDs4) + .then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + expect(displayNameText?.props?.children?.[0]).toBe('Test chat'); + + return navigateToSidebarOption(0); + }) + .then(waitForBatchedUpdates) + .then(async () => { + await act(() => transitionEndCB?.()); + const name = 'Test chat'; + const displayNameTexts = screen.queryAllByLabelText(name); + return waitFor(() => expect(displayNameTexts).toHaveLength(1)); + })); + + it('Should show exact name in header when report name is available with 8 participants', () => + signInAndGetApp("Let's talk", participantAccountIDs8) + .then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + expect(displayNameText?.props?.children?.[0]).toBe("Let's talk"); + + return navigateToSidebarOption(0); + }) + .then(waitForBatchedUpdates) + .then(async () => { + await act(() => transitionEndCB?.()); + const name = "Let's talk"; + const displayNameTexts = screen.queryAllByLabelText(name); + return waitFor(() => expect(displayNameTexts).toHaveLength(1)); + })); + + it('Should show last message preview in LHN', () => + signInAndGetApp('A, B, C, D', participantAccountIDs4).then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const lastChatHintText = Localize.translateLocal('accessibilityHints.lastChatMessagePreview'); + const lastChatText = screen.queryByLabelText(lastChatHintText); + + return waitFor(() => expect(lastChatText?.props?.children).toBe('B: Test')); + })); + + it('Should sort the names before displaying', () => + signInAndGetApp('', [USER_E_ACCOUNT_ID, ...participantAccountIDs4]).then(() => { + // Verify the sidebar links are rendered + const sidebarLinksHintText = Localize.translateLocal('sidebarScreen.listOfChats'); + const sidebarLinks = screen.queryAllByLabelText(sidebarLinksHintText); + expect(sidebarLinks).toHaveLength(1); + + // Verify there is only one option in the sidebar + const optionRowsHintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRows = screen.queryAllByAccessibilityHint(optionRowsHintText); + expect(optionRows).toHaveLength(1); + + const displayNameHintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); + const displayNameText = screen.queryByLabelText(displayNameHintText); + + return waitFor(() => expect(displayNameText?.props?.children?.[0]).toBe('A, B, C, D, E')); + })); +}); diff --git a/tests/ui/UnreadIndicatorsTest.tsx b/tests/ui/UnreadIndicatorsTest.tsx index 576696ef1965..e6acd3e9a19d 100644 --- a/tests/ui/UnreadIndicatorsTest.tsx +++ b/tests/ui/UnreadIndicatorsTest.tsx @@ -25,6 +25,7 @@ import type {ReportAction, ReportActions} from '@src/types/onyx'; import type {NativeNavigationMock} from '../../__mocks__/@react-navigation/native'; import PusherHelper from '../utils/PusherHelper'; import * as TestHelper from '../utils/TestHelper'; +import {navigateToSidebarOption} from '../utils/TestHelper'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; import waitForBatchedUpdatesWithAct from '../utils/waitForBatchedUpdatesWithAct'; @@ -82,16 +83,6 @@ function navigateToSidebar(): Promise { return waitForBatchedUpdates(); } -async function navigateToSidebarOption(index: number): Promise { - const hintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); - const optionRow = screen.queryAllByAccessibilityHint(hintText).at(index); - if (!optionRow) { - return; - } - fireEvent(optionRow, 'press'); - await waitForBatchedUpdatesWithAct(); -} - function areYouOnChatListScreen(): boolean { const hintText = Localize.translateLocal('sidebarScreen.listOfChats'); const sidebarLinks = screen.queryAllByLabelText(hintText); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 2af8a0777c74..4144a6334150 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -10,6 +10,7 @@ import type {PersonalDetailsList, Policy, Report, ReportAction} from '@src/types import {toCollectionDataSet} from '@src/types/utils/CollectionDataSet'; import * as NumberUtils from '../../src/libs/NumberUtils'; import * as LHNTestUtils from '../utils/LHNTestUtils'; +import {fakePersonalDetails} from '../utils/LHNTestUtils'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; // Be sure to include the mocked permissions library or else the beta tests won't work @@ -1068,4 +1069,115 @@ describe('ReportUtils', () => { expect(report).toEqual(undefined); }); }); + + describe('getGroupChatName tests', () => { + afterEach(() => Onyx.clear()); + + const fourParticipants = [ + {accountID: 1, login: 'email1@test.com'}, + {accountID: 2, login: 'email2@test.com'}, + {accountID: 3, login: 'email3@test.com'}, + {accountID: 4, login: 'email4@test.com'}, + ]; + + const eightParticipants = [ + {accountID: 1, login: 'email1@test.com'}, + {accountID: 2, login: 'email2@test.com'}, + {accountID: 3, login: 'email3@test.com'}, + {accountID: 4, login: 'email4@test.com'}, + {accountID: 5, login: 'email5@test.com'}, + {accountID: 6, login: 'email6@test.com'}, + {accountID: 7, login: 'email7@test.com'}, + {accountID: 8, login: 'email8@test.com'}, + ]; + + describe('When participantAccountIDs is passed to getGroupChatName', () => { + it('Should show all participants name if count <= 5 and shouldApplyLimit is false', async () => { + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(fourParticipants)).toEqual('Four, One, Three, Two'); + }); + + it('Should show all participants name if count <= 5 and shouldApplyLimit is true', async () => { + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(fourParticipants)).toEqual('Four, One, Three, Two'); + }); + + it('Should show 5 participants name if count > 5 and shouldApplyLimit is true', async () => { + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(eightParticipants, true)).toEqual('Five, Four, One, Three, Two'); + }); + + it('Should show all participants name if count > 5 and shouldApplyLimit is false', async () => { + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(eightParticipants, false)).toEqual('Eight, Five, Four, One, Seven, Six, Three, Two'); + }); + + it('Should use correct display name for participants', async () => { + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, participantsPersonalDetails); + expect(ReportUtils.getGroupChatName(fourParticipants, true)).toEqual('(833) 240-3627, floki@vikings.net, Lagertha, Ragnar'); + }); + }); + + describe('When participantAccountIDs is not passed to getGroupChatName and report ID is passed', () => { + it('Should show report name if count <= 5 and shouldApplyLimit is false', async () => { + const report = { + ...LHNTestUtils.getFakeReport([1, 2, 3, 4], 0, false, [1]), + chatType: CONST.REPORT.CHAT_TYPE.GROUP, + reportID: `1`, + reportName: "Let's talk", + }; + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}1`, report); + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(undefined, false, report)).toEqual("Let's talk"); + }); + + it('Should show report name if count <= 5 and shouldApplyLimit is true', async () => { + const report = { + ...LHNTestUtils.getFakeReport([1, 2, 3, 4], 0, false, [1]), + chatType: CONST.REPORT.CHAT_TYPE.GROUP, + reportID: `1`, + reportName: "Let's talk", + }; + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}1`, report); + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(undefined, true, report)).toEqual("Let's talk"); + }); + + it('Should show report name if count > 5 and shouldApplyLimit is true', async () => { + const report = { + ...LHNTestUtils.getFakeReport([1, 2, 3, 4, 5, 6, 7, 8], 0, false, [1, 2]), + chatType: CONST.REPORT.CHAT_TYPE.GROUP, + reportID: `1`, + reportName: "Let's talk", + }; + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}1`, report); + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(undefined, true, report)).toEqual("Let's talk"); + }); + + it('Should show report name if count > 5 and shouldApplyLimit is false', async () => { + const report = { + ...LHNTestUtils.getFakeReport([1, 2, 3, 4, 5, 6, 7, 8], 0, false, [1, 2]), + chatType: CONST.REPORT.CHAT_TYPE.GROUP, + reportID: `1`, + reportName: "Let's talk", + }; + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}1`, report); + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(undefined, false, report)).toEqual("Let's talk"); + }); + + it('Should show participant names if report name is not available', async () => { + const report = { + ...LHNTestUtils.getFakeReport([1, 2, 3, 4, 5, 6, 7, 8], 0, false, [1, 2]), + chatType: CONST.REPORT.CHAT_TYPE.GROUP, + reportID: `1`, + reportName: '', + }; + await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}1`, report); + await Onyx.merge(ONYXKEYS.PERSONAL_DETAILS_LIST, fakePersonalDetails); + expect(ReportUtils.getGroupChatName(undefined, false, report)).toEqual('Eight, Five, Four, One, Seven, Six, Three, Two'); + }); + }); + }); }); diff --git a/tests/utils/LHNTestUtils.tsx b/tests/utils/LHNTestUtils.tsx index cdb9f51bb3b7..73d10365c272 100644 --- a/tests/utils/LHNTestUtils.tsx +++ b/tests/utils/LHNTestUtils.tsx @@ -113,6 +113,13 @@ const fakePersonalDetails: PersonalDetailsList = { avatar: 'none', firstName: 'Nine', }, + 10: { + accountID: 10, + login: 'email10@test.com', + displayName: 'Email Ten', + avatar: 'none', + firstName: 'Ten', + }, }; let lastFakeReportID = 0; @@ -121,16 +128,25 @@ let lastFakeReportActionID = 0; /** * @param millisecondsInThePast the number of milliseconds in the past for the last message timestamp (to order reports by most recent messages) */ -function getFakeReport(participantAccountIDs = [1, 2], millisecondsInThePast = 0, isUnread = false): Report { +function getFakeReport(participantAccountIDs = [1, 2], millisecondsInThePast = 0, isUnread = false, adminIDs: number[] = []): Report { const lastVisibleActionCreated = DateUtils.getDBTime(Date.now() - millisecondsInThePast); + const participants = ReportUtils.buildParticipantsFromAccountIDs(participantAccountIDs); + + adminIDs.forEach((id) => { + participants[id] = { + notificationPreference: 'always', + role: CONST.REPORT.ROLE.ADMIN, + }; + }); + return { type: CONST.REPORT.TYPE.CHAT, reportID: `${++lastFakeReportID}`, reportName: 'Report', lastVisibleActionCreated, lastReadTime: isUnread ? DateUtils.subtractMillisecondsFromDateTime(lastVisibleActionCreated, 1) : lastVisibleActionCreated, - participants: ReportUtils.buildParticipantsFromAccountIDs(participantAccountIDs), + participants, }; } diff --git a/tests/utils/TestHelper.ts b/tests/utils/TestHelper.ts index c44710f5f466..394c05fe8b7c 100644 --- a/tests/utils/TestHelper.ts +++ b/tests/utils/TestHelper.ts @@ -1,7 +1,9 @@ +import {fireEvent, screen} from '@testing-library/react-native'; import {Str} from 'expensify-common'; import {Linking} from 'react-native'; import Onyx from 'react-native-onyx'; import type {ApiCommand, ApiRequestCommandParameters} from '@libs/API/types'; +import * as Localize from '@libs/Localize'; import * as Pusher from '@libs/Pusher/pusher'; import PusherConnectionManager from '@libs/PusherConnectionManager'; import CONFIG from '@src/CONFIG'; @@ -13,6 +15,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import appSetup from '@src/setup'; import type {Response as OnyxResponse, PersonalDetails, Report} from '@src/types/onyx'; import waitForBatchedUpdates from './waitForBatchedUpdates'; +import waitForBatchedUpdatesWithAct from './waitForBatchedUpdatesWithAct'; type MockFetch = jest.MockedFn & { pause: () => void; @@ -308,6 +311,16 @@ function assertFormDataMatchesObject(obj: Report, formData?: FormData) { } } +async function navigateToSidebarOption(index: number): Promise { + const hintText = Localize.translateLocal('accessibilityHints.navigatesToChat'); + const optionRow = screen.queryAllByAccessibilityHint(hintText).at(index); + if (!optionRow) { + return; + } + fireEvent(optionRow, 'press'); + await waitForBatchedUpdatesWithAct(); +} + export type {MockFetch, FormData}; export { assertFormDataMatchesObject, @@ -321,4 +334,5 @@ export { expectAPICommandToHaveBeenCalled, expectAPICommandToHaveBeenCalledWith, setupGlobalFetchMock, + navigateToSidebarOption, };