Skip to content

Commit

Permalink
fix: [ANDROAPP-5821] Add no options available category selector (#3460)
Browse files Browse the repository at this point in the history
* fix: [ANDROAPP-5821] add new no options available logic

* feat: [ANDROAPP-5821] sonar code smell fixes refactor and clean-up code

* feat: [ANDROAPP-5821] refactor code for sonar fix and remove options available for create new event button visibility

* fix: [ANDROAPP-5821] add test for empty category selector
  • Loading branch information
xavimolloy authored Jan 16, 2024
1 parent 63aa296 commit bbf47a8
Show file tree
Hide file tree
Showing 14 changed files with 507 additions and 347 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package org.dhis2.usescases.eventsWithoutRegistration.eventDetails

import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
Expand All @@ -23,8 +24,13 @@ import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.domain.Configu
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.domain.ConfigureEventTemp
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.domain.ConfigureOrgUnit
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.domain.CreateOrUpdateEventDetails
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventCatComboUiModel
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventCategory
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventInputDateUiModel
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.EMPTY_CATEGORY_SELECTOR
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.EventDetailResourcesProvider
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.INPUT_EVENT_INITIAL_DATE
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.ProvideCategorySelector
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.ProvideInputDate
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.ui.EventDetailsViewModel
import org.hisp.dhis.android.core.category.CategoryCombo
Expand Down Expand Up @@ -55,7 +61,7 @@ class EventInitialTest {
val date: Date? = dateFormat.parse(dateString)

private val eventDetailsRepository: EventDetailsRepository = mock {
on { getProgramStage()} doReturn programStage
on { getProgramStage() } doReturn programStage
on { catCombo() } doReturn catCombo
on { getEvent() } doReturn null
on { getObjectStyle() } doReturn style
Expand All @@ -64,7 +70,8 @@ class EventInitialTest {
on { getCatOptionCombos(CAT_COMBO_UID) } doReturn listOf(categoryOptionCombo)
on { getEditableStatus() } doReturn EventEditableStatus.Editable()
on { getEnrollmentDate(ENROLLMENT_UID) } doReturn date
on { getStageLastDate(ENROLLMENT_UID) } doReturn DateUtils.uiDateFormat().parse("20/8/2023")!!
on { getStageLastDate(ENROLLMENT_UID) } doReturn DateUtils.uiDateFormat()
.parse("20/8/2023")!!

}

Expand Down Expand Up @@ -99,9 +106,9 @@ class EventInitialTest {
on { value } doReturn COORDINATES
}

val eventDetailResourcesProvider: EventDetailResourcesProvider = mock {
on { provideDueDate() } doReturn "Due date"
}
private val eventDetailResourcesProvider: EventDetailResourcesProvider = mock {
on { provideDueDate() } doReturn "Due date"
}

private fun createConfigureEventTemp(eventCreationType: EventCreationType) = ConfigureEventTemp(
creationType = eventCreationType,
Expand Down Expand Up @@ -213,14 +220,16 @@ class EventInitialTest {
val date by viewModel.eventDate.collectAsState()
val details by viewModel.eventDetails.collectAsState()
ProvideInputDate(
eventDate = date,
detailsEnabled = details.enabled,
onDateClick = { viewModel.onDateClick() },
onDateSet = { dateValues ->
viewModel.onDateSet(dateValues.year, dateValues.month, dateValues.day)
},
onClear = { viewModel.onClearEventReportDate() },
required = true,
EventInputDateUiModel(
eventDate = date,
detailsEnabled = details.enabled,
onDateClick = { viewModel.onDateClick() },
onDateSet = { dateValues ->
viewModel.onDateSet(dateValues.year, dateValues.month, dateValues.day)
},
onClear = { viewModel.onClearEventReportDate() },
required = true,
)
)

}
Expand All @@ -244,19 +253,58 @@ class EventInitialTest {
val date by viewModel.eventDate.collectAsState()
val details by viewModel.eventDetails.collectAsState()
ProvideInputDate(
eventDate = date,
detailsEnabled = details.enabled,
onDateClick = { viewModel.onDateClick() },
onDateSet = { dateValues ->
viewModel.onDateSet(dateValues.year, dateValues.month, dateValues.day)
},
onClear = { viewModel.onClearEventReportDate() },
required = true,
EventInputDateUiModel(
eventDate = date,
detailsEnabled = details.enabled,
onDateClick = { viewModel.onDateClick() },
onDateSet = { dateValues ->
viewModel.onDateSet(dateValues.year, dateValues.month, dateValues.day)
},
onClear = { viewModel.onClearEventReportDate() },
required = true,
)

)

}
composeTestRule.onNodeWithTag(INPUT_EVENT_INITIAL_DATE).assertIsDisplayed()
assert(viewModel.eventDate.value.dateValue == "20/8/2023")
}

@Test
fun shouldShowEmptyCategorySelectorIfCategoryHasNoOptions() {

viewModel = initViewModel(
periodType = null,
eventCreationType = EventCreationType.SCHEDULE,
enrollmentStatus = EnrollmentStatus.ACTIVE,
scheduleInterval = 0
)
composeTestRule.setContent {
val date by viewModel.eventDate.collectAsState()
val details by viewModel.eventDetails.collectAsState()
val catCombo by viewModel.eventCatCombo.collectAsState()

ProvideCategorySelector(
modifier = Modifier,
eventCatComboUiModel = EventCatComboUiModel(
EventCategory("UID", "NO OPTIONS ", 0, emptyList()),
eventCatCombo = catCombo,
detailsEnabled = details.enabled,
currentDate = date.currentDate,
selectedOrgUnit = details.selectedOrgUnit,
onShowCategoryDialog = {
},
onClearCatCombo = {
},
onOptionSelected = {
},
required = true,
noOptionsText = "No options available",
catComboText = "No options catCombo",
)
)
}
composeTestRule.onNodeWithTag(EMPTY_CATEGORY_SELECTOR).assertIsDisplayed()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import android.os.Bundle
import android.view.View
import android.widget.DatePicker
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.unit.dp
import androidx.databinding.DataBindingUtil
import org.dhis2.App
import org.dhis2.R
Expand All @@ -20,6 +16,7 @@ import org.dhis2.commons.dialogs.calendarpicker.OnDatePickerListener
import org.dhis2.databinding.ActivityEventScheduledBinding
import org.dhis2.usescases.eventsWithoutRegistration.eventCapture.EventCaptureActivity
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventDate
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models.EventInputDateUiModel
import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.ProvideInputDate
import org.dhis2.usescases.eventsWithoutRegistration.eventInitial.EventInitialActivity
import org.dhis2.usescases.general.ActivityGlobalAbstract
Expand Down Expand Up @@ -111,28 +108,31 @@ class ScheduledEventActivity : ActivityGlobalAbstract(), ScheduledEventContract.
?: getString(R.string.report_date),
dateValue = "",
)
Spacer(modifier = Modifier.height(16.dp))

ProvideInputDate(
eventDate = eventDate,
allowsManualInput = false,
detailsEnabled = true,
onDateClick = { setEvenDateListener(programStage.periodType()) },
onDateSet = {},
onClear = {},
EventInputDateUiModel(
eventDate = eventDate,
allowsManualInput = false,
detailsEnabled = true,
onDateClick = { setEvenDateListener(programStage.periodType()) },
onDateSet = {},
onClear = {},
),

)
if (programStage.hideDueDate() == false) {
val dueDate = EventDate(
label = programStage.dueDateLabel() ?: getString(R.string.due_date),
dateValue = DateUtils.uiDateFormat().format(event.dueDate() ?: ""),
)
Spacer(modifier = Modifier.height(16.dp))
ProvideInputDate(
eventDate = dueDate,
detailsEnabled = true,
onDateClick = { setDueDateListener(programStage.periodType()) },
onDateSet = {},
onClear = {},
EventInputDateUiModel(
eventDate = dueDate,
detailsEnabled = true,
onDateClick = { setDueDateListener(programStage.periodType()) },
onDateSet = {},
onClear = {},
),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,11 @@ class EventDetailsRepository(
.one().blockingGet()?.uid()
}

fun getCatOptionComboDisplayName(categoryComboUid: String): String? {
return d2.categoryModule().categoryCombos().uid(categoryComboUid)
.blockingGet()?.displayName()
}

fun getCatOption(selectedOption: String?): CategoryOption? {
return d2.categoryModule().categoryOptions().uid(selectedOption).blockingGet()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,13 @@ class ConfigureEventCatCombo(
repository.catCombo().apply {
val categories = getCategories(this?.categories())
val categoryOptions = getCategoryOptions()

val catComboUid = getCatComboUid(this?.uid() ?: "", this?.isDefault ?: false)
val catComboDisplayName = getCatComboDisplayName(this?.uid() ?: "")
updateSelectedOptions(categoryOption, categories, categoryOptions)

return flowOf(
EventCatCombo(
uid = getCatComboUid(this?.uid() ?: "", this?.isDefault ?: false),
uid = catComboUid,
isDefault = this?.isDefault ?: false,
categories = categories,
categoryOptions = categoryOptions,
Expand All @@ -34,6 +35,7 @@ class ConfigureEventCatCombo(
categories = this?.categories(),
selectedCategoryOptions = selectedCategoryOptions,
),
displayName = catComboDisplayName,
),
)
}
Expand Down Expand Up @@ -73,6 +75,10 @@ class ConfigureEventCatCombo(
return null
}

private fun getCatComboDisplayName(categoryComboUid: String): String? {
return repository.getCatOptionComboDisplayName(categoryComboUid)
}

private fun updateSelectedOptions(
categoryOption: Pair<String, String?>?,
categories: List<EventCategory>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ data class EventCatCombo(
val categoryOptions: Map<String, CategoryOption>? = null,
val selectedCategoryOptions: Map<String, CategoryOption?> = HashMap(),
val isCompleted: Boolean = false,
val displayName: String? = "",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models

import org.hisp.dhis.android.core.category.CategoryOption
import java.util.Date

data class EventCatComboUiModel(
val category: EventCategory,
val eventCatCombo: EventCatCombo,
val detailsEnabled: Boolean,
val currentDate: Date?,
val selectedOrgUnit: String?,
val onShowCategoryDialog: (EventCategory) -> Unit,
val onClearCatCombo: (EventCategory) -> Unit,
val onOptionSelected: (CategoryOption?) -> Unit,
val required: Boolean = false,
val noOptionsText: String,
val catComboText: String,
val showField: Boolean = true,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.dhis2.usescases.eventsWithoutRegistration.eventDetails.models

import org.dhis2.usescases.eventsWithoutRegistration.eventDetails.providers.InputDateValues

data class EventInputDateUiModel(
val eventDate: EventDate,
val detailsEnabled: Boolean,
val onDateClick: () -> Unit,
val allowsManualInput: Boolean = true,
val onDateSet: (InputDateValues) -> Unit,
val onClear: () -> Unit,
val required: Boolean = false,
val showField: Boolean = true,
)
Loading

0 comments on commit bbf47a8

Please sign in to comment.