mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 15:15:34 +03:00
BIT-810: Implement resend notification (#803)
This commit is contained in:
parent
a7e393e325
commit
e5bfdd0fa7
4 changed files with 61 additions and 18 deletions
|
@ -4,12 +4,14 @@ import android.widget.Toast
|
|||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
|
@ -198,14 +200,28 @@ private fun LoginWithDeviceScreenContent(
|
|||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
BitwardenClickableText(
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.semantics { testTag = "ResendNotificationButton" }
|
||||
.fillMaxWidth(),
|
||||
label = stringResource(id = R.string.resend_notification),
|
||||
onClick = onResendNotificationClick,
|
||||
)
|
||||
.defaultMinSize(minHeight = 32.dp)
|
||||
.align(Alignment.Start),
|
||||
) {
|
||||
if (state.isResendNotificationLoading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 64.dp)
|
||||
.size(size = 16.dp),
|
||||
)
|
||||
} else {
|
||||
BitwardenClickableText(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 16.dp)
|
||||
.semantics { testTag = "ResendNotificationButton" }
|
||||
.fillMaxWidth(),
|
||||
label = stringResource(id = R.string.resend_notification),
|
||||
onClick = onResendNotificationClick,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(24.dp))
|
||||
|
||||
|
|
|
@ -52,8 +52,7 @@ class LoginWithDeviceViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun handleResendNotificationClicked() {
|
||||
// TODO BIT-810: implement Resend Notification button
|
||||
sendEvent(LoginWithDeviceEvent.ShowToast("Not yet implemented."))
|
||||
sendNewAuthRequest()
|
||||
}
|
||||
|
||||
private fun handleViewAllLogInOptionsClicked() {
|
||||
|
@ -69,6 +68,7 @@ class LoginWithDeviceViewModel @Inject constructor(
|
|||
it.copy(
|
||||
viewState = LoginWithDeviceState.ViewState.Content(
|
||||
fingerprintPhrase = action.result.authRequest.fingerprint,
|
||||
isResendNotificationLoading = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ class LoginWithDeviceViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun sendNewAuthRequest() {
|
||||
setIsResendNotificationLoading(true)
|
||||
viewModelScope.launch {
|
||||
trySendAction(
|
||||
LoginWithDeviceAction.Internal.NewAuthRequestResultReceive(
|
||||
|
@ -98,6 +99,21 @@ class LoginWithDeviceViewModel @Inject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setIsResendNotificationLoading(isLoading: Boolean) {
|
||||
when (val viewState = mutableStateFlow.value.viewState) {
|
||||
is LoginWithDeviceState.ViewState.Content -> {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
viewState = viewState.copy(
|
||||
isResendNotificationLoading = isLoading,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -139,6 +155,7 @@ data class LoginWithDeviceState(
|
|||
@Parcelize
|
||||
data class Content(
|
||||
val fingerprintPhrase: String,
|
||||
val isResendNotificationLoading: Boolean,
|
||||
) : ViewState()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@ class LoginWithDeviceScreenTest : BaseComposeTest() {
|
|||
emailAddress = EMAIL,
|
||||
viewState = LoginWithDeviceState.ViewState.Content(
|
||||
fingerprintPhrase = "alabster-drinkable-mystified-rapping-irrigate",
|
||||
isResendNotificationLoading = false,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@ class LoginWithDeviceViewModelTest : BaseViewModelTest() {
|
|||
emailAddress = newEmail,
|
||||
viewState = LoginWithDeviceState.ViewState.Content(
|
||||
fingerprintPhrase = FINGERPRINT,
|
||||
isResendNotificationLoading = false,
|
||||
),
|
||||
)
|
||||
val viewModel = createViewModel(state)
|
||||
|
@ -69,16 +70,22 @@ class LoginWithDeviceViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `ResendNotificationClick should emit ShowToast`() = runTest {
|
||||
fun `ResendNotificationClick should create new auth request and update state`() = runTest {
|
||||
val newFingerprint = "newFingerprint"
|
||||
coEvery {
|
||||
authRepository.createAuthRequest(EMAIL)
|
||||
} returns AuthRequestResult.Success(AUTH_REQUEST.copy(fingerprint = newFingerprint))
|
||||
val viewModel = createViewModel()
|
||||
viewModel.eventFlow.test {
|
||||
viewModel.actionChannel.trySend(LoginWithDeviceAction.ResendNotificationClick)
|
||||
assertEquals(DEFAULT_STATE, viewModel.stateFlow.value)
|
||||
assertEquals(
|
||||
LoginWithDeviceEvent.ShowToast("Not yet implemented."),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
viewModel.actionChannel.trySend(LoginWithDeviceAction.ResendNotificationClick)
|
||||
assertEquals(
|
||||
DEFAULT_STATE.copy(
|
||||
viewState = LoginWithDeviceState.ViewState.Content(
|
||||
fingerprintPhrase = newFingerprint,
|
||||
isResendNotificationLoading = false,
|
||||
),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -112,6 +119,7 @@ class LoginWithDeviceViewModelTest : BaseViewModelTest() {
|
|||
DEFAULT_STATE.copy(
|
||||
viewState = LoginWithDeviceState.ViewState.Content(
|
||||
fingerprintPhrase = newFingerprint,
|
||||
isResendNotificationLoading = false,
|
||||
),
|
||||
),
|
||||
viewModel.stateFlow.value,
|
||||
|
@ -152,6 +160,7 @@ class LoginWithDeviceViewModelTest : BaseViewModelTest() {
|
|||
emailAddress = EMAIL,
|
||||
viewState = LoginWithDeviceState.ViewState.Content(
|
||||
fingerprintPhrase = FINGERPRINT,
|
||||
isResendNotificationLoading = false,
|
||||
),
|
||||
)
|
||||
private val AUTH_REQUEST = AuthRequest(
|
||||
|
|
Loading…
Reference in a new issue