Skip to content

Commit

Permalink
tech: add reporting validation
Browse files Browse the repository at this point in the history
  • Loading branch information
maximeperrault committed Jan 20, 2025
1 parent 345f406 commit aff2b85
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@ package fr.gouv.cacem.monitorenv.domain.use_cases.reportings
import fr.gouv.cacem.monitorenv.config.UseCase
import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingEntity
import fr.gouv.cacem.monitorenv.domain.exceptions.ReportingAlreadyAttachedException
import fr.gouv.cacem.monitorenv.domain.repositories.*
import fr.gouv.cacem.monitorenv.domain.repositories.IFacadeAreasRepository
import fr.gouv.cacem.monitorenv.domain.repositories.IPostgisFunctionRepository
import fr.gouv.cacem.monitorenv.domain.repositories.IReportingRepository
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.dtos.ReportingDTO
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.events.UpdateReportingEvent
import fr.gouv.cacem.monitorenv.domain.validators.UseCaseValidation
import fr.gouv.cacem.monitorenv.domain.validators.reporting.ReportingValidator
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.context.ApplicationEventPublisher
Expand All @@ -20,7 +24,10 @@ class CreateOrUpdateReporting(
private val logger: Logger = LoggerFactory.getLogger(CreateOrUpdateReporting::class.java)

@Throws(IllegalArgumentException::class)
fun execute(reporting: ReportingEntity): ReportingDTO {
fun execute(
@UseCaseValidation<ReportingEntity>(validator = ReportingValidator::class)
reporting: ReportingEntity,
): ReportingDTO {
logger.info("Attempt to CREATE or UPDATE reporting ${reporting.id}")
reporting.validate()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package fr.gouv.cacem.monitorenv.domain.validators.reporting

import fr.gouv.cacem.monitorenv.domain.entities.reporting.ReportingEntity
import fr.gouv.cacem.monitorenv.domain.entities.reporting.SourceTypeEnum
import fr.gouv.cacem.monitorenv.domain.exceptions.BackendUsageErrorCode
import fr.gouv.cacem.monitorenv.domain.exceptions.BackendUsageException
import fr.gouv.cacem.monitorenv.domain.validators.Validator
import org.slf4j.LoggerFactory
import org.springframework.stereotype.Component

private const val NB_CHAR_MAX = 3

@Component
class ReportingValidator : Validator<ReportingEntity> {
private val logger = LoggerFactory.getLogger(ReportingValidator::class.java)

override fun validate(reporting: ReportingEntity) {
logger.info("Validating reporting: ${reporting.id}")

if (reporting.openBy !== null && reporting.openBy.length != NB_CHAR_MAX) {
throw BackendUsageException(
BackendUsageErrorCode.UNVALID_PROPERTY,
"Le trigramme \"ouvert par\" doit avoir 3 lettres",
)
}
if (reporting.reportingSources.isEmpty()) {
throw BackendUsageException(
BackendUsageErrorCode.UNVALID_PROPERTY,
"Une source du signalement est obligatoire",
)
}
if (reporting.validityTime == 0) {
throw BackendUsageException(
BackendUsageErrorCode.UNVALID_PROPERTY,
"La validité du signalement doit être supérieur à 0",
)
}
reporting.reportingSources.forEach { source ->
when (source.sourceType) {
SourceTypeEnum.SEMAPHORE -> {
if (source.semaphoreId === null || source.controlUnitId !== null || source.sourceName !== null) {
throw BackendUsageException(
BackendUsageErrorCode.UNVALID_PROPERTY,
"La source du signalement est invalide",
)
}
}

SourceTypeEnum.CONTROL_UNIT -> {
if (source.semaphoreId !== null || source.controlUnitId === null || source.sourceName !== null) {
throw BackendUsageException(
BackendUsageErrorCode.UNVALID_PROPERTY,
"La source du signalement est invalide",
)
}
}

SourceTypeEnum.OTHER -> {
if (source.semaphoreId !== null || source.controlUnitId !== null || source.sourceName === null) {
throw BackendUsageException(
BackendUsageErrorCode.UNVALID_PROPERTY,
"La source du signalement est invalide",
)
}
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import org.springframework.data.repository.CrudRepository
interface IDBDepartmentAreaRepository : CrudRepository<DepartmentAreaModel, Int> {
@Query(
value =
"""
"""
SELECT *
FROM departments_areas
WHERE insee_dep = :inseeCode
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class EnvActionFixture {
actionNumberOfControls: Int? = infractions.size,
actionTargetTypeEnum: ActionTargetTypeEnum? = null,
vehicleTypeEnum: VehicleTypeEnum? = null,
controlPlans: List<EnvActionControlPlanEntity>? =
listOf(EnvActionControlPlanEntity(subThemeIds = listOf(1))),
): EnvActionControlEntity {
return EnvActionControlEntity(
id = UUID.randomUUID(),
Expand All @@ -73,20 +75,23 @@ class EnvActionFixture {
actionNumberOfControls = actionNumberOfControls,
actionTargetType = actionTargetTypeEnum,
vehicleType = vehicleTypeEnum,
controlPlans = controlPlans,
)
}

fun anEnvActionSurveillance(
startTime: ZonedDateTime? = null,
endTime: ZonedDateTime? = null,
openBy: String? = "CDA",
controlPlans: List<EnvActionControlPlanEntity>? = listOf(),
): EnvActionSurveillanceEntity {
return EnvActionSurveillanceEntity(
id = UUID.randomUUID(),
actionStartDateTimeUtc = startTime,
actionEndDateTimeUtc = endTime,
openBy = openBy,
awareness = null,
controlPlans = controlPlans,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ class ReportingFixture {
companion object {
fun aReporting(
id: Int? = null,
reportingSources: List<ReportingSourceEntity> = listOf(),
reportingSources: List<ReportingSourceEntity> = listOf(aReportingSourceSemaphore()),
missionId: Int? = null,
attachedToMissionAtUtc: ZonedDateTime? = null,
attachedEnvActionId: UUID? = null,
validityTime: Int = 10,
openBy: String = "CDA",
): ReportingEntity {
val wktReader = WKTReader()

Expand All @@ -43,11 +45,11 @@ class ReportingFixture {
isControlRequired = true,
hasNoUnitAvailable = true,
createdAt = ZonedDateTime.parse("2022-01-15T04:50:09Z"),
validityTime = 10,
validityTime = validityTime,
isArchived = false,
isDeleted = false,
updatedAtUtc = ZonedDateTime.now(),
openBy = "CDA",
openBy = openBy,
isInfractionProven = true,
missionId = missionId,
attachedToMissionAtUtc = attachedToMissionAtUtc,
Expand Down Expand Up @@ -100,5 +102,19 @@ class ReportingFixture {
sourceName = null,
)
}

fun aReportingSourceOther(
reportingId: Int? = null,
sourceName: String = "test",
): ReportingSourceEntity {
return ReportingSourceEntity(
id = null,
reportingId = reportingId,
sourceType = SourceTypeEnum.OTHER,
semaphoreId = null,
controlUnitId = null,
sourceName = sourceName,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package fr.gouv.cacem.monitorenv.domain.validators.reporting

import fr.gouv.cacem.monitorenv.domain.exceptions.BackendUsageException
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.fixtures.ReportingFixture.Companion.aReporting
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.fixtures.ReportingFixture.Companion.aReportingSourceControlUnit
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.fixtures.ReportingFixture.Companion.aReportingSourceOther
import fr.gouv.cacem.monitorenv.domain.use_cases.reportings.fixtures.ReportingFixture.Companion.aReportingSourceSemaphore
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.ValueSource

class ReportingValidatorUTest {
private val reportingValidator = ReportingValidator()

@ParameterizedTest
@ValueSource(strings = ["A", "AA", "AAAA"])
fun `validate should throw an exception if there is a control with openBy is not a trigram`(openBy: String) {
val reporting = aReporting(openBy = openBy)

val assertThrows = assertThrows(BackendUsageException::class.java) { reportingValidator.validate(reporting) }
assertThat(assertThrows.message).isEqualTo("Le trigramme \"ouvert par\" doit avoir 3 lettres")
}

@Test
fun `validate should throw an exception if reportingSource is empty`() {
val reporting = aReporting(reportingSources = listOf())

val assertThrows = assertThrows(BackendUsageException::class.java) { reportingValidator.validate(reporting) }
assertThat(assertThrows.message).isEqualTo("Une source du signalement est obligatoire")
}

@Test
fun `validate should throw an exception if reportingSource from control unit is invalid`() {
val reporting = aReporting(reportingSources = listOf(aReportingSourceControlUnit().copy(semaphoreId = 1)))

val assertThrows = assertThrows(BackendUsageException::class.java) { reportingValidator.validate(reporting) }
assertThat(assertThrows.message).isEqualTo("La source du signalement est invalide")
}

@Test
fun `validate should throw an exception if reportingSource from semaphore is invalid`() {
val reporting = aReporting(reportingSources = listOf(aReportingSourceSemaphore().copy(sourceName = "test")))

val assertThrows = assertThrows(BackendUsageException::class.java) { reportingValidator.validate(reporting) }
assertThat(assertThrows.message).isEqualTo("La source du signalement est invalide")
}

@Test
fun `validate should throw an exception if reportingSource from other is invalid`() {
val reporting = aReporting(reportingSources = listOf(aReportingSourceOther().copy(controlUnitId = 1)))

val assertThrows = assertThrows(BackendUsageException::class.java) { reportingValidator.validate(reporting) }
assertThat(assertThrows.message).isEqualTo("La source du signalement est invalide")
}

@Test
fun `validate should throw an exception if validityTime is less than 1`() {
val reporting = aReporting(validityTime = 0)

val assertThrows = assertThrows(BackendUsageException::class.java) { reportingValidator.validate(reporting) }
assertThat(assertThrows.message).isEqualTo("La validité du signalement doit être supérieur à 0")
}

@Test
fun `validate should pass for a valid ReportingEntity`() {
val reporting = aReporting()

reportingValidator.validate(reporting)
}
}

0 comments on commit aff2b85

Please sign in to comment.