Validate private areas across apartment form (#44)

This commit is contained in:
nessar committed 2026-08-17 14:18:16 +02:00
1 parent b9f5540394
commit 72d3f0ccfa
9 files changed
+323 -44

No files matched your search

@@ -6,6 +6,7 @@ import fr.nessar.lmnporganizer.rental.domain.apartment.ApartmentLegalProfile.Bui
import fr.nessar.lmnporganizer.rental.domain.apartment.ApartmentLegalProfile.ConstructionPeriod;
import fr.nessar.lmnporganizer.rental.domain.apartment.PrivateArea;
import jakarta.validation.Valid;
import jakarta.validation.constraints.AssertTrue;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
@@ -106,6 +107,11 @@ record PrivateAreaRequest(
@NotNull PrivateArea.Family family,
@NotNull PrivateArea.Subtype subtype,
@NotBlank String label) {
@AssertTrue
boolean isSubtypeCompatibleWithFamily() {
return family == null || subtype == null || family.accepts(subtype);
}
PrivateArea toDomain() {
return new PrivateArea(id, family, subtype, label);
}
@@ -813,6 +813,37 @@ void apartmentRequestsExposeEveryCoreValidationFailureWithStableFieldsAndCodes()
jsonPath("$.errors[*].code", containsInAnyOrder("not_blank", "not_blank", "positive")));
}
@Test
void apartmentRequestsExposeEveryInvalidPrivateAreaWithIndexedStableFieldsAndCodes()
throws Exception {
mockMvc
.perform(
post("/api/apartments")
.with(asLandlord())
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(
"""
{"name":"Studio","address":"1 rue du Test","purchasePrice":1,"privateAreas":[
{"id":"area-1","family":"ANNEXE","subtype":"BEDROOM","label":" "},
{"id":"area-2","family":"PIECE_DE_SERVICE","subtype":"BEDROOM","label":""}]}
"""))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.code").value("validation_failed"))
.andExpect(
jsonPath(
"$.errors[*].field",
containsInAnyOrder(
"privateAreas[0].label",
"privateAreas[0].subtypeCompatibleWithFamily",
"privateAreas[1].label",
"privateAreas[1].subtypeCompatibleWithFamily")))
.andExpect(
jsonPath(
"$.errors[*].code",
containsInAnyOrder("not_blank", "assert_true", "not_blank", "assert_true")));
}
@Test
void apartmentRequestsAcceptSubEuroPricesAndReturnTrimmedCoreFields() throws Exception {
when(apartments.create(eq(LANDLORD_ID), any()))