| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package org.chromium.chrome.browser; |
| |
| import android.app.Dialog; |
| import android.graphics.drawable.Drawable; |
| import android.support.graphics.drawable.VectorDrawableCompat; |
| import android.support.test.filters.LargeTest; |
| import android.support.v4.util.ObjectsCompat; |
| import android.text.SpannableString; |
| import android.view.View; |
| import android.widget.Button; |
| import android.widget.ImageView; |
| import android.widget.ListView; |
| import android.widget.TextView; |
| |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import org.chromium.base.test.util.CommandLineFlags; |
| import org.chromium.base.test.util.DisabledTest; |
| import org.chromium.base.test.util.RetryOnFailure; |
| import org.chromium.chrome.R; |
| import org.chromium.chrome.test.ChromeActivityTestRule; |
| import org.chromium.chrome.test.ChromeJUnit4ClassRunner; |
| import org.chromium.content_public.browser.test.util.Criteria; |
| import org.chromium.content_public.browser.test.util.CriteriaHelper; |
| import org.chromium.content_public.browser.test.util.TestThreadUtils; |
| import org.chromium.content_public.browser.test.util.TouchCommon; |
| import org.chromium.ui.widget.TextViewWithClickableSpans; |
| |
| /** |
| * Tests for the ItemChooserDialog class. |
| */ |
| @RunWith(ChromeJUnit4ClassRunner.class) |
| @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) |
| @RetryOnFailure |
| public class ItemChooserDialogTest implements ItemChooserDialog.ItemSelectedCallback { |
| @Rule |
| public ChromeActivityTestRule<ChromeActivity> mActivityTestRule = |
| new ChromeActivityTestRule<>(ChromeActivity.class); |
| |
| ItemChooserDialog mChooserDialog; |
| |
| String mLastSelectedId = "None"; |
| |
| Drawable mTestDrawable1; |
| String mTestDrawableDescription1; |
| |
| Drawable mTestDrawable2; |
| String mTestDrawableDescription2; |
| |
| @Before |
| public void setUp() throws Exception { |
| mActivityTestRule.startMainActivityOnBlankPage(); |
| mChooserDialog = createDialog(); |
| |
| mTestDrawable1 = getNewTestDrawable(); |
| mTestDrawableDescription1 = "icon1 description"; |
| |
| mTestDrawable2 = getNewTestDrawable(); |
| mTestDrawableDescription2 = "icon2 description"; |
| |
| Assert.assertFalse(ObjectsCompat.equals(mTestDrawable1, mTestDrawable2)); |
| } |
| |
| // ItemChooserDialog.ItemSelectedCallback: |
| |
| @Override |
| public void onItemSelected(String id) { |
| mLastSelectedId = id; |
| } |
| |
| private Drawable getNewTestDrawable() { |
| Drawable drawable = |
| VectorDrawableCompat.create(mActivityTestRule.getActivity().getResources(), |
| R.drawable.ic_bluetooth_connected, null); |
| // Calling mutate() on a Drawable should typically create a new ConstantState |
| // for that Drawable. Ensure the new drawable doesn't share a state with other |
| // drwables. |
| return drawable.mutate(); |
| } |
| |
| private ItemChooserDialog createDialog() { |
| SpannableString title = new SpannableString("title"); |
| SpannableString searching = new SpannableString("searching"); |
| SpannableString noneFound = new SpannableString("noneFound"); |
| SpannableString statusActive = new SpannableString("statusActive"); |
| SpannableString statusIdleNoneFound = new SpannableString("statusIdleNoneFound"); |
| SpannableString statusIdleSomeFound = new SpannableString("statusIdleSomeFound"); |
| String positiveButton = new String("positiveButton"); |
| final ItemChooserDialog.ItemChooserLabels labels = |
| new ItemChooserDialog.ItemChooserLabels(title, searching, noneFound, statusActive, |
| statusIdleNoneFound, statusIdleSomeFound, positiveButton); |
| ItemChooserDialog dialog = TestThreadUtils.runOnUiThreadBlockingNoException(() -> { |
| ItemChooserDialog dialog1 = new ItemChooserDialog( |
| mActivityTestRule.getActivity(), ItemChooserDialogTest.this, labels); |
| return dialog1; |
| }); |
| return dialog; |
| } |
| |
| private void selectItem(Dialog dialog, int position, String expectedItemId, |
| boolean expectedEnabledState) { |
| final ListView items = (ListView) dialog.findViewById(R.id.items); |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| |
| CriteriaHelper.pollUiThread(new Criteria() { |
| @Override |
| public boolean isSatisfied() { |
| return items.getChildAt(0) != null; |
| } |
| }); |
| |
| // Verify first item selected gets selected. |
| TouchCommon.singleClickView(items.getChildAt(position - 1)); |
| |
| CriteriaHelper.pollUiThread( |
| Criteria.equals(expectedEnabledState, () -> button.isEnabled())); |
| |
| if (!expectedEnabledState) return; |
| |
| TouchCommon.singleClickView(button); |
| |
| CriteriaHelper.pollUiThread( |
| Criteria.equals(expectedItemId, () -> mLastSelectedId)); |
| } |
| |
| private View getRowView(Dialog dialog, int position) { |
| ListView items = (ListView) dialog.findViewById(R.id.items); |
| int actualPosition = position - 1; |
| int first = items.getFirstVisiblePosition(); |
| int last = items.getLastVisiblePosition(); |
| |
| if (actualPosition < first || actualPosition > last) { |
| return items.getAdapter().getView(actualPosition, null, items); |
| } else { |
| final int visiblePos = actualPosition - first; |
| return items.getChildAt(visiblePos); |
| } |
| } |
| |
| private ImageView getIconImageView(Dialog dialog, int position) { |
| return (ImageView) getRowView(dialog, position).findViewById(R.id.icon); |
| } |
| |
| private TextView getDescriptionTextView(Dialog dialog, int position) { |
| return (TextView) getRowView(dialog, position).findViewById(R.id.description); |
| } |
| |
| @Test |
| @LargeTest |
| public void testAddItemsWithNoIcons() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| { |
| // Add item 1 with no icon. |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.GONE, icon1.getVisibility()); |
| Assert.assertEquals(null, icon1.getDrawable()); |
| } |
| |
| { |
| // Add item 2 with no icon. |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| ImageView icon2 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.GONE, icon2.getVisibility()); |
| Assert.assertEquals(null, icon2.getDrawable()); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testAddItemsWithIcons() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| { |
| // Add item 1 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable1, icon1.getDrawable()); |
| Assert.assertEquals(mTestDrawableDescription1, icon1.getContentDescription()); |
| } |
| |
| { |
| // Add item 2 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key2", "desc2", mTestDrawable2, mTestDrawableDescription2); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable1, icon1.getDrawable()); |
| Assert.assertEquals(mTestDrawableDescription1, icon1.getContentDescription()); |
| ImageView icon2 = getIconImageView(dialog, 2); |
| Assert.assertEquals(View.VISIBLE, icon2.getVisibility()); |
| Assert.assertEquals(mTestDrawable2, icon2.getDrawable()); |
| Assert.assertEquals(mTestDrawableDescription2, icon2.getContentDescription()); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testAddItemWithIconAfterItemWithNoIcon() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| { |
| // Add item 1 with no icon. |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.GONE, icon1.getVisibility()); |
| Assert.assertEquals(null, icon1.getDrawable()); |
| } |
| |
| { |
| // Add item 2 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key2", "desc2", mTestDrawable2, mTestDrawableDescription2); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| ImageView icon2 = getIconImageView(dialog, 2); |
| Assert.assertEquals(View.INVISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(View.VISIBLE, icon2.getVisibility()); |
| Assert.assertEquals(mTestDrawable2, icon2.getDrawable()); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testAddItemWithNoIconAfterItemWithIcon() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| { |
| // Add item 1 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable1, icon1.getDrawable()); |
| } |
| |
| { |
| // Add item 2 with no icon. |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| ImageView icon2 = getIconImageView(dialog, 2); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable1, icon1.getDrawable()); |
| Assert.assertEquals(View.INVISIBLE, icon2.getVisibility()); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testRemoveItemWithIconNoItemsWithIconsLeft() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| { |
| // Add item 1 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable1, icon1.getDrawable()); |
| } |
| |
| { |
| // Add item 2 with no icon. |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| ImageView icon2 = getIconImageView(dialog, 2); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(View.INVISIBLE, icon2.getVisibility()); |
| } |
| |
| { |
| // Remove item 1 with icon. No items with icons left. |
| mChooserDialog.removeItemFromList("key1"); |
| ImageView icon2 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.GONE, icon2.getVisibility()); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testRemoveItemWithIconOneItemWithIconLeft() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| { |
| // Add item 1 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| } |
| |
| { |
| // Add item 2 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key2", "desc2", mTestDrawable2, mTestDrawableDescription2); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| ImageView icon2 = getIconImageView(dialog, 2); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(View.VISIBLE, icon2.getVisibility()); |
| } |
| |
| { |
| // Add item 3 with no icon. |
| mChooserDialog.addOrUpdateItem("key3", "desc3"); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| ImageView icon2 = getIconImageView(dialog, 2); |
| ImageView icon3 = getIconImageView(dialog, 3); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(View.VISIBLE, icon2.getVisibility()); |
| Assert.assertEquals(View.INVISIBLE, icon3.getVisibility()); |
| } |
| |
| { |
| mChooserDialog.removeItemFromList("key1"); |
| ImageView icon2 = getIconImageView(dialog, 1); |
| ImageView icon3 = getIconImageView(dialog, 2); |
| Assert.assertEquals(View.VISIBLE, icon2.getVisibility()); |
| Assert.assertEquals(mTestDrawable2, icon2.getDrawable()); |
| Assert.assertEquals(View.INVISIBLE, icon3.getVisibility()); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testUpdateItemWithIconToNoIcon() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| |
| { |
| // Add item 1 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawableDescription1, icon1.getContentDescription()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1)); |
| } |
| |
| { |
| // Update item 1 to no icon. |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.GONE, icon1.getVisibility()); |
| Assert.assertEquals(null, icon1.getContentDescription()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testUpdateItemWithNoIconToIcon() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| |
| { |
| // Add item 1 to no icon. |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.GONE, icon1.getVisibility()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| } |
| |
| { |
| // Update item 1 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable1, icon1.getDrawable()); |
| Assert.assertEquals(mTestDrawableDescription1, icon1.getContentDescription()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1)); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testUpdateItemIcon() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| |
| { |
| // Update item 1 with icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable1, icon1.getDrawable()); |
| Assert.assertEquals(mTestDrawableDescription1, icon1.getContentDescription()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", mTestDrawable1, mTestDrawableDescription1)); |
| } |
| |
| { |
| // Update item 1 with different icon. |
| mChooserDialog.addOrUpdateItem( |
| "key1", "desc1", mTestDrawable2, mTestDrawableDescription2); |
| ImageView icon1 = getIconImageView(dialog, 1); |
| Assert.assertEquals(View.VISIBLE, icon1.getVisibility()); |
| Assert.assertEquals(mTestDrawable2, icon1.getDrawable()); |
| Assert.assertEquals(mTestDrawableDescription2, icon1.getContentDescription()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", mTestDrawable2, mTestDrawableDescription2)); |
| } |
| |
| mChooserDialog.setIdleState(); |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| @DisabledTest(message = "crbug.com/958558") |
| public void testSimpleItemSelection() { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| TextViewWithClickableSpans statusView = (TextViewWithClickableSpans) |
| dialog.findViewById(R.id.status); |
| final ListView items = (ListView) dialog.findViewById(R.id.items); |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| |
| // Before we add items to the dialog, the 'searching' message should be |
| // showing, the Commit button should be disabled and the list view hidden. |
| Assert.assertEquals("searching", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| Assert.assertEquals(View.GONE, items.getVisibility()); |
| |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| }); |
| |
| // Two items showing, the empty view should be no more and the button |
| // should now be enabled. |
| Assert.assertEquals(View.VISIBLE, items.getVisibility()); |
| Assert.assertEquals(View.GONE, items.getEmptyView().getVisibility()); |
| Assert.assertEquals("statusActive", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| |
| TestThreadUtils.runOnUiThreadBlocking(() -> { mChooserDialog.setIdleState(); }); |
| |
| // After discovery stops the list should be visible with two items, |
| // it should not show the empty view and the button should not be enabled. |
| // The chooser should show the status idle text. |
| Assert.assertEquals(View.VISIBLE, items.getVisibility()); |
| Assert.assertEquals(View.GONE, items.getEmptyView().getVisibility()); |
| Assert.assertEquals("statusIdleSomeFound", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| |
| // Select the first item and verify it got selected. |
| selectItem(dialog, 1, "key1", true); |
| Assert.assertTrue(getDescriptionTextView(dialog, 1).isSelected()); |
| |
| mChooserDialog.dismiss(); |
| } |
| |
| @Test |
| @LargeTest |
| public void testNoItemsAddedDiscoveryIdle() { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| TextViewWithClickableSpans statusView = (TextViewWithClickableSpans) |
| dialog.findViewById(R.id.status); |
| final ListView items = (ListView) dialog.findViewById(R.id.items); |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| |
| // Before we add items to the dialog, the 'searching' message should be |
| // showing, the Commit button should be disabled and the list view hidden. |
| Assert.assertEquals("searching", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| Assert.assertEquals(View.GONE, items.getVisibility()); |
| |
| TestThreadUtils.runOnUiThreadBlocking(() -> { mChooserDialog.setIdleState(); }); |
| |
| // Listview should now be showing empty, with an empty view visible to |
| // drive home the point and a status message at the bottom. |
| Assert.assertEquals(View.GONE, items.getVisibility()); |
| Assert.assertEquals(View.VISIBLE, items.getEmptyView().getVisibility()); |
| Assert.assertEquals("statusIdleNoneFound", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| |
| mChooserDialog.dismiss(); |
| } |
| |
| @Test |
| @LargeTest |
| public void testDisabledSelection() { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| }); |
| |
| // Disable one item and try to select it. |
| mChooserDialog.setEnabled("key1", false); |
| selectItem(dialog, 1, "None", false); |
| // The other is still selectable. |
| selectItem(dialog, 2, "key2", true); |
| |
| mChooserDialog.dismiss(); |
| } |
| |
| @Test |
| @LargeTest |
| public void testSelectOneItemThenDisableTheSelectedItem() throws Throwable { |
| final Dialog dialog = TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog1 = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog1.isShowing()); |
| |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| return dialog1; |
| }); |
| |
| selectItem(dialog, 1, "key1", true); |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| Assert.assertEquals("key1", itemAdapter.getSelectedItemKey()); |
| mChooserDialog.setEnabled("key1", false); |
| // The selected item is disabled, so no item is selected. |
| Assert.assertEquals("", itemAdapter.getSelectedItemKey()); |
| mChooserDialog.setEnabled("key1", true); |
| // The disabled item is not automatically selected again when it is re-enabled. |
| Assert.assertEquals("", itemAdapter.getSelectedItemKey()); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testPairButtonDisabledOrEnabledAfterSelectedItemDisabledOrEnabled() |
| throws Throwable { |
| final Dialog dialog = TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog1 = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog1.isShowing()); |
| |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| return dialog1; |
| }); |
| |
| selectItem(dialog, 1, "key1", true); |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| Assert.assertTrue(button.isEnabled()); |
| |
| mChooserDialog.setEnabled("key1", false); |
| Assert.assertFalse(button.isEnabled()); |
| |
| mChooserDialog.setEnabled("key1", true); |
| // The disabled item is not automatically selected again when it is re-enabled, |
| // so the button is still disabled. |
| Assert.assertFalse(button.isEnabled()); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testPairButtonDisabledAfterSelectedItemRemoved() throws Throwable { |
| final Dialog dialog = TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog1 = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog1.isShowing()); |
| |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| |
| return dialog1; |
| }); |
| |
| selectItem(dialog, 1, "key1", true); |
| |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| Assert.assertTrue(button.isEnabled()); |
| |
| mChooserDialog.removeItemFromList("key1"); |
| Assert.assertFalse(button.isEnabled()); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testSelectAnItemAndRemoveAnotherItem() throws Throwable { |
| final Dialog dialog = TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog1 = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog1.isShowing()); |
| |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| mChooserDialog.addOrUpdateItem("key3", "desc3"); |
| return dialog1; |
| }); |
| selectItem(dialog, 2, "key2", true); |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| |
| Assert.assertTrue(button.isEnabled()); |
| |
| // Remove the item before the currently selected item. |
| mChooserDialog.removeItemFromList("key1"); |
| Assert.assertTrue(button.isEnabled()); |
| Assert.assertEquals("key2", itemAdapter.getSelectedItemKey()); |
| |
| // Remove the item after the currently selected item. |
| mChooserDialog.removeItemFromList("key3"); |
| Assert.assertTrue(button.isEnabled()); |
| Assert.assertEquals("key2", itemAdapter.getSelectedItemKey()); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testSelectAnItemAndRemoveTheSelectedItem() throws Throwable { |
| final Dialog dialog = TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog1 = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog1.isShowing()); |
| |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| mChooserDialog.addOrUpdateItem("key3", "desc3"); |
| return dialog1; |
| }); |
| |
| selectItem(dialog, 2, "key2", true); |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Button button = (Button) dialog.findViewById(R.id.positive); |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| Assert.assertTrue(button.isEnabled()); |
| |
| // Remove the selected item. |
| mChooserDialog.removeItemFromList("key2"); |
| Assert.assertFalse(button.isEnabled()); |
| Assert.assertEquals("", itemAdapter.getSelectedItemKey()); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testUpdateItemAndRemoveItemFromList() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| TextViewWithClickableSpans statusView = |
| (TextViewWithClickableSpans) dialog.findViewById(R.id.status); |
| final ListView items = (ListView) dialog.findViewById(R.id.items); |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| final String nonExistentKey = "key"; |
| |
| // Initially the itemAdapter is empty. |
| Assert.assertTrue(itemAdapter.isEmpty()); |
| |
| // Try removing an item from an empty itemAdapter. |
| mChooserDialog.removeItemFromList(nonExistentKey); |
| Assert.assertTrue(itemAdapter.isEmpty()); |
| |
| // Add item 1. |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| Assert.assertEquals(1, itemAdapter.getCount()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| |
| // Update item 1 with different description. |
| mChooserDialog.addOrUpdateItem("key1", "desc2"); |
| Assert.assertEquals(1, itemAdapter.getCount()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc2", null /* icon */, null /* iconDescription */)); |
| |
| mChooserDialog.setIdleState(); |
| |
| // Remove item 1. |
| mChooserDialog.removeItemFromList("key1"); |
| Assert.assertTrue(itemAdapter.isEmpty()); |
| |
| // Listview should now be showing empty, with an empty view visible |
| // and the button should not be enabled. |
| // The chooser should show a status message at the bottom. |
| Assert.assertEquals(View.GONE, items.getVisibility()); |
| Assert.assertEquals(View.VISIBLE, items.getEmptyView().getVisibility()); |
| Assert.assertEquals("statusIdleNoneFound", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testAddItemAndRemoveItemFromList() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| TextViewWithClickableSpans statusView = |
| (TextViewWithClickableSpans) dialog.findViewById(R.id.status); |
| final ListView items = (ListView) dialog.findViewById(R.id.items); |
| final Button button = (Button) dialog.findViewById(R.id.positive); |
| |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| final String nonExistentKey = "key"; |
| |
| // Initially the itemAdapter is empty. |
| Assert.assertTrue(itemAdapter.isEmpty()); |
| |
| // Try removing an item from an empty itemAdapter. |
| mChooserDialog.removeItemFromList(nonExistentKey); |
| Assert.assertTrue(itemAdapter.isEmpty()); |
| |
| // Add item 1. |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| Assert.assertEquals(1, itemAdapter.getCount()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| |
| // Add item 2. |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| Assert.assertEquals(2, itemAdapter.getCount()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| Assert.assertTrue(itemAdapter.getItem(1).hasSameContents( |
| "key2", "desc2", null /* icon */, null /* iconDescription */)); |
| |
| mChooserDialog.setIdleState(); |
| |
| // Try removing an item that doesn't exist. |
| mChooserDialog.removeItemFromList(nonExistentKey); |
| Assert.assertEquals(2, itemAdapter.getCount()); |
| |
| // Remove item 2. |
| mChooserDialog.removeItemFromList("key2"); |
| Assert.assertEquals(1, itemAdapter.getCount()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| |
| // The list should be visible with one item, it should not show |
| // the empty view and the button should not be enabled. |
| // The chooser should show a status message at the bottom. |
| Assert.assertEquals(View.VISIBLE, items.getVisibility()); |
| Assert.assertEquals(View.GONE, items.getEmptyView().getVisibility()); |
| Assert.assertEquals("statusIdleSomeFound", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| |
| // Remove item 1. |
| mChooserDialog.removeItemFromList("key1"); |
| Assert.assertTrue(itemAdapter.isEmpty()); |
| |
| // Listview should now be showing empty, with an empty view visible |
| // and the button should not be enabled. |
| // The chooser should show a status message at the bottom. |
| Assert.assertEquals(View.GONE, items.getVisibility()); |
| Assert.assertEquals(View.VISIBLE, items.getEmptyView().getVisibility()); |
| Assert.assertEquals("statusIdleNoneFound", statusView.getText().toString()); |
| Assert.assertFalse(button.isEnabled()); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testAddItemWithSameNameToListAndRemoveItemFromList() throws Throwable { |
| TestThreadUtils.runOnUiThreadBlocking(() -> { |
| Dialog dialog = mChooserDialog.getDialogForTesting(); |
| Assert.assertTrue(dialog.isShowing()); |
| |
| ItemChooserDialog.ItemAdapter itemAdapter = mChooserDialog.getItemAdapterForTesting(); |
| |
| // Add item 1. |
| mChooserDialog.addOrUpdateItem("key1", "desc1"); |
| Assert.assertEquals(1, itemAdapter.getCount()); |
| // Add item 2. |
| mChooserDialog.addOrUpdateItem("key2", "desc2"); |
| Assert.assertEquals(2, itemAdapter.getCount()); |
| // Add item 3 with same description as item 1. |
| mChooserDialog.addOrUpdateItem("key3", "desc1"); |
| Assert.assertEquals(3, itemAdapter.getCount()); |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| Assert.assertTrue(itemAdapter.getItem(1).hasSameContents( |
| "key2", "desc2", null /* icon */, null /* iconDescription */)); |
| Assert.assertTrue(itemAdapter.getItem(2).hasSameContents( |
| "key3", "desc1", null /* icon */, null /* iconDescription */)); |
| |
| // Since two items have the same name, their display text should have their unique |
| // keys appended. |
| Assert.assertEquals("desc1 (key1)", itemAdapter.getDisplayText(0)); |
| Assert.assertEquals("desc2", itemAdapter.getDisplayText(1)); |
| Assert.assertEquals("desc1 (key3)", itemAdapter.getDisplayText(2)); |
| |
| // Remove item 2. |
| mChooserDialog.removeItemFromList("key2"); |
| Assert.assertEquals(2, itemAdapter.getCount()); |
| // Make sure the remaining items are item 1 and item 3. |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key1", "desc1", null /* icon */, null /* iconDescription */)); |
| Assert.assertTrue(itemAdapter.getItem(1).hasSameContents( |
| "key3", "desc1", null /* icon */, null /* iconDescription */)); |
| Assert.assertEquals("desc1 (key1)", itemAdapter.getDisplayText(0)); |
| Assert.assertEquals("desc1 (key3)", itemAdapter.getDisplayText(1)); |
| |
| // Remove item 1. |
| mChooserDialog.removeItemFromList("key1"); |
| Assert.assertEquals(1, itemAdapter.getCount()); |
| // Make sure the remaining item is item 3. |
| Assert.assertTrue(itemAdapter.getItem(0).hasSameContents( |
| "key3", "desc1", null /* icon */, null /* iconDescription */)); |
| // After removing item 1, item 3 is the only remaining item, so its display text |
| // also changed to its original description. |
| Assert.assertEquals("desc1", itemAdapter.getDisplayText(0)); |
| |
| mChooserDialog.dismiss(); |
| }); |
| } |
| |
| @Test |
| @LargeTest |
| public void testListHeight() { |
| // 500 * .3 is 150, which is 48 * 3.125. 48 * 3.5 is 168. |
| Assert.assertEquals(168, ItemChooserDialog.getListHeight(500, 1.0f)); |
| |
| // 150 * .3 is 45, which rounds below the minimum height. |
| Assert.assertEquals(72, ItemChooserDialog.getListHeight(150, 1.0f)); |
| |
| // 1460 * .3 is 438, which rounds above the maximum height. |
| Assert.assertEquals(408, ItemChooserDialog.getListHeight(1460, 1.0f)); |
| |
| // 1100px is 500dp at a density of 2.2. 500 * .3 is 150dp, which is 48dp * |
| // 3.125. 48dp * 3.5 is 168dp. 168dp * 2.2px/dp is 369.6, which rounds to |
| // 370. |
| Assert.assertEquals(370, ItemChooserDialog.getListHeight(1100, 2.2f)); |
| } |
| } |