1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 18 package android.support.v4.app; 19 20 import static org.junit.Assert.assertEquals; 21 import static org.junit.Assert.assertNull; 22 import static org.junit.Assert.assertSame; 23 import static org.junit.Assert.assertTrue; 24 25 import android.support.test.filters.MediumTest; 26 import android.support.test.rule.ActivityTestRule; 27 import android.support.test.runner.AndroidJUnit4; 28 import android.support.v4.app.test.EmptyFragmentTestActivity; 29 30 import org.junit.Rule; 31 import org.junit.Test; 32 import org.junit.runner.RunWith; 33 34 @RunWith(AndroidJUnit4.class) 35 @MediumTest 36 public class PrimaryNavFragmentTest { 37 @Rule 38 public ActivityTestRule<EmptyFragmentTestActivity> mActivityRule = 39 new ActivityTestRule<EmptyFragmentTestActivity>(EmptyFragmentTestActivity.class); 40 41 @Test 42 public void delegateBackToPrimaryNav() throws Throwable { 43 final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 44 final StrictFragment strictFragment = new StrictFragment(); 45 46 fm.beginTransaction().add(strictFragment, null).setPrimaryNavigationFragment(strictFragment) 47 .commit(); 48 executePendingTransactions(fm); 49 50 assertSame("new fragment is not primary nav fragment", strictFragment, 51 fm.getPrimaryNavigationFragment()); 52 53 final StrictFragment child = new StrictFragment(); 54 FragmentManager cfm = strictFragment.getChildFragmentManager(); 55 cfm.beginTransaction().add(child, null).addToBackStack(null).commit(); 56 executePendingTransactions(cfm); 57 58 assertEquals("child transaction not on back stack", 1, cfm.getBackStackEntryCount()); 59 60 // Should execute the pop for the child fragmentmanager 61 assertTrue("popBackStackImmediate returned no action performed", 62 popBackStackImmediate(fm)); 63 64 assertEquals("child transaction still on back stack", 0, cfm.getBackStackEntryCount()); 65 } 66 67 @Test 68 public void popPrimaryNav() throws Throwable { 69 final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 70 final StrictFragment strictFragment1 = new StrictFragment(); 71 72 fm.beginTransaction().add(strictFragment1, null) 73 .setPrimaryNavigationFragment(strictFragment1) 74 .commit(); 75 executePendingTransactions(fm); 76 77 assertSame("new fragment is not primary nav fragment", strictFragment1, 78 fm.getPrimaryNavigationFragment()); 79 80 fm.beginTransaction().remove(strictFragment1).addToBackStack(null).commit(); 81 executePendingTransactions(fm); 82 83 assertNull("primary nav fragment is not null after remove", 84 fm.getPrimaryNavigationFragment()); 85 86 popBackStackImmediate(fm); 87 88 assertSame("primary nav fragment was not restored on pop", strictFragment1, 89 fm.getPrimaryNavigationFragment()); 90 91 final StrictFragment strictFragment2 = new StrictFragment(); 92 fm.beginTransaction().remove(strictFragment1).add(strictFragment2, null) 93 .setPrimaryNavigationFragment(strictFragment2).addToBackStack(null).commit(); 94 executePendingTransactions(fm); 95 96 assertSame("primary nav fragment not updated to new fragment", strictFragment2, 97 fm.getPrimaryNavigationFragment()); 98 99 popBackStackImmediate(fm); 100 101 assertSame("primary nav fragment not restored on pop", strictFragment1, 102 fm.getPrimaryNavigationFragment()); 103 104 fm.beginTransaction().setPrimaryNavigationFragment(strictFragment1) 105 .addToBackStack(null).commit(); 106 executePendingTransactions(fm); 107 108 assertSame("primary nav fragment not retained when set again in new transaction", 109 strictFragment1, fm.getPrimaryNavigationFragment()); 110 popBackStackImmediate(fm); 111 112 assertSame("same primary nav fragment not retained when set primary nav transaction popped", 113 strictFragment1, fm.getPrimaryNavigationFragment()); 114 } 115 116 @Test 117 public void replacePrimaryNav() throws Throwable { 118 final FragmentManager fm = mActivityRule.getActivity().getSupportFragmentManager(); 119 final StrictFragment strictFragment1 = new StrictFragment(); 120 121 fm.beginTransaction().add(android.R.id.content, strictFragment1) 122 .setPrimaryNavigationFragment(strictFragment1).commit(); 123 executePendingTransactions(fm); 124 125 assertSame("new fragment is not primary nav fragment", strictFragment1, 126 fm.getPrimaryNavigationFragment()); 127 128 final StrictFragment strictFragment2 = new StrictFragment(); 129 fm.beginTransaction().replace(android.R.id.content, strictFragment2) 130 .addToBackStack(null).commit(); 131 132 executePendingTransactions(fm); 133 134 assertNull("primary nav fragment not null after replace", 135 fm.getPrimaryNavigationFragment()); 136 137 popBackStackImmediate(fm); 138 139 assertSame("primary nav fragment not restored after popping replace", strictFragment1, 140 fm.getPrimaryNavigationFragment()); 141 142 fm.beginTransaction().setPrimaryNavigationFragment(null).commit(); 143 executePendingTransactions(fm); 144 145 assertNull("primary nav fragment not null after explicit set to null", 146 fm.getPrimaryNavigationFragment()); 147 148 fm.beginTransaction().replace(android.R.id.content, strictFragment2) 149 .setPrimaryNavigationFragment(strictFragment2).addToBackStack(null).commit(); 150 executePendingTransactions(fm); 151 152 assertSame("primary nav fragment not set correctly after replace", strictFragment2, 153 fm.getPrimaryNavigationFragment()); 154 155 popBackStackImmediate(fm); 156 157 assertNull("primary nav fragment not null after popping replace", 158 fm.getPrimaryNavigationFragment()); 159 } 160 161 private void executePendingTransactions(final FragmentManager fm) throws Throwable { 162 mActivityRule.runOnUiThread(new Runnable() { 163 @Override 164 public void run() { 165 fm.executePendingTransactions(); 166 } 167 }); 168 } 169 170 private boolean popBackStackImmediate(final FragmentManager fm) throws Throwable { 171 final boolean[] result = new boolean[1]; 172 mActivityRule.runOnUiThread(new Runnable() { 173 @Override 174 public void run() { 175 result[0] = fm.popBackStackImmediate(); 176 } 177 }); 178 return result[0]; 179 } 180 } 181