1
0
Fork 0
fenix/app/src/test/java/org/mozilla/fenix/settings/quicksettings/QuickSettingsFragmentStoreT...

331 lines
15 KiB
Kotlin

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.settings.quicksettings
import android.content.pm.PackageManager
import assertk.assertAll
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isFalse
import assertk.assertions.isInstanceOf
import assertk.assertions.isNotNull
import assertk.assertions.isNotSameAs
import assertk.assertions.isSameAs
import assertk.assertions.isTrue
import io.mockk.every
import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import mozilla.components.feature.sitepermissions.SitePermissions
import mozilla.components.support.test.robolectric.testContext
import org.junit.Test
import org.junit.runner.RunWith
import org.mozilla.fenix.R
import org.mozilla.fenix.TestApplication
import org.mozilla.fenix.settings.PhoneFeature
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.getInsecureWebsiteUiValues
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.getPermissionStatus
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.getSecuredWebsiteUiValues
import org.mozilla.fenix.settings.quicksettings.QuickSettingsFragmentStore.Companion.toWebsitePermission
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeEnabled
import org.mozilla.fenix.settings.quicksettings.ext.shouldBeVisible
import org.mozilla.fenix.utils.Settings
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
@RunWith(RobolectricTestRunner::class)
@UseExperimental(kotlinx.coroutines.ObsoleteCoroutinesApi::class)
@Config(application = TestApplication::class)
class QuickSettingsFragmentStoreTest {
private val context = spyk(testContext)
private val permissions = mockk<SitePermissions>()
private val appSettings = mockk<Settings>()
private val secureStringRes = R.string.quick_settings_sheet_secure_connection
private val secureDrawableRes = R.drawable.mozac_ic_lock
private val secureColorRes = R.color.photonGreen50
private val insecureStringRes = R.string.quick_settings_sheet_insecure_connection
private val insecureDrawableRes = R.drawable.mozac_ic_globe
private val insecureColorRes = R.color.photonRed50
@Test
fun `createStore constructs a QuickSettingsFragmentState`() {
val settings = mockk<Settings>(relaxed = true)
val permissions = mockk<SitePermissions>(relaxed = true)
val store = QuickSettingsFragmentStore.createStore(
context, "url", true, permissions, settings
)
assertAll {
assertThat(store).isNotNull()
assertThat(store.state).isNotNull()
assertThat(store.state.webInfoState).isNotNull()
assertThat(store.state.websitePermissionsState).isNotNull()
}
}
@Test
fun `createWebsiteInfoState constructs a WebsiteInfoState with the right values for a secure connection`() {
val websiteUrl = "https://host.com/page1"
val securedStatus = true
val state = QuickSettingsFragmentStore.createWebsiteInfoState(websiteUrl, securedStatus)
assertAll {
assertThat(state).isNotNull()
assertThat(state.websiteUrl).isSameAs(websiteUrl)
assertThat(state.securityInfoRes).isEqualTo(secureStringRes)
assertThat(state.iconRes).isEqualTo(secureDrawableRes)
assertThat(state.iconTintRes).isEqualTo(secureColorRes)
}
}
@Test
fun `createWebsiteInfoState constructs a WebsiteInfoState with the right values for an insecure connection`() {
val websiteUrl = "https://host.com/page1"
val securedStatus = false
val state = QuickSettingsFragmentStore.createWebsiteInfoState(websiteUrl, securedStatus)
assertAll {
assertThat(state).isNotNull()
assertThat(state.websiteUrl).isSameAs(websiteUrl)
assertThat(state.securityInfoRes).isEqualTo(insecureStringRes)
assertThat(state.iconRes).isEqualTo(insecureDrawableRes)
assertThat(state.iconTintRes).isEqualTo(insecureColorRes)
}
}
@Test
fun `createWebsitePermissionState helps in constructing an initial WebsitePermissionState for it's Store`() {
every {
context.checkPermission(
any(),
any(),
any()
)
}.returns(PackageManager.PERMISSION_GRANTED)
every { permissions.camera } returns SitePermissions.Status.ALLOWED
every { permissions.microphone } returns SitePermissions.Status.NO_DECISION
every { permissions.notification } returns SitePermissions.Status.BLOCKED
every { permissions.location } returns SitePermissions.Status.ALLOWED
val state = QuickSettingsFragmentStore.createWebsitePermissionState(
context, permissions, appSettings
)
// Just need to know that the WebsitePermissionsState properties are initialized.
// Making sure they are correctly initialized is tested in the `initWebsitePermission` test.
assertAll {
assertThat(state).isNotNull()
assertThat(state.camera).isNotNull()
assertThat(state.microphone).isNotNull()
assertThat(state.notification).isNotNull()
assertThat(state.location).isNotNull()
}
}
@Test
fun `PhoneFeature#toWebsitePermission helps in constructing the right WebsitePermission`() {
val cameraFeature = PhoneFeature.CAMERA
val allowedStatus = testContext.getString(R.string.preference_option_phone_feature_allowed)
every {
context.checkPermission(
any(),
any(),
any()
)
}.returns(PackageManager.PERMISSION_GRANTED)
every { permissions.camera } returns SitePermissions.Status.ALLOWED
val websitePermission = cameraFeature.toWebsitePermission(context, permissions, appSettings)
assertAll {
assertThat(websitePermission).isNotNull()
assertThat(websitePermission).isInstanceOf(WebsitePermission.Camera::class)
assertThat(websitePermission.status).isEqualTo(allowedStatus)
assertThat(websitePermission.isVisible).isTrue()
assertThat(websitePermission.isEnabled).isTrue()
assertThat(websitePermission.isBlockedByAndroid).isFalse()
}
}
@Test
fun `PhoneFeature#getPermissionStatus gets the permission properties from delegates`() {
val phoneFeature = PhoneFeature.CAMERA
every { permissions.camera } returns SitePermissions.Status.NO_DECISION
val permissionsStatus = phoneFeature.getPermissionStatus(context, permissions, appSettings)
verify {
// Verifying phoneFeature.getActionLabel gets "Status(child of #2#4).ordinal()) was not called"
// phoneFeature.getActionLabel(context, permissions, appSettings)
phoneFeature.shouldBeVisible(permissions, appSettings)
phoneFeature.shouldBeEnabled(context, permissions, appSettings)
phoneFeature.isAndroidPermissionGranted(context)
}
assertAll {
// Check that we only have a non-null permission status.
// Having each property calculated in a separate delegate means their correctness is
// to be tested in that delegated method.
assertThat(permissionsStatus).isNotNull()
}
}
@Test
@ExperimentalCoroutinesApi
fun `TogglePermission should only modify status and visibility of a specific WebsitePermissionsState`() =
runBlocking {
val cameraPermissionName = "Camera"
val microphonePermissionName = "Microphone"
val notificationPermissionName = "Notification"
val locationPermissionName = "Location"
val initialCameraStatus = "initialCameraStatus"
val initialMicStatus = "initialMicStatus"
val initialNotificationStatus = "initialNotificationStatus"
val initialLocationStatus = "initialLocationStatus"
val updatedMicrophoneStatus = "updatedNotificationStatus"
val updatedMicrophoneEnabledStatus = false
val defaultVisibilityStatus = true
val defaultEnabledStatus = true
val defaultBlockedByAndroidStatus = true
val websiteInfoState = mockk<WebsiteInfoState>()
val initialWebsitePermissionsState = WebsitePermissionsState(
isVisible = true,
camera = WebsitePermission.Camera(
initialCameraStatus, defaultVisibilityStatus,
defaultEnabledStatus, defaultBlockedByAndroidStatus, cameraPermissionName
),
microphone = WebsitePermission.Microphone(
initialMicStatus, defaultVisibilityStatus,
defaultEnabledStatus, defaultBlockedByAndroidStatus, microphonePermissionName
),
notification = WebsitePermission.Notification(
initialNotificationStatus, defaultVisibilityStatus,
defaultEnabledStatus, defaultBlockedByAndroidStatus, notificationPermissionName
),
location = WebsitePermission.Location(
initialLocationStatus, defaultVisibilityStatus,
defaultEnabledStatus, defaultBlockedByAndroidStatus, locationPermissionName
)
)
val initialState = QuickSettingsFragmentState(
websiteInfoState, initialWebsitePermissionsState
)
val store = QuickSettingsFragmentStore(initialState)
store.dispatch(
WebsitePermissionAction.TogglePermission(
mockk<WebsitePermission.Microphone>(),
updatedMicrophoneStatus,
updatedMicrophoneEnabledStatus
)
).join()
assertAll {
assertThat(store.state).isNotNull()
assertThat(store.state).isNotSameAs(initialState)
assertThat(store.state.websitePermissionsState).isNotSameAs(
initialWebsitePermissionsState
)
assertThat(store.state.webInfoState).isSameAs(websiteInfoState)
assertThat(store.state.websitePermissionsState.camera).isNotNull()
assertThat((store.state.websitePermissionsState.camera as WebsitePermission.Camera).name).isEqualTo(
cameraPermissionName
)
assertThat(store.state.websitePermissionsState.camera.status).isEqualTo(
initialCameraStatus
)
assertThat(store.state.websitePermissionsState.camera.isVisible).isEqualTo(
defaultVisibilityStatus
)
assertThat(store.state.websitePermissionsState.camera.isEnabled).isEqualTo(
defaultEnabledStatus
)
assertThat(store.state.websitePermissionsState.camera.isBlockedByAndroid).isEqualTo(
defaultBlockedByAndroidStatus
)
assertThat(store.state.websitePermissionsState.microphone).isNotNull()
assertThat((store.state.websitePermissionsState.microphone as WebsitePermission.Microphone).name).isEqualTo(
microphonePermissionName
)
// Only the following two properties must have been changed!
assertThat(store.state.websitePermissionsState.microphone.status).isEqualTo(
updatedMicrophoneStatus
)
assertThat(store.state.websitePermissionsState.microphone.isEnabled).isEqualTo(
updatedMicrophoneEnabledStatus
)
assertThat(store.state.websitePermissionsState.microphone.isVisible).isEqualTo(
defaultVisibilityStatus
)
assertThat(store.state.websitePermissionsState.microphone.isBlockedByAndroid).isEqualTo(
defaultBlockedByAndroidStatus
)
assertThat(store.state.websitePermissionsState.notification).isNotNull()
assertThat((store.state.websitePermissionsState.notification as WebsitePermission.Notification).name).isEqualTo(
notificationPermissionName
)
assertThat(store.state.websitePermissionsState.notification.status).isEqualTo(
initialNotificationStatus
)
assertThat(store.state.websitePermissionsState.notification.isVisible).isEqualTo(
defaultVisibilityStatus
)
assertThat(store.state.websitePermissionsState.notification.isEnabled).isEqualTo(
defaultEnabledStatus
)
assertThat(store.state.websitePermissionsState.notification.isBlockedByAndroid).isEqualTo(
defaultBlockedByAndroidStatus
)
assertThat(store.state.websitePermissionsState.location).isNotNull()
assertThat((store.state.websitePermissionsState.location as WebsitePermission.Location).name).isEqualTo(
locationPermissionName
)
assertThat(store.state.websitePermissionsState.location.status).isEqualTo(
initialLocationStatus
)
assertThat(store.state.websitePermissionsState.location.isVisible).isEqualTo(
defaultVisibilityStatus
)
assertThat(store.state.websitePermissionsState.location.isEnabled).isEqualTo(
defaultEnabledStatus
)
assertThat(store.state.websitePermissionsState.location.isBlockedByAndroid).isEqualTo(
defaultBlockedByAndroidStatus
)
}
}
@Test
fun `getSecuredWebsiteUiValues() should return the right values`() {
val uiValues = getSecuredWebsiteUiValues
assertAll {
assertThat(uiValues.first).isEqualTo(secureStringRes)
assertThat(uiValues.second).isEqualTo(secureDrawableRes)
assertThat(uiValues.third).isEqualTo(secureColorRes)
}
}
@Test
fun `getInsecureWebsiteUiValues() should return the right values`() {
val uiValues = getInsecureWebsiteUiValues
assertAll {
assertThat(uiValues.first).isEqualTo(insecureStringRes)
assertThat(uiValues.second).isEqualTo(insecureDrawableRes)
assertThat(uiValues.third).isEqualTo(insecureColorRes)
}
}
}