From 1d44acce672508632b5474d30ebb3278f0fdd7ad Mon Sep 17 00:00:00 2001 From: tmfang Date: Tue, 17 Jul 2018 09:54:14 +0800 Subject: [PATCH] Fix test cases broken - AndroiX AlertDialog needs to use Theme.AppCompat. - Create a ShadowAlertDialogCompat which can be compatible with AndroidX AlertDialog. Fix: 111247403 Test: make RunSettingsRoboTests -j56 ROBOTEST_FILTER=com.android.settings.password.ChooseLockTypeDialogFragmentTest Change-Id: I3e4bca285ecaefa5705c8d170050c21d1bc649e0 --- tests/robotests/res/values/themes.xml | 5 +- .../ChooseLockTypeDialogFragmentTest.java | 37 ++++----- .../shadow/SettingsShadowResourcesImpl.java | 3 +- .../shadow/ShadowAlertDialogCompat.java | 83 +++++++++++++++++++ 4 files changed, 107 insertions(+), 21 deletions(-) create mode 100644 tests/robotests/src/com/android/settings/testutils/shadow/ShadowAlertDialogCompat.java diff --git a/tests/robotests/res/values/themes.xml b/tests/robotests/res/values/themes.xml index 74bdd9b1d79..9a247f6abd8 100644 --- a/tests/robotests/res/values/themes.xml +++ b/tests/robotests/res/values/themes.xml @@ -1,5 +1,8 @@ - diff --git a/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java b/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java index f76a5ca8517..5068f852cb1 100644 --- a/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java +++ b/tests/robotests/src/com/android/settings/password/ChooseLockTypeDialogFragmentTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Google Inc. + * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,38 +16,33 @@ package com.android.settings.password; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; +import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import android.app.AlertDialog; import android.content.Context; import com.android.settings.R; import com.android.settings.password.ChooseLockTypeDialogFragment.OnLockTypeSelectedListener; import com.android.settings.testutils.SettingsRobolectricTestRunner; -import com.android.settings.testutils.shadow.ShadowUserManager; -import com.android.settings.testutils.shadow.ShadowUtils; +import com.android.settings.testutils.shadow.SettingsShadowResourcesImpl; +import com.android.settings.testutils.shadow.ShadowAlertDialogCompat; import com.android.settingslib.testutils.FragmentTestUtils; import org.junit.Before; -import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RuntimeEnvironment; -import org.robolectric.Shadows; import org.robolectric.annotation.Config; -import org.robolectric.shadows.ShadowAlertDialog; -import org.robolectric.shadows.ShadowDialog; +import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; @RunWith(SettingsRobolectricTestRunner.class) -@Config(shadows = {ShadowUserManager.class, ShadowUtils.class}) +@Config(shadows = {SettingsShadowResourcesImpl.class, ShadowAlertDialogCompat.class}) public class ChooseLockTypeDialogFragmentTest { private Context mContext; @@ -61,32 +56,36 @@ public class ChooseLockTypeDialogFragmentTest { } @Test - @Ignore("b/111247403") public void testThatDialog_IsShown() { AlertDialog latestDialog = startLockFragment(); - assertNotNull(latestDialog); - ShadowDialog shadowDialog = Shadows.shadowOf(latestDialog); + ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf( + latestDialog); + + assertThat(latestDialog).isNotNull(); + assertThat(latestDialog.isShowing()).isTrue(); // verify that we are looking at the expected dialog. - assertEquals(shadowDialog.getTitle(), + assertThat(shadowAlertDialog.getTitle()).isEqualTo( mContext.getString(R.string.setup_lock_settings_options_dialog_title)); } @Test - @Ignore("b/111247403") public void testThat_OnClickListener_IsCalled() { mFragment.mDelegate = mock(OnLockTypeSelectedListener.class); AlertDialog lockDialog = startLockFragment(); - ShadowAlertDialog shadowAlertDialog = Shadows.shadowOf(lockDialog); + ShadowAlertDialogCompat shadowAlertDialog = ShadowAlertDialogCompat.shadowOf(lockDialog); + shadowAlertDialog.clickOnItem(0); + verify(mFragment.mDelegate, times(1)).onLockTypeSelected(any(ScreenLockType.class)); } @Test - @Ignore("b/111247403") public void testThat_OnClickListener_IsNotCalledWhenCancelled() { mFragment.mDelegate = mock(OnLockTypeSelectedListener.class); AlertDialog lockDialog = startLockFragment(); + lockDialog.dismiss(); + verify(mFragment.mDelegate, never()).onLockTypeSelected(any(ScreenLockType.class)); } @@ -94,7 +93,7 @@ public class ChooseLockTypeDialogFragmentTest { ChooseLockTypeDialogFragment chooseLockTypeDialogFragment = ChooseLockTypeDialogFragment.newInstance(1234); chooseLockTypeDialogFragment.show(mFragment.getChildFragmentManager(), null); - return ShadowAlertDialog.getLatestAlertDialog(); + return ShadowAlertDialogCompat.getLatestAlertDialog(); } public static class TestFragment extends Fragment implements OnLockTypeSelectedListener { diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java index 9fb69a32552..dd51687296b 100644 --- a/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java +++ b/tests/robotests/src/com/android/settings/testutils/shadow/SettingsShadowResourcesImpl.java @@ -43,7 +43,8 @@ public class SettingsShadowResourcesImpl extends ShadowResourcesImpl { // that Robolectric isn't yet aware of. // TODO: Remove this once Robolectric is updated. if (id == R.drawable.switchbar_background - || id == R.color.ripple_material_light) { + || id == R.color.ripple_material_light + || id == R.color.ripple_material_dark) { return new ColorDrawable(); } else if (id == R.drawable.ic_launcher_settings) { // ic_launcher_settings uses adaptive-icon, which is not supported by robolectric, diff --git a/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAlertDialogCompat.java b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAlertDialogCompat.java new file mode 100644 index 00000000000..a682d85e2b1 --- /dev/null +++ b/tests/robotests/src/com/android/settings/testutils/shadow/ShadowAlertDialogCompat.java @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.settings.testutils.shadow; + +import android.annotation.SuppressLint; +import android.view.View; + +import org.robolectric.Shadows; +import org.robolectric.annotation.Implementation; +import org.robolectric.annotation.Implements; +import org.robolectric.annotation.RealObject; +import org.robolectric.annotation.Resetter; +import org.robolectric.shadow.api.Shadow; +import org.robolectric.shadows.ShadowDialog; +import org.robolectric.util.ReflectionHelpers; + +import javax.annotation.Nullable; + +import androidx.appcompat.app.AlertDialog; + +/* Robolectric shadow for the androidx alert dialog. */ +@Implements(AlertDialog.class) +public class ShadowAlertDialogCompat extends ShadowDialog { + + @SuppressLint("StaticFieldLeak") + @Nullable + private static ShadowAlertDialogCompat latestSupportAlertDialog; + @RealObject + private AlertDialog realAlertDialog; + + @Implementation + public void show() { + super.show(); + latestSupportAlertDialog = this; + } + + public CharSequence getMessage() { + final Object alertController = ReflectionHelpers.getField(realAlertDialog, "mAlert"); + return ReflectionHelpers.getField(alertController, "mMessage"); + } + + public CharSequence getTitle() { + final Object alertController = ReflectionHelpers.getField(realAlertDialog, "mAlert"); + return ReflectionHelpers.getField(alertController, "mTitle"); + } + + public View getView() { + final Object alertController = ReflectionHelpers.getField(realAlertDialog, "mAlert"); + return ReflectionHelpers.getField(alertController, "mView"); + } + + @Nullable + public static AlertDialog getLatestAlertDialog() { + return latestSupportAlertDialog == null ? null : latestSupportAlertDialog.realAlertDialog; + } + + @Resetter + public static void reset() { + latestSupportAlertDialog = null; + } + + public static ShadowAlertDialogCompat shadowOf(AlertDialog alertDialog) { + return (ShadowAlertDialogCompat) Shadow.extract(alertDialog); + } + + public void clickOnItem(int index) { + Shadows.shadowOf(realAlertDialog.getListView()).performItemClick(index); + } +} \ No newline at end of file