da-autodelete-dev / src /test /java /com /dalab /autodelete /service /impl /DeletionTaskServiceImplTest.java
Ajay Yadav
Initial deployment of da-autodelete-dev
2b88acc
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.*;
@ExtendWith(MockitoExtension.class)
class DeletionTaskServiceImplTest {
@Mock
private DeletionTaskRepository taskRepository;
@Mock
private DeletionTaskMapper taskMapper;
@Mock
private IDeletionConfigService deletionConfigService;
@InjectMocks
private DeletionTaskServiceImpl taskService;
private DeletionTaskRequest sampleTaskRequest;
private DeletionTaskEntity sampleTaskEntity;
private DeletionTaskStatusDTO sampleTaskStatusDTO;
private DeletionTaskResponse sampleTaskResponse;
private DeletionConfigDTO globalConfigDefault;
private DeletionConfigDTO globalConfigSoftDeleteApproval;
private String sampleTaskId;
@BeforeEach
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();
}
@Test
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());
}
@Test
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());
}
@Test
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());
}
@Test
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());
}
@Test
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());
}
@Test
void getTaskStatus_TaskNotExists_ShouldReturnNull() {
when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.empty());
DeletionTaskStatusDTO result = taskService.getTaskStatus(sampleTaskId);
assertNull(result);
}
@Test
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());
}
@Test
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);
}
@Test
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());
}
@Test
void approveTask_TaskNotFound_ShouldThrowException() {
when(taskRepository.findById(sampleTaskId)).thenReturn(Optional.empty());
assertThrows(DeletionTaskNotFoundException.class, () -> {
taskService.approveTask(sampleTaskId, new TaskApprovalRequest());
});
}
@Test
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);
}
}