da-autodelete-dev / src /test /java /com /dalab /autodelete /controller /DeletionTaskControllerTest.java
Ajay Yadav
Initial deployment of da-autodelete-dev
2b88acc
package com.dalab.autodelete.controller;
import com.dalab.autodelete.dto.*;
import com.dalab.autodelete.service.IDeletionTaskService;
import com.dalab.autodelete.service.exception.DeletionTaskNotFoundException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;
import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(DeletionTaskController.class)
class DeletionTaskControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private IDeletionTaskService taskService;
@Autowired
private ObjectMapper objectMapper;
private DeletionTaskRequest sampleTaskRequest;
private DeletionTaskResponse sampleTaskResponse;
private DeletionTaskStatusDTO sampleTaskStatusDTO;
private String sampleTaskId;
@BeforeEach
void setUp() {
sampleTaskId = UUID.randomUUID().toString();
DeletionTaskRequest.DeletionScope scope = DeletionTaskRequest.DeletionScope.builder()
.assetIds(List.of("asset1", "asset2"))
.build();
sampleTaskRequest = DeletionTaskRequest.builder()
.taskName("Test Deletion Task")
.scope(scope)
.build();
sampleTaskResponse = DeletionTaskResponse.builder()
.taskId(sampleTaskId)
.taskName("Test Deletion Task")
.status("SUBMITTED")
.submittedAt(LocalDateTime.now())
.build();
sampleTaskStatusDTO = DeletionTaskStatusDTO.builder()
.taskId(sampleTaskId)
.taskName("Test Deletion Task")
.status("SUBMITTED")
.submittedAt(LocalDateTime.now())
.scope(scope) // Assuming DeletionTaskRequest.DeletionScope is compatible or mapped
.totalAssetsInScope(2)
.build();
}
@Test
@WithMockUser(authorities = "ROLE_ADMIN")
void submitDeletionTask_AsAdmin_ValidRequest_ShouldReturnAccepted() throws Exception {
when(taskService.submitDeletionTask(any(DeletionTaskRequest.class))).thenReturn(sampleTaskResponse);
mockMvc.perform(post("/api/v1/deletion/tasks")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(sampleTaskRequest)))
.andExpect(status().isAccepted())
.andExpect(jsonPath("$.taskId").value(sampleTaskId))
.andExpect(jsonPath("$.status").value("SUBMITTED"));
}
@Test
@WithMockUser(authorities = "ROLE_ADMIN")
void submitDeletionTask_InvalidScope_ShouldReturnBadRequest() throws Exception {
DeletionTaskRequest invalidRequest = DeletionTaskRequest.builder().taskName("Invalid Task").scope(null).build();
// Service returns a specific response for validation failure
DeletionTaskResponse validationFailedResponse = DeletionTaskResponse.builder()
.taskId(null)
.taskName(invalidRequest.getTaskName())
.status("FAILED_VALIDATION")
.message("Scope is null or empty")
.submittedAt(LocalDateTime.now())
.build();
when(taskService.submitDeletionTask(any(DeletionTaskRequest.class))).thenReturn(validationFailedResponse);
mockMvc.perform(post("/api/v1/deletion/tasks")
.with(csrf())
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(invalidRequest)))
.andExpect(status().isBadRequest()) // Controller logic changes status for FAILED_VALIDATION
.andExpect(jsonPath("$.status").value("FAILED_VALIDATION"));
}
@Test
@WithMockUser(authorities = "ROLE_USER") // Assuming USER can get status of their own tasks (logic in service)
void getDeletionTaskStatus_WhenTaskExists_ShouldReturnStatus() throws Exception {
when(taskService.getTaskStatus(sampleTaskId)).thenReturn(sampleTaskStatusDTO);
mockMvc.perform(get("/api/v1/deletion/tasks/{taskId}", sampleTaskId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.taskId").value(sampleTaskId))
.andExpect(jsonPath("$.status").value("SUBMITTED"));
}
@Test
@WithMockUser(authorities = "ROLE_USER")
void getDeletionTaskStatus_WhenTaskNotExists_ShouldReturnNotFound() throws Exception {
when(taskService.getTaskStatus(sampleTaskId)).thenReturn(null); // Service returns null for not found
mockMvc.perform(get("/api/v1/deletion/tasks/{taskId}", sampleTaskId))
.andExpect(status().isNotFound());
}
@Test
@WithMockUser(authorities = "ROLE_DATA_STEWARD")
void listDeletionTasks_ShouldReturnPageOfTasks() throws Exception {
List<DeletionTaskStatusDTO> taskList = Collections.singletonList(sampleTaskStatusDTO);
PageImpl<DeletionTaskStatusDTO> page = new PageImpl<>(taskList, PageRequest.of(0, 20), 1);
DeletionTaskListResponse listResponse = DeletionTaskListResponse.fromPage(page);
when(taskService.listTasks(any(Pageable.class))).thenReturn(listResponse);
mockMvc.perform(get("/api/v1/deletion/tasks").param("page", "0").param("size", "20"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.tasks[0].taskId").value(sampleTaskId));
}
@Test
@WithMockUser(authorities = "ROLE_ADMIN")
void approveDeletionTask_AsAdmin_WhenTaskApprovable_ShouldReturnOk() throws Exception {
DeletionTaskStatusDTO approvedStatus = DeletionTaskStatusDTO.builder().taskId(sampleTaskId).status("APPROVED").build();
when(taskService.approveTask(eq(sampleTaskId), any())).thenReturn(approvedStatus);
mockMvc.perform(post("/api/v1/deletion/tasks/{taskId}/approve", sampleTaskId)
.with(csrf()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("APPROVED"));
}
@Test
@WithMockUser(authorities = "ROLE_ADMIN")
void approveDeletionTask_TaskNotApprovable_ShouldReturnConflict() throws Exception {
DeletionTaskStatusDTO conflictStatus = DeletionTaskStatusDTO.builder()
.taskId(sampleTaskId)
.status("COMPLETED") // Example of a non-approvable state
.errorMessages(List.of("Task not in approvable state"))
.build();
when(taskService.approveTask(eq(sampleTaskId), any())).thenReturn(conflictStatus);
mockMvc.perform(post("/api/v1/deletion/tasks/{taskId}/approve", sampleTaskId)
.with(csrf()))
.andExpect(status().isConflict()) // Controller maps this from DTO having errorMessages
.andExpect(jsonPath("$.status").value("COMPLETED"));
}
@Test
@WithMockUser(authorities = "ROLE_DATA_STEWARD")
void rejectDeletionTask_AsDataSteward_WhenTaskRejectable_ShouldReturnOk() throws Exception {
DeletionTaskStatusDTO rejectedStatus = DeletionTaskStatusDTO.builder().taskId(sampleTaskId).status("REJECTED").build();
when(taskService.rejectTask(eq(sampleTaskId), any())).thenReturn(rejectedStatus);
mockMvc.perform(post("/api/v1/deletion/tasks/{taskId}/reject", sampleTaskId)
.with(csrf()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.status").value("REJECTED"));
}
}