From f23131eac82c63adda0bdbc359d45c4cd7403299 Mon Sep 17 00:00:00 2001 From: Yogev Ben David Date: Wed, 23 Nov 2022 18:09:17 +0200 Subject: [PATCH] Avoid returning being dismissed modal as the top presented viewController --- lib/ios/RNNModalManager.m | 2 +- .../ios/NavigationTests/RNNModalManagerTest.m | 52 +++++++++++-------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/lib/ios/RNNModalManager.m b/lib/ios/RNNModalManager.m index 970556db145..6d49ed15f36 100644 --- a/lib/ios/RNNModalManager.m +++ b/lib/ios/RNNModalManager.m @@ -191,7 +191,7 @@ - (UIViewController *)rootViewController { - (UIViewController *)topPresentedVC { UIViewController *root = [self rootViewController]; - while (root.presentedViewController) { + while (root.presentedViewController && !root.presentedViewController.isBeingDismissed) { root = root.presentedViewController; } return root; diff --git a/playground/ios/NavigationTests/RNNModalManagerTest.m b/playground/ios/NavigationTests/RNNModalManagerTest.m index 32cb8aa944d..c0ad2cf898b 100644 --- a/playground/ios/NavigationTests/RNNModalManagerTest.m +++ b/playground/ios/NavigationTests/RNNModalManagerTest.m @@ -21,14 +21,6 @@ - (void)presentViewController:(UIViewController *)viewControllerToPresent @end -@interface MockModalManager : RNNModalManager -@property(nonatomic, strong) MockViewController *rootViewController; -@property(nonatomic, strong) MockViewController *topPresentedVC; -@end - -@implementation MockModalManager -@end - @interface RNNModalManagerTest : XCTestCase { CGFloat _modalDismissedCount; } @@ -39,7 +31,7 @@ @implementation RNNModalManagerTest { RNNComponentViewController *_vc1; RNNComponentViewController *_vc2; RNNComponentViewController *_vc3; - MockModalManager *_modalManager; + RNNModalManager *_modalManager; id _modalManagerEventHandler; } @@ -53,16 +45,22 @@ - (void)setUp { _vc3.layoutInfo = [RNNLayoutInfo new]; _modalManagerEventHandler = [OCMockObject partialMockForObject:[RNNModalManagerEventHandler new]]; - _modalManager = [[MockModalManager alloc] initWithBridge:nil - eventHandler:_modalManagerEventHandler]; - _modalManager.topPresentedVC = [MockViewController new]; + _modalManager = [OCMockObject + partialMockForObject:[[RNNModalManager alloc] initWithBridge:nil + eventHandler:_modalManagerEventHandler]]; + + UIApplication.sharedApplication.delegate.window.rootViewController = + [OCMockObject partialMockForObject:MockViewController.new]; } -- (void)testDismissMultipleModalsInvokeDelegateWithCorrectParameters { - _modalManager.rootViewController = [OCMockObject partialMockForObject:UIViewController.new]; - OCMStub(_modalManager.rootViewController.presentedViewController) - .andReturn(UIViewController.new); +- (void)tearDown { + UIApplication.sharedApplication.delegate.window.rootViewController = UIViewController.new; +} +- (void)testDismissMultipleModalsInvokeDelegateWithCorrectParameters { + OCMStub( + UIApplication.sharedApplication.delegate.window.rootViewController.presentedViewController) + .andReturn(MockViewController.new); [_modalManager showModal:_vc1 animated:NO completion:nil]; [_modalManager showModal:_vc2 animated:NO completion:nil]; [_modalManager showModal:_vc3 animated:NO completion:nil]; @@ -105,10 +103,9 @@ - (void)testDismissPreviousModal_InvokeDelegateWithCorrectParameters { } - (void)testDismissAllModals_AfterDismissingPreviousModal_InvokeDelegateWithCorrectParameters { - _modalManager.rootViewController = [OCMockObject partialMockForObject:UIViewController.new]; - OCMStub(_modalManager.rootViewController.presentedViewController) - .andReturn(UIViewController.new); - + OCMStub( + UIApplication.sharedApplication.delegate.window.rootViewController.presentedViewController) + .andReturn(MockViewController.new); [_modalManager showModal:_vc1 animated:NO completion:nil]; [_modalManager showModal:_vc2 animated:NO completion:nil]; [_modalManager showModal:_vc3 animated:NO completion:nil]; @@ -133,8 +130,10 @@ - (void)testShowModal_NilModalThrows { } - (void)testShowModal_CallPresentViewController { + OCMStub([_modalManager topPresentedVC]).andReturn([MockViewController new]); [_modalManager showModal:_vc1 animated:NO completion:nil]; - XCTAssertTrue(_modalManager.topPresentedVC.presentViewControllerCalls == 1); + XCTAssertTrue(((MockViewController *)_modalManager.topPresentedVC).presentViewControllerCalls == + 1); } - (void)testPresentationControllerDidDismiss_ShouldInvokeDelegateDismissedModal { @@ -171,4 +170,15 @@ - (void)testApplyOptionsOnInit_shouldShowModalWithDefaultTransitionStyle { XCTAssertEqual(_vc1.modalTransitionStyle, UIModalTransitionStyleCoverVertical); } +- (void)testTopPresentedVC_shouldNotReturnModalThatIsBeingDismissed { + UIApplication.sharedApplication.delegate.window.rootViewController = + [OCMockObject partialMockForObject:UIViewController.new]; + UIViewController *beingDismissedModal = + [OCMockObject partialMockForObject:[UIViewController new]]; + [_modalManager showModal:beingDismissedModal animated:NO completion:nil]; + XCTAssertEqual(_modalManager.topPresentedVC, beingDismissedModal); + OCMStub(beingDismissedModal.isBeingDismissed).andReturn(YES); + XCTAssertNotEqual(_modalManager.topPresentedVC, beingDismissedModal); +} + @end