@@ -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