1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.bluetooth; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyBoolean; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.anyString; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.verify; 27 import static org.mockito.Mockito.when; 28 29 import android.view.View; 30 import android.widget.Button; 31 32 import androidx.fragment.app.FragmentManager; 33 import androidx.fragment.app.FragmentTransaction; 34 35 import com.android.settings.R; 36 import com.android.settingslib.widget.ActionButtonsPreference; 37 38 import org.junit.Ignore; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 import org.mockito.ArgumentCaptor; 42 import org.robolectric.RobolectricTestRunner; 43 import org.robolectric.RuntimeEnvironment; 44 45 @RunWith(RobolectricTestRunner.class) 46 @Ignore 47 public class BluetoothDetailsButtonsControllerTest extends BluetoothDetailsControllerTestBase { 48 private BluetoothDetailsButtonsController mController; 49 private ActionButtonsPreference mButtonsPref; 50 private Button mConnectButton; 51 private Button mForgetButton; 52 53 @Override setUp()54 public void setUp() { 55 super.setUp(); 56 final View buttons = View.inflate( 57 RuntimeEnvironment.application, R.layout.settingslib_action_buttons, 58 null /* parent */); 59 mConnectButton = buttons.findViewById(R.id.button2); 60 mForgetButton = buttons.findViewById(R.id.button1); 61 mController = 62 new BluetoothDetailsButtonsController(mContext, mFragment, mCachedDevice, 63 mLifecycle); 64 mButtonsPref = createMock(); 65 when(mButtonsPref.getKey()).thenReturn(mController.getPreferenceKey()); 66 when(mButtonsPref.setButton2OnClickListener(any(View.OnClickListener.class))) 67 .thenAnswer(invocation -> { 68 final Object[] args = invocation.getArguments(); 69 mConnectButton.setOnClickListener((View.OnClickListener) args[0]); 70 return mButtonsPref; 71 }); 72 when(mButtonsPref.setButton1OnClickListener(any(View.OnClickListener.class))) 73 .thenAnswer(invocation -> { 74 final Object[] args = invocation.getArguments(); 75 mForgetButton.setOnClickListener((View.OnClickListener) args[0]); 76 return mButtonsPref; 77 }); 78 mScreen.addPreference(mButtonsPref); 79 setupDevice(mDeviceConfig); 80 when(mCachedDevice.isBusy()).thenReturn(false); 81 } 82 83 @Test connected()84 public void connected() { 85 showScreen(mController); 86 87 verify(mButtonsPref).setButton2Text(R.string.bluetooth_device_context_disconnect); 88 verify(mButtonsPref).setButton1Text(R.string.forget); 89 } 90 91 @Test clickOnDisconnect()92 public void clickOnDisconnect() { 93 showScreen(mController); 94 mConnectButton.callOnClick(); 95 96 verify(mCachedDevice).disconnect(); 97 } 98 99 @Test clickOnConnect()100 public void clickOnConnect() { 101 when(mCachedDevice.isConnected()).thenReturn(false); 102 showScreen(mController); 103 104 verify(mButtonsPref).setButton2Text(R.string.bluetooth_device_context_connect); 105 106 mConnectButton.callOnClick(); 107 verify(mCachedDevice).connect(); 108 } 109 110 @Test becomeDisconnected()111 public void becomeDisconnected() { 112 showScreen(mController); 113 // By default we start out with the device connected. 114 verify(mButtonsPref).setButton2Text(R.string.bluetooth_device_context_disconnect); 115 116 // Now make the device appear to have changed to disconnected. 117 when(mCachedDevice.isConnected()).thenReturn(false); 118 mController.onDeviceAttributesChanged(); 119 verify(mButtonsPref).setButton2Text(R.string.bluetooth_device_context_connect); 120 121 // Click the button and make sure that connect (not disconnect) gets called. 122 mConnectButton.callOnClick(); 123 verify(mCachedDevice).connect(); 124 } 125 126 @Test becomeConnected()127 public void becomeConnected() { 128 // Start out with the device disconnected. 129 when(mCachedDevice.isConnected()).thenReturn(false); 130 showScreen(mController); 131 132 verify(mButtonsPref).setButton2Text(R.string.bluetooth_device_context_connect); 133 134 135 // Now make the device appear to have changed to connected. 136 when(mCachedDevice.isConnected()).thenReturn(true); 137 mController.onDeviceAttributesChanged(); 138 verify(mButtonsPref).setButton2Text(R.string.bluetooth_device_context_disconnect); 139 140 // Click the button and make sure that disconnect (not connect) gets called. 141 mConnectButton.callOnClick(); 142 verify(mCachedDevice).disconnect(); 143 } 144 145 @Test forgetDialog()146 public void forgetDialog() { 147 showScreen(mController); 148 FragmentManager fragmentManager = mock(FragmentManager.class); 149 when(mFragment.getFragmentManager()).thenReturn(fragmentManager); 150 FragmentTransaction ft = mock(FragmentTransaction.class); 151 when(fragmentManager.beginTransaction()).thenReturn(ft); 152 mForgetButton.callOnClick(); 153 154 ArgumentCaptor<ForgetDeviceDialogFragment> dialogCaptor = 155 ArgumentCaptor.forClass(ForgetDeviceDialogFragment.class); 156 verify(ft).add(dialogCaptor.capture(), anyString()); 157 158 ForgetDeviceDialogFragment dialogFragment = dialogCaptor.getValue(); 159 assertThat(dialogFragment).isNotNull(); 160 } 161 162 @Test startsOutBusy()163 public void startsOutBusy() { 164 when(mCachedDevice.isBusy()).thenReturn(true); 165 showScreen(mController); 166 167 verify(mButtonsPref).setButton2Text(R.string.bluetooth_device_context_disconnect); 168 verify(mButtonsPref).setButton2Enabled(false); 169 verify(mButtonsPref).setButton1Text(R.string.forget); 170 171 // Now pretend the device became non-busy. 172 when(mCachedDevice.isBusy()).thenReturn(false); 173 mController.onDeviceAttributesChanged(); 174 175 verify(mButtonsPref).setButton2Enabled(true); 176 } 177 178 @Test becomesBusy()179 public void becomesBusy() { 180 showScreen(mController); 181 verify(mButtonsPref).setButton2Enabled(true); 182 183 // Now pretend the device became busy. 184 when(mCachedDevice.isBusy()).thenReturn(true); 185 mController.onDeviceAttributesChanged(); 186 187 verify(mButtonsPref).setButton2Enabled(false); 188 } 189 createMock()190 private ActionButtonsPreference createMock() { 191 final ActionButtonsPreference pref = mock(ActionButtonsPreference.class); 192 when(pref.setButton1Text(anyInt())).thenReturn(pref); 193 when(pref.setButton1Icon(anyInt())).thenReturn(pref); 194 when(pref.setButton1Enabled(anyBoolean())).thenReturn(pref); 195 when(pref.setButton1Visible(anyBoolean())).thenReturn(pref); 196 when(pref.setButton1OnClickListener(any(View.OnClickListener.class))).thenReturn(pref); 197 198 when(pref.setButton2Text(anyInt())).thenReturn(pref); 199 when(pref.setButton2Icon(anyInt())).thenReturn(pref); 200 when(pref.setButton2Enabled(anyBoolean())).thenReturn(pref); 201 when(pref.setButton2Visible(anyBoolean())).thenReturn(pref); 202 when(pref.setButton2OnClickListener(any(View.OnClickListener.class))).thenReturn(pref); 203 204 return pref; 205 } 206 } 207