blob: 05459f16093349466167fa896952fba07e4fe960 [file] [log] [blame]
/*
* Copyright (C) 2021 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.car.settings.enterprise;
import static com.android.car.settings.common.PreferenceController.AVAILABLE;
import static com.android.car.settings.common.PreferenceController.CONDITIONALLY_UNAVAILABLE;
import static com.android.car.settings.common.PreferenceController.DISABLED_FOR_PROFILE;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import android.annotation.Nullable;
import android.util.Log;
import androidx.preference.Preference;
import com.android.car.settings.R;
import com.android.car.settingslib.applications.ApplicationFeatureProvider;
import com.android.car.settingslib.applications.ApplicationFeatureProvider.NumberOfAppsCallback;
import com.android.internal.util.Preconditions;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import java.util.Objects;
abstract class BaseAdminGrantedPermissionsPreferenceControllerTestCase
<C extends BaseAdminGrantedPermissionsPreferenceController> extends
BaseEnterprisePrivacyPreferenceControllerTestCase {
private static final String TAG = BaseAdminGrantedPermissionsPreferenceControllerTestCase.class
.getSimpleName();
// Must be a spy to verify refreshUi() is called
private C mSpiedController;
protected final String[] mPermissions;
@Mock
private Preference mPreference;
BaseAdminGrantedPermissionsPreferenceControllerTestCase(String... permissions) {
mPermissions = permissions;
}
@Before
public void setController() {
mSpiedController = spy(newController(mApplicationFeatureProvider));
}
protected abstract C newController(ApplicationFeatureProvider provider);
@Test
public void testGetAvailabilityStatus_noPermissionsGranted() {
CallbackHolder callbackHolder = mockCalculateNumberOfAppsWithAdminGrantedPermissions();
// Assert initial state
assertAvailability(mSpiedController.getAvailabilityStatus(), CONDITIONALLY_UNAVAILABLE);
// Unblock async call
callbackHolder.release(0);
// Assert post-callback result
assertAvailability(mSpiedController.getAvailabilityStatus(), DISABLED_FOR_PROFILE);
assertUiNotRefreshed();
}
@Test
public void testGetAvailabilityStatus_permissionsGranted() {
expectUiRefreshed();
CallbackHolder callbackHolder = mockCalculateNumberOfAppsWithAdminGrantedPermissions();
// Assert initial state
assertAvailability(mSpiedController.getAvailabilityStatus(), CONDITIONALLY_UNAVAILABLE);
// Unblock async call
callbackHolder.release(42);
// Assert post-callback result
assertAvailability(mSpiedController.getAvailabilityStatus(), AVAILABLE);
assertUiRefreshed();
}
@Test
public void testUpdateState() {
expectUiRefreshed();
CallbackHolder callbackHolder = mockCalculateNumberOfAppsWithAdminGrantedPermissions();
mSpiedController.getAvailabilityStatus();
callbackHolder.release(42);
assertUiRefreshed();
mSpiedController.updateState(mPreference);
assertPreferenceStateSet(42);
}
private CallbackHolder mockCalculateNumberOfAppsWithAdminGrantedPermissions() {
CallbackHolder callbackHolder = new CallbackHolder();
doAnswer((inv) -> {
Log.d(TAG, "answering to " + inv);
NumberOfAppsCallback callback = (NumberOfAppsCallback) inv.getArguments()[2];
callbackHolder.setCallback(callback);
return null;
}).when(mApplicationFeatureProvider)
.calculateNumberOfAppsWithAdminGrantedPermissions(eq(mPermissions),
/* sync= */ eq(true), any());
return callbackHolder;
}
private void assertPreferenceStateSet(int count) {
String expectedSummary = mRealContext.getResources().getQuantityString(
R.plurals.enterprise_privacy_number_packages_lower_bound, count, count);
verifyPreferenceTitleNeverSet(mPreference);
verifyPreferenceSummarySet(mPreference, expectedSummary);
verifyPreferenceIconNeverSet(mPreference);
}
private void expectUiRefreshed() {
doNothing().when(mSpiedController).refreshUi();
}
private void assertUiRefreshed() {
verify(mSpiedController).refreshUi();
}
private void assertUiNotRefreshed() {
verify(mSpiedController, never()).refreshUi();
}
private final class CallbackHolder {
@Nullable
private NumberOfAppsCallback mCallback;
void release(int result) {
Preconditions.checkState(mCallback != null, "release() called before setCallback()");
Log.d(TAG, "setting result to " + result + " and releasing latch on"
+ Thread.currentThread());
mCallback.onNumberOfAppsResult(result);
}
void setCallback(NumberOfAppsCallback callback) {
Log.d(TAG, "setting callback to " + callback);
mCallback = Objects.requireNonNull(callback, "callback cannot be null");
}
}
}