RED-10335: New entity created when editing/working with annotation while auto-analysis is disabled #820

Open
maverick.studer wants to merge 1 commits from RED-10335-1 into master
2 changed files with 163 additions and 8 deletions

View File

@ -393,7 +393,7 @@ public class EntityLogMergeService {
entityLogEntry.setState(EntryState.IGNORED);
//special case, only for add local and remove only
if (entityLogEntry.getEngines().equals(Set.of(Engine.MANUAL))) {
if (entityLogEntry.getEngines().contains(Engine.MANUAL)) {
entityLogEntry.setState(EntryState.REMOVED);
change.setType(ChangeType.REMOVED);
}

View File

@ -681,12 +681,7 @@ public class EntityLogMergeTest {
String entryId = UUID.randomUUID().toString();
ManualRedactions manualRedactions = ManualRedactions.builder()
.idsToRemove(Set.of(IdRemoval.builder()
.annotationId(entryId)
.fileId("file")
.requestDate(OffsetDateTime.now())
.user("user")
.build()))
.idsToRemove(Set.of(IdRemoval.builder().annotationId(entryId).fileId("file").requestDate(OffsetDateTime.now()).user("user").build()))
.build();
var entityLog = new EntityLog(1,
@ -725,7 +720,8 @@ public class EntityLogMergeTest {
.findFirst();
assertTrue(optionalEntityLogEntry.isPresent());
assertEquals(optionalEntityLogEntry.get().getChanges().size(), 1);
assertEquals(optionalEntityLogEntry.get().getChanges().get(0).getType(), ChangeType.IGNORED);
assertEquals(optionalEntityLogEntry.get().getChanges()
.get(0).getType(), ChangeType.IGNORED);
}
@ -914,5 +910,164 @@ public class EntityLogMergeTest {
.build();
}
@Test
public void testRecategorizeWithoutCreatingOverlap() {
String fileId = "fileId";
String dossierId = "dossierId";
String dossierTemplateId = "dossierTemplateId";
String entryId = UUID.randomUUID().toString();
String dictId = UUID.randomUUID().toString();
ManualRedactionEntry add = provideManualAdd(entryId, "Sensitive information");
add.setType("CBI_author");
ManualRedactions manualRedactions = ManualRedactions.builder()
.entriesToAdd(Set.of(add))
.recategorizations(Set.of(ManualRecategorization.builder()
.annotationId(entryId)
.fileId(fileId)
.legalBasis("New legal basis")
.type("PII")
.requestDate(OffsetDateTime.now())
.basedOnDictAnnotationId(dictId)
.user("User")
.build()))
.build();
List<Position> positions = new ArrayList<>();
positions.add(new Position(1, 1, 1, 1, 1));
EntityLogEntry existingEntry = EntityLogEntry.builder()
.id(dictId)
.type("CBI_author")
.value("Sensitive Information")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.positions(positions)
.legalBasis("Initial legal basis")
.build();
EntityLog entityLog = new EntityLog(1, 1, Lists.newArrayList(existingEntry), Collections.emptyList(), 0, 0, 0, 0);
when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions);
when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(fileId).build());
when(fileManagementStorageService.getEntityLog(dossierId, fileId)).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(fileId)).thenReturn(FileEntity.builder().id(fileId).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, "The merged EntityLog should not be null.");
assertFalse(response.getEntityLogEntry().isEmpty(), "The merged EntityLog should contain entries.");
var updatedEntryOpt = response.getEntityLogEntry()
.stream()
.filter(e -> e.getId().equals(entryId))
.findFirst();
assertTrue(updatedEntryOpt.isPresent(), "The recategorized entry should be present in the EntityLog.");
EntityLogEntry updatedEntry = updatedEntryOpt.get();
assertEquals("PII", updatedEntry.getType(), "The entry type should be updated to PII.");
assertEquals("New legal basis", updatedEntry.getLegalBasis(), "The legal basis should be updated.");
assertEquals(EntryState.APPLIED, updatedEntry.getState(), "The entry state should remain APPLIED.");
assertEquals(1,
response.getEntityLogEntry()
.stream()
.filter(entityLogEntry -> !entityLogEntry.getState().equals(EntryState.REMOVED))
.count(),
"There should be only one entry in the EntityLog after recategorization.");
}
@Test
public void testForceRedactSkippedCBIAddressAndLocalRemoveWithoutCreatingDuplicate() {
String fileId = "fileId";
String dossierId = "dossierId";
String dossierTemplateId = "dossierTemplateId";
String entryId = UUID.randomUUID().toString();
String dictId = UUID.randomUUID().toString();
ManualRedactionEntry add = provideManualAdd(entryId, "123 Main St");
add.setType("CBI_address");
ManualRedactions manualRedactions = ManualRedactions.builder()
.entriesToAdd(Set.of(add))
.forceRedactions(Set.of(ManualForceRedaction.builder()
.annotationId(entryId)
.fileId(fileId)
.legalBasis("Force")
.user("User")
.requestDate(OffsetDateTime.now())
.basedOnDictAnnotationId(dictId)
.build()))
.idsToRemove(Set.of(IdRemoval.builder().annotationId(entryId).fileId(fileId).user("User").requestDate(OffsetDateTime.now()).build()))
.build();
List<Position> positions = new ArrayList<>();
positions.add(new Position(1, 1, 1, 1, 1));
EntityLogEntry existingEntry = EntityLogEntry.builder()
.id(dictId)
.type("CBI_address")
.value("123 Main St")
.entryType(EntryType.ENTITY)
.state(EntryState.SKIPPED)
.dictionaryEntry(true)
.positions(positions)
.legalBasis("Initial legal basis")
.build();
EntityLog entityLog = new EntityLog(1, 1, Lists.newArrayList(existingEntry), Collections.emptyList(), 0, 0, 0, 0);
when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions);
when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(fileId).build());
when(fileManagementStorageService.getEntityLog(dossierId, fileId)).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(fileId)).thenReturn(FileEntity.builder().id(fileId).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, "The merged EntityLog should not be null.");
assertFalse(response.getEntityLogEntry().isEmpty(), "The merged EntityLog should contain entries.");
List<EntityLogEntry> relatedEntries = response.getEntityLogEntry()
.stream()
.filter(e -> e.getId().equals(entryId))
.toList();
assertEquals(1, relatedEntries.size(), "There should be only one entry for the entryId after force redaction and local removal.");
EntityLogEntry updatedEntry = relatedEntries.get(0);
assertEquals("CBI_address", updatedEntry.getType(), "The entry type should remain CBI_address after force redaction and local removal.");
long skippedAnnotations = response.getEntityLogEntry()
.stream()
.filter(e -> e.getType().equals("manual") && e.getEntryType() == EntryType.AREA && e.getState() == EntryState.SKIPPED)
.count();
assertEquals(0, skippedAnnotations, "No additional skipped annotations (Cross Marks) should be present.");
var nonRemovedEntries = response.getEntityLogEntry()
.stream()
.filter(e -> !e.getId().equals(entryId) && !e.getState().equals(EntryState.REMOVED))
.toList();
assertEquals(1, nonRemovedEntries.size(), "There should be only one entry in the EntityLog after force and local remove.");
}
}