Merge pull request #4239 from element-hq/feature/bma/fixNightlyReports2
Fix nightly reports - next step
This commit is contained in:
@@ -23,17 +23,19 @@ open class PinUnlockStateProvider : PreviewParameterProvider<PinUnlockState> {
|
||||
aPinUnlockState(showWrongPinTitle = true),
|
||||
aPinUnlockState(showSignOutPrompt = true),
|
||||
aPinUnlockState(showBiometricUnlock = false),
|
||||
aPinUnlockState(showSignOutPrompt = true, remainingAttempts = 0),
|
||||
aPinUnlockState(showSignOutPrompt = true, remainingAttempts = AsyncData.Success(0)),
|
||||
aPinUnlockState(signOutAction = AsyncAction.Loading),
|
||||
aPinUnlockState(biometricUnlockResult = BiometricAuthenticator.AuthenticationResult.Failure(
|
||||
BiometricUnlockError(BiometricPrompt.ERROR_LOCKOUT, "Biometric auth disabled")
|
||||
)),
|
||||
aPinUnlockState(
|
||||
biometricUnlockResult = BiometricAuthenticator.AuthenticationResult.Failure(
|
||||
BiometricUnlockError(BiometricPrompt.ERROR_LOCKOUT, "Biometric auth disabled")
|
||||
)
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun aPinUnlockState(
|
||||
pinEntry: PinEntry = PinEntry.createEmpty(4),
|
||||
remainingAttempts: Int = 3,
|
||||
remainingAttempts: AsyncData<Int> = AsyncData.Success(3),
|
||||
showWrongPinTitle: Boolean = false,
|
||||
showSignOutPrompt: Boolean = false,
|
||||
showBiometricUnlock: Boolean = true,
|
||||
@@ -43,7 +45,7 @@ fun aPinUnlockState(
|
||||
) = PinUnlockState(
|
||||
pinEntry = AsyncData.Success(pinEntry),
|
||||
showWrongPinTitle = showWrongPinTitle,
|
||||
remainingAttempts = AsyncData.Success(remainingAttempts),
|
||||
remainingAttempts = remainingAttempts,
|
||||
showSignOutPrompt = showSignOutPrompt,
|
||||
showBiometricUnlock = showBiometricUnlock,
|
||||
signOutAction = signOutAction,
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.lockscreen.impl.unlock
|
||||
|
||||
import androidx.biometric.BiometricPrompt
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.features.lockscreen.impl.biometric.BiometricAuthenticator
|
||||
import io.element.android.features.lockscreen.impl.biometric.BiometricUnlockError
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import org.junit.Test
|
||||
|
||||
class PinUnlockStateTest {
|
||||
@Test
|
||||
fun `isSignOutPromptCancellable should have expected values`() {
|
||||
assertThat(aPinUnlockState(remainingAttempts = AsyncData.Uninitialized).isSignOutPromptCancellable).isTrue()
|
||||
assertThat(aPinUnlockState(remainingAttempts = AsyncData.Success(1)).isSignOutPromptCancellable).isTrue()
|
||||
assertThat(aPinUnlockState(remainingAttempts = AsyncData.Success(0)).isSignOutPromptCancellable).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `biometricUnlockErrorMessage and showBiometricUnlockError should have expected values`() {
|
||||
listOf(
|
||||
null,
|
||||
BiometricAuthenticator.AuthenticationResult.Failure(),
|
||||
BiometricAuthenticator.AuthenticationResult.Success,
|
||||
).forEach { biometricUnlockResult ->
|
||||
aPinUnlockState(
|
||||
biometricUnlockResult = biometricUnlockResult,
|
||||
).let {
|
||||
assertThat(it.biometricUnlockErrorMessage).isNull()
|
||||
assertThat(it.showBiometricUnlockError).isFalse()
|
||||
}
|
||||
}
|
||||
listOf(
|
||||
BiometricPrompt.ERROR_HW_UNAVAILABLE,
|
||||
BiometricPrompt.ERROR_UNABLE_TO_PROCESS,
|
||||
BiometricPrompt.ERROR_TIMEOUT,
|
||||
BiometricPrompt.ERROR_NO_SPACE,
|
||||
BiometricPrompt.ERROR_CANCELED,
|
||||
BiometricPrompt.ERROR_VENDOR,
|
||||
BiometricPrompt.ERROR_USER_CANCELED,
|
||||
BiometricPrompt.ERROR_NO_BIOMETRICS,
|
||||
BiometricPrompt.ERROR_HW_NOT_PRESENT,
|
||||
BiometricPrompt.ERROR_NEGATIVE_BUTTON,
|
||||
BiometricPrompt.ERROR_NO_DEVICE_CREDENTIAL,
|
||||
BiometricPrompt.ERROR_SECURITY_UPDATE_REQUIRED,
|
||||
).forEach { code ->
|
||||
aPinUnlockState(
|
||||
biometricUnlockResult = BiometricAuthenticator.AuthenticationResult.Failure(
|
||||
error = BiometricUnlockError(code, "Error message")
|
||||
),
|
||||
).let {
|
||||
assertThat(it.biometricUnlockErrorMessage).isNull()
|
||||
assertThat(it.showBiometricUnlockError).isFalse()
|
||||
}
|
||||
}
|
||||
listOf(
|
||||
BiometricPrompt.ERROR_LOCKOUT,
|
||||
BiometricPrompt.ERROR_LOCKOUT_PERMANENT,
|
||||
).forEach { code ->
|
||||
aPinUnlockState(
|
||||
biometricUnlockResult = BiometricAuthenticator.AuthenticationResult.Failure(
|
||||
error = BiometricUnlockError(code, "Error message")
|
||||
),
|
||||
).let {
|
||||
assertThat(it.biometricUnlockErrorMessage).isEqualTo("Error message")
|
||||
assertThat(it.showBiometricUnlockError).isTrue()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2025 New Vector Ltd.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
* Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
package io.element.android.features.securebackup.impl.root
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import io.element.android.libraries.architecture.AsyncData
|
||||
import io.element.android.libraries.matrix.api.encryption.BackupState
|
||||
import io.element.android.libraries.matrix.test.AN_EXCEPTION
|
||||
import org.junit.Test
|
||||
|
||||
class SecureBackupRootStateTest {
|
||||
@Test
|
||||
fun `isKeyStorageEnabled should be true for all these backup states`() {
|
||||
listOf(
|
||||
BackupState.CREATING,
|
||||
BackupState.ENABLING,
|
||||
BackupState.RESUMING,
|
||||
BackupState.DOWNLOADING,
|
||||
BackupState.ENABLED,
|
||||
).forEach { backupState ->
|
||||
assertThat(aSecureBackupRootState(backupState = backupState).isKeyStorageEnabled).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isKeyStorageEnabled should be false for all these backup states`() {
|
||||
listOf(
|
||||
BackupState.WAITING_FOR_SYNC,
|
||||
BackupState.DISABLING,
|
||||
).forEach { backupState ->
|
||||
assertThat(aSecureBackupRootState(backupState = backupState).isKeyStorageEnabled).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `isKeyStorageEnabled should have value depending on doesBackupExistOnServer when state is UNKNOWN`() {
|
||||
assertThat(
|
||||
aSecureBackupRootState(
|
||||
backupState = BackupState.UNKNOWN,
|
||||
doesBackupExistOnServer = AsyncData.Success(true),
|
||||
).isKeyStorageEnabled
|
||||
).isTrue()
|
||||
|
||||
listOf(
|
||||
AsyncData.Uninitialized,
|
||||
AsyncData.Loading(),
|
||||
AsyncData.Failure(AN_EXCEPTION),
|
||||
AsyncData.Success(false),
|
||||
).forEach { doesBackupExistOnServer ->
|
||||
assertThat(
|
||||
aSecureBackupRootState(
|
||||
backupState = BackupState.UNKNOWN,
|
||||
doesBackupExistOnServer = doesBackupExistOnServer,
|
||||
).isKeyStorageEnabled
|
||||
).isFalse()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,6 @@ fun Project.setupKover() {
|
||||
description = "Verifies the code coverage of all subprojects."
|
||||
val dependencies = listOf(":app:koverVerifyGplayDebug") + koverVariants.map { ":app:koverVerify${it.replaceFirstChar(Char::titlecase)}" }
|
||||
dependsOn(dependencies)
|
||||
|
||||
}
|
||||
// https://kotlin.github.io/kotlinx-kover/
|
||||
// Run `./gradlew :app:koverHtmlReport` to get report at ./app/build/reports/kover
|
||||
@@ -180,7 +179,9 @@ fun Project.setupKover() {
|
||||
"io.element.android.libraries.matrix.api.timeline.item.event.OtherState$*",
|
||||
"io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState*",
|
||||
"io.element.android.libraries.mediaviewer.impl.local.pdf.PdfViewerState",
|
||||
"io.element.android.libraries.mediaviewer.impl.local.player.MediaPlayerControllerState",
|
||||
"io.element.android.libraries.textcomposer.model.TextEditorState",
|
||||
"io.element.android.libraries.textcomposer.components.FormattingOptionState",
|
||||
)
|
||||
includes.classes("*State")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user