Merge "Robotests for BluetoothPairingDialog"
This commit is contained in:
committed by
Android (Google) Code Review
commit
45a072ecac
@@ -188,7 +188,7 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
|
|||||||
*
|
*
|
||||||
* @return - The message ID to show the user.
|
* @return - The message ID to show the user.
|
||||||
*/
|
*/
|
||||||
public int getDeviceVariantMessageID() {
|
public int getDeviceVariantMessageId() {
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
|
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
|
||||||
case BluetoothDevice.PAIRING_VARIANT_PIN:
|
case BluetoothDevice.PAIRING_VARIANT_PIN:
|
||||||
@@ -198,7 +198,7 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
|
|||||||
return R.string.bluetooth_enter_passkey_other_device;
|
return R.string.bluetooth_enter_passkey_other_device;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return INVALID_DIALOG_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
|
|||||||
*
|
*
|
||||||
* @return - The message ID to show the user.
|
* @return - The message ID to show the user.
|
||||||
*/
|
*/
|
||||||
public int getDeviceVariantMessageHint() {
|
public int getDeviceVariantMessageHintId() {
|
||||||
switch (mType) {
|
switch (mType) {
|
||||||
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
|
case BluetoothDevice.PAIRING_VARIANT_PIN_16_DIGITS:
|
||||||
return R.string.bluetooth_pin_values_hint_16_digits;
|
return R.string.bluetooth_pin_values_hint_16_digits;
|
||||||
@@ -218,7 +218,7 @@ public class BluetoothPairingController implements OnCheckedChangeListener,
|
|||||||
return R.string.bluetooth_pin_values_hint;
|
return R.string.bluetooth_pin_values_hint;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return -1;
|
return INVALID_DIALOG_TYPE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,10 +45,9 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
|
|||||||
private static final String TAG = "BTPairingDialogFragment";
|
private static final String TAG = "BTPairingDialogFragment";
|
||||||
|
|
||||||
private AlertDialog.Builder mBuilder;
|
private AlertDialog.Builder mBuilder;
|
||||||
private BluetoothPairingController mPairingController;
|
|
||||||
private AlertDialog mDialog;
|
private AlertDialog mDialog;
|
||||||
|
private BluetoothPairingController mPairingController;
|
||||||
private EditText mPairingView;
|
private EditText mPairingView;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The interface we expect a listener to implement. Typically this should be done by
|
* The interface we expect a listener to implement. Typically this should be done by
|
||||||
* the controller.
|
* the controller.
|
||||||
@@ -105,12 +104,26 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
|
|||||||
return MetricsEvent.BLUETOOTH_DIALOG_FRAGMENT;
|
return MetricsEvent.BLUETOOTH_DIALOG_FRAGMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used in testing to get a reference to the dialog.
|
||||||
|
* @return - The fragments current dialog
|
||||||
|
*/
|
||||||
|
protected AlertDialog getmDialog() {
|
||||||
|
return mDialog;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the controller that the fragment should use. this method MUST be called
|
* Sets the controller that the fragment should use. this method MUST be called
|
||||||
* before you try to show the dialog or an error will be thrown. An implementation
|
* before you try to show the dialog or an error will be thrown. An implementation
|
||||||
* of a pairing controller can be found at {@link BluetoothPairingController}.
|
* of a pairing controller can be found at {@link BluetoothPairingController}. A
|
||||||
|
* controller may not be substituted once it is assigned. Forcibly switching a
|
||||||
|
* controller for a new one will lead to undefined behavior.
|
||||||
*/
|
*/
|
||||||
public void setPairingController(BluetoothPairingController pairingController) {
|
public void setPairingController(BluetoothPairingController pairingController) {
|
||||||
|
if (mPairingController != null) {
|
||||||
|
throw new IllegalStateException("The controller can only be set once. "
|
||||||
|
+ "Forcibly replacing it will lead to undefined behavior");
|
||||||
|
}
|
||||||
mPairingController = pairingController;
|
mPairingController = pairingController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +159,7 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
|
|||||||
mBuilder.setPositiveButton(getString(android.R.string.ok), this);
|
mBuilder.setPositiveButton(getString(android.R.string.ok), this);
|
||||||
mBuilder.setNegativeButton(getString(android.R.string.cancel), this);
|
mBuilder.setNegativeButton(getString(android.R.string.cancel), this);
|
||||||
AlertDialog dialog = mBuilder.create();
|
AlertDialog dialog = mBuilder.create();
|
||||||
dialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false);
|
dialog.setOnShowListener(d -> mDialog.getButton(Dialog.BUTTON_POSITIVE).setEnabled(false));
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,6 +184,7 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
|
|||||||
|
|
||||||
mPairingView = pairingView;
|
mPairingView = pairingView;
|
||||||
|
|
||||||
|
pairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||||
pairingView.addTextChangedListener(this);
|
pairingView.addTextChangedListener(this);
|
||||||
alphanumericPin.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
alphanumericPin.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||||
// change input type for soft keyboard to numeric or alphanumeric
|
// change input type for soft keyboard to numeric or alphanumeric
|
||||||
@@ -181,15 +195,21 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
int messageId = mPairingController.getDeviceVariantMessageID();
|
int messageId = mPairingController.getDeviceVariantMessageId();
|
||||||
int messageIdHint = mPairingController.getDeviceVariantMessageHint();
|
int messageIdHint = mPairingController.getDeviceVariantMessageHintId();
|
||||||
int maxLength = mPairingController.getDeviceMaxPasskeyLength();
|
int maxLength = mPairingController.getDeviceMaxPasskeyLength();
|
||||||
alphanumericPin.setVisibility(mPairingController.pairingCodeIsAlphanumeric()
|
alphanumericPin.setVisibility(mPairingController.pairingCodeIsAlphanumeric()
|
||||||
? View.VISIBLE : View.GONE);
|
? View.VISIBLE : View.GONE);
|
||||||
|
if (messageId != BluetoothPairingController.INVALID_DIALOG_TYPE) {
|
||||||
messageViewCaptionHint.setText(messageIdHint);
|
|
||||||
messageView2.setText(messageId);
|
messageView2.setText(messageId);
|
||||||
pairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
|
} else {
|
||||||
|
messageView2.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
if (messageIdHint != BluetoothPairingController.INVALID_DIALOG_TYPE) {
|
||||||
|
messageViewCaptionHint.setText(messageIdHint);
|
||||||
|
} else {
|
||||||
|
messageViewCaptionHint.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
pairingView.setFilters(new InputFilter[]{
|
pairingView.setFilters(new InputFilter[]{
|
||||||
new LengthFilter(maxLength)});
|
new LengthFilter(maxLength)});
|
||||||
|
|
||||||
@@ -203,10 +223,8 @@ public class BluetoothPairingDialogFragment extends InstrumentedDialogFragment i
|
|||||||
mBuilder.setTitle(getString(R.string.bluetooth_pairing_request,
|
mBuilder.setTitle(getString(R.string.bluetooth_pairing_request,
|
||||||
mPairingController.getDeviceName()));
|
mPairingController.getDeviceName()));
|
||||||
mBuilder.setView(createView());
|
mBuilder.setView(createView());
|
||||||
mBuilder.setPositiveButton(getString(R.string.bluetooth_pairing_accept),
|
mBuilder.setPositiveButton(getString(R.string.bluetooth_pairing_accept), this);
|
||||||
this);
|
mBuilder.setNegativeButton(getString(R.string.bluetooth_pairing_decline), this);
|
||||||
mBuilder.setNegativeButton(getString(R.string.bluetooth_pairing_decline),
|
|
||||||
this);
|
|
||||||
AlertDialog dialog = mBuilder.create();
|
AlertDialog dialog = mBuilder.create();
|
||||||
return dialog;
|
return dialog;
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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;
|
||||||
|
|
||||||
|
import org.junit.runners.model.InitializationError;
|
||||||
|
import org.robolectric.RobolectricTestRunner;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.manifest.AndroidManifest;
|
||||||
|
import org.robolectric.res.Fs;
|
||||||
|
import org.robolectric.res.ResourcePath;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom test runner for the testing of BluetoothPairingDialogs. This is needed because the
|
||||||
|
* default behavior for robolectric is just to grab the resource directory in the target package.
|
||||||
|
* We want to override this to add several spanning different projects.
|
||||||
|
*/
|
||||||
|
public class SettingsRobolectricTestRunner extends RobolectricTestRunner {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We don't actually want to change this behavior, so we just call super.
|
||||||
|
*/
|
||||||
|
public SettingsRobolectricTestRunner(Class<?> testClass) throws InitializationError {
|
||||||
|
super(testClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We are going to create our own custom manifest so that we can add multiple resource
|
||||||
|
* paths to it. This lets us access resources in both Settings and SettingsLib in our tests.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected AndroidManifest getAppManifest(Config config) {
|
||||||
|
// Using the manifest file's relative path, we can figure out the application directory.
|
||||||
|
final String appRoot = "packages/apps/Settings";
|
||||||
|
final String manifestPath = appRoot + "/AndroidManifest.xml";
|
||||||
|
final String resDir = appRoot + "/res";
|
||||||
|
final String assetsDir = appRoot + "/assets";
|
||||||
|
|
||||||
|
// By adding any resources from libraries we need to the AndroidManifest, we can access
|
||||||
|
// them from within the parallel universe's resource loader.
|
||||||
|
final AndroidManifest manifest = new AndroidManifest(Fs.fileFromPath(manifestPath),
|
||||||
|
Fs.fileFromPath(resDir), Fs.fileFromPath(assetsDir)) {
|
||||||
|
@Override
|
||||||
|
public List<ResourcePath> getIncludedResourcePaths() {
|
||||||
|
List<ResourcePath> paths = super.getIncludedResourcePaths();
|
||||||
|
paths.add(new ResourcePath(
|
||||||
|
getPackageName(),
|
||||||
|
Fs.fileFromPath("./packages/apps/Settings/res"),
|
||||||
|
null));
|
||||||
|
paths.add(new ResourcePath(
|
||||||
|
getPackageName(),
|
||||||
|
Fs.fileFromPath("./frameworks/base/packages/SettingsLib/res"),
|
||||||
|
null));
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Set the package name to the renamed one
|
||||||
|
manifest.setPackageName("com.android.settings");
|
||||||
|
return manifest;
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,340 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.bluetooth;
|
||||||
|
|
||||||
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
import static org.junit.Assert.fail;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.doNothing;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import com.android.settings.SettingsRobolectricTestRunner;
|
||||||
|
import com.android.settings.R;
|
||||||
|
import com.android.settings.TestConfig;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
import org.robolectric.annotation.Config;
|
||||||
|
import org.robolectric.util.FragmentTestUtil;
|
||||||
|
|
||||||
|
@RunWith(SettingsRobolectricTestRunner.class)
|
||||||
|
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||||
|
public class BluetoothPairingDialogTest {
|
||||||
|
|
||||||
|
private static final String FILLER = "text that goes in a view";
|
||||||
|
private static final String FAKE_DEVICE_NAME = "Fake Bluetooth Device";
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BluetoothPairingController controller;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogUpdatesControllerWithUserInput() {
|
||||||
|
// set the correct dialog type
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
|
||||||
|
|
||||||
|
// we don't care about these for this test
|
||||||
|
when(controller.getDeviceVariantMessageId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
when(controller.getDeviceVariantMessageHintId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
|
||||||
|
// build fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// test that controller is updated on text change
|
||||||
|
frag.afterTextChanged(new SpannableStringBuilder(FILLER));
|
||||||
|
verify(controller, times(1)).updateUserInput(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogEnablesSubmitButtonOnValidationFromController() {
|
||||||
|
// set the correct dialog type
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
|
||||||
|
|
||||||
|
// we don't care about these for this test
|
||||||
|
when(controller.getDeviceVariantMessageId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
when(controller.getDeviceVariantMessageHintId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
|
||||||
|
// force the controller to say that any passkey is valid
|
||||||
|
when(controller.isPasskeyValid(any())).thenReturn(true);
|
||||||
|
|
||||||
|
// build fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// test that the positive button is enabled when passkey is valid
|
||||||
|
frag.afterTextChanged(new SpannableStringBuilder(FILLER));
|
||||||
|
View button = frag.getmDialog().getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
|
assertThat(button).isNotNull();
|
||||||
|
assertThat(button.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogDoesNotAskForPairCodeOnConsentVariant() {
|
||||||
|
// set the dialog variant to confirmation/consent
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// check that the input field used by the entry dialog fragment does not exist
|
||||||
|
View view = frag.getmDialog().findViewById(R.id.text);
|
||||||
|
assertThat(view).isNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogAsksForPairCodeOnUserEntryVariant() {
|
||||||
|
// set the dialog variant to user entry
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
|
||||||
|
|
||||||
|
// we don't care about these for this test
|
||||||
|
when(controller.getDeviceVariantMessageId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
when(controller.getDeviceVariantMessageHintId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// check that the pin/passkey input field is visible to the user
|
||||||
|
View view = frag.getmDialog().findViewById(R.id.text);
|
||||||
|
assertThat(view.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogDisplaysPairCodeOnDisplayPasskeyVariant() {
|
||||||
|
// set the dialog variant to display passkey
|
||||||
|
when(controller.getDialogType())
|
||||||
|
.thenReturn(BluetoothPairingController.DISPLAY_PASSKEY_DIALOG);
|
||||||
|
|
||||||
|
// ensure that the controller returns good values to indicate a passkey needs to be shown
|
||||||
|
when(controller.isDisplayPairingKeyVariant()).thenReturn(true);
|
||||||
|
when(controller.hasPairingContent()).thenReturn(true);
|
||||||
|
when(controller.getPairingContent()).thenReturn(FILLER);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// get the relevant views
|
||||||
|
View messagePairing = frag.getmDialog().findViewById(R.id.pairing_code_message);
|
||||||
|
TextView pairingViewContent =
|
||||||
|
(TextView) frag.getmDialog().findViewById(R.id.pairing_subhead);
|
||||||
|
View pairingViewCaption = frag.getmDialog().findViewById(R.id.pairing_caption);
|
||||||
|
|
||||||
|
// check that the relevant views are visible and that the passkey is shown
|
||||||
|
assertThat(messagePairing.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(pairingViewCaption.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(pairingViewContent.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(TextUtils.equals(FILLER, pairingViewContent.getText())).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void dialogThrowsExceptionIfNoControllerSet() {
|
||||||
|
// instantiate a fragment
|
||||||
|
BluetoothPairingDialogFragment frag = new BluetoothPairingDialogFragment();
|
||||||
|
|
||||||
|
// this should throw an error
|
||||||
|
FragmentTestUtil.startFragment(frag);
|
||||||
|
fail("Starting the fragment with no controller set should have thrown an exception.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogCallsHookOnPositiveButtonPress() {
|
||||||
|
// set the dialog variant to confirmation/consent
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
|
||||||
|
|
||||||
|
// we don't care what this does, just that it is called
|
||||||
|
doNothing().when(controller).onDialogPositiveClick(any());
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// click the button and verify that the controller hook was called
|
||||||
|
frag.onClick(frag.getmDialog(), AlertDialog.BUTTON_POSITIVE);
|
||||||
|
verify(controller, times(1)).onDialogPositiveClick(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogCallsHookOnNegativeButtonPress() {
|
||||||
|
// set the dialog variant to confirmation/consent
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
|
||||||
|
|
||||||
|
// we don't care what this does, just that it is called
|
||||||
|
doNothing().when(controller).onDialogNegativeClick(any());
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// click the button and verify that the controller hook was called
|
||||||
|
frag.onClick(frag.getmDialog(), AlertDialog.BUTTON_NEGATIVE);
|
||||||
|
verify(controller, times(1)).onDialogNegativeClick(any());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void dialogDoesNotAllowSwappingController() {
|
||||||
|
// instantiate a fragment
|
||||||
|
BluetoothPairingDialogFragment frag = new BluetoothPairingDialogFragment();
|
||||||
|
frag.setPairingController(controller);
|
||||||
|
|
||||||
|
// this should throw an error
|
||||||
|
frag.setPairingController(controller);
|
||||||
|
fail("Setting the controller multiple times should throw an exception.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogPositiveButtonDisabledWhenUserInputInvalid() {
|
||||||
|
// set the correct dialog type
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
|
||||||
|
|
||||||
|
// we don't care about these for this test
|
||||||
|
when(controller.getDeviceVariantMessageId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
when(controller.getDeviceVariantMessageHintId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
|
||||||
|
// force the controller to say that any passkey is valid
|
||||||
|
when(controller.isPasskeyValid(any())).thenReturn(false);
|
||||||
|
|
||||||
|
// build fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// test that the positive button is enabled when passkey is valid
|
||||||
|
frag.afterTextChanged(new SpannableStringBuilder(FILLER));
|
||||||
|
View button = frag.getmDialog().getButton(AlertDialog.BUTTON_POSITIVE);
|
||||||
|
assertThat(button).isNotNull();
|
||||||
|
assertThat(button.isEnabled()).isFalse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogShowsContactSharingCheckboxWhenBluetoothProfileNotReady() {
|
||||||
|
// set the dialog variant to confirmation/consent
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
|
||||||
|
|
||||||
|
// set a fake device name and pretend the profile has not been set up for it
|
||||||
|
when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME);
|
||||||
|
when(controller.isProfileReady()).thenReturn(false);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// verify that the checkbox is visible and that the device name is correct
|
||||||
|
CheckBox sharingCheckbox = (CheckBox) frag.getmDialog()
|
||||||
|
.findViewById(R.id.phonebook_sharing_message_confirm_pin);
|
||||||
|
assertThat(sharingCheckbox.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(sharingCheckbox.getText().toString().contains(FAKE_DEVICE_NAME)).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogHidesContactSharingCheckboxWhenBluetoothProfileIsReady() {
|
||||||
|
// set the dialog variant to confirmation/consent
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.CONFIRMATION_DIALOG);
|
||||||
|
|
||||||
|
// set a fake device name and pretend the profile has been set up for it
|
||||||
|
when(controller.getDeviceName()).thenReturn(FAKE_DEVICE_NAME);
|
||||||
|
when(controller.isProfileReady()).thenReturn(true);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// verify that the checkbox is gone
|
||||||
|
CheckBox sharingCheckbox = (CheckBox) frag.getmDialog()
|
||||||
|
.findViewById(R.id.phonebook_sharing_message_confirm_pin);
|
||||||
|
assertThat(sharingCheckbox.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogShowsMessageOnPinEntryView() {
|
||||||
|
// set the correct dialog type
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
|
||||||
|
|
||||||
|
// Set the message id to something specific to verify later
|
||||||
|
when(controller.getDeviceVariantMessageId()).thenReturn(R.string.cancel);
|
||||||
|
when(controller.getDeviceVariantMessageHintId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// verify message is what we expect it to be and is visible
|
||||||
|
TextView message = (TextView) frag.getmDialog().findViewById(R.id.message_below_pin);
|
||||||
|
assertThat(message.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(TextUtils.equals(frag.getString(R.string.cancel), message.getText())).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogShowsMessageHintOnPinEntryView() {
|
||||||
|
// set the correct dialog type
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
|
||||||
|
|
||||||
|
// Set the message id hint to something specific to verify later
|
||||||
|
when(controller.getDeviceVariantMessageHintId()).thenReturn(R.string.cancel);
|
||||||
|
when(controller.getDeviceVariantMessageId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// verify message is what we expect it to be and is visible
|
||||||
|
TextView hint = (TextView) frag.getmDialog().findViewById(R.id.pin_values_hint);
|
||||||
|
assertThat(hint.getVisibility()).isEqualTo(View.VISIBLE);
|
||||||
|
assertThat(TextUtils.equals(frag.getString(R.string.cancel), hint.getText())).isTrue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void dialogHidesMessageAndHintWhenNotProvidedOnPinEntryView() {
|
||||||
|
// set the correct dialog type
|
||||||
|
when(controller.getDialogType()).thenReturn(BluetoothPairingController.USER_ENTRY_DIALOG);
|
||||||
|
|
||||||
|
// Set the id's to what is returned when it is not provided
|
||||||
|
when(controller.getDeviceVariantMessageHintId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
when(controller.getDeviceVariantMessageId())
|
||||||
|
.thenReturn(BluetoothPairingController.INVALID_DIALOG_TYPE);
|
||||||
|
|
||||||
|
// build the fragment
|
||||||
|
BluetoothPairingDialogFragment frag = makeFragment();
|
||||||
|
|
||||||
|
// verify message is what we expect it to be and is visible
|
||||||
|
TextView hint = (TextView) frag.getmDialog().findViewById(R.id.pin_values_hint);
|
||||||
|
assertThat(hint.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
TextView message = (TextView) frag.getmDialog().findViewById(R.id.message_below_pin);
|
||||||
|
assertThat(message.getVisibility()).isEqualTo(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BluetoothPairingDialogFragment makeFragment() {
|
||||||
|
BluetoothPairingDialogFragment frag = new BluetoothPairingDialogFragment();
|
||||||
|
frag.setPairingController(controller);
|
||||||
|
FragmentTestUtil.startFragment(frag);
|
||||||
|
assertThat(frag.getmDialog()).isNotNull();
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user