diff --git a/tests/unit/src/com/android/settings/slices/SliceTestUtils.java b/tests/unit/src/com/android/settings/slices/SliceTestUtils.java
deleted file mode 100644
index 020bde2..0000000
--- a/tests/unit/src/com/android/settings/slices/SliceTestUtils.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2020 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.slices;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.provider.SettingsSlicesContract;
-
-import com.android.settings.testutils.FakeIndexProvider;
-import com.android.settings.testutils.FakeToggleController;
-
-class SliceTestUtils {
-
-    public static final String FAKE_TITLE = "title";
-    public static final String FAKE_SUMMARY = "summary";
-    public static final String FAKE_SCREEN_TITLE = "screen_title";
-    public static final String FAKE_KEYWORDS = "a, b, c";
-    public static final int FAKE_ICON = 1234;
-    public static final String FAKE_FRAGMENT_NAME = FakeIndexProvider.class.getName();
-    public static final String FAKE_CONTROLLER_NAME = FakeToggleController.class.getName();
-    public static final int FAKE_HIGHLIGHT_MENU_RES = FakeToggleController.HIGHLIGHT_MENU_RES;
-
-
-    public static void insertSliceToDb(Context context, String key) {
-        insertSliceToDb(context, key, true /* isPlatformSlice */);
-    }
-
-    public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice) {
-        insertSliceToDb(context, key, isPlatformSlice, null /*customizedUnavailableSliceSubtitle*/);
-    }
-
-    public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
-            String customizedUnavailableSliceSubtitle) {
-        insertSliceToDb(context, key, isPlatformSlice, customizedUnavailableSliceSubtitle, false);
-    }
-
-    public static void insertSliceToDb(Context context, String key, boolean isPlatformSlice,
-            String customizedUnavailableSliceSubtitle, boolean isPublicSlice) {
-        final SQLiteDatabase db = SlicesDatabaseHelper.getInstance(context).getWritableDatabase();
-        ContentValues values = new ContentValues();
-        values.put(SlicesDatabaseHelper.IndexColumns.KEY, key);
-        values.put(SlicesDatabaseHelper.IndexColumns.SLICE_URI,
-                new Uri.Builder()
-                        .scheme(ContentResolver.SCHEME_CONTENT)
-                        .authority(isPlatformSlice
-                                ? SettingsSlicesContract.AUTHORITY
-                                : SettingsSliceProvider.SLICE_AUTHORITY)
-                        .appendPath(SettingsSlicesContract.PATH_SETTING_ACTION)
-                        .appendPath(key)
-                        .build().toString());
-        values.put(SlicesDatabaseHelper.IndexColumns.TITLE, FAKE_TITLE);
-        values.put(SlicesDatabaseHelper.IndexColumns.SUMMARY, FAKE_SUMMARY);
-        values.put(SlicesDatabaseHelper.IndexColumns.SCREENTITLE, FAKE_SCREEN_TITLE);
-        values.put(SlicesDatabaseHelper.IndexColumns.KEYWORDS, FAKE_KEYWORDS);
-        values.put(SlicesDatabaseHelper.IndexColumns.ICON_RESOURCE, FAKE_ICON);
-        values.put(SlicesDatabaseHelper.IndexColumns.FRAGMENT, FAKE_FRAGMENT_NAME);
-        values.put(SlicesDatabaseHelper.IndexColumns.CONTROLLER, FAKE_CONTROLLER_NAME);
-        values.put(SlicesDatabaseHelper.IndexColumns.SLICE_TYPE, SliceData.SliceType.INTENT);
-        values.put(SlicesDatabaseHelper.IndexColumns.UNAVAILABLE_SLICE_SUBTITLE,
-                customizedUnavailableSliceSubtitle);
-        values.put(SlicesDatabaseHelper.IndexColumns.PUBLIC_SLICE, isPublicSlice);
-        values.put(SlicesDatabaseHelper.IndexColumns.HIGHLIGHT_MENU_RESOURCE,
-                FAKE_HIGHLIGHT_MENU_RES);
-
-        db.replaceOrThrow(SlicesDatabaseHelper.Tables.TABLE_SLICES_INDEX, null, values);
-        db.close();
-    }
-}
diff --git a/tests/unit/src/com/android/settings/testutils/AirplaneModeRule.java b/tests/unit/src/com/android/settings/testutils/AirplaneModeRule.java
deleted file mode 100644
index 459ac15..0000000
--- a/tests/unit/src/com/android/settings/testutils/AirplaneModeRule.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import android.content.ContentResolver;
-import android.content.Context;
-import android.provider.Settings;
-import android.util.Log;
-
-import androidx.test.core.app.ApplicationProvider;
-
-import org.junit.rules.ExternalResource;
-
-/** A test rule that is used to manager the Airplane Mode resource for testing. */
-public final class AirplaneModeRule extends ExternalResource {
-
-    private static final String TAG = "AirplaneModeRule";
-
-    private Context mContext;
-    private ContentResolver mContentResolver;
-    private boolean mBackupValue;
-    private boolean mShouldRestore;
-
-    @Override
-    protected void before() throws Throwable {
-        mContext = ApplicationProvider.getApplicationContext();
-        mContentResolver = mContext.getContentResolver();
-    }
-
-    @Override
-    protected void after() {
-        if (!mShouldRestore) {
-            return;
-        }
-        Log.d(TAG, "Restore Airplane Mode value:" + mBackupValue);
-        Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON,
-                mBackupValue ? 1 : 0);
-    }
-
-    public void setAirplaneMode(boolean enable) {
-        if (enable == isAirplaneModeOn()) {
-            return;
-        }
-        if (!mShouldRestore) {
-            mShouldRestore = true;
-            mBackupValue = !enable;
-            Log.d(TAG, "Backup Airplane Mode value:" + mBackupValue);
-        }
-        Log.d(TAG, "Set Airplane Mode enable:" + enable);
-        Settings.Global.putInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, enable ? 1 : 0);
-    }
-
-    public boolean isAirplaneModeOn() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-            Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
-    }
-}
diff --git a/tests/unit/src/com/android/settings/testutils/FakeIndexProvider.java b/tests/unit/src/com/android/settings/testutils/FakeIndexProvider.java
deleted file mode 100644
index 5cbfb54..0000000
--- a/tests/unit/src/com/android/settings/testutils/FakeIndexProvider.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import android.content.Context;
-
-import com.android.settings.R;
-import com.android.settings.search.BaseSearchIndexProvider;
-import com.android.settingslib.search.Indexable;
-
-import java.util.List;
-
-public class FakeIndexProvider implements Indexable {
-
-    public static final String KEY = "TestKey";
-
-    /**
-     * The fake SearchIndexProvider. Note that the use of location_settings below implies that tests
-     * using this should be using the res/xml-mcc999/location_settings.xml or
-     * res/xml-mcc998/location_settings.xml. Annotate tests with
-     * {@code @Config(qualifiers = "mcc999")}.
-     */
-    public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
-            new BaseSearchIndexProvider(R.xml.location_settings) {
-
-                @Override
-                public List<String> getNonIndexableKeys(Context context) {
-                    List<String> result = super.getNonIndexableKeys(context);
-                    result.add(KEY);
-                    return result;
-                }
-            };
-}
diff --git a/tests/unit/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java b/tests/unit/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java
deleted file mode 100644
index 97379e3..0000000
--- a/tests/unit/src/com/android/settings/testutils/FakeUnavailablePreferenceController.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import android.content.Context;
-import android.provider.Settings;
-
-import com.android.settings.core.BasePreferenceController;
-
-public class FakeUnavailablePreferenceController extends BasePreferenceController {
-
-    public static final String AVAILABILITY_KEY = "fake_availability_key";
-
-    public FakeUnavailablePreferenceController(Context context) {
-        super(context, "key");
-    }
-
-    @Override
-    public int getAvailabilityStatus() {
-        return Settings.Global.getInt(mContext.getContentResolver(), AVAILABILITY_KEY, 0);
-    }
-
-    @Override
-    public boolean isSliceable() {
-        return true;
-    }
-}
diff --git a/tests/unit/src/com/android/settings/testutils/ResolveInfoBuilder.java b/tests/unit/src/com/android/settings/testutils/ResolveInfoBuilder.java
deleted file mode 100644
index 5eaf2a4..0000000
--- a/tests/unit/src/com/android/settings/testutils/ResolveInfoBuilder.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-
-import com.google.common.base.Preconditions;
-
-/**
- * Helper for building {@link ResolveInfo}s to be used in Robolectric tests.
- *
- * <p>The resulting {@link PackageInfo}s should typically be added to {@link
- * org.robolectric.shadows.ShadowPackageManager#addResolveInfoForIntent(Intent, ResolveInfo)}.
- */
-public final class ResolveInfoBuilder {
-
-    private final String mPackageName;
-    private ActivityInfo mActivityInfo;
-    private ProviderInfo mProviderInfo;
-
-    public ResolveInfoBuilder(String packageName) {
-        this.mPackageName = Preconditions.checkNotNull(packageName);
-    }
-
-    public ResolveInfoBuilder setActivity(String packageName, String className) {
-        mActivityInfo = new ActivityInfo();
-        mActivityInfo.packageName = packageName;
-        mActivityInfo.name = className;
-        return this;
-    }
-
-    public ResolveInfoBuilder setProvider(
-            String packageName, String className, String authority, boolean isSystemApp) {
-        mProviderInfo = new ProviderInfo();
-        mProviderInfo.authority = authority;
-        mProviderInfo.applicationInfo = new ApplicationInfo();
-        if (isSystemApp) {
-            mProviderInfo.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
-        }
-        mProviderInfo.packageName = mPackageName;
-        mProviderInfo.applicationInfo.packageName  = mPackageName;
-        mProviderInfo.name = className;
-        return this;
-    }
-
-    public ResolveInfo build() {
-        ResolveInfo info = new ResolveInfo();
-        info.activityInfo = mActivityInfo;
-        info.resolvePackageName = mPackageName;
-        info.providerInfo = mProviderInfo;
-        return info;
-    }
-}
diff --git a/tests/unit/src/com/android/settings/testutils/SliceTester.java b/tests/unit/src/com/android/settings/testutils/SliceTester.java
deleted file mode 100644
index be13e13..0000000
--- a/tests/unit/src/com/android/settings/testutils/SliceTester.java
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * Copyright (C) 2020 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;
-
-import static android.app.slice.Slice.HINT_TITLE;
-import static android.app.slice.Slice.SUBTYPE_COLOR;
-import static android.app.slice.SliceItem.FORMAT_IMAGE;
-import static android.app.slice.SliceItem.FORMAT_INT;
-import static android.app.slice.SliceItem.FORMAT_TEXT;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.app.PendingIntent;
-import android.content.Context;
-import android.text.TextUtils;
-
-import androidx.core.graphics.drawable.IconCompat;
-import androidx.slice.Slice;
-import androidx.slice.SliceItem;
-import androidx.slice.SliceMetadata;
-import androidx.slice.builders.ListBuilder;
-import androidx.slice.core.SliceAction;
-import androidx.slice.core.SliceQuery;
-import androidx.slice.widget.EventInfo;
-
-import com.android.settings.Utils;
-import com.android.settings.slices.SettingsSliceProvider;
-import com.android.settings.slices.SliceBuilderUtils;
-import com.android.settings.slices.SliceData;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Testing utility class to verify the contents of the different Settings Slices.
- *
- * TODO (77712944) check Summary, range (metadata.getRange()), toggle icons.
- */
-public class SliceTester {
-
-    /**
-     * Test the contents of an intent based slice, including:
-     * - No toggles
-     * - Correct intent
-     * - Correct title
-     * - Correct keywords
-     * - TTL
-     * - Color
-     */
-    public static void testSettingsIntentSlice(Context context, Slice slice, SliceData sliceData) {
-        final SliceMetadata metadata = SliceMetadata.from(context, slice);
-
-        final long sliceTTL = metadata.getExpiry();
-        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
-
-        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
-        final int color = colorItem.getInt();
-        assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
-
-        final List<SliceAction> toggles = metadata.getToggles();
-        assertThat(toggles).isEmpty();
-
-        final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
-        assertThat(primaryPendingIntent).isEqualTo(
-                SliceBuilderUtils.getContentPendingIntent(context, sliceData));
-
-        assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
-
-        assertKeywords(metadata, sliceData);
-    }
-
-    /**
-     * Test the contents of an toggle based slice, including:
-     * - Contains one toggle
-     * - Correct toggle intent
-     * - Correct content intent
-     * - Correct title
-     * - Correct keywords
-     * - TTL
-     * - Color
-     */
-    public static void testSettingsToggleSlice(Context context, Slice slice, SliceData sliceData) {
-        final SliceMetadata metadata = SliceMetadata.from(context, slice);
-
-        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
-        final int color = colorItem.getInt();
-        assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
-
-        final List<SliceAction> toggles = metadata.getToggles();
-        assertThat(toggles).hasSize(1);
-
-        final long sliceTTL = metadata.getExpiry();
-        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
-
-        final SliceAction mainToggleAction = toggles.get(0);
-
-        assertThat(mainToggleAction.getIcon()).isNull();
-
-        // Check intent in Toggle Action
-        final PendingIntent togglePendingIntent = mainToggleAction.getAction();
-        assertThat(togglePendingIntent).isEqualTo(SliceBuilderUtils.getActionIntent(context,
-                SettingsSliceProvider.ACTION_TOGGLE_CHANGED, sliceData));
-
-        // Check primary intent
-        final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
-        assertThat(primaryPendingIntent).isEqualTo(
-                SliceBuilderUtils.getContentPendingIntent(context, sliceData));
-
-        assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
-
-        assertKeywords(metadata, sliceData);
-    }
-
-    /**
-     * Test the contents of an slider based slice, including:
-     * - No intent
-     * - Correct title
-     * - Correct keywords
-     * - TTL
-     * - Color
-     */
-    public static void testSettingsSliderSlice(Context context, Slice slice, SliceData sliceData) {
-        final SliceMetadata metadata = SliceMetadata.from(context, slice);
-        final SliceAction primaryAction = metadata.getPrimaryAction();
-
-        final IconCompat icon = primaryAction.getIcon();
-        if (icon == null) {
-            final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
-            final int color = colorItem.getInt();
-            assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
-
-        } else {
-            final IconCompat expectedIcon = IconCompat.createWithResource(context,
-                    sliceData.getIconResource());
-            assertThat(expectedIcon.toString()).isEqualTo(icon.toString());
-        }
-
-        final long sliceTTL = metadata.getExpiry();
-        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
-
-        final int headerType = metadata.getHeaderType();
-        assertThat(headerType).isEqualTo(EventInfo.ROW_TYPE_SLIDER);
-
-        // Check primary intent
-        final PendingIntent primaryPendingIntent = primaryAction.getAction();
-        assertThat(primaryPendingIntent).isEqualTo(
-                SliceBuilderUtils.getContentPendingIntent(context, sliceData));
-
-        assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
-
-        assertKeywords(metadata, sliceData);
-    }
-
-    /**
-     * Test the copyable slice, including:
-     * - No intent
-     * - Correct title
-     * - Correct intent
-     * - Correct keywords
-     * - TTL
-     * - Color
-     */
-    public static void testSettingsCopyableSlice(Context context, Slice slice,
-            SliceData sliceData) {
-        final SliceMetadata metadata = SliceMetadata.from(context, slice);
-
-        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
-        final int color = colorItem.getInt();
-        assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
-
-        final SliceAction primaryAction = metadata.getPrimaryAction();
-
-        final IconCompat expectedIcon = IconCompat.createWithResource(context,
-                sliceData.getIconResource());
-        assertThat(expectedIcon.toString()).isEqualTo(primaryAction.getIcon().toString());
-
-        final long sliceTTL = metadata.getExpiry();
-        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
-
-        // Check primary intent
-        final PendingIntent primaryPendingIntent = primaryAction.getAction();
-        assertThat(primaryPendingIntent).isEqualTo(
-                SliceBuilderUtils.getContentPendingIntent(context, sliceData));
-
-        assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
-
-        assertKeywords(metadata, sliceData);
-    }
-
-    /**
-     * Test the contents of an unavailable slice, including:
-     * - No toggles
-     * - Correct title
-     * - Correct intent
-     * - Correct keywords
-     * - Color
-     * - TTL
-     */
-    public static void testSettingsUnavailableSlice(Context context, Slice slice,
-            SliceData sliceData) {
-        final SliceMetadata metadata = SliceMetadata.from(context, slice);
-
-        final long sliceTTL = metadata.getExpiry();
-        assertThat(sliceTTL).isEqualTo(ListBuilder.INFINITY);
-
-        final SliceItem colorItem = SliceQuery.findSubtype(slice, FORMAT_INT, SUBTYPE_COLOR);
-        final int color = colorItem.getInt();
-        assertThat(color).isEqualTo(Utils.getColorAccentDefaultColor(context));
-
-        final List<SliceAction> toggles = metadata.getToggles();
-        assertThat(toggles).isEmpty();
-
-        final PendingIntent primaryPendingIntent = metadata.getPrimaryAction().getAction();
-        assertThat(primaryPendingIntent).isEqualTo(SliceBuilderUtils.getContentPendingIntent(
-                context, sliceData));
-
-        assertThat(metadata.getTitle()).isEqualTo(sliceData.getTitle());
-
-        assertKeywords(metadata, sliceData);
-    }
-
-    /**
-     * Assert any slice item contains title.
-     *
-     * @param sliceItems All slice items of a Slice.
-     * @param title Title for asserting.
-     */
-    public static void assertAnySliceItemContainsTitle(List<SliceItem> sliceItems, String title) {
-        assertThat(hasText(sliceItems, title, HINT_TITLE)).isTrue();
-    }
-
-    /**
-     * Assert any slice item contains subtitle.
-     *
-     * @param sliceItems All slice items of a Slice.
-     * @param subtitle Subtitle for asserting.
-     */
-    public static void assertAnySliceItemContainsSubtitle(List<SliceItem> sliceItems,
-            String subtitle) {
-        // Subtitle has no hints
-        assertThat(hasText(sliceItems, subtitle, null /* hints */)).isTrue();
-    }
-
-    /**
-     * Assert no slice item contains subtitle.
-     *
-     * @param sliceItems All slice items of a Slice.
-     * @param subtitle Subtitle for asserting.
-     */
-    public static void assertNoSliceItemContainsSubtitle(List<SliceItem> sliceItems,
-            String subtitle) {
-        // Subtitle has no hints
-        assertThat(hasText(sliceItems, subtitle, null /* hints */)).isFalse();
-    }
-
-    private static boolean hasText(List<SliceItem> sliceItems, String text, String hints) {
-        boolean hasText = false;
-        for (SliceItem item : sliceItems) {
-            List<SliceItem> textItems = SliceQuery.findAll(item, FORMAT_TEXT, hints,
-                    null /* non-hints */);
-            if (textItems == null) {
-                continue;
-            }
-
-            for (SliceItem textItem : textItems) {
-                if (TextUtils.equals(textItem.getText(), text)) {
-                    hasText = true;
-                    break;
-                }
-            }
-        }
-        return hasText;
-    }
-
-    /**
-     * Assert any slice item contains icon.
-     *
-     * @param sliceItems All slice items of a Slice.
-     * @param icon Icon for asserting.
-     */
-    public static void assertAnySliceItemContainsIcon(List<SliceItem> sliceItems, IconCompat icon) {
-        boolean hasIcon = false;
-        for (SliceItem item : sliceItems) {
-            List<SliceItem> iconItems = SliceQuery.findAll(item, FORMAT_IMAGE,
-                    (String) null /* hints */, null /* non-hints */);
-            if (iconItems == null) {
-                continue;
-            }
-
-            for (SliceItem iconItem : iconItems) {
-                if (icon.toString().equals(iconItem.getIcon().toString())) {
-                    hasIcon = true;
-                    break;
-                }
-            }
-        }
-        assertThat(hasIcon).isTrue();
-    }
-
-    private static void assertKeywords(SliceMetadata metadata, SliceData data) {
-        final List<String> keywords = metadata.getSliceKeywords();
-        final Set<String> expectedKeywords = Arrays.stream(data.getKeywords().split(","))
-                .map(s -> s = s.trim())
-                .collect(Collectors.toSet());
-        expectedKeywords.add(data.getTitle());
-        expectedKeywords.add(data.getScreenTitle().toString());
-        assertThat(keywords).containsExactlyElementsIn(expectedKeywords);
-    }
-}
