Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ internal class LoginFormFragment : Fragment(R.layout.fragment_login_form) {
private val viewModel by viewModels<LoginFormViewModel>()

private lateinit var checkForPlayServicesResultLauncher: ActivityResultLauncher<IntentSenderRequest>

init {
checkForPlayServicesResultLauncher =
registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) {
Expand Down Expand Up @@ -93,11 +94,6 @@ internal class LoginFormFragment : Fragment(R.layout.fragment_login_form) {
}
binding.loginButtonSignIn.setOnClickListener {
Simber.tag(LoggingConstants.CrashReportTag.LOGIN.name).i("Login button clicked")

binding.loginProgress.isVisible = true
binding.loginButtonScanQr.isEnabled = false
binding.loginButtonSignIn.isEnabled = false

viewModel.signInClicked(
args.loginParams,
binding.loginProjectId.text.toString(),
Expand All @@ -107,17 +103,18 @@ internal class LoginFormFragment : Fragment(R.layout.fragment_login_form) {
}

private fun observeUiState() {
viewModel.isProcessingSignIn.observe(viewLifecycleOwner) { isProcessingSignIn ->
binding.loginProgress.isVisible = isProcessingSignIn
binding.loginButtonScanQr.isEnabled = !isProcessingSignIn
binding.loginButtonSignIn.isEnabled = !isProcessingSignIn
}
viewModel.signInState.observe(viewLifecycleOwner) { event ->
event?.getContentIfNotHandled()?.let(::handleSignInResult)
}
}

private fun handleSignInResult(result: SignInState) {
binding.loginProgress.isVisible = false
binding.loginErrorCard.isVisible = false
binding.loginButtonScanQr.isEnabled = true
binding.loginButtonSignIn.isEnabled = true


when (result) {
// Showing toast
Expand Down Expand Up @@ -153,7 +150,12 @@ internal class LoginFormFragment : Fragment(R.layout.fragment_login_form) {

private fun showOutageErrorCard(estimatedOutage: String?) {
binding.loginErrorText.text = estimatedOutage
?.let { getString(IDR.string.error_backend_maintenance_with_time_message, estimatedOutage) }
?.let {
getString(
IDR.string.error_backend_maintenance_with_time_message,
estimatedOutage
)
}
?: getString(IDR.string.error_backend_maintenance_message)
binding.loginErrorCard.isVisible = true
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ internal class LoginFormViewModel @Inject constructor(
private val jsonHelper: JsonHelper,
) : ViewModel() {

val isProcessingSignIn: LiveData<Boolean>
get() = _isProcessingSignIn
private val _isProcessingSignIn = MutableLiveData<Boolean>()
val signInState: LiveData<LiveDataEventWithContent<SignInState>>
get() = _signInState
private val _signInState = MutableLiveData<LiveDataEventWithContent<SignInState>>(null)
Expand All @@ -46,8 +49,15 @@ internal class LoginFormViewModel @Inject constructor(
_signInState.send(SignInState.ProjectIdMismatch)
} else {
viewModelScope.launch {
val result = authManager.authenticateSafely(loginParams.userId.value, projectId, projectSecret, deviceId)
_isProcessingSignIn.value = true
val result = authManager.authenticateSafely(
userId = loginParams.userId.value,
projectId = projectId,
projectSecret = projectSecret,
deviceId = deviceId
)
_signInState.send(mapAuthDataResult(result))
_isProcessingSignIn.value = false
}
}
}
Expand Down Expand Up @@ -81,7 +91,12 @@ internal class LoginFormViewModel @Inject constructor(

Simber.tag(CrashReportTag.LOGIN.name).i("QR scanning successful")
qrContent.apiBaseUrl?.let { simNetwork.setApiBaseUrl(it) }
_signInState.send(SignInState.QrCodeValid(qrContent.projectId, qrContent.projectSecret))
_signInState.send(
SignInState.QrCodeValid(
qrContent.projectId,
qrContent.projectSecret
)
)
} catch (e: Exception) {
Simber.tag(CrashReportTag.LOGIN.name).i("QR scanning unsuccessful")
_signInState.send(SignInState.QrInvalidCode)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.simprints.feature.login.screens.form

import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import androidx.lifecycle.Observer
import com.google.common.truth.Truth.assertThat
import com.simprints.core.domain.tokenization.asTokenizableRaw
import com.simprints.core.tools.json.JsonHelper
Expand All @@ -18,6 +19,8 @@ import io.mockk.clearMocks
import io.mockk.coEvery
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.mockk
import io.mockk.slot
import io.mockk.verify
import org.junit.Before
import org.junit.Rule
Expand Down Expand Up @@ -93,6 +96,23 @@ internal class LoginFormViewModelTest {
assertThat(result.getContentIfNotHandled()).isInstanceOf(SignInState.ProjectIdMismatch::class.java)
}

@Test
fun `returns false from isProcessingSignIn sign in request is processed`() {
coEvery { authManager.authenticateSafely(any(), any(), any(), any()) } returns AuthenticateDataResult.Authenticated
val observer = mockk<Observer<Boolean>>()
val slot = slot<Boolean>()
val capturedValues = mutableListOf<Boolean>()
every { observer.onChanged(capture(slot)) } answers {
capturedValues.add(slot.captured)
}
viewModel.isProcessingSignIn.observeForever(observer)

viewModel.signInClicked(LoginParams(PROJECT_ID, USER_ID), PROJECT_ID, PROJECT_SECRET)

// Checking that captured values sequence contains 'true' and 'false', in that order
assertThat(capturedValues).isEqualTo(listOf(true, false))
}

@Test
fun `returns correct SignInState for each auth result class`() {
mapOf(
Expand Down