Skip to content

Commit

Permalink
[ANDROAPP-5931] Collapse event details and cat combo sections if comp…
Browse files Browse the repository at this point in the history
…leted (#3530)

Signed-off-by: Pablo <[email protected]>
  • Loading branch information
Balcan authored Mar 13, 2024
1 parent c95c237 commit d2b822c
Show file tree
Hide file tree
Showing 2 changed files with 250 additions and 7 deletions.
54 changes: 47 additions & 7 deletions form/src/main/java/org/dhis2/form/data/EventRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,53 @@ class EventRepository(
.blockingGet()
}

private val programStage by lazy {
d2.programModule()
.programStages()
.uid(event?.programStage())
.blockingGet()
}

override fun firstSectionToOpen(): String? {
return when (eventMode) {
EventMode.NEW -> super.firstSectionToOpen()
EventMode.CHECK -> firstSectionToOpenForEvent()
}
}

private fun firstSectionToOpenForEvent(): String? {
val (eventDataCompleted, attrOptionComboCompleted) = isEventDataCompleted()
return when {
!eventDataCompleted ->
EVENT_DETAILS_SECTION_UID

!attrOptionComboCompleted ->
EVENT_CATEGORY_COMBO_SECTION_UID

else -> sectionUids().blockingFirst().firstOrNull { sectionUid ->
sectionUid != EVENT_DETAILS_SECTION_UID &&
sectionUid != EVENT_CATEGORY_COMBO_SECTION_UID
}
}
}

private fun isEventDataCompleted(): Pair<Boolean, Boolean> {
val eventDateCompleted = event?.eventDate() != null
val orgUnitCompleted = event?.organisationUnit() != null
val hasFeatureType = programStage?.featureType() != null &&
programStage?.featureType() == FeatureType.NONE
val coordinatesCompleted = if (programStage?.featureType() != null) {
hasFeatureType && event?.geometry() != null
} else {
true
}

val dataCompleted = eventDateCompleted && orgUnitCompleted && coordinatesCompleted
val attrOptionComboCompleted = event?.attributeOptionCombo() != null

return Pair(dataCompleted, attrOptionComboCompleted)
}

override val programUid by lazy {
event?.program()
}
Expand All @@ -65,13 +112,6 @@ class EventRepository(
.toMap()
}

private val programStage by lazy {
d2.programModule()
.programStages()
.uid(event?.programStage())
.blockingGet()
}

override fun sectionUids(): Flowable<List<String>> {
val sectionUIDs = mutableListOf(EVENT_DETAILS_SECTION_UID)
if (shouldAddCategoryComboSection()) {
Expand Down
203 changes: 203 additions & 0 deletions form/src/test/java/org/dhis2/form/data/EventRepositoryTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
package org.dhis2.form.data

import io.reactivex.Single
import junit.framework.Assert.assertTrue
import org.dhis2.commons.date.DateUtils
import org.dhis2.commons.resources.ResourceManager
import org.dhis2.form.model.EventMode
import org.dhis2.form.ui.FieldViewModelFactory
import org.hisp.dhis.android.core.D2
import org.hisp.dhis.android.core.category.CategoryCombo
import org.hisp.dhis.android.core.common.Geometry
import org.hisp.dhis.android.core.event.Event
import org.hisp.dhis.android.core.program.Program
import org.hisp.dhis.android.core.program.ProgramStage
import org.hisp.dhis.android.core.program.ProgramStageSection
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito
import org.mockito.kotlin.anyOrNull
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.mockito.kotlin.whenever
import java.util.Date

class EventRepositoryTest {

private val eventUid = "eventUid"
private val programStageUid = "programStageUid"
private val programUid = "programUid"
private val orgUnitUid = "orgUnitUid"
private val catComboUid = "catComboUid"
private val attributeOptionComboUid = "attrOptionComboUid"
private val firstSectionUid = "firsSectionUid"
private val secondSectionUid = "secondSectionUid"

private val d2: D2 = Mockito.mock(D2::class.java, Mockito.RETURNS_DEEP_STUBS)
private val fieldViewModelFactory: FieldViewModelFactory = mock()
private val resources: ResourceManager = mock()
private val dateUtil: DateUtils = mock()

private val mockedProgram: Program = mock {
on { categoryComboUid() } doReturn catComboUid
}

private val catCombo: CategoryCombo = mock {
on { isDefault } doReturn false
}

private val mockedFirstSection: ProgramStageSection = mock {
on { uid() } doReturn firstSectionUid
}

private val mockedSecondSection: ProgramStageSection = mock {
on { uid() } doReturn secondSectionUid
}

@Before
fun setUp() {
whenever(
d2.programModule().programs().uid(programUid).get(),
) doReturn Single.just(mockedProgram)

whenever(
d2.categoryModule().categoryCombos().withCategories(),
) doReturn mock()
whenever(
d2.categoryModule().categoryCombos()
.withCategories()
.uid(catComboUid),
) doReturn mock()
whenever(
d2.categoryModule().categoryCombos()
.withCategories()
.uid(catComboUid)
.get(),
) doReturn Single.just(catCombo)
}

@Test
fun openEventDetailSectionsIfNewEvent() {
whenever(
d2.eventModule().events().uid(eventUid).blockingGet(),
) doReturn mockedEventWithDetails

mockSections()

val result = eventRepository(EventMode.NEW).firstSectionToOpen()
assertTrue(
result == EventRepository.EVENT_DETAILS_SECTION_UID,
)
}

@Test
fun openEventDetailSectionsIfCheckEvent() {
whenever(
d2.eventModule().events().uid(eventUid).blockingGet(),
) doReturn mockedEventNoDetails

whenever(
d2.programModule()
.programStages()
.uid(programStageUid)
.blockingGet(),
) doReturn mockedStage

val result = eventRepository(EventMode.CHECK).firstSectionToOpen()
assertTrue(
result == EventRepository.EVENT_DETAILS_SECTION_UID,
)
}

@Test
fun openCategoryComboSectionIfCheckEvent() {
whenever(
d2.eventModule().events().uid(eventUid).blockingGet(),
) doReturn mockedEventNoAttr

val result = eventRepository(EventMode.CHECK).firstSectionToOpen()
assertTrue(
result == EventRepository.EVENT_CATEGORY_COMBO_SECTION_UID,
)
}

@Test
fun openDataSectionIfCheckEvent() {
whenever(
d2.eventModule().events().uid(eventUid).blockingGet(),
) doReturn mockedEventWithDetails

mockSections()

val result = eventRepository(EventMode.CHECK).firstSectionToOpen()
assertTrue(
result == firstSectionUid,
)
}

private fun eventRepository(eventMode: EventMode) = EventRepository(
fieldFactory = fieldViewModelFactory,
eventUid = eventUid,
d2 = d2,
resources = resources,
dateUtils = dateUtil,
eventMode = eventMode,
)

private val mockedStage = mock<ProgramStage> {
on { featureType() } doReturn null
}

private val mockedEventNoDetails = mock<Event> {
on { program() } doReturn programUid
on { programStage() } doReturn programStageUid
on { eventDate() } doReturn null
on { organisationUnit() } doReturn null
on { geometry() } doReturn null
on { attributeOptionCombo() } doReturn null
}

private val mockedEventNoAttr = mock<Event> {
on { program() } doReturn programUid
on { programStage() } doReturn programStageUid
on { eventDate() } doReturn Date()
on { organisationUnit() } doReturn orgUnitUid
on { geometry() } doReturn mock<Geometry>()
on { attributeOptionCombo() } doReturn null
}

private val mockedEventWithDetails = mock<Event> {
on { program() } doReturn programUid
on { programStage() } doReturn programStageUid
on { eventDate() } doReturn Date()
on { organisationUnit() } doReturn orgUnitUid
on { geometry() } doReturn mock<Geometry>()
on { attributeOptionCombo() } doReturn attributeOptionComboUid
}

private fun mockSections() {
whenever(
d2.programModule().programStageSections()
.byProgramStageUid(),
) doReturn mock()
whenever(
d2.programModule().programStageSections()
.byProgramStageUid(),
) doReturn mock()
whenever(
d2.programModule().programStageSections()
.byProgramStageUid().eq(anyOrNull()),
) doReturn mock()
whenever(
d2.programModule().programStageSections()
.byProgramStageUid().eq(anyOrNull())
.withDataElements(),
) doReturn mock()
whenever(
d2.programModule().programStageSections()
.byProgramStageUid().eq(anyOrNull())
.withDataElements()
.blockingGet(),
) doReturn listOf(mockedFirstSection, mockedSecondSection)
}
}

0 comments on commit d2b822c

Please sign in to comment.