Browse Source

Test TopTab navigationOptions is applied correctly (#2379)

* minor refactor - moved some logic from view o controller
Guy Carmeli 6 years ago
parent
commit
a6f19787f6
No account linked to committer's email address

+ 1
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabController.java View File

@@ -68,6 +68,7 @@ public class TopTabController extends ViewController implements NavigationOption
68 68
     @Override
69 69
     public void mergeNavigationOptions(NavigationOptions options) {
70 70
         this.options.mergeWith(options);
71
+        applyOptions(this.options);
71 72
     }
72 73
 
73 74
     String getTabTitle() {

+ 4
- 0
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsAdapter.java View File

@@ -51,4 +51,8 @@ public class TopTabsAdapter extends PagerAdapter implements ViewPager.OnPageChan
51 51
     public void onPageScrollStateChanged(int state) {
52 52
 
53 53
     }
54
+
55
+    int getCurrentItem() {
56
+        return currentPage;
57
+    }
54 58
 }

+ 10
- 3
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsController.java View File

@@ -6,6 +6,7 @@ import android.view.ViewGroup;
6 6
 
7 7
 import com.reactnativenavigation.parse.NavigationOptions;
8 8
 import com.reactnativenavigation.presentation.NavigationOptionsListener;
9
+import com.reactnativenavigation.utils.Task;
9 10
 import com.reactnativenavigation.viewcontrollers.ParentController;
10 11
 import com.reactnativenavigation.viewcontrollers.ViewController;
11 12
 import com.reactnativenavigation.views.TopTabsLayout;
@@ -17,10 +18,12 @@ public class TopTabsController extends ParentController implements NavigationOpt
17 18
 
18 19
     private List<TopTabController> tabs;
19 20
     private TopTabsLayout topTabsLayout;
21
+    private TopTabsAdapter adapter;
20 22
 
21 23
     public TopTabsController(Activity activity, String id, List<TopTabController> tabs) {
22 24
         super(activity, id);
23 25
         this.tabs = tabs;
26
+        this.adapter = new TopTabsAdapter(tabs);
24 27
         for (ViewController tab : tabs) {
25 28
             tab.setParentController(this);
26 29
         }
@@ -29,7 +32,7 @@ public class TopTabsController extends ParentController implements NavigationOpt
29 32
     @NonNull
30 33
     @Override
31 34
     protected ViewGroup createView() {
32
-        topTabsLayout = new TopTabsLayout(getActivity(), tabs);
35
+        topTabsLayout = new TopTabsLayout(getActivity(), tabs, adapter);
33 36
         return topTabsLayout;
34 37
     }
35 38
 
@@ -41,12 +44,12 @@ public class TopTabsController extends ParentController implements NavigationOpt
41 44
 
42 45
     @Override
43 46
     public void onViewAppeared() {
44
-        topTabsLayout.performOnCurrentTab(TopTabController::onViewAppeared);
47
+        performOnCurrentTab(TopTabController::onViewAppeared);
45 48
     }
46 49
 
47 50
     @Override
48 51
     public void onViewDisappear() {
49
-        topTabsLayout.performOnCurrentTab(TopTabController::onViewDisappear);
52
+        performOnCurrentTab(TopTabController::onViewDisappear);
50 53
     }
51 54
 
52 55
     @Override
@@ -62,4 +65,8 @@ public class TopTabsController extends ParentController implements NavigationOpt
62 65
     public void switchToTab(int index) {
63 66
         topTabsLayout.switchToTab(index);
64 67
     }
68
+
69
+    private void performOnCurrentTab(Task<TopTabController> task) {
70
+        task.run(tabs.get(adapter.getCurrentItem()));
71
+    }
65 72
 }

+ 3
- 4
lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/toptabs/TopTabsViewPager.java View File

@@ -16,18 +16,17 @@ public class TopTabsViewPager extends ViewPager {
16 16
     private static final int OFFSCREEN_PAGE_LIMIT = 99;
17 17
     private List<TopTabController> tabs;
18 18
 
19
-    public TopTabsViewPager(Context context, List<TopTabController> tabs) {
19
+    public TopTabsViewPager(Context context, List<TopTabController> tabs, TopTabsAdapter adapter) {
20 20
         super(context);
21 21
         this.tabs = tabs;
22
-        init();
22
+        init(adapter);
23 23
     }
24 24
 
25
-    private void init() {
25
+    private void init(TopTabsAdapter adapter) {
26 26
         setOffscreenPageLimit(OFFSCREEN_PAGE_LIMIT);
27 27
         for (ViewController tab : tabs) {
28 28
             addView(tab.getView(), new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
29 29
         }
30
-        TopTabsAdapter adapter = new TopTabsAdapter(tabs);
31 30
         setAdapter(adapter);
32 31
         addOnPageChangeListener(adapter);
33 32
     }

+ 3
- 10
lib/android/app/src/main/java/com/reactnativenavigation/views/TopTabsLayout.java View File

@@ -8,8 +8,8 @@ import android.widget.LinearLayout;
8 8
 
9 9
 import com.reactnativenavigation.parse.NavigationOptions;
10 10
 import com.reactnativenavigation.presentation.OptionsPresenter;
11
-import com.reactnativenavigation.utils.Task;
12 11
 import com.reactnativenavigation.viewcontrollers.toptabs.TopTabController;
12
+import com.reactnativenavigation.viewcontrollers.toptabs.TopTabsAdapter;
13 13
 import com.reactnativenavigation.viewcontrollers.toptabs.TopTabsViewPager;
14 14
 
15 15
 import java.util.List;
@@ -18,16 +18,14 @@ import java.util.List;
18 18
 public class TopTabsLayout extends LinearLayout implements Container {
19 19
 
20 20
     private TopBar topBar;
21
-    private List<TopTabController> tabs;
22 21
     private TopTabsViewPager viewPager;
23 22
     private final OptionsPresenter optionsPresenter;
24 23
 
25
-    public TopTabsLayout(Context context, List<TopTabController> tabs) {
24
+    public TopTabsLayout(Context context, List<TopTabController> tabs, TopTabsAdapter adapter) {
26 25
         super(context);
27 26
         topBar = new TopBar(context);
28
-        this.tabs = tabs;
29
-        viewPager = new TopTabsViewPager(context, tabs);
30 27
         optionsPresenter = new OptionsPresenter(topBar, viewPager);
28
+        viewPager = new TopTabsViewPager(context, tabs, adapter);
31 29
         initViews();
32 30
     }
33 31
 
@@ -54,11 +52,6 @@ public class TopTabsLayout extends LinearLayout implements Container {
54 52
         return viewPager;
55 53
     }
56 54
 
57
-
58
-    public void performOnCurrentTab(Task<TopTabController> task) {
59
-        task.run(tabs.get(viewPager.getCurrentItem()));
60
-    }
61
-
62 55
     public void switchToTab(int index) {
63 56
         viewPager.setCurrentItem(index);
64 57
     }

+ 53
- 0
lib/android/app/src/test/java/com/reactnativenavigation/viewcontrollers/TopTabControllerTest.java View File

@@ -0,0 +1,53 @@
1
+package com.reactnativenavigation.viewcontrollers;
2
+
3
+import android.app.Activity;
4
+
5
+import com.reactnativenavigation.BaseTest;
6
+import com.reactnativenavigation.mocks.TopTabLayoutMock;
7
+import com.reactnativenavigation.parse.NavigationOptions;
8
+import com.reactnativenavigation.viewcontrollers.toptabs.TopTabController;
9
+
10
+import org.junit.Test;
11
+
12
+import static org.mockito.Mockito.spy;
13
+import static org.mockito.Mockito.times;
14
+import static org.mockito.Mockito.verify;
15
+
16
+public class TopTabControllerTest extends BaseTest {
17
+    private TopTabController uut;
18
+    private TopTabLayoutMock view;
19
+    private ParentController parentController;
20
+    private NavigationOptions initialOptions;
21
+
22
+    @Override
23
+    public void beforeEach() {
24
+        super.beforeEach();
25
+        Activity activity = newActivity();
26
+        view = spy(new TopTabLayoutMock(activity));
27
+        initialOptions = new NavigationOptions();
28
+        uut = new TopTabController(activity,
29
+                "containerId",
30
+                "containerName",
31
+                (activity1, containerId, containerName) -> view,
32
+                initialOptions
33
+        );
34
+        parentController = spy(new TopTabsControllerMock(activity, "parentContainerId"));
35
+        uut.setParentController(parentController);
36
+    }
37
+
38
+    @Test
39
+    public void styleIsAppliedOnParentControllerWhenTabIsVisible() throws Exception {
40
+        uut.ensureViewIsCreated();
41
+        uut.onViewAppeared();
42
+        verify(parentController, times(1)).applyOptions(initialOptions);
43
+    }
44
+
45
+    @Test
46
+    public void styleIsAppliedOnParentControllerWhenOptionsAreSetDynamically() throws Exception {
47
+        uut.ensureViewIsCreated();
48
+        uut.onViewAppeared();
49
+        uut.mergeNavigationOptions(new NavigationOptions());
50
+        verify(parentController, times(2)).applyOptions(initialOptions);
51
+    }
52
+
53
+}

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

@@ -0,0 +1,25 @@
1
+package com.reactnativenavigation.viewcontrollers;
2
+
3
+import android.app.Activity;
4
+import android.support.annotation.NonNull;
5
+import android.view.ViewGroup;
6
+
7
+import java.util.Collection;
8
+
9
+public class TopTabsControllerMock extends ParentController {
10
+    public TopTabsControllerMock(Activity activity, String id) {
11
+        super(activity, id);
12
+    }
13
+
14
+    @NonNull
15
+    @Override
16
+    protected ViewGroup createView() {
17
+        return null;
18
+    }
19
+
20
+    @NonNull
21
+    @Override
22
+    public Collection<? extends ViewController> getChildControllers() {
23
+        return null;
24
+    }
25
+}

+ 22
- 2
playground/src/containers/TopTabOptionsScreen.js View File

@@ -1,7 +1,8 @@
1 1
 const React = require('react');
2 2
 const { PureComponent } = require('react');
3
-
4
-const { View, Text } = require('react-native');
3
+const testIDs = require('../testIDs');
4
+const { View, Text, Button } = require('react-native');
5
+const Navigation = require('react-native-navigation');
5 6
 
6 7
 class TopTabOptionsScreen extends PureComponent {
7 8
   static get navigationOptions() {
@@ -15,14 +16,33 @@ class TopTabOptionsScreen extends PureComponent {
15 16
     };
16 17
   }
17 18
 
19
+  constructor(props) {
20
+    super(props);
21
+    this.onClickDynamicOptions = this.onClickDynamicOptions.bind(this);
22
+  }
23
+
18 24
   render() {
19 25
     return (
20 26
       <View style={styles.root}>
21 27
         <Text style={styles.h1}>{this.props.text || 'Top Tab Screen'}</Text>
22 28
         <Text style={styles.footer}>{`this.props.containerId = ${this.props.containerId}`}</Text>
29
+        <Button title="Dynamic Options" testID={testIDs.DYNAMIC_OPTIONS_BUTTON} onPress={this.onClickDynamicOptions} />
23 30
       </View>
24 31
     );
25 32
   }
33
+
34
+  onClickDynamicOptions() {
35
+    Navigation.setOptions(this.props.containerId, {
36
+      topBar: {
37
+        title: 'Dynamic Title',
38
+        textColor: '#00FFFF',
39
+        largeTitle: false,
40
+        buttonColor: 'red',
41
+        textFontSize: 20,
42
+        textFontFamily: 'HelveticaNeue-CondensedBold'
43
+      }
44
+    });
45
+  }
26 46
 }
27 47
 
28 48
 const styles = {