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
This commit is contained in:
parent
fa0a16210b
commit
27ac2ddcb8
@ -56,7 +56,8 @@ public class CommentPersistenceService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void softDeleteCommentsForFiles(List<String> fileId, OffsetDateTime softDeletedTime) {
|
public void softDeleteCommentsForFiles(List<String> fileId, OffsetDateTime softDeletedTime) {
|
||||||
commentRepository.softDeleteCommentsByFilesAndAnnotationSoftDeletedTime(fileId, softDeletedTime);
|
// commentRepository.softDeleteCommentsByFilesAndAnnotationSoftDeletedTime(fileId, softDeletedTime);
|
||||||
|
commentRepository.softDeleteCommentsByFiles(fileId, softDeletedTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void undeleteByFileId(String fileId, OffsetDateTime deletionTime) {
|
public void undeleteByFileId(String fileId, OffsetDateTime deletionTime) {
|
||||||
|
|||||||
@ -43,6 +43,10 @@ public interface CommentRepository extends JpaRepository<CommentEntity, Long> {
|
|||||||
"exists (select a from ManualLegalBasisChangeEntity a where a.id.annotationId = c.annotationId and a.softDeletedTime = :softDeleteTime)) ")
|
"exists (select a from ManualLegalBasisChangeEntity a where a.id.annotationId = c.annotationId and a.softDeletedTime = :softDeleteTime)) ")
|
||||||
void softDeleteCommentsByFilesAndAnnotationSoftDeletedTime(@Param("fileIds") List<String> fileIds, @Param("softDeleteTime") OffsetDateTime softDeleteTime);
|
void softDeleteCommentsByFilesAndAnnotationSoftDeletedTime(@Param("fileIds") List<String> fileIds, @Param("softDeleteTime") OffsetDateTime softDeleteTime);
|
||||||
|
|
||||||
|
@Modifying
|
||||||
|
@Query("update CommentEntity c set c.softDeletedTime = :softDeleteTime where c.fileId in (:fileIds)")
|
||||||
|
void softDeleteCommentsByFiles(@Param("fileIds") List<String> fileIds, @Param("softDeleteTime") OffsetDateTime softDeleteTime);
|
||||||
|
|
||||||
@Modifying
|
@Modifying
|
||||||
@Query("delete from CommentEntity c where c.fileId in (:fileIds)")
|
@Query("delete from CommentEntity c where c.fileId in (:fileIds)")
|
||||||
void deleteCommentsByFiles(@Param("fileIds") List<String> fileIds);
|
void deleteCommentsByFiles(@Param("fileIds") List<String> fileIds);
|
||||||
@ -56,6 +60,10 @@ public interface CommentRepository extends JpaRepository<CommentEntity, Long> {
|
|||||||
"exists (select a from ManualRecategorizationEntity a where a.id.annotationId = c.annotationId and a.softDeletedTime >= :deletionTime) or "+
|
"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 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)) ")
|
"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);
|
void undeleteByFileId(@Param("fileId") String fileId,@Param("deletionTime") OffsetDateTime deletionTime);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -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.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
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.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyString;
|
import static org.mockito.ArgumentMatchers.anyString;
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
@ -22,7 +21,6 @@ import org.junit.jupiter.api.Assertions;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
|
|
||||||
import com.google.common.collect.Sets;
|
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.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.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.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.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.Dossier;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileAttributeConfig;
|
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
|
@Autowired
|
||||||
private FileStatusService fileStatusService;
|
private FileStatusService fileStatusService;
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFileSoftDeleteReupload() {
|
public void testFileSoftDeleteReupload() {
|
||||||
|
|
||||||
@ -376,6 +376,7 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
|||||||
var type = typeProvider.testAndProvideType(dossierTemplate, null, "manual");
|
var type = typeProvider.testAndProvideType(dossierTemplate, null, "manual");
|
||||||
typeProvider.testAndProvideType(dossierTemplate, null, "new-type", false, 2000);
|
typeProvider.testAndProvideType(dossierTemplate, null, "new-type", false, 2000);
|
||||||
var annotationId = "imagine_this_makes_sense";
|
var annotationId = "imagine_this_makes_sense";
|
||||||
|
var commentId = "commentId";
|
||||||
EntityLog entityLog = new EntityLog(1,
|
EntityLog entityLog = new EntityLog(1,
|
||||||
1,
|
1,
|
||||||
List.of(EntityLogEntry.builder()
|
List.of(EntityLogEntry.builder()
|
||||||
@ -398,6 +399,14 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
|||||||
.value("value entry 3")
|
.value("value entry 3")
|
||||||
.state(EntryState.APPLIED)
|
.state(EntryState.APPLIED)
|
||||||
.entryType(EntryType.ENTITY)
|
.entryType(EntryType.ENTITY)
|
||||||
|
.build(),
|
||||||
|
EntityLogEntry.builder()
|
||||||
|
.id(commentId)
|
||||||
|
.type(type.getType())
|
||||||
|
.value("value entry 4")
|
||||||
|
.dictionaryEntry(true)
|
||||||
|
.state(EntryState.APPLIED)
|
||||||
|
.entryType(EntryType.ENTITY)
|
||||||
.build()),
|
.build()),
|
||||||
null,
|
null,
|
||||||
0,
|
0,
|
||||||
@ -446,19 +455,39 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
|
|||||||
.build()),
|
.build()),
|
||||||
false);
|
false);
|
||||||
|
|
||||||
|
manualRedactionClient.addComment(dossierId, fileId, commentId, AddCommentRequestModel.builder().text("comment added via text fileId").build());
|
||||||
|
|
||||||
var loadedFile = fileClient.getFileStatus(dossierId, fileId);
|
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());
|
fileManagementClient.deleteFile(dossier.getId(), file.getId());
|
||||||
var softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId());
|
var softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId());
|
||||||
assertThat(softDeletedFiles).hasSize(1);
|
assertThat(softDeletedFiles).hasSize(1);
|
||||||
var activeFiles = fileClient.getDossierStatus(dossier.getId());
|
var activeFiles = fileClient.getDossierStatus(dossier.getId());
|
||||||
assertThat(activeFiles).isEmpty();
|
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()));
|
fileManagementClient.restoreFiles(dossier.getId(), Sets.newHashSet(file.getId()));
|
||||||
softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId());
|
softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.getId());
|
||||||
assertThat(softDeletedFiles).isEmpty();
|
assertThat(softDeletedFiles).isEmpty();
|
||||||
activeFiles = fileClient.getDossierStatus(dossier.getId());
|
activeFiles = fileClient.getDossierStatus(dossier.getId());
|
||||||
assertThat(activeFiles).hasSize(1);
|
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()));
|
fileManagementClient.hardDeleteFiles(dossier.getId(), List.of(file.getId()));
|
||||||
softDeletedFiles = fileClient.getSoftDeletedDossierStatus(dossier.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)));
|
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());
|
when(fileAttributeConfigPersistenceService.getFileAttributes(anyString())).thenReturn(Collections.emptyList());
|
||||||
assertThrows(FeignException.class, () -> uploadClient.upload(malformedCsvFile, dossier.getId(), false));
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user