Skip to content

Commit

Permalink
fix: [ANDROAPP-6705] allow future dates (#3929)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmmateos authored Jan 7, 2025
1 parent f8a5a7c commit 6546046
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.dhis2.usescases.teidashboard.robot

import android.content.Context
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.hasAnySibling
import androidx.compose.ui.test.hasTestTag
Expand Down Expand Up @@ -97,7 +98,9 @@ class TeiDashboardRobot(val composeTestRule: ComposeTestRule) : BaseRobot() {
composeTestRule.onNodeWithText("Enrollment cancelled").assertIsDisplayed()
}

@OptIn(ExperimentalTestApi::class)
fun clickOnEventWithTitle(title: String) {
composeTestRule.waitUntilExactlyOneExists(hasText(title))
composeTestRule.onNodeWithText(title).performClick()
}

Expand Down
21 changes: 12 additions & 9 deletions form/src/main/java/org/dhis2/form/ui/FormViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -343,20 +343,23 @@ class FormViewModel(
private fun saveLastFocusedItem(rowAction: RowAction) = getLastFocusedTextItem()?.let {
if (previousActionItem == null) previousActionItem = rowAction
if (previousActionItem?.value != it.value && previousActionItem?.id == it.uid) {
val error = checkFieldError(it.valueType, it.value, it.fieldMask)
if (error != null) {
val action = rowActionFromIntent(
FormIntent.OnSave(it.uid, it.value, it.valueType, it.fieldMask),
)
val action = rowActionFromIntent(
FormIntent.OnSave(
it.uid,
it.value,
it.valueType,
it.fieldMask,
it.allowFutureDates,
),
)
if (action.error != null) {
repository.updateErrorList(action)
StoreResult(
rowAction.id,
ValueStoreResult.VALUE_HAS_NOT_CHANGED,
)
} else {
checkAutoCompleteForLastFocusedItem(it)
val intent = FormIntent.OnSave(it.uid, it.value, it.valueType, it.fieldMask)
val action = rowActionFromIntent(intent)
val result = repository.save(it.uid, it.value, action.extraData)
repository.updateValueOnList(it.uid, it.value, it.valueType)
repository.updateErrorList(action)
Expand Down Expand Up @@ -809,13 +812,13 @@ class FormViewModel(

fun discardChanges() {
repository.backupOfChangedItems().forEach {
submitIntent(FormIntent.OnSave(it.uid, it.value, it.valueType, it.fieldMask))
submitIntent(FormIntent.OnSave(it.uid, it.value, it.valueType, it.fieldMask, it.allowFutureDates))
}
}

fun saveDataEntry() {
getLastFocusedTextItem()?.let {
submitIntent(FormIntent.OnSave(it.uid, it.value, it.valueType, it.fieldMask))
submitIntent(FormIntent.OnSave(it.uid, it.value, it.valueType, it.fieldMask, it.allowFutureDates))
}
submitIntent(FormIntent.OnFinish())
}
Expand Down
59 changes: 56 additions & 3 deletions form/src/test/java/org/dhis2/form/ui/FormViewModelTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import android.content.Intent
import androidx.arch.core.executor.testing.InstantTaskExecutorRule
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.StandardTestDispatcher
import kotlinx.coroutines.test.advanceUntilIdle
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.test.setMain
import org.dhis2.commons.prefs.PreferenceProvider
Expand All @@ -16,6 +17,7 @@ import org.dhis2.form.data.GeometryController
import org.dhis2.form.data.MissingMandatoryResult
import org.dhis2.form.data.SuccessfulResult
import org.dhis2.form.model.ActionType
import org.dhis2.form.model.FieldUiModel
import org.dhis2.form.model.RowAction
import org.dhis2.form.model.StoreResult
import org.dhis2.form.model.ValueStoreResult
Expand All @@ -28,9 +30,13 @@ import org.junit.Before
import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.mockito.kotlin.whenever
import java.time.LocalDate
import java.time.format.DateTimeFormatter

@ExperimentalCoroutinesApi
class FormViewModelTest {
Expand All @@ -39,8 +45,9 @@ class FormViewModelTest {
val instantExecutorRule = InstantTaskExecutorRule()

private val repository: FormRepository = mock()
private val testingDispatcher = StandardTestDispatcher()
private val dispatcher: DispatcherProvider = mock {
on { io() } doReturn Dispatchers.IO
on { io() } doReturn testingDispatcher
}
private val preferenceProvider: PreferenceProvider = mock()
private val geometryController: GeometryController = mock()
Expand All @@ -49,13 +56,14 @@ class FormViewModelTest {

@Before
fun setUp() {
Dispatchers.setMain(UnconfinedTestDispatcher())
Dispatchers.setMain(testingDispatcher)

viewModel = FormViewModel(
repository,
dispatcher,
geometryController,
)
whenever(repository.getDateFormatConfiguration()) doReturn "ddMMyyyy"
}

@Ignore("We need to update Kotlin version in order to test coroutines")
Expand Down Expand Up @@ -161,4 +169,49 @@ class FormViewModelTest {

assertTrue(viewModel.getUpdatedData(uiEvent).value == uiEvent.value)
}

@Test
fun `Should not save last focused item when is not allowed future dates`() = runTest {
val dateField = dateFieldNotAllowedFuture
whenever(repository.currentFocusedItem()) doReturn dateField
viewModel.previousActionItem = RowAction(
id = dateField.uid,
value = "2024-12-12",
type = ActionType.ON_FOCUS,
)
viewModel.submitIntent(FormIntent.OnFocus("newField", null))
advanceUntilIdle()
verify(repository).updateErrorList(any())
}

@Test
fun `Should save last focused item with future date when is allowed future dates`() = runTest {
val dateField = dateFieldFuture
whenever(repository.currentFocusedItem()) doReturn dateField
viewModel.previousActionItem = RowAction(
id = dateField.uid,
value = "2024-12-12",
type = ActionType.ON_FOCUS,
)
viewModel.submitIntent(FormIntent.OnFocus("newField", null))
advanceUntilIdle()
verify(repository).save(dateField.uid, dateField.value, null)
verify(repository).updateValueOnList(dateField.uid, dateField.value, dateField.valueType)
}

private val futureDate: String = LocalDate.now().plusDays(1).format(DateTimeFormatter.ISO_DATE)

private val dateFieldFuture: FieldUiModel = mock {
on { uid } doReturn "fieldUid"
on { valueType } doReturn ValueType.DATE
on { allowFutureDates } doReturn true
on { value } doReturn futureDate
}

private val dateFieldNotAllowedFuture: FieldUiModel = mock {
on { uid } doReturn "fieldUid"
on { valueType } doReturn ValueType.DATE
on { allowFutureDates } doReturn false
on { value } doReturn futureDate
}
}

0 comments on commit 6546046

Please sign in to comment.