diff --git a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/controller/WorkFlowController.java b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/controller/WorkFlowController.java index e5b956a40..758bfd5c7 100644 --- a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/controller/WorkFlowController.java +++ b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/controller/WorkFlowController.java @@ -68,6 +68,10 @@ public WorkFlowController(WorkFlowService workFlowService) { @PostMapping public ResponseEntity execute(@RequestBody @Valid WorkFlowRequestDTO workFlowRequestDTO) { WorkReport workReport = workFlowService.execute(workFlowRequestDTO); + if (workReport == null) { + return ResponseEntity.status(500).build(); + } + return ResponseEntity.ok(WorkFlowResponseDTO.builder() .workFlowExecutionId(WorkContextDelegate.read(workReport.getWorkContext(), WorkContextDelegate.ProcessType.WORKFLOW_EXECUTION, WorkContextDelegate.Resource.ID).toString()) diff --git a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java index 567c34bf0..4a5541c11 100644 --- a/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java +++ b/workflow-service/src/main/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImpl.java @@ -150,6 +150,10 @@ private String validateWorkflow(String workflowName, WorkFlow workFlow) { // validate if workflow is master WorkFlowDefinition workFlowDefinition = workFlowDefinitionRepository.findFirstByName(workflowName); + if (workFlowDefinition == null) { + return String.format("workflow '%s' is not registered!", workflowName); + } + if (!workFlowWorkRepository.findByWorkDefinitionId(workFlowDefinition.getId()).isEmpty()) { log.error("workflow '{}' is not master workflow!", workflowName); return String.format("workflow '%s' is not master workflow!", workflowName); diff --git a/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/controller/WorkFlowControllerTest.java b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/controller/WorkFlowControllerTest.java new file mode 100644 index 000000000..22cf36c61 --- /dev/null +++ b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/controller/WorkFlowControllerTest.java @@ -0,0 +1,115 @@ +package com.redhat.parodos.workflow.execution.controller; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.redhat.parodos.ControllerMockClient; +import com.redhat.parodos.workflow.definition.service.WorkFlowDefinitionServiceImpl; +import com.redhat.parodos.workflow.execution.dto.WorkFlowRequestDTO; +import com.redhat.parodos.workflow.execution.service.WorkFlowServiceImpl; +import com.redhat.parodos.workflows.work.WorkContext; +import com.redhat.parodos.workflows.work.WorkReport; +import org.hamcrest.Matchers; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.http.MediaType; +import org.springframework.test.annotation.DirtiesContext; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +import java.util.UUID; + +import static org.junit.jupiter.api.Assertions.*; + +@SpringBootTest +@DirtiesContext +@AutoConfigureMockMvc +@ActiveProfiles("local") +class WorkFlowControllerTest extends ControllerMockClient { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private WorkFlowServiceImpl workFlowService; + + @Test + public void ExecuteWithoutAuth() throws Exception { + // when + this.mockMvc.perform(this.getRequestWithInValidCredentials("/api/v1/workflows")) + .andExpect(MockMvcResultMatchers.status().isUnauthorized()); + // then + Mockito.verify(this.workFlowService, Mockito.never()).execute(Mockito.any()); + } + + @Test + public void ExecuteWithValidData() throws Exception { + + // given + WorkFlowRequestDTO workFlowRequestDTO = new WorkFlowRequestDTO().builder().build(); + workFlowRequestDTO.setProjectId(UUID.randomUUID().toString()); + workFlowRequestDTO.setWorkFlowName("FooWorkFlow"); + + ObjectMapper objectMapper = new ObjectMapper(); + String json = objectMapper.writeValueAsString(workFlowRequestDTO); + + WorkReport report = Mockito.mock(WorkReport.class); + WorkContext workContext = new WorkContext(); + workContext.put("WORKFLOW_EXECUTION_ID", UUID.randomUUID().toString()); + Mockito.when(report.getWorkContext()).thenReturn(workContext); + Mockito.when(this.workFlowService.execute(Mockito.any())).thenReturn(report); + + // when + this.mockMvc.perform(this.postRequestWithValidCredentials("/api/v1/workflows").content(json)) + .andExpect(MockMvcResultMatchers.status().isOk()) + .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(MockMvcResultMatchers.jsonPath("$.workFlowExecutionId", + Matchers.is(workContext.get("WORKFLOW_EXECUTION_ID")))); + + // then + Mockito.verify(this.workFlowService, Mockito.times(1)).execute(Mockito.any()); + } + + @Test + public void ServiceExecuteFails() throws Exception { + // given + WorkFlowRequestDTO workFlowRequestDTO = new WorkFlowRequestDTO().builder().build(); + workFlowRequestDTO.setProjectId(UUID.randomUUID().toString()); + workFlowRequestDTO.setWorkFlowName("FooWorkFlow"); + + ObjectMapper objectMapper = new ObjectMapper(); + String json = objectMapper.writeValueAsString(workFlowRequestDTO); + + Mockito.when(this.workFlowService.execute(Mockito.any())).thenReturn(null); + + // when + this.mockMvc.perform(this.postRequestWithValidCredentials("/api/v1/workflows").content(json)) + .andExpect(MockMvcResultMatchers.status().isInternalServerError()); + + // then + Mockito.verify(this.workFlowService, Mockito.times(1)).execute(Mockito.any()); + } + + @Test + public void TestGetStatusWithoutAuth() throws Exception { + // when + this.mockMvc + .perform(this.getRequestWithInValidCredentials( + String.format("/api/v1/workflows/%s/status", UUID.randomUUID().toString()))) + .andExpect(MockMvcResultMatchers.status().isUnauthorized()); + } + + @Test + public void TestGetStatusWithValidData() throws Exception { + // @TODO this test should be completed when the API is implemented + // when + this.mockMvc + .perform(this.getRequestWithValidCredentials( + String.format("/api/v1/workflows/%s/status", UUID.randomUUID().toString()))) + .andExpect(MockMvcResultMatchers.status().isOk()); + } + +} \ No newline at end of file diff --git a/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java index b6a720d70..ff829db40 100644 --- a/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java +++ b/workflow-service/src/test/java/com/redhat/parodos/workflow/execution/service/WorkFlowServiceImplTest.java @@ -2,6 +2,7 @@ import com.redhat.parodos.workflow.WorkFlowDelegate; import com.redhat.parodos.workflow.definition.entity.WorkFlowDefinition; +import com.redhat.parodos.workflow.definition.entity.WorkFlowWorkDefinition; import com.redhat.parodos.workflow.definition.repository.WorkFlowDefinitionRepository; import com.redhat.parodos.workflow.definition.repository.WorkFlowWorkRepository; import com.redhat.parodos.workflow.enums.WorkFlowStatus; @@ -21,6 +22,7 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import org.mockito.stubbing.OngoingStubbing; import java.util.LinkedList; import java.util.List; @@ -46,14 +48,15 @@ class WorkFlowServiceImplTest { private WorkFlowServiceImpl workFlowService; @BeforeEach - void init_earch() { + void init_each() { this.workFlowRepository = Mockito.mock(WorkFlowRepository.class); this.workFlowDefinitionRepository = Mockito.mock(WorkFlowDefinitionRepository.class); this.workFlowTaskRepository = Mockito.mock(WorkFlowTaskRepository.class); this.workFlowDelegate = Mockito.mock(WorkFlowDelegate.class); + this.workFlowWorkRepository = Mockito.mock(WorkFlowWorkRepository.class); this.workFlowService = new WorkFlowServiceImpl(this.workFlowDelegate, this.workFlowDefinitionRepository, - this.workFlowRepository, this.workFlowTaskRepository, workFlowWorkRepository); + this.workFlowRepository, this.workFlowTaskRepository, this.workFlowWorkRepository); } @Test @@ -109,6 +112,89 @@ void executeTestWithNoValidWorkflow() { Mockito.verify(this.workFlowDefinitionRepository, Mockito.times(0)).findFirstByName(Mockito.any()); } + @Test + void executeWithDTOWithValidData() { + // given + Work work = Mockito.mock(Work.class); + SequentialFlow workFlow = SequentialFlow.Builder.aNewSequentialFlow().named("test").execute(work).build(); + Mockito.when(work.execute(Mockito.any())) + .thenReturn(new DefaultWorkReport(WorkStatus.COMPLETED, new WorkContext() { + { + put("foo", "bar"); + } + })); + Mockito.when(this.workFlowDefinitionRepository.findFirstByName(Mockito.any())) + .thenReturn(this.sampleWorkflowDefinition("test")); + Mockito.when(this.workFlowWorkRepository.findByWorkDefinitionId(Mockito.any())).thenReturn(List.of()); + Mockito.when(this.workFlowDelegate.initWorkFlowContext(Mockito.any())).thenReturn(new WorkContext()); + Mockito.when(this.workFlowDelegate.getWorkFlowExecutionByName("test-workflow")).thenReturn(workFlow); + + // when + WorkReport report = this.workFlowService.execute(WorkFlowRequestDTO.builder().projectId("test-project") + .works(List.of()).workFlowName("test-workflow").build()); + // then + assertNotNull(report); + assertEquals(report.getStatus().toString(), "COMPLETED"); + assertNull(report.getError()); + + assertNotNull(report.getWorkContext()); + + Mockito.verify(this.workFlowDelegate, Mockito.times(2)).getWorkFlowExecutionByName(Mockito.any()); + Mockito.verify(this.workFlowDelegate, Mockito.times(1)).initWorkFlowContext(Mockito.any()); + Mockito.verify(this.workFlowDefinitionRepository, Mockito.times(1)).findFirstByName(Mockito.any()); + } + + @Test + void executeWithDTOWithNoMasterWorkFlow() { + // given + Work work = Mockito.mock(Work.class); + SequentialFlow workFlow = SequentialFlow.Builder.aNewSequentialFlow().named("test").execute(work).build(); + Mockito.when(this.workFlowDefinitionRepository.findFirstByName(Mockito.any())) + .thenReturn(this.sampleWorkflowDefinition("test")); + Mockito.when(this.workFlowWorkRepository.findByWorkDefinitionId(Mockito.any())) + .thenReturn(List.of(WorkFlowWorkDefinition.builder().build())); + + Mockito.when(this.workFlowDelegate.getWorkFlowExecutionByName("test-workflow")).thenReturn(workFlow); + + // when + WorkReport report = this.workFlowService.execute(WorkFlowRequestDTO.builder().projectId("test-project") + .works(List.of()).workFlowName("test-workflow").build()); + // then + assertNotNull(report); + assertEquals(report.getStatus().toString(), "FAILED"); + assertNotNull(report.getError()); + + assertNotNull(report.getWorkContext()); + + Mockito.verify(this.workFlowDelegate, Mockito.times(1)).getWorkFlowExecutionByName(Mockito.any()); + Mockito.verify(this.workFlowDelegate, Mockito.times(0)).initWorkFlowContext(Mockito.any()); + Mockito.verify(this.workFlowDefinitionRepository, Mockito.times(1)).findFirstByName(Mockito.any()); + } + + @Test + void executeWithDTOWithNoWorkFlowDefinition() { + // given + Work work = Mockito.mock(Work.class); + SequentialFlow workFlow = SequentialFlow.Builder.aNewSequentialFlow().named("test").execute(work).build(); + Mockito.when(this.workFlowDefinitionRepository.findFirstByName(Mockito.any())).thenReturn(null); + Mockito.when(this.workFlowDelegate.getWorkFlowExecutionByName("test-workflow")).thenReturn(workFlow); + + // when + WorkReport report = this.workFlowService.execute(WorkFlowRequestDTO.builder().projectId("test-project") + .works(List.of()).workFlowName("test-workflow").build()); + // then + assertNotNull(report); + assertEquals(report.getStatus().toString(), "FAILED"); + assertNotNull(report.getError()); + + assertNotNull(report.getWorkContext()); + + Mockito.verify(this.workFlowDelegate, Mockito.times(1)).getWorkFlowExecutionByName(Mockito.any()); + Mockito.verify(this.workFlowDelegate, Mockito.never()).initWorkFlowContext(Mockito.any()); + Mockito.verify(this.workFlowDefinitionRepository, Mockito.times(1)).findFirstByName(Mockito.any()); + Mockito.verify(this.workFlowWorkRepository, Mockito.never()).findByWorkDefinitionId(Mockito.any()); + } + @Test void getWorkFlowByIDTestWithValidData() { // given