From 27ac2ddcb80994b0fb41ad78e5a17c5c763eec2a Mon Sep 17 00:00:00 2001 From: corinaolariu Date: Mon, 15 Jul 2024 16:01:54 +0300 Subject: [PATCH 1/2] RED-9608 - Comments not removed after uploading multiple files via ZIP-Archive with "Overwrite and start over" selected - remove (soft-delete) all comments, not just the ones related to the manual redactions at overwrite - restore back all comments (not just the ones related to the manual redactions) when file is restored - unit tests added --- .../CommentPersistenceService.java | 3 +- .../repository/CommentRepository.java | 8 ++ .../v1/server/integration/tests/FileTest.java | 119 +++++++++++++++++- 3 files changed, 126 insertions(+), 4 deletions(-) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/CommentPersistenceService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/CommentPersistenceService.java index c905d0db3..73e47c219 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/CommentPersistenceService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/annotations/CommentPersistenceService.java @@ -56,7 +56,8 @@ public class CommentPersistenceService { } public void softDeleteCommentsForFiles(List fileId, OffsetDateTime softDeletedTime) { - commentRepository.softDeleteCommentsByFilesAndAnnotationSoftDeletedTime(fileId, softDeletedTime); +// commentRepository.softDeleteCommentsByFilesAndAnnotationSoftDeletedTime(fileId, softDeletedTime); + commentRepository.softDeleteCommentsByFiles(fileId, softDeletedTime); } public void undeleteByFileId(String fileId, OffsetDateTime deletionTime) { diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java index 75830cbec..28e8dab83 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/persistence/repository/CommentRepository.java @@ -43,6 +43,10 @@ public interface CommentRepository extends JpaRepository { "exists (select a from ManualLegalBasisChangeEntity a where a.id.annotationId = c.annotationId and a.softDeletedTime = :softDeleteTime)) ") void softDeleteCommentsByFilesAndAnnotationSoftDeletedTime(@Param("fileIds") List fileIds, @Param("softDeleteTime") OffsetDateTime softDeleteTime); + @Modifying + @Query("update CommentEntity c set c.softDeletedTime = :softDeleteTime where c.fileId in (:fileIds)") + void softDeleteCommentsByFiles(@Param("fileIds") List fileIds, @Param("softDeleteTime") OffsetDateTime softDeleteTime); + @Modifying @Query("delete from CommentEntity c where c.fileId in (:fileIds)") void deleteCommentsByFiles(@Param("fileIds") List fileIds); @@ -56,6 +60,10 @@ public interface CommentRepository extends JpaRepository { "exists (select a from ManualRecategorizationEntity a where a.id.annotationId = c.annotationId and a.softDeletedTime >= :deletionTime) or "+ "exists (select a from ManualResizeRedactionEntity a where a.id.annotationId = c.annotationId and a.softDeletedTime >= :deletionTime) or "+ "exists (select a from ManualLegalBasisChangeEntity a where a.id.annotationId = c.annotationId and a.softDeletedTime >= :deletionTime)) ") + void undeleteByFileIdAndAnnotationSoftDeletedTime(@Param("fileId") String fileId,@Param("deletionTime") OffsetDateTime deletionTime); + + @Modifying + @Query("update CommentEntity c set c.softDeletedTime = null where c.fileId = :fileId and c.softDeletedTime >= :deletionTime") void undeleteByFileId(@Param("fileId") String fileId,@Param("deletionTime") OffsetDateTime deletionTime); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java index a5ca14b1b..746fbaddf 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java @@ -2,7 +2,6 @@ package com.iqser.red.service.peristence.v1.server.integration.tests; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.any; @@ -22,7 +21,6 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.mock.web.MockMultipartFile; import com.google.common.collect.Sets; @@ -60,6 +58,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.annotations.AnnotationComments; import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier; import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileAttributeConfig; @@ -130,6 +129,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest { @Autowired private FileStatusService fileStatusService; + @Test public void testFileSoftDeleteReupload() { @@ -376,6 +376,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest { var type = typeProvider.testAndProvideType(dossierTemplate, null, "manual"); typeProvider.testAndProvideType(dossierTemplate, null, "new-type", false, 2000); var annotationId = "imagine_this_makes_sense"; + var commentId = "commentId"; EntityLog entityLog = new EntityLog(1, 1, List.of(EntityLogEntry.builder() @@ -398,6 +399,14 @@ public class FileTest extends AbstractPersistenceServerServiceTest { .value("value entry 3") .state(EntryState.APPLIED) .entryType(EntryType.ENTITY) + .build(), + EntityLogEntry.builder() + .id(commentId) + .type(type.getType()) + .value("value entry 4") + .dictionaryEntry(true) + .state(EntryState.APPLIED) + .entryType(EntryType.ENTITY) .build()), null, 0, @@ -446,19 +455,39 @@ public class FileTest extends AbstractPersistenceServerServiceTest { .build()), false); + manualRedactionClient.addComment(dossierId, fileId, commentId, AddCommentRequestModel.builder().text("comment added via text fileId").build()); + var loadedFile = fileClient.getFileStatus(dossierId, fileId); + //check comments are restored + AnnotationComments annotationComments = manualRedactionClient.getComments(dossierId, fileId, commentId); + assertThat(annotationComments.getComments().size()).isEqualTo(1); + AnnotationComments annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotationId); + assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(2); + fileManagementClient.deleteFile(dossier.getId(), file.getId()); var softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId()); assertThat(softDeletedFiles).hasSize(1); var activeFiles = fileClient.getDossierStatus(dossier.getId()); assertThat(activeFiles).isEmpty(); + // check the comment added to an annotation that has no manual redaction + Exception exception = Assertions.assertThrows(FeignException.NotFound.class, () -> manualRedactionClient.getComments(dossierId, fileId, commentId)); + + String expectedMessage = "The requested file has been soft deleted on"; + String actualMessage = exception.getMessage(); + assertThat(actualMessage).contains(expectedMessage); + fileManagementClient.restoreFiles(dossier.getId(), Sets.newHashSet(file.getId())); softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId()); assertThat(softDeletedFiles).isEmpty(); activeFiles = fileClient.getDossierStatus(dossier.getId()); assertThat(activeFiles).hasSize(1); + //check comments are restored + annotationComments = manualRedactionClient.getComments(dossierId, fileId, commentId); + assertThat(annotationComments.getComments().size()).isEqualTo(1); + annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotationId); + assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(2); fileManagementClient.hardDeleteFiles(dossier.getId(), List.of(file.getId())); softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId()); @@ -691,9 +720,93 @@ public class FileTest extends AbstractPersistenceServerServiceTest { fileManagementStorageService.storeObject(dossier.getId(), fileId, FileType.UNTOUCHED, new ByteArrayInputStream("test".getBytes(StandardCharsets.UTF_8))); - when(fileAttributeConfigPersistenceService.getFileAttributesGeneralConfiguration(anyString())).thenReturn(FileAttributesGeneralConfigurationEntity.builder().delimiter(",").encoding("UTF-8").build()); + when(fileAttributeConfigPersistenceService.getFileAttributesGeneralConfiguration(anyString())).thenReturn(FileAttributesGeneralConfigurationEntity.builder() + .delimiter(",") + .encoding("UTF-8") + .build()); when(fileAttributeConfigPersistenceService.getFileAttributes(anyString())).thenReturn(Collections.emptyList()); assertThrows(FeignException.class, () -> uploadClient.upload(malformedCsvFile, dossier.getId(), false)); } + + @Test + public void testFileWithCommentsAtReupload() { + + var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate(); + + var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate); + String dossierId = dossier.getId(); + + var file = fileTesterAndProvider.testAndProvideFile(dossier); + String fileId = file.getId(); + + var type = typeProvider.testAndProvideType(dossierTemplate, null, "manual"); + typeProvider.testAndProvideType(dossierTemplate, null, "new-type", false, 2000); + var annotationId = "imagine_this_makes_sense"; + var annotation2Id = "imagine_this_makes_sense 2"; + EntityLog entityLog = new EntityLog(1, + 1, + List.of(EntityLogEntry.builder() + .id(annotationId) + .type(type.getType()) + .value("value entry") + .state(EntryState.APPLIED) + .entryType(EntryType.ENTITY) + .build(), + EntityLogEntry.builder() + .id(annotation2Id) + .type(type.getType()) + .value("value entry 3") + .state(EntryState.APPLIED) + .entryType(EntryType.ENTITY) + .build()), + null, + 0, + 0, + 0, + 0); + + fileManagementStorageService.saveEntityLog(dossier.getId(), file.getId(), entityLog); + when(entityLogService.getEntityLog(any(), any(), anyBoolean())).thenReturn(entityLog); + + assertThat(fileClient.getDossierStatus(dossier.getId()).size()).isEqualTo(1); + + manualRedactionClient.recategorizeBulk(dossierId, + fileId, + Set.of(RecategorizationRequestModel.builder() + .annotationId(annotation2Id) + .comment("comment edit via edit dialog") + .type(type.getType()) + .legalBasis("") + .section("section") + .value("value entry 3") + .build()), + false); + + var loadedFile = fileClient.getFileStatus(dossierId, fileId); + + manualRedactionClient.addComment(dossierId, fileId, annotationId, AddCommentRequestModel.builder().text("comment added via text fileId").build()); + + //check comments are restored + AnnotationComments annotationComments = manualRedactionClient.getComments(dossierId, fileId, annotationId); + assertThat(annotationComments.getComments().size()).isEqualTo(1); + AnnotationComments annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotation2Id); + assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(1); + + //overwrite the file + var fileUpload = new MockMultipartFile(file.getFilename(), file.getFilename(), "application/pdf", "content".getBytes()); + var uploadResult = uploadClient.upload(fileUpload, dossier.getId(), false); + + loadedFile = fileClient.getFileStatus(dossier.getId(), + uploadResult.getFileIds() + .iterator().next()); + + //check comments are soft deleted + annotationComments = manualRedactionClient.getComments(dossierId, loadedFile.getId(), annotation2Id); + assertThat(annotationComments.getComments().size()).isEqualTo(0); + annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotation2Id); + assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(0); + + } + } -- 2.47.2 From d1ad080e27a208d6f09b5f3d6847c5f4c257c351 Mon Sep 17 00:00:00 2001 From: corinaolariu Date: Mon, 15 Jul 2024 16:43:59 +0300 Subject: [PATCH 2/2] RED-9608 - Comments not removed after uploading multiple files via ZIP-Archive with "Overwrite and start over" selected - solve sonar issues --- .../v1/server/integration/tests/FileTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java index 746fbaddf..3d597732e 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/FileTest.java @@ -461,9 +461,9 @@ public class FileTest extends AbstractPersistenceServerServiceTest { //check comments are restored AnnotationComments annotationComments = manualRedactionClient.getComments(dossierId, fileId, commentId); - assertThat(annotationComments.getComments().size()).isEqualTo(1); + assertThat(annotationComments.getComments()).hasSize(1); AnnotationComments annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotationId); - assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(2); + assertThat(annotationCommentsForManualRedactions.getComments()).hasSize(2); fileManagementClient.deleteFile(dossier.getId(), file.getId()); var softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId()); @@ -485,9 +485,9 @@ public class FileTest extends AbstractPersistenceServerServiceTest { assertThat(activeFiles).hasSize(1); //check comments are restored annotationComments = manualRedactionClient.getComments(dossierId, fileId, commentId); - assertThat(annotationComments.getComments().size()).isEqualTo(1); + assertThat(annotationComments.getComments()).hasSize(1); annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotationId); - assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(2); + assertThat(annotationCommentsForManualRedactions.getComments()).hasSize(2); fileManagementClient.hardDeleteFiles(dossier.getId(), List.of(file.getId())); softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId()); @@ -730,7 +730,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest { @Test - public void testFileWithCommentsAtReupload() { + void testFileWithCommentsAtReupload() { var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate(); @@ -789,9 +789,9 @@ public class FileTest extends AbstractPersistenceServerServiceTest { //check comments are restored AnnotationComments annotationComments = manualRedactionClient.getComments(dossierId, fileId, annotationId); - assertThat(annotationComments.getComments().size()).isEqualTo(1); + assertThat(annotationComments.getComments()).hasSize(1); AnnotationComments annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotation2Id); - assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(1); + assertThat(annotationCommentsForManualRedactions.getComments()).hasSize(1); //overwrite the file var fileUpload = new MockMultipartFile(file.getFilename(), file.getFilename(), "application/pdf", "content".getBytes()); @@ -803,9 +803,9 @@ public class FileTest extends AbstractPersistenceServerServiceTest { //check comments are soft deleted annotationComments = manualRedactionClient.getComments(dossierId, loadedFile.getId(), annotation2Id); - assertThat(annotationComments.getComments().size()).isEqualTo(0); + assertThat(annotationComments.getComments()).hasSize(0); annotationCommentsForManualRedactions = manualRedactionClient.getComments(dossierId, fileId, annotation2Id); - assertThat(annotationCommentsForManualRedactions.getComments().size()).isEqualTo(0); + assertThat(annotationCommentsForManualRedactions.getComments()).hasSize(0); } -- 2.47.2