Skip to content

Commit 76f5480

Browse files
committed
✅ same day Date patching
1 parent 777bed6 commit 76f5480

2 files changed

Lines changed: 41 additions & 8 deletions

File tree

sormas-backend/src/main/java/de/symeda/sormas/backend/patch/BusinessDtoFacade.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public class BusinessDtoFacade {
4343
@EJB
4444
private UserFacadeEjb.UserFacadeEjbLocal userFacade;
4545

46-
private final Map<Class<? extends EntityDto>, Function<? extends EntityDto, ? extends EntityDto>> dtoSaveDictionary = new HashMap<>();
46+
private final Map<Class<? extends EntityDto>, Function<? extends EntityDto, ? extends EntityDto>> directDtoSaveDictionary = new HashMap<>();
4747

4848
private final Map<Class<? extends EntityDto>, Function<CaseDataDto, ? extends EntityDto>> dtoRetrieverDictionary = new HashMap<>();
4949

@@ -76,7 +76,7 @@ private void registerSaveOperations() {
7676
}
7777

7878
private <T extends EntityDto> void registerSave(Class<T> dtoClass, Function<T, T> consumer) {
79-
dtoSaveDictionary.put(dtoClass, consumer);
79+
directDtoSaveDictionary.put(dtoClass, consumer);
8080
}
8181

8282
private void registerFetchOperations() {
@@ -110,17 +110,21 @@ private void registerFetchByI18nOperationsCreateUpdate() {
110110
caseDataDto -> personFacade.getByUuid(caseDataDto.getPerson().getUuid()));
111111
registerFetchByI18nCreateUpdate(
112112
ImmunizationDto.I18N_PREFIX,
113-
caseDataDto -> {
114-
ImmunizationDto build = ImmunizationDto.build(caseDataDto.getPerson());
115-
build.setRelatedCase(caseDataDto.toReference());
116-
return build;
117-
});
113+
createImmunizationDtoFromCaseFct());
118114

119115
registerFetchByI18nCreateUpdate(
120116
VaccinationDto.I18N_PREFIX,
121117
caseDataDto -> VaccinationDto.build(userFacade.getCurrentUserAsReference()));
122118
}
123119

120+
private static Function<CaseDataDto, EntityDto> createImmunizationDtoFromCaseFct() {
121+
return caseDataDto -> {
122+
ImmunizationDto build = ImmunizationDto.build(caseDataDto.getPerson());
123+
build.setRelatedCase(caseDataDto.toReference());
124+
return build;
125+
};
126+
}
127+
124128
private void registerFetchByI18nRead(String i18nName, Function<CaseDataDto, List<? extends EntityDto>> fct) {
125129
dtoRetrieverByI18nDictionaryRead.put(i18nName, fct);
126130
}
@@ -208,7 +212,7 @@ public Set<String> fetchablePrefixes() {
208212
public <T extends EntityDto> T save(@NotNull EntityDto entityDto) {
209213
Class<? extends EntityDto> entityDtoClass = entityDto.getClass();
210214

211-
return Optional.ofNullable((Function<T, T>) dtoSaveDictionary.get(entityDtoClass))
215+
return Optional.ofNullable((Function<T, T>) directDtoSaveDictionary.get(entityDtoClass))
212216
.orElseThrow(() -> new IllegalStateException(String.format("No save function defined for: [%s]", entityDtoClass)))
213217
.apply((T) entityDto);
214218
}

sormas-backend/src/test/java/de/symeda/sormas/patch/DataPatcherImplTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import java.sql.Date;
44
import java.time.LocalDate;
5+
import java.time.LocalDateTime;
56
import java.time.ZoneId;
67
import java.util.Collections;
78
import java.util.HashMap;
@@ -941,6 +942,34 @@ void patch_fieldDoesNoExist() {
941942
() -> Assertions.assertEquals(Map.of(), response.getValidPatchDictionary()));
942943
}
943944

945+
@Test
946+
void patch_ifNotAlreadyPresent_sameDayDifferentTime_noForbiddenValueOverride() {
947+
// PREPARE
948+
CaseDataDto originalCase = creator.createUnclassifiedCase(Disease.PERTUSSIS);
949+
950+
// Set classificationDate to 08:30 on 2024-06-15 — a non-midnight timestamp on the same calendar day that will be patched
951+
java.util.Date existingDate =
952+
java.util.Date.from(LocalDateTime.of(2024, 6, 15, 8, 30, 0).atZone(ZoneId.systemDefault()).toInstant());
953+
originalCase.setClassificationDate(existingDate);
954+
getCaseFacade().save(originalCase);
955+
956+
// Patch with the same calendar day as a plain date string — DatePatchMapper resolves this to midnight (00:00:00),
957+
// which differs in time from existingDate. Without DateEqualityChecker this would trigger FORBIDDEN_VALUE_OVERRIDE.
958+
String patchDate = "2024-06-15";
959+
CaseDataPatchRequest request = new CaseDataPatchRequest().setCaseUuid(originalCase.getUuid())
960+
.setPatchDictionary(Map.of("CaseData.classificationDate", patchDate));
961+
962+
// EXECUTE
963+
DataPatchResponse response = victim().patch(request);
964+
965+
// CHECK
966+
logger.info("response: [{}]", response);
967+
968+
Assertions.assertAll(
969+
() -> Assertions.assertTrue(response.getFailures().isEmpty(), "FORBIDDEN_VALUE_OVERRIDE must not fire for same-day dates"),
970+
() -> Assertions.assertTrue(response.isApplied()));
971+
}
972+
944973
private DataPatcher victim() {
945974
return getCaseDataPatcher();
946975
}

0 commit comments

Comments
 (0)