Spaces:
Runtime error
Runtime error
da-autodelete-dev
/
src
/test
/java
/com
/dalab
/autodelete
/service
/impl
/DeletionTaskServiceImplTest.java
| package com.dalab.autodelete.service.impl; | |
| import com.dalab.autodelete.dto.*; | |
| import com.dalab.autodelete.mapper.DeletionTaskMapper; | |
| import com.dalab.autodelete.model.DeletionStatus; | |
| import com.dalab.autodelete.model.DeletionTaskEntity; | |
| import com.dalab.autodelete.repository.DeletionTaskRepository; | |
| import com.dalab.autodelete.service.IDeletionConfigService; | |
| import com.dalab.autodelete.service.exception.DeletionTaskNotFoundException; | |
| import org.junit.jupiter.api.BeforeEach; | |
| import org.junit.jupiter.api.Test; | |
| import org.junit.jupiter.api.extension.ExtendWith; | |
| import org.mockito.ArgumentCaptor; | |
| import org.mockito.InjectMocks; | |
| import org.mockito.Mock; | |
| import org.mockito.junit.jupiter.MockitoExtension; | |
| import org.springframework.data.domain.Page; | |
| import org.springframework.data.domain.PageImpl; | |
| import org.springframework.data.domain.PageRequest; | |
| import org.springframework.data.domain.Pageable; | |
| import java.time.LocalDateTime; | |
| import java.util.ArrayList; | |
| import java.util.Collections; | |
| import java.util.List; | |
| import java.util.Optional; | |
| import java.util.UUID; | |
| import static org.junit.jupiter.api.Assertions.*; | |
| import static org.mockito.ArgumentMatchers.any; | |
| import static org.mockito.Mockito.*; | |
| class DeletionTaskServiceImplTest { | |
| private DeletionTaskRepository taskRepository; | |
| private DeletionTaskMapper taskMapper; | |
| private IDeletionConfigService deletionConfigService; | |
| private DeletionTaskServiceImpl taskService; | |
| private DeletionTaskRequest sampleTaskRequest; | |
| private DeletionTaskEntity sampleTaskEntity; | |
| private DeletionTaskStatusDTO sampleTaskStatusDTO; | |
| private DeletionTaskResponse sampleTaskResponse; | |
| private DeletionConfigDTO globalConfigDefault; | |
| private DeletionConfigDTO globalConfigSoftDeleteApproval; | |
| private String sampleTaskId; | |
| void setUp() { | |
| sampleTaskId = UUID.randomUUID().toString(); | |
| DeletionTaskRequest.DeletionScope scope = DeletionTaskRequest.DeletionScope.builder() | |
| .assetIds(List.of("asset1")).build(); | |
| sampleTaskRequest = DeletionTaskRequest.builder() | |
| .taskName("Test Task") | |
| .scope(scope) | |
| .triggeredBy("user@test.com") | |
| .build(); | |
| sampleTaskEntity = new DeletionTaskEntity(); | |
| sampleTaskEntity.setTaskId(sampleTaskId); | |
| sampleTaskEntity.setTaskName("Test Task"); | |
| sampleTaskEntity.setStatus(DeletionStatus.SUBMITTED); | |
| sampleTaskEntity.setSubmittedAt(LocalDateTime.now()); | |
| sampleTaskEntity.setScope(new DeletionTaskEntity.DeletionScopeData(List.of("asset1"))); | |
| sampleTaskEntity.setAssetStatuses(new ArrayList<>()); | |
| sampleTaskStatusDTO = DeletionTaskStatusDTO.builder().taskId(sampleTaskId).status(DeletionStatus.SUBMITTED.name()).build(); | |
| sampleTaskResponse = DeletionTaskResponse.builder().taskId(sampleTaskId).status(DeletionStatus.SUBMITTED.name()).build(); | |
| globalConfigDefault = DeletionConfigDTO.builder() | |
| .enabled(true) | |
| .softDeleteByDefault(false) // Hard delete by default | |
| .requireApprovalForHardDelete(false) // No approval for hard delete | |
| .requireApprovalForSoftDelete(true) // Approval for soft delete | |
| .build(); | |
| globalConfigSoftDeleteApproval = DeletionConfigDTO.builder() | |
| .enabled(true) | |
| .softDeleteByDefault(true) // Soft delete by default | |
| .requireApprovalForHardDelete(true) // Approval for hard delete | |
| .requireApprovalForSoftDelete(true) // Approval for soft delete | |
| .build(); | |
| } | |
| void submitDeletionTask_ValidRequest_NoApprovalNeeded_ShouldSaveAndReturnResponse() { | |
| when(deletionConfigService.getDeletionConfig()).thenReturn(globalConfigDefault); | |
| when(taskMapper.requestToEntity(sampleTaskRequest)).thenReturn(sampleTaskEntity); // sampleTaskEntity is already set up | |
| when(taskRepository.save(any(DeletionTaskEntity.class))).thenReturn(sampleTaskEntity); | |
| when(taskMapper.entityToTaskResponse(sampleTaskEntity)).thenReturn(sampleTaskResponse); | |
| DeletionTaskResponse response = taskService.submitDeletionTask(sampleTaskRequest); | |
| assertNotNull(response); | |
| assertEquals(DeletionStatus.SUBMITTED.name(), response.getStatus()); | |
| ArgumentCaptor<DeletionTaskEntity> entityCaptor = ArgumentCaptor.forClass(DeletionTaskEntity.class); | |
| verify(taskRepository).save(entityCaptor.capture()); | |
| assertEquals(DeletionStatus.SUBMITTED, entityCaptor.getValue().getStatus()); | |
| assertNotNull(entityCaptor.getValue().getAssetStatuses()); | |
| assertEquals(1, entityCaptor.getValue().getAssetsPendingProcessing()); | |
| assertEquals("HARD", entityCaptor.getValue().getAssetStatuses().get(0).getDeletionType()); | |
| } | |
| void submitDeletionTask_RequiresHardDeleteApproval_ShouldSetPendingApproval() { | |
| DeletionConfigDTO config = DeletionConfigDTO.builder().softDeleteByDefault(false).requireApprovalForHardDelete(true).build(); | |
| when(deletionConfigService.getDeletionConfig()).thenReturn(config); | |
| when(taskMapper.requestToEntity(sampleTaskRequest)).thenReturn(sampleTaskEntity); | |
| when(taskRepository.save(any(DeletionTaskEntity.class))).thenReturn(sampleTaskEntity); | |
| taskService.submitDeletionTask(sampleTaskRequest); | |
| ArgumentCaptor<DeletionTaskEntity> entityCaptor = ArgumentCaptor.forClass(DeletionTaskEntity.class); | |
| verify(taskRepository).save(entityCaptor.capture()); | |
| assertEquals(DeletionStatus.PENDING_APPROVAL, entityCaptor.getValue().getStatus()); | |
| } | |
| void submitDeletionTask_SoftDeleteOverride_RequiresSoftApproval_ShouldSetPendingApproval() { | |
| sampleTaskRequest.setOverrideConfig(DeletionTaskRequest.DeletionConfigOverride.builder().softDelete(true).build()); | |
| when(deletionConfigService.getDeletionConfig()).thenReturn(globalConfigSoftDeleteApproval); | |
| when(taskMapper.requestToEntity(sampleTaskRequest)).thenReturn(sampleTaskEntity); | |
| when(taskRepository.save(any(DeletionTaskEntity.class))).thenReturn(sampleTaskEntity); | |
| taskService.submitDeletionTask(sampleTaskRequest); | |
| ArgumentCaptor<DeletionTaskEntity> entityCaptor = ArgumentCaptor.forClass(DeletionTaskEntity.class); | |
| verify(taskRepository).save(entityCaptor.capture()); | |
| assertEquals(DeletionStatus.PENDING_APPROVAL, entityCaptor.getValue().getStatus()); | |
| assertEquals("SOFT", entityCaptor.getValue().getAssetStatuses().get(0).getDeletionType()); | |
| } | |
| void submitDeletionTask_InvalidScope_ShouldReturnFailedStatus() { | |
| DeletionTaskRequest invalidRequest = DeletionTaskRequest.builder().taskName("Invalid").scope(null).build(); | |
| DeletionTaskResponse response = taskService.submitDeletionTask(invalidRequest); | |
| assertEquals(DeletionStatus.FAILED.name(), response.getStatus()); | |
| verify(taskRepository, never()).save(any()); | |
| } | |
| void getTaskStatus_TaskExists_ShouldReturnDTO() { | |
| when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.of(sampleTaskEntity)); | |
| when(taskMapper.entityToStatusDTO(sampleTaskEntity)).thenReturn(sampleTaskStatusDTO); | |
| DeletionTaskStatusDTO result = taskService.getTaskStatus(sampleTaskId); | |
| assertNotNull(result); | |
| assertEquals(sampleTaskId, result.getTaskId()); | |
| } | |
| void getTaskStatus_TaskNotExists_ShouldReturnNull() { | |
| when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.empty()); | |
| DeletionTaskStatusDTO result = taskService.getTaskStatus(sampleTaskId); | |
| assertNull(result); | |
| } | |
| void listTasks_ShouldReturnPaginatedDTOs() { | |
| Pageable pageable = PageRequest.of(0, 10); | |
| List<DeletionTaskEntity> taskList = Collections.singletonList(sampleTaskEntity); | |
| Page<DeletionTaskEntity> page = new PageImpl<>(taskList, pageable, 1); | |
| when(taskRepository.findAll(pageable)).thenReturn(page); | |
| when(taskMapper.entityToStatusDTO(sampleTaskEntity)).thenReturn(sampleTaskStatusDTO); | |
| DeletionTaskListResponse response = taskService.listTasks(pageable); | |
| assertNotNull(response); | |
| assertEquals(1, response.getTasks().size()); | |
| assertEquals(sampleTaskId, response.getTasks().get(0).getTaskId()); | |
| } | |
| void approveTask_TaskExistsAndPending_ShouldApprove() { | |
| sampleTaskEntity.setStatus(DeletionStatus.PENDING_APPROVAL); | |
| when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.of(sampleTaskEntity)); | |
| when(taskRepository.save(any(DeletionTaskEntity.class))).thenReturn(sampleTaskEntity); | |
| when(taskMapper.entityToStatusDTO(any(DeletionTaskEntity.class))).thenAnswer(invocation -> { | |
| DeletionTaskEntity entity = invocation.getArgument(0); | |
| return DeletionTaskStatusDTO.builder().taskId(entity.getTaskId()).status(entity.getStatus().name()).build(); | |
| }); | |
| TaskApprovalRequest approvalReq = TaskApprovalRequest.builder().comments("Approved by test").build(); | |
| DeletionTaskStatusDTO result = taskService.approveTask(sampleTaskId, approvalReq); | |
| assertEquals(DeletionStatus.APPROVED.name(), result.getStatus()); | |
| assertEquals("Approved by test", sampleTaskEntity.getApprovalComments()); | |
| verify(taskRepository).save(sampleTaskEntity); | |
| } | |
| void approveTask_TaskNotPending_ShouldReturnCurrentStatusWithErrors() { | |
| sampleTaskEntity.setStatus(DeletionStatus.COMPLETED); | |
| when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.of(sampleTaskEntity)); | |
| // Mapper will be called to return the current DTO | |
| when(taskMapper.entityToStatusDTO(sampleTaskEntity)).thenReturn(DeletionTaskStatusDTO.builder().taskId(sampleTaskId).status(DeletionStatus.COMPLETED.name()).build()); | |
| DeletionTaskStatusDTO result = taskService.approveTask(sampleTaskId, new TaskApprovalRequest()); | |
| assertEquals(DeletionStatus.COMPLETED.name(), result.getStatus()); | |
| assertNotNull(result.getErrorMessages()); | |
| assertFalse(result.getErrorMessages().isEmpty()); | |
| verify(taskRepository, never()).save(any()); | |
| } | |
| void approveTask_TaskNotFound_ShouldThrowException() { | |
| when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.empty()); | |
| assertThrows(DeletionTaskNotFoundException.class, () -> { | |
| taskService.approveTask(sampleTaskId, new TaskApprovalRequest()); | |
| }); | |
| } | |
| void rejectTask_TaskExistsAndPending_ShouldReject() { | |
| sampleTaskEntity.setStatus(DeletionStatus.PENDING_APPROVAL); | |
| when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.of(sampleTaskEntity)); | |
| when(taskRepository.save(any(DeletionTaskEntity.class))).thenReturn(sampleTaskEntity); | |
| when(taskMapper.entityToStatusDTO(any(DeletionTaskEntity.class))).thenAnswer(invocation -> { | |
| DeletionTaskEntity entity = invocation.getArgument(0); | |
| return DeletionTaskStatusDTO.builder().taskId(entity.getTaskId()).status(entity.getStatus().name()).build(); | |
| }); | |
| TaskApprovalRequest rejectionReq = TaskApprovalRequest.builder().comments("Rejected by test").build(); | |
| DeletionTaskStatusDTO result = taskService.rejectTask(sampleTaskId, rejectionReq); | |
| assertEquals(DeletionStatus.REJECTED.name(), result.getStatus()); | |
| assertEquals("Rejected by test", sampleTaskEntity.getRejectionComments()); | |
| verify(taskRepository).save(sampleTaskEntity); | |
| } | |
| } |