Browse Source

Don't crash if Modal related commands are called before root is set

We should also support showingModals on Android regardless of root
Guy Carmeli 5 years ago
parent
commit
aa8135dcbf

+ 14
- 1
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenter.java View File

@@ -3,6 +3,7 @@ package com.reactnativenavigation.viewcontrollers.modal;
3 3
 import android.animation.Animator;
4 4
 import android.animation.AnimatorListenerAdapter;
5 5
 import android.support.annotation.NonNull;
6
+import android.support.annotation.Nullable;
6 7
 import android.view.ViewGroup;
7 8
 
8 9
 import com.reactnativenavigation.anim.ModalAnimator;
@@ -14,7 +15,7 @@ import com.reactnativenavigation.viewcontrollers.ViewController;
14 15
 
15 16
 public class ModalPresenter {
16 17
 
17
-    private ViewGroup content;
18
+    @Nullable private ViewGroup content;
18 19
     private ModalAnimator animator;
19 20
     private Options defaultOptions = new Options();
20 21
     private EventEmitter eventEmitter;
@@ -32,6 +33,10 @@ public class ModalPresenter {
32 33
     }
33 34
 
34 35
     public void showModal(ViewController toAdd, ViewController toRemove, CommandListener listener) {
36
+        if (content == null) {
37
+            listener.onError("Could not show modal before setRoot is called");
38
+            return;
39
+        }
35 40
         Options options = toAdd.resolveCurrentOptions(defaultOptions);
36 41
         toAdd.setWaitForRender(options.animations.showModal.waitForRender);
37 42
         content.addView(toAdd.getView());
@@ -67,11 +72,19 @@ public class ModalPresenter {
67 72
     }
68 73
 
69 74
     public void dismissTopModal(ViewController toDismiss, @NonNull ViewController toAdd, CommandListener listener) {
75
+        if (content == null) {
76
+            listener.onError("Could not dismiss modal before setRoot is called");
77
+            return;
78
+        }
70 79
         toAdd.attachView(content, 0);
71 80
         dismissModal(toDismiss, listener);
72 81
     }
73 82
 
74 83
     public void dismissModal(ViewController toDismiss, CommandListener listener) {
84
+        if (content == null) {
85
+            listener.onError("Could not dismiss modal before setRoot is called");
86
+            return;
87
+        }
75 88
         if (toDismiss.options.animations.dismissModal.enable.isTrueOrUndefined()) {
76 89
             animator.dismiss(toDismiss.getView(), toDismiss.options.animations.dismissModal, new AnimatorListenerAdapter() {
77 90
                 @Override

+ 25
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/modal/ModalPresenterTest.java View File

@@ -19,6 +19,7 @@ import com.reactnativenavigation.viewcontrollers.ViewController;
19 19
 import org.json.JSONException;
20 20
 import org.json.JSONObject;
21 21
 import org.junit.Test;
22
+import org.mockito.Mockito;
22 23
 
23 24
 import static org.assertj.core.api.Java6Assertions.assertThat;
24 25
 import static org.mockito.ArgumentMatchers.any;
@@ -136,6 +137,14 @@ public class ModalPresenterTest extends BaseTest {
136 137
         verifyZeroInteractions(animator);
137 138
     }
138 139
 
140
+    @Test
141
+    public void showModal_rejectIfContentIsNull() {
142
+        uut.setContentLayout(null);
143
+        CommandListenerAdapter listener = Mockito.mock(CommandListenerAdapter.class);
144
+        uut.showModal(modal1, modal2, listener);
145
+        verify(listener).onError(any());
146
+    }
147
+
139 148
     @Test
140 149
     public void dismissModal_animatesByDefault() {
141 150
         disableShowModalAnimation(modal1);
@@ -210,4 +219,20 @@ public class ModalPresenterTest extends BaseTest {
210 219
         assertThat(root.getView().getParent()).isNotNull();
211 220
         verify(root, times(0)).onViewDisappear();
212 221
     }
222
+
223
+    @Test
224
+    public void dismissTopModal_rejectIfContentIsNull() {
225
+        uut.setContentLayout(null);
226
+        CommandListenerAdapter listener = Mockito.mock(CommandListenerAdapter.class);
227
+        uut.dismissTopModal(modal1, modal2, listener);
228
+        verify(listener).onError(any());
229
+    }
230
+
231
+    @Test
232
+    public void dismissModal_rejectIfContentIsNull() {
233
+        uut.setContentLayout(null);
234
+        CommandListenerAdapter listener = Mockito.mock(CommandListenerAdapter.class);
235
+        uut.dismissModal(modal1, listener);
236
+        verify(listener).onError(any());
237
+    }
213 238
 }