Skip to content

Commit 1f78460

Browse files
committed
add tests
1 parent d9e526c commit 1f78460

3 files changed

Lines changed: 215 additions & 12 deletions

File tree

src/libs/actions/Report/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4227,8 +4227,8 @@ function leaveRoom(
42274227
report: Report,
42284228
currentUserAccountID: number,
42294229
conciergeReportID: string | undefined,
4230-
isWorkspaceMemberLeavingWorkspaceRoom = false,
42314230
introSelected: OnyxEntry<IntroSelected>,
4231+
isWorkspaceMemberLeavingWorkspaceRoom = false,
42324232
) {
42334233
const reportID = report.reportID;
42344234
const isChatThread = isChatThreadReportUtils(report);

src/pages/ReportDetailsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,7 +333,7 @@ function ReportDetailsPage({policy, report, route, reportMetadata}: ReportDetail
333333
}
334334

335335
const isWorkspaceMemberLeavingWorkspaceRoom = isWorkspaceMemberLeavingWorkspaceRoomUtil(report, isPolicyEmployee, isPolicyAdmin);
336-
leaveRoom(report, currentUserPersonalDetails.accountID, conciergeReportID, isWorkspaceMemberLeavingWorkspaceRoom, introSelected);
336+
leaveRoom(report, currentUserPersonalDetails.accountID, conciergeReportID, introSelected, isWorkspaceMemberLeavingWorkspaceRoom);
337337
}, [isRootGroupChat, isPolicyEmployee, isPolicyAdmin, quickAction?.chatReportID, report, currentUserPersonalDetails.accountID, conciergeReportID, introSelected]);
338338

339339
const showLastMemberLeavingModal = useCallback(async () => {

tests/actions/ReportTest.ts

Lines changed: 213 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4404,7 +4404,7 @@ describe('actions/Report', () => {
44044404
await Onyx.merge(ONYXKEYS.CONCIERGE_REPORT_ID, TEST_CONCIERGE_REPORT_ID);
44054405
await waitForBatchedUpdates();
44064406

4407-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, TEST_INTRO_SELECTED);
4407+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, false);
44084408
await waitForBatchedUpdates();
44094409

44104410
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_ROOM, 1);
@@ -4423,7 +4423,7 @@ describe('actions/Report', () => {
44234423
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}`, roomReport);
44244424
await waitForBatchedUpdates();
44254425

4426-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, true, TEST_INTRO_SELECTED);
4426+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, true);
44274427
await waitForBatchedUpdates();
44284428

44294429
const updatedReport = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}` as const);
@@ -4447,7 +4447,7 @@ describe('actions/Report', () => {
44474447
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}`, roomReport);
44484448
await waitForBatchedUpdates();
44494449

4450-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, TEST_INTRO_SELECTED);
4450+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, false);
44514451
await waitForBatchedUpdates();
44524452

44534453
// After success, the report should only have reportName (all other fields removed)
@@ -4481,7 +4481,7 @@ describe('actions/Report', () => {
44814481
});
44824482
await waitForBatchedUpdates();
44834483

4484-
Report.leaveRoom(threadReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, TEST_INTRO_SELECTED);
4484+
Report.leaveRoom(threadReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, false);
44854485
await waitForBatchedUpdates();
44864486

44874487
const updatedParentReportActions = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${PARENT_REPORT_ID}` as const);
@@ -4503,7 +4503,7 @@ describe('actions/Report', () => {
45034503

45044504
// Should not throw an error with undefined conciergeReportID
45054505
expect(() => {
4506-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, undefined, false, TEST_INTRO_SELECTED);
4506+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, undefined, TEST_INTRO_SELECTED, false);
45074507
}).not.toThrow();
45084508

45094509
await waitForBatchedUpdates();
@@ -4528,7 +4528,7 @@ describe('actions/Report', () => {
45284528
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}`, threadReport);
45294529
await waitForBatchedUpdates();
45304530

4531-
Report.leaveRoom(threadReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, TEST_INTRO_SELECTED);
4531+
Report.leaveRoom(threadReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, false);
45324532
await waitForBatchedUpdates();
45334533

45344534
const updatedReport = await getOnyxValue(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}` as const);
@@ -4551,7 +4551,7 @@ describe('actions/Report', () => {
45514551

45524552
// Should not throw when introSelected is provided
45534553
expect(() => {
4554-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, TEST_INTRO_SELECTED);
4554+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, false);
45554555
}).not.toThrow();
45564556

45574557
await waitForBatchedUpdates();
@@ -4659,7 +4659,7 @@ describe('actions/Report', () => {
46594659
await waitForBatchedUpdates();
46604660

46614661
expect(() => {
4662-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, customIntroSelected);
4662+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, customIntroSelected, false);
46634663
}).not.toThrow();
46644664

46654665
await waitForBatchedUpdates();
@@ -4680,7 +4680,7 @@ describe('actions/Report', () => {
46804680
await waitForBatchedUpdates();
46814681

46824682
expect(() => {
4683-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, undefined);
4683+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, undefined, false);
46844684
}).not.toThrow();
46854685

46864686
await waitForBatchedUpdates();
@@ -4701,14 +4701,217 @@ describe('actions/Report', () => {
47014701
await waitForBatchedUpdates();
47024702

47034703
expect(() => {
4704-
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, false, {});
4704+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, {}, false);
47054705
}).not.toThrow();
47064706

47074707
await waitForBatchedUpdates();
47084708
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_ROOM, 1);
47094709
});
47104710
});
47114711

4712+
describe('navigateToMostRecentReport via leaveRoom', () => {
4713+
const ROOM_REPORT_ID = '2001';
4714+
const OTHER_REPORT_ID = '5001';
4715+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
4716+
const mockNavigation: {goBack: jest.Mock; dismissToSuperWideRHP: jest.Mock; navigate: jest.Mock; getTopmostSuperWideRHPReportID: jest.Mock} =
4717+
jest.requireMock('@libs/Navigation/Navigation');
4718+
4719+
beforeEach(async () => {
4720+
jest.clearAllMocks();
4721+
await Onyx.clear();
4722+
await waitForBatchedUpdates();
4723+
});
4724+
4725+
it('should navigate to last accessed report when one exists', async () => {
4726+
TestHelper.getGlobalFetchMock();
4727+
4728+
const roomReport = {
4729+
...createRandomReport(Number(ROOM_REPORT_ID), CONST.REPORT.CHAT_TYPE.POLICY_ROOM),
4730+
participants: {
4731+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4732+
},
4733+
};
4734+
4735+
// Create another report that findLastAccessedReport can return
4736+
const otherReport = {
4737+
...createRandomReport(Number(OTHER_REPORT_ID), undefined),
4738+
lastVisibleActionCreated: new Date().toISOString(),
4739+
participants: {
4740+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4741+
},
4742+
};
4743+
4744+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}`, roomReport);
4745+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${OTHER_REPORT_ID}`, otherReport);
4746+
await Onyx.merge(ONYXKEYS.SESSION, {accountID: TEST_CURRENT_USER_ACCOUNT_ID});
4747+
await waitForBatchedUpdates();
4748+
4749+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, false);
4750+
await waitForBatchedUpdates();
4751+
4752+
// Should navigate via goBack since there's another report to navigate to
4753+
expect(mockNavigation.goBack).toHaveBeenCalled();
4754+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_ROOM, 1);
4755+
});
4756+
4757+
it('should navigate to concierge when leaving a chat thread and no other report exists', async () => {
4758+
TestHelper.getGlobalFetchMock();
4759+
4760+
const PARENT_REPORT_ID = '2002';
4761+
const PARENT_REPORT_ACTION_ID = '3001';
4762+
4763+
const threadReport = {
4764+
...createRandomReport(Number(ROOM_REPORT_ID), undefined),
4765+
type: CONST.REPORT.TYPE.CHAT,
4766+
parentReportID: PARENT_REPORT_ID,
4767+
parentReportActionID: PARENT_REPORT_ACTION_ID,
4768+
participants: {
4769+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4770+
},
4771+
};
4772+
4773+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}`, threadReport);
4774+
await Onyx.merge(ONYXKEYS.SESSION, {accountID: TEST_CURRENT_USER_ACCOUNT_ID});
4775+
await waitForBatchedUpdates();
4776+
4777+
// Chat thread with no other report → navigateToMostRecentReport calls navigateToConciergeChat without goBack
4778+
Report.leaveRoom(threadReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, false);
4779+
await waitForBatchedUpdates();
4780+
4781+
// For chat threads, goBack should NOT be called before navigating to concierge (the isChatThread branch)
4782+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_ROOM, 1);
4783+
});
4784+
});
4785+
4786+
describe('navigateToMostRecentReport via leaveGroupChat', () => {
4787+
const GROUP_CHAT_REPORT_ID = '1001';
4788+
const OTHER_REPORT_ID = '5001';
4789+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
4790+
const mockNavigation: {goBack: jest.Mock; navigate: jest.Mock} = jest.requireMock('@libs/Navigation/Navigation');
4791+
4792+
beforeEach(async () => {
4793+
jest.clearAllMocks();
4794+
await Onyx.clear();
4795+
await waitForBatchedUpdates();
4796+
});
4797+
4798+
it('should navigate to last accessed report when one exists', async () => {
4799+
TestHelper.getGlobalFetchMock();
4800+
4801+
const groupChatReport = {
4802+
...createRandomReport(Number(GROUP_CHAT_REPORT_ID), CONST.REPORT.CHAT_TYPE.GROUP),
4803+
participants: {
4804+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4805+
},
4806+
};
4807+
4808+
const otherReport = {
4809+
...createRandomReport(Number(OTHER_REPORT_ID), undefined),
4810+
lastVisibleActionCreated: new Date().toISOString(),
4811+
participants: {
4812+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4813+
},
4814+
};
4815+
4816+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${GROUP_CHAT_REPORT_ID}`, groupChatReport);
4817+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${OTHER_REPORT_ID}`, otherReport);
4818+
await Onyx.merge(ONYXKEYS.SESSION, {accountID: TEST_CURRENT_USER_ACCOUNT_ID});
4819+
await waitForBatchedUpdates();
4820+
4821+
Report.leaveGroupChat(groupChatReport, false, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED);
4822+
await waitForBatchedUpdates();
4823+
4824+
expect(mockNavigation.goBack).toHaveBeenCalled();
4825+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_GROUP_CHAT, 1);
4826+
});
4827+
4828+
it('should navigate to concierge when no other report exists', async () => {
4829+
TestHelper.getGlobalFetchMock();
4830+
4831+
const groupChatReport = {
4832+
...createRandomReport(Number(GROUP_CHAT_REPORT_ID), CONST.REPORT.CHAT_TYPE.GROUP),
4833+
participants: {
4834+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4835+
},
4836+
};
4837+
4838+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${GROUP_CHAT_REPORT_ID}`, groupChatReport);
4839+
await Onyx.merge(ONYXKEYS.SESSION, {accountID: TEST_CURRENT_USER_ACCOUNT_ID});
4840+
await waitForBatchedUpdates();
4841+
4842+
Report.leaveGroupChat(groupChatReport, false, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED);
4843+
await waitForBatchedUpdates();
4844+
4845+
// With no other reports, navigateToMostRecentReport calls goBack (not a chat thread) then navigateToConciergeChat
4846+
expect(mockNavigation.goBack).toHaveBeenCalled();
4847+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_GROUP_CHAT, 1);
4848+
});
4849+
});
4850+
4851+
describe('leaveRoom dismissModal branch', () => {
4852+
const ROOM_REPORT_ID = '2001';
4853+
4854+
beforeEach(async () => {
4855+
await Onyx.clear();
4856+
await waitForBatchedUpdates();
4857+
});
4858+
4859+
it('should dismiss modal when workspace member leaves a non-thread workspace room', async () => {
4860+
TestHelper.getGlobalFetchMock();
4861+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
4862+
const mockNavigation: {dismissModal: jest.Mock; goBack: jest.Mock; navigate: jest.Mock} = jest.requireMock('@libs/Navigation/Navigation');
4863+
mockNavigation.dismissModal.mockClear();
4864+
4865+
const roomReport = {
4866+
...createRandomReport(Number(ROOM_REPORT_ID), CONST.REPORT.CHAT_TYPE.POLICY_ROOM),
4867+
participants: {
4868+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4869+
},
4870+
};
4871+
4872+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}`, roomReport);
4873+
await waitForBatchedUpdates();
4874+
4875+
// isWorkspaceMemberLeavingWorkspaceRoom=true and report is NOT a chat thread → should dismissModal
4876+
Report.leaveRoom(roomReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, true);
4877+
await waitForBatchedUpdates();
4878+
4879+
expect(mockNavigation.dismissModal).toHaveBeenCalled();
4880+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_ROOM, 1);
4881+
});
4882+
4883+
it('should NOT dismiss modal when workspace member leaves a chat thread in workspace room', async () => {
4884+
TestHelper.getGlobalFetchMock();
4885+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
4886+
const mockNavigation: {dismissModal: jest.Mock} = jest.requireMock('@libs/Navigation/Navigation');
4887+
mockNavigation.dismissModal.mockClear();
4888+
4889+
const PARENT_REPORT_ID = '2002';
4890+
const PARENT_REPORT_ACTION_ID = '3001';
4891+
4892+
// A chat thread has parentReportID and parentReportActionID set
4893+
const threadReport = {
4894+
...createRandomReport(Number(ROOM_REPORT_ID), CONST.REPORT.CHAT_TYPE.POLICY_ROOM),
4895+
type: CONST.REPORT.TYPE.CHAT,
4896+
parentReportID: PARENT_REPORT_ID,
4897+
parentReportActionID: PARENT_REPORT_ACTION_ID,
4898+
participants: {
4899+
[TEST_CURRENT_USER_ACCOUNT_ID]: {notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS},
4900+
},
4901+
};
4902+
4903+
await Onyx.merge(`${ONYXKEYS.COLLECTION.REPORT}${ROOM_REPORT_ID}`, threadReport);
4904+
await waitForBatchedUpdates();
4905+
4906+
// isWorkspaceMemberLeavingWorkspaceRoom=true but report IS a chat thread → should NOT dismissModal, should navigateToMostRecentReport instead
4907+
Report.leaveRoom(threadReport, TEST_CURRENT_USER_ACCOUNT_ID, TEST_CONCIERGE_REPORT_ID, TEST_INTRO_SELECTED, true);
4908+
await waitForBatchedUpdates();
4909+
4910+
expect(mockNavigation.dismissModal).not.toHaveBeenCalled();
4911+
TestHelper.expectAPICommandToHaveBeenCalled(WRITE_COMMANDS.LEAVE_ROOM, 1);
4912+
});
4913+
});
4914+
47124915
describe('navigateToAndCreateGroupChat', () => {
47134916
it('should create a group chat and navigate to it', async () => {
47144917
// Given a test user with initial data

0 commit comments

Comments
 (0)