Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3170042b authored by Chaohui Wang's avatar Chaohui Wang Committed by Android (Google) Code Review
Browse files

Merge "Add RestrictedMenuItem for Spa"

parents 4c5e8320 a8d1d466
Loading
Loading
Loading
Loading
+57 −0
Original line number Diff line number Diff line
/*
 * 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()
        }
    }
}
+4 −23
Original line number Diff line number Diff line
@@ -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)
}
+151 −0
Original line number Diff line number Diff line
/*
 * 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"
    }
}
+44 −0
Original line number Diff line number Diff line
/*
 * 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)
}