From 99c7ef2529524060ecfa545523cc621067491380 Mon Sep 17 00:00:00 2001 From: Andrei Isvoran Date: Mon, 15 Jul 2024 15:47:46 +0300 Subject: [PATCH] RED-9555 - Keep force redacted image applied after changing legal basis --- .../service/EntityLogMergeService.java | 40 +++++- .../integration/tests/EntityLogMergeTest.java | 134 ++++++++++++++++-- 2 files changed, 157 insertions(+), 17 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java index 9b9d23e79..39e0ad9cd 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java @@ -36,6 +36,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualRedactionType; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.PropertyChange; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ChangeFactory; @@ -119,20 +120,30 @@ public class EntityLogMergeService { adjustEntityLogEntriesAfterLocalChangesBasedOnDict(entityLogEntries, trackLocalChangesBasedOnDictEntriesMap, analysisNumber); } - private void adjustEntityLogEntriesAfterLocalChangesBasedOnDict(List entityLogEntries, Map trackLocalChangesBasedOnDictEntriesMap, int analysisNumber) { + + private void adjustEntityLogEntriesAfterLocalChangesBasedOnDict(List entityLogEntries, + Map trackLocalChangesBasedOnDictEntriesMap, + int analysisNumber) { + var dictEntryIdsToUpdate = trackLocalChangesBasedOnDictEntriesMap.values(); - entityLogEntries.stream().filter(entityLogEntry -> dictEntryIdsToUpdate.contains(entityLogEntry.getId())) + entityLogEntries.stream() + .filter(entityLogEntry -> dictEntryIdsToUpdate.contains(entityLogEntry.getId())) .forEach(entityLogEntry -> { List changes = new ArrayList<>(); changes.add(ChangeFactory.toChange(ChangeType.REMOVED, OffsetDateTime.now(), analysisNumber, - PropertyChange.builder().property("state").oldValue(entityLogEntry.getState().name()).newValue(EntryState.REMOVED.name()).build())); + PropertyChange.builder() + .property("state") + .oldValue(entityLogEntry.getState().name()) + .newValue(EntryState.REMOVED.name()) + .build())); addChanges(entityLogEntry, changes); entityLogEntry.setState(EntryState.REMOVED); }); } + private void processEntityLogEntries(DossierEntity dossier, List entityLogEntries, Map addedLocalManualEntries, @@ -487,6 +498,10 @@ public class EntityLogMergeService { if (!Strings.isNullOrEmpty(recategorization.getLegalBasis())) { boolean isHint = isHint(entityLogEntry.getType(), dossier); + if ((entityLogEntry.getEntryType().equals(EntryType.IMAGE) || entityLogEntry.getEntryType().equals(EntryType.IMAGE_HINT)) && !entityLogEntry.getManualChanges() + .isEmpty() && determineHintForImages(entityLogEntry.getManualChanges())) { + isHint = false; + } ChangeFactory.addPropertyChanges(change, PropertyChange.builder() .property("legalBasis") @@ -558,6 +573,25 @@ public class EntityLogMergeService { } + private boolean determineHintForImages(List manualChanges) { + + boolean hasForce = false; + boolean hasRemoveAfterForce = false; + + for (ManualChange change : manualChanges) { + if (change.getManualRedactionType() == ManualRedactionType.FORCE) { + hasForce = true; + } + if (hasForce && change.getManualRedactionType() == ManualRedactionType.REMOVE) { + hasRemoveAfterForce = true; + break; + } + } + + return hasForce && !hasRemoveAfterForce; + } + + public boolean isHint(String type, DossierEntity dossier) { String typeId = toTypeId(type, dossier.getDossierTemplateId()); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java index 61baa7d5c..1cba06dbf 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMergeTest.java @@ -45,6 +45,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualRedactionType; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions; @@ -61,6 +62,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.mongo.service.Ent @ExtendWith(SpringExtension.class) public class EntityLogMergeTest { + final String FILE_ID = "fileId"; @MockBean private FileStatusService fileStatusService; @@ -120,7 +122,14 @@ public class EntityLogMergeTest { String forceRedactionId = UUID.randomUUID().toString(); String entryToRecategorizeId = UUID.randomUUID().toString(); - ManualRedactions manualRedactions = provideManualRedactions(entryToAddId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, fileId, rectangleToAddId, entryToRecategorizeId); + ManualRedactions manualRedactions = provideManualRedactions(entryToAddId, + entryToRemoveId, + entryToResizeId, + entryLegalBasisId, + forceRedactionId, + fileId, + rectangleToAddId, + entryToRecategorizeId); var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, entryToRecategorizeId, false); @@ -188,8 +197,12 @@ public class EntityLogMergeTest { .get(0).getManualRedactionType(), ManualRedactionType.RESIZE); assertEquals(resizeEntryLogEntry.getChanges() .get(0).getType(), ChangeType.RESIZED); - assertEquals(resizeEntryLogEntry.getChanges().get(0).getPropertyChanges().get("value"), "Darth Vader -> Random"); - assertEquals(resizeEntryLogEntry.getChanges().get(0).getPropertyChanges().get("positions"), "[1.0, 1.0, 1.0, 1.0, 1] -> [2.0, 2.0, 2.0, 2.0, 1]"); + assertEquals(resizeEntryLogEntry.getChanges() + .get(0).getPropertyChanges() + .get("value"), "Darth Vader -> Random"); + assertEquals(resizeEntryLogEntry.getChanges() + .get(0).getPropertyChanges() + .get("positions"), "[1.0, 1.0, 1.0, 1.0, 1] -> [2.0, 2.0, 2.0, 2.0, 1]"); assertTrue(resizeEntryLogEntry.getEngines().contains(Engine.MANUAL)); var optionalLegalBasisEntryLogEntry = response.getEntityLogEntry() @@ -205,7 +218,9 @@ public class EntityLogMergeTest { .get(0).getManualRedactionType(), ManualRedactionType.LEGAL_BASIS_CHANGE); assertEquals(legalBasisEntryLogEntry.getChanges() .get(0).getType(), ChangeType.LEGAL_BASIS_CHANGE); - assertEquals(legalBasisEntryLogEntry.getChanges().get(0).getPropertyChanges().get("legalBasis"), "legalBasis -> New legal basis"); + assertEquals(legalBasisEntryLogEntry.getChanges() + .get(0).getPropertyChanges() + .get("legalBasis"), "legalBasis -> New legal basis"); assertTrue(legalBasisEntryLogEntry.getEngines().contains(Engine.MANUAL)); var optionalForceRedactionEntryLogEntry = response.getEntityLogEntry() @@ -221,8 +236,12 @@ public class EntityLogMergeTest { .get(0).getManualRedactionType(), ManualRedactionType.FORCE); assertEquals(forceRedactionEntryLogEntry.getChanges() .get(0).getType(), ChangeType.FORCE_REDACT); - assertEquals(forceRedactionEntryLogEntry.getChanges().get(0).getPropertyChanges().get("legalBasis"), "null -> Force"); - assertEquals(forceRedactionEntryLogEntry.getChanges().get(0).getPropertyChanges().get("state"), "SKIPPED -> APPLIED"); + assertEquals(forceRedactionEntryLogEntry.getChanges() + .get(0).getPropertyChanges() + .get("legalBasis"), "null -> Force"); + assertEquals(forceRedactionEntryLogEntry.getChanges() + .get(0).getPropertyChanges() + .get("state"), "SKIPPED -> APPLIED"); assertTrue(forceRedactionEntryLogEntry.getEngines().contains(Engine.MANUAL)); var optionalRectangleEntryLogEntry = response.getEntityLogEntry() @@ -253,8 +272,12 @@ public class EntityLogMergeTest { .get(0).getManualRedactionType(), ManualRedactionType.RECATEGORIZE); assertEquals(recategorizationEntryLogEntry.getChanges() .get(0).getType(), ChangeType.RECATEGORIZE); - assertEquals(recategorizationEntryLogEntry.getChanges().get(0).getPropertyChanges().get("legalBasis"), "legalBasis -> New legal basis"); - assertEquals(recategorizationEntryLogEntry.getChanges().get(0).getPropertyChanges().get("type"), "CBI_author -> PII"); + assertEquals(recategorizationEntryLogEntry.getChanges() + .get(0).getPropertyChanges() + .get("legalBasis"), "legalBasis -> New legal basis"); + assertEquals(recategorizationEntryLogEntry.getChanges() + .get(0).getPropertyChanges() + .get("type"), "CBI_author -> PII"); assertTrue(recategorizationEntryLogEntry.getEngines().contains(Engine.MANUAL)); } @@ -279,7 +302,8 @@ public class EntityLogMergeTest { entryLegalBasisId, forceRedactionId, fileId, - rectangleToAddId, entryToRecategorizeId); + rectangleToAddId, + entryToRecategorizeId); var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, entryToRecategorizeId, true); @@ -378,6 +402,7 @@ public class EntityLogMergeTest { .get(index + 1).getState(), EntryState.PENDING); } + //dict entry, resize local @Test public void testMergeEntityLogWithManualResizeBasedOnDictRedaction() { @@ -447,7 +472,7 @@ public class EntityLogMergeTest { String localId = UUID.randomUUID().toString(); - ManualRedactions manualRedactions = ManualRedactions.builder() + ManualRedactions manualRedactions = ManualRedactions.builder() .entriesToAdd(Set.of(provideManualAdd(localId, "Darth Vader"))) .resizeRedactions(Set.of(provideManualResize(localId, "Darth", dictEntryToResizeId))) .idsToRemove(Set.of(IdRemoval.builder().annotationId(localId).requestDate(OffsetDateTime.now()).user("user").fileId(FILE_ID).build())) @@ -487,6 +512,7 @@ public class EntityLogMergeTest { } + @Test void testMergeEntityLogWithManualAddAndRemoveChanges() { @@ -501,7 +527,7 @@ public class EntityLogMergeTest { String localId = UUID.randomUUID().toString(); - ManualRedactions manualRedactions = ManualRedactions.builder() + ManualRedactions manualRedactions = ManualRedactions.builder() .entriesToAdd(Set.of(provideManualAdd(localId, "Darth Vader"))) .idsToRemove(Set.of(IdRemoval.builder().annotationId(localId).requestDate(OffsetDateTime.now()).user("user").fileId(FILE_ID).build())) .build(); @@ -531,6 +557,7 @@ public class EntityLogMergeTest { } + @Test void testMergeEntityLogWithManualAddAndResizeAndRemoveChanges() { @@ -545,7 +572,7 @@ public class EntityLogMergeTest { String localId = UUID.randomUUID().toString(); - ManualRedactions manualRedactions = ManualRedactions.builder() + ManualRedactions manualRedactions = ManualRedactions.builder() .entriesToAdd(Set.of(provideManualAdd(localId, "Darth Vader"))) .resizeRedactions(Set.of(provideManualResize(localId, "Darth", dictEntryToResizeId))) .idsToRemove(Set.of(IdRemoval.builder().annotationId(localId).requestDate(OffsetDateTime.now()).user("user").fileId(FILE_ID).build())) @@ -576,7 +603,81 @@ public class EntityLogMergeTest { } - private EntityLog provideEntityLog(String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId, String entryToRecategorizeId, boolean dictEntry) { + + @Test + public void testForceAndRecategorizeImage() { + + String dossierId = "dossierId"; + String dossierTemplateId = "dossierTemplateId"; + + String entryId = UUID.randomUUID().toString(); + + ManualRedactions manualRedactions = ManualRedactions.builder() + .recategorizations(Set.of(ManualRecategorization.builder() + .legalBasis("1") + .type("manual") + .annotationId(entryId) + .fileId("file") + .requestDate(OffsetDateTime.now()) + .user("user") + .build())) + .build(); + + List manualChanges = new ArrayList<>(); + manualChanges.add(ManualChange.builder() + .manualRedactionType(ManualRedactionType.FORCE) + .processedDate(OffsetDateTime.now()) + .propertyChanges(Collections.emptyMap()) + .userId("user") + .requestedDate(OffsetDateTime.now()) + .build()); + var entityLog = new EntityLog(1, + 1, + Lists.newArrayList(EntityLogEntry.builder() + .id(entryId) + .type("manual") + .value("Image:Other") + .entryType(EntryType.IMAGE) + .state(EntryState.APPLIED) + .dictionaryEntry(false) + .positions(List.of(new Position(1, 1, 1, 1, 1))) + .manualChanges(manualChanges) + .build()), + Collections.emptyList(), + 0, + 0, + 0, + 0); + + when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions); + when(fileStatusService.getStatus(FILE_ID)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(FILE_ID).build()); + when(fileManagementStorageService.getEntityLog(dossierId, FILE_ID)).thenReturn(entityLog); + when(dossierService.getDossierById(dossierId)).thenReturn(DossierEntity.builder().dossierTemplateId(dossierTemplateId).build()); + when(dictionaryPersistenceService.getType(anyString())).thenReturn(TypeEntity.builder().isHint(false).build()); + when(fileStatusPersistenceService.getStatus(FILE_ID)).thenReturn(FileEntity.builder().id(FILE_ID).fileAttributes(Collections.emptyList()).build()); + when(fileStatusService.convertAttributes(any(), anyString())).thenReturn(Collections.emptyList()); + + EntityLog response = entityLogMergeService.mergeEntityLog(manualRedactions, entityLog, DossierEntity.builder().dossierTemplateId(dossierTemplateId).build()); + + assertNotNull(response); + assertFalse(response.getEntityLogEntry().isEmpty()); + + var optionalEntityLogEntry = response.getEntityLogEntry() + .stream() + .filter(entityLogEntry -> entityLogEntry.getId().equals(entryId)) + .findFirst(); + assertTrue(optionalEntityLogEntry.isPresent()); + assertEquals(EntryType.IMAGE, optionalEntityLogEntry.get().getEntryType()); + assertEquals(EntryState.APPLIED, optionalEntityLogEntry.get().getState()); + } + + + private EntityLog provideEntityLog(String entryToRemoveId, + String entryToResizeId, + String entryLegalBasisId, + String forceRedactionId, + String entryToRecategorizeId, + boolean dictEntry) { List positions = new ArrayList<>(); positions.add(new Position(1, 1, 1, 1, 1)); @@ -643,7 +744,8 @@ public class EntityLogMergeTest { String entryLegalBasisId, String forceRedactionId, String fileId, - String rectangleToAddId, String entryToRecategorizeId) { + String rectangleToAddId, + String entryToRecategorizeId) { List positions = new ArrayList<>(); positions.add(new Rectangle(2, 2, 2, 2, 1)); @@ -717,7 +819,9 @@ public class EntityLogMergeTest { .build(); } + private ManualRedactionEntry provideManualAdd(String entryToAddId, String valueToAdd) { + return ManualRedactionEntry.builder() .positions(List.of(new Rectangle(1f, 2f, 3f, 4f, 1))) .annotationId(entryToAddId) @@ -734,7 +838,9 @@ public class EntityLogMergeTest { .build(); } + private ManualResizeRedaction provideManualResize(String entryToResizeId, String resizedValue, String dictId) { + List positions = new ArrayList<>(); positions.add(new Rectangle(2, 2, 2, 2, 1)); return ManualResizeRedaction.builder() -- 2.47.2