diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt new file mode 100644 index 0000000000000..8c1421a665641 --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItem.kt @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2022 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.settingslib.spaprivileged.template.scaffold + +import android.content.Context +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.platform.LocalContext +import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope +import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted +import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProviderImpl + +@Composable +fun MoreOptionsScope.RestrictedMenuItem( + text: String, + restrictions: Restrictions, + onClick: () -> Unit, +) { + RestrictedMenuItemImpl(text, restrictions, onClick, ::RestrictionsProviderImpl) +} + +@Composable +internal fun MoreOptionsScope.RestrictedMenuItemImpl( + text: String, + restrictions: Restrictions, + onClick: () -> Unit, + restrictionsProviderFactory: (Context, Restrictions) -> RestrictionsProvider, +) { + val context = LocalContext.current + val restrictionsProvider = remember(restrictions) { + restrictionsProviderFactory(context, restrictions) + } + val restrictedMode = restrictionsProvider.restrictedModeState().value + MenuItem(text = text, enabled = restrictedMode !is BaseUserRestricted) { + when (restrictedMode) { + is BlockedByAdmin -> restrictedMode.sendShowAdminSupportDetailsIntent() + else -> onClick() + } + } +} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt index a5352b2f575d4..7f57025c5fe5c 100644 --- a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/preference/RestrictedSwitchPreferenceTest.kt @@ -16,7 +16,6 @@ package com.android.settingslib.spaprivileged.template.preference -import androidx.compose.runtime.Composable import androidx.compose.runtime.mutableStateOf import androidx.compose.ui.test.assertIsDisplayed import androidx.compose.ui.test.assertIsEnabled @@ -28,14 +27,12 @@ import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.onRoot import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 -import com.android.settingslib.spa.framework.compose.stateOf import com.android.settingslib.spa.widget.preference.SwitchPreferenceModel import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted -import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted -import com.android.settingslib.spaprivileged.model.enterprise.RestrictedMode import com.android.settingslib.spaprivileged.model.enterprise.Restrictions -import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider +import com.android.settingslib.spaprivileged.tests.testutils.FakeBlockedByAdmin +import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsProvider import com.google.common.truth.Truth.assertThat import org.junit.Rule import org.junit.Test @@ -46,15 +43,7 @@ class RestrictedSwitchPreferenceTest { @get:Rule val composeTestRule = createComposeRule() - private val fakeBlockedByAdmin = object : BlockedByAdmin { - var sendShowAdminSupportDetailsIntentIsCalled = false - - override fun getSummary(checked: Boolean?) = BLOCKED_BY_ADMIN_SUMMARY - - override fun sendShowAdminSupportDetailsIntent() { - sendShowAdminSupportDetailsIntentIsCalled = true - } - } + private val fakeBlockedByAdmin = FakeBlockedByAdmin() private val fakeRestrictionsProvider = FakeRestrictionsProvider() @@ -136,7 +125,7 @@ class RestrictedSwitchPreferenceTest { setContent(restrictions) composeTestRule.onNodeWithText(TITLE).assertIsDisplayed().assertIsEnabled() - composeTestRule.onNodeWithText(BLOCKED_BY_ADMIN_SUMMARY).assertIsDisplayed() + composeTestRule.onNodeWithText(FakeBlockedByAdmin.SUMMARY).assertIsDisplayed() composeTestRule.onNode(isOn()).assertIsDisplayed() } @@ -163,13 +152,5 @@ class RestrictedSwitchPreferenceTest { const val TITLE = "Title" const val USER_ID = 0 const val RESTRICTION_KEY = "restriction_key" - const val BLOCKED_BY_ADMIN_SUMMARY = "Blocked by admin" } } - -private class FakeRestrictionsProvider : RestrictionsProvider { - var restrictedMode: RestrictedMode? = null - - @Composable - override fun restrictedModeState() = stateOf(restrictedMode) -} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt new file mode 100644 index 0000000000000..983284cbabb7e --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/template/scaffold/RestrictedMenuItemTest.kt @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2022 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.settingslib.spaprivileged.template.scaffold + +import androidx.compose.ui.test.assertIsDisplayed +import androidx.compose.ui.test.assertIsEnabled +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.onRoot +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.android.settingslib.spa.widget.scaffold.MoreOptionsScope +import com.android.settingslib.spaprivileged.model.enterprise.BaseUserRestricted +import com.android.settingslib.spaprivileged.model.enterprise.NoRestricted +import com.android.settingslib.spaprivileged.model.enterprise.Restrictions +import com.android.settingslib.spaprivileged.tests.testutils.FakeBlockedByAdmin +import com.android.settingslib.spaprivileged.tests.testutils.FakeRestrictionsProvider +import com.google.common.truth.Truth.assertThat +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class RestrictedMenuItemTest { + @get:Rule + val composeTestRule = createComposeRule() + + private val fakeBlockedByAdmin = FakeBlockedByAdmin() + + private val fakeRestrictionsProvider = FakeRestrictionsProvider() + + private var menuItemOnClickIsCalled = false + + @Test + fun whenRestrictionsKeysIsEmpty_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenRestrictionsKeysIsEmpty_clickable() { + val restrictions = Restrictions(userId = USER_ID, keys = emptyList()) + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(menuItemOnClickIsCalled).isTrue() + } + + @Test + fun whenNoRestricted_enabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenNoRestricted_clickable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = NoRestricted + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(menuItemOnClickIsCalled).isTrue() + } + + @Test + fun whenBaseUserRestricted_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsNotEnabled() + } + + @Test + fun whenBaseUserRestricted_notClickable() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = BaseUserRestricted + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(menuItemOnClickIsCalled).isFalse() + } + + @Test + fun whenBlockedByAdmin_disabled() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + + composeTestRule.onNodeWithText(TEXT).assertIsDisplayed().assertIsEnabled() + } + + @Test + fun whenBlockedByAdmin_onClick_showAdminSupportDetails() { + val restrictions = Restrictions(userId = USER_ID, keys = listOf(RESTRICTION_KEY)) + fakeRestrictionsProvider.restrictedMode = fakeBlockedByAdmin + + setContent(restrictions) + composeTestRule.onRoot().performClick() + + assertThat(fakeBlockedByAdmin.sendShowAdminSupportDetailsIntentIsCalled).isTrue() + assertThat(menuItemOnClickIsCalled).isFalse() + } + + private fun setContent(restrictions: Restrictions) { + val fakeMoreOptionsScope = object : MoreOptionsScope { + override fun dismiss() {} + } + composeTestRule.setContent { + fakeMoreOptionsScope.RestrictedMenuItemImpl( + text = TEXT, + restrictions = restrictions, + onClick = { menuItemOnClickIsCalled = true }, + restrictionsProviderFactory = { _, _ -> fakeRestrictionsProvider }, + ) + } + } + + private companion object { + const val TEXT = "Text" + const val USER_ID = 0 + const val RESTRICTION_KEY = "restriction_key" + } +} diff --git a/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt new file mode 100644 index 0000000000000..93fa17d1eeca4 --- /dev/null +++ b/packages/SettingsLib/SpaPrivileged/tests/src/com/android/settingslib/spaprivileged/tests/testutils/RestrictedTestUtils.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2022 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.settingslib.spaprivileged.tests.testutils + +import androidx.compose.runtime.Composable +import com.android.settingslib.spa.framework.compose.stateOf +import com.android.settingslib.spaprivileged.model.enterprise.BlockedByAdmin +import com.android.settingslib.spaprivileged.model.enterprise.RestrictedMode +import com.android.settingslib.spaprivileged.model.enterprise.RestrictionsProvider + +class FakeBlockedByAdmin : BlockedByAdmin { + var sendShowAdminSupportDetailsIntentIsCalled = false + + override fun getSummary(checked: Boolean?) = SUMMARY + + override fun sendShowAdminSupportDetailsIntent() { + sendShowAdminSupportDetailsIntentIsCalled = true + } + + companion object { + const val SUMMARY = "Blocked by admin" + } +} + +class FakeRestrictionsProvider : RestrictionsProvider { + var restrictedMode: RestrictedMode? = null + + @Composable + override fun restrictedModeState() = stateOf(restrictedMode) +}