From f53d2b0f67bb0b281c03b7246bf4125cc69eb931 Mon Sep 17 00:00:00 2001 From: lwih Date: Wed, 6 Dec 2023 18:20:18 +0100 Subject: [PATCH 1/3] feature(PublicMissionApi): add filter by controlUnits --- .../domain/use_cases/missions/GetMissions.kt | 13 ++++++++++++- .../endpoints/publicapi/ApiMissionsController.kt | 4 ++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt index 40b87e54b0..d5e763bdd5 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt @@ -24,8 +24,9 @@ class GetMissions(private val missionRepository: IMissionRepository) { pageNumber: Int?, pageSize: Int?, seaFronts: List?, + controlUnits: List? = null, ): List { - val missions = + var missions: List = missionRepository.findAll( startedAfter = startedAfterDateTime?.toInstant() ?: ZonedDateTime.now().minusDays(30).toInstant(), @@ -49,6 +50,16 @@ class GetMissions(private val missionRepository: IMissionRepository) { }, ) + if (controlUnits != null) { + missions = missions.filter { mission -> + controlUnits.any { unit -> + mission.controlUnits.any { controlUnit -> + controlUnit.id == unit + } + } + }.toList() + } + logger.info("Found ${missions.size} mission(s)") return missions diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/publicapi/ApiMissionsController.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/publicapi/ApiMissionsController.kt index 22a7e90077..352f835381 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/publicapi/ApiMissionsController.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/infrastructure/api/endpoints/publicapi/ApiMissionsController.kt @@ -59,6 +59,9 @@ class ApiMissionsController( @Parameter(description = "Facades") @RequestParam(name = "seaFronts", required = false) seaFronts: List?, + @Parameter(description = "Unités de contrôle") + @RequestParam(name = "controlUnits", required = false) + controlUnits: List? = null, ): List { val missions = getMissions.execute( @@ -68,6 +71,7 @@ class ApiMissionsController( missionStatuses = missionStatuses, missionTypes = missionTypes, seaFronts = seaFronts, + controlUnits = controlUnits, pageNumber = pageNumber, pageSize = pageSize, ) From 909b9d231204e45ef2eae79eadf42e505f3b6924 Mon Sep 17 00:00:00 2001 From: lwih Date: Wed, 6 Dec 2023 19:34:08 +0100 Subject: [PATCH 2/3] test(GetMissions): add tests around filtering missions by controlUnits --- .../use_cases/missions/GetMissionsUTests.kt | 210 ++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt diff --git a/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt new file mode 100644 index 0000000000..ab07479ea7 --- /dev/null +++ b/backend/src/test/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissionsUTests.kt @@ -0,0 +1,210 @@ +package fr.gouv.cacem.monitorenv.domain.use_cases.missions + +import com.nhaarman.mockitokotlin2.given +import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionEntity +import fr.gouv.cacem.monitorenv.domain.repositories.IMissionRepository +import fr.gouv.cacem.monitorenv.domain.entities.controlUnit.LegacyControlUnitEntity +import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionTypeEnum +import fr.gouv.cacem.monitorenv.domain.entities.mission.MissionSourceEnum +import java.time.ZonedDateTime +import org.assertj.core.api.Assertions.assertThat +import org.junit.Test +import org.junit.jupiter.api.extension.ExtendWith +import org.springframework.boot.test.mock.mockito.MockBean +import org.springframework.test.context.junit.jupiter.SpringExtension +import com.nhaarman.mockitokotlin2.any + +@ExtendWith(SpringExtension::class) +class GetMissionsUTests { + @MockBean + private lateinit var missionRepository: IMissionRepository + + private val controlUnit1: LegacyControlUnitEntity = LegacyControlUnitEntity( + id = 1, + administration = "whatever", + isArchived = false, + name = "whatever", + resources = listOf(), + ) + + private val controlUnit2: LegacyControlUnitEntity = LegacyControlUnitEntity( + id = 2, + administration = "whatever", + isArchived = false, + name = "whatever", + resources = listOf(), + ) + + private val controlUnit3: LegacyControlUnitEntity = LegacyControlUnitEntity( + id = 3, + administration = "whatever", + isArchived = false, + name = "whatever", + resources = listOf(), + ) + + private val mission1 = + MissionEntity( + id = 10, + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isDeleted = false, + missionSource = MissionSourceEnum.MONITORFISH, + isClosed = false, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + controlUnits = listOf(controlUnit1, controlUnit2) + ) + + private val mission2 = + MissionEntity( + id = 11, + missionTypes = listOf(MissionTypeEnum.SEA), + startDateTimeUtc = ZonedDateTime.parse("2022-01-15T04:50:09Z"), + isDeleted = false, + missionSource = MissionSourceEnum.MONITORFISH, + isClosed = false, + hasMissionOrder = false, + isUnderJdp = false, + isGeometryComputedFromControls = false, + controlUnits = listOf(controlUnit1, controlUnit3) + ) + + @Test + fun `execute should return all missions when filter for controlUnits is null`() { + given(missionRepository.findAll( + startedAfter = any(), + startedBefore = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + seaFronts = any(), + pageable = any(), + )).willReturn(listOf(mission1, mission2)) + + val result = GetMissions(missionRepository).execute( + startedAfterDateTime = any(), + startedBeforeDateTime = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + pageNumber = any(), + pageSize = any(), + seaFronts = any(), + controlUnits = null + ) + + assertThat(result.size).isEqualTo(2) + } + + @Test + fun `execute should return all missions when filter for controlUnits is an empty list`() { + given(missionRepository.findAll( + startedAfter = any(), + startedBefore = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + seaFronts = any(), + pageable = any(), + )).willReturn(listOf(mission1, mission2)) + + val result = GetMissions(missionRepository).execute( + startedAfterDateTime = any(), + startedBeforeDateTime = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + pageNumber = any(), + pageSize = any(), + seaFronts = any(), + controlUnits = listOf() + ) + + assertThat(result.size).isEqualTo(2) + } + + @Test + fun `execute should only one missions when the controlUnits input matches 1 mission`() { + given(missionRepository.findAll( + startedAfter = any(), + startedBefore = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + seaFronts = any(), + pageable = any(), + )).willReturn(listOf(mission1, mission2)) + + val result = GetMissions(missionRepository).execute( + startedAfterDateTime = any(), + startedBeforeDateTime = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + pageNumber = any(), + pageSize = any(), + seaFronts = any(), + controlUnits = listOf(controlUnit2.id) + ) + + assertThat(result.size).isEqualTo(1) + assertThat(result.first()).isEqualTo(controlUnit2) + } + + @Test + fun `execute should only two missions when the same controlUnits input matches 2 missions`() { + given(missionRepository.findAll( + startedAfter = any(), + startedBefore = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + seaFronts = any(), + pageable = any(), + )).willReturn(listOf(mission1, mission2)) + + val result = GetMissions(missionRepository).execute( + startedAfterDateTime = any(), + startedBeforeDateTime = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + pageNumber = any(), + pageSize = any(), + seaFronts = any(), + controlUnits = listOf(controlUnit1.id) + ) + + assertThat(result.size).isEqualTo(2) + } + + @Test + fun `execute should return filtered missions matching nultiple controlUnits input`() { + given(missionRepository.findAll( + startedAfter = any(), + startedBefore = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + seaFronts = any(), + pageable = any(), + )).willReturn(listOf(mission1, mission2)) + + val result = GetMissions(missionRepository).execute( + startedAfterDateTime = any(), + startedBeforeDateTime = any(), + missionSources = any(), + missionTypes = any(), + missionStatuses = any(), + pageNumber = any(), + pageSize = any(), + seaFronts = any(), + controlUnits = listOf(controlUnit2.id, controlUnit3.id) + ) + + assertThat(result.size).isEqualTo(2) + } + +} From df1876f2930a828cdf2770eeccec3272733f8b98 Mon Sep 17 00:00:00 2001 From: Louis H <4593884+lwih@users.noreply.github.com> Date: Fri, 8 Dec 2023 10:25:31 +0100 Subject: [PATCH 3/3] refactor(GetMssions): use more explicit variable name Co-authored-by: Loup Theron --- .../cacem/monitorenv/domain/use_cases/missions/GetMissions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt index d5e763bdd5..b2db0c2216 100644 --- a/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt +++ b/backend/src/main/kotlin/fr/gouv/cacem/monitorenv/domain/use_cases/missions/GetMissions.kt @@ -52,7 +52,7 @@ class GetMissions(private val missionRepository: IMissionRepository) { if (controlUnits != null) { missions = missions.filter { mission -> - controlUnits.any { unit -> + controlUnits.any { unitId -> mission.controlUnits.any { controlUnit -> controlUnit.id == unit }