From 54df6410a7364d71c1ee5976b0071847e1492d9f Mon Sep 17 00:00:00 2001 From: andrea999 <74648528+Andrea2000728@users.noreply.github.com> Date: Thu, 11 Jan 2024 12:10:10 +0800 Subject: [PATCH] ADM-709:[backend][docs]:Verify buildkite and obtain buildkite data with new API (#889) * ADM-709:[backend]feat: add verify token and get info for buildKite controller Co-authored-by: Andrea --- .../pipeline/PipelineController.java | 24 ++ .../pipeline/dto/request/PipelineType.java | 26 ++ .../pipeline/dto/request/TokenParam.java | 20 ++ .../pipeline/buildkite/BuildKiteService.java | 65 ++++- .../pipeline/BuildKiteControllerTest.java | 87 +++++- .../dto/response/PipelineTypeTest.java | 24 ++ .../buildkite/BuildKiteServiceTest.java | 251 ++++++++++++------ .../tech-spikes-split-verify-of-buildkite.mdx | 26 +- 8 files changed, 425 insertions(+), 98 deletions(-) create mode 100644 backend/src/main/java/heartbeat/controller/pipeline/dto/request/PipelineType.java create mode 100644 backend/src/main/java/heartbeat/controller/pipeline/dto/request/TokenParam.java create mode 100644 backend/src/test/java/heartbeat/controller/pipeline/dto/response/PipelineTypeTest.java diff --git a/backend/src/main/java/heartbeat/controller/pipeline/PipelineController.java b/backend/src/main/java/heartbeat/controller/pipeline/PipelineController.java index 4d449f11f4..af80edf7a0 100644 --- a/backend/src/main/java/heartbeat/controller/pipeline/PipelineController.java +++ b/backend/src/main/java/heartbeat/controller/pipeline/PipelineController.java @@ -1,5 +1,7 @@ package heartbeat.controller.pipeline; +import heartbeat.controller.pipeline.dto.request.PipelineType; +import heartbeat.controller.pipeline.dto.request.TokenParam; import heartbeat.controller.pipeline.dto.request.PipelineParam; import heartbeat.controller.pipeline.dto.request.PipelineStepsParam; import heartbeat.controller.pipeline.dto.response.BuildKiteResponseDTO; @@ -29,12 +31,34 @@ public class PipelineController { private final BuildKiteService buildKiteService; + @Deprecated @PostMapping("/{pipelineType}") public BuildKiteResponseDTO getBuildKiteInfo(@PathVariable String pipelineType, @Valid @RequestBody PipelineParam pipelineParam) { return buildKiteService.fetchPipelineInfo(pipelineParam); } + @PostMapping("/{pipelineType}/verify") + public ResponseEntity verifyBuildKiteToken(@PathVariable @NotBlank String pipelineType, + @Valid @RequestBody TokenParam tokenParam) { + PipelineType.fromValue(pipelineType); + buildKiteService.verifyToken(tokenParam.getToken()); + return ResponseEntity.noContent().build(); + } + + @PostMapping("/{pipelineType}/info") + public ResponseEntity fetchBuildKiteInfo(@PathVariable @NotBlank String pipelineType, + @Valid @RequestBody PipelineParam pipelineParam) { + PipelineType.fromValue(pipelineType); + BuildKiteResponseDTO buildKiteResponse = buildKiteService.getBuildKiteInfo(pipelineParam); + if (buildKiteResponse.getPipelineList().isEmpty()) { + return ResponseEntity.noContent().build(); + } + else { + return ResponseEntity.ok(buildKiteResponse); + } + } + @GetMapping("/{pipelineType}/{organizationId}/pipelines/{buildId}/steps") public ResponseEntity getPipelineSteps( @RequestHeader("Authorization") @NotBlank(message = "Token must not be blank") String token, diff --git a/backend/src/main/java/heartbeat/controller/pipeline/dto/request/PipelineType.java b/backend/src/main/java/heartbeat/controller/pipeline/dto/request/PipelineType.java new file mode 100644 index 0000000000..ba42169952 --- /dev/null +++ b/backend/src/main/java/heartbeat/controller/pipeline/dto/request/PipelineType.java @@ -0,0 +1,26 @@ +package heartbeat.controller.pipeline.dto.request; + +import lombok.extern.log4j.Log4j2; + +@Log4j2 +public enum PipelineType { + + BUILDKITE("buildkite"); + + public final String pipelineType; + + PipelineType(String pipelineType) { + this.pipelineType = pipelineType; + } + + public static PipelineType fromValue(String type) { + return switch (type) { + case "buildkite" -> BUILDKITE; + default -> { + log.error("Failed to match Pipeline type: {} ", type); + throw new IllegalArgumentException("Pipeline type does not find!"); + } + }; + } + +} diff --git a/backend/src/main/java/heartbeat/controller/pipeline/dto/request/TokenParam.java b/backend/src/main/java/heartbeat/controller/pipeline/dto/request/TokenParam.java new file mode 100644 index 0000000000..3952fae8f6 --- /dev/null +++ b/backend/src/main/java/heartbeat/controller/pipeline/dto/request/TokenParam.java @@ -0,0 +1,20 @@ +package heartbeat.controller.pipeline.dto.request; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class TokenParam { + + @Valid + @NotBlank(message = "Token cannot be empty.") + private String token; + +} diff --git a/backend/src/main/java/heartbeat/service/pipeline/buildkite/BuildKiteService.java b/backend/src/main/java/heartbeat/service/pipeline/buildkite/BuildKiteService.java index ab69452c31..08799f70f2 100644 --- a/backend/src/main/java/heartbeat/service/pipeline/buildkite/BuildKiteService.java +++ b/backend/src/main/java/heartbeat/service/pipeline/buildkite/BuildKiteService.java @@ -38,7 +38,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.IntStream; -import java.net.URLEncoder; @Service @RequiredArgsConstructor @@ -58,6 +57,7 @@ public void shutdownExecutor() { customTaskExecutor.shutdown(); } + @Deprecated public BuildKiteResponseDTO fetchPipelineInfo(PipelineParam pipelineParam) { try { String buildKiteToken = "Bearer " + pipelineParam.getToken(); @@ -65,13 +65,13 @@ public BuildKiteResponseDTO fetchPipelineInfo(PipelineParam pipelineParam) { BuildKiteTokenInfo buildKiteTokenInfo = buildKiteFeignClient.getTokenInfo(buildKiteToken); log.info("Successfully query token permissions by token, token info scopes: {}", buildKiteTokenInfo.getScopes()); - verifyToken(buildKiteTokenInfo); + verifyTokenScopes(buildKiteTokenInfo); log.info("Start to query BuildKite organizations by token"); List buildKiteOrganizationsInfo = buildKiteFeignClient .getBuildKiteOrganizationsInfo(buildKiteToken); log.info("Successfully query BuildKite organizations by token, slug: {}", buildKiteOrganizationsInfo); - log.info("Start to query buildKite pipelineInfo by organizations slug: {}", buildKiteOrganizationsInfo); + log.info("Start to query BuildKite pipelineInfo by organizations slug: {}", buildKiteOrganizationsInfo); List buildKiteInfoList = buildKiteOrganizationsInfo.stream() .flatMap(org -> buildKiteFeignClient .getPipelineInfo(buildKiteToken, org.getSlug(), "1", "100", pipelineParam.getStartTime(), @@ -80,7 +80,7 @@ public BuildKiteResponseDTO fetchPipelineInfo(PipelineParam pipelineParam) { .map(pipeline -> PipelineTransformer.fromBuildKitePipelineDto(pipeline, org.getSlug(), org.getName()))) .collect(Collectors.toList()); - log.info("Successfully get buildKite pipelineInfo, slug:{}, pipelineInfoList size:{}", + log.info("Successfully get BuildKite pipelineInfo, slug:{}, pipelineInfoList size:{}", buildKiteOrganizationsInfo, buildKiteInfoList.size()); return BuildKiteResponseDTO.builder().pipelineList(buildKiteInfoList).build(); @@ -98,7 +98,7 @@ public BuildKiteResponseDTO fetchPipelineInfo(PipelineParam pipelineParam) { } } - private void verifyToken(BuildKiteTokenInfo buildKiteTokenInfo) { + private void verifyTokenScopes(BuildKiteTokenInfo buildKiteTokenInfo) { for (String permission : permissions) { if (!buildKiteTokenInfo.getScopes().contains(permission)) { log.error("Failed to call BuildKite, because of insufficient permission, current permissions: {}", @@ -300,4 +300,59 @@ private List getBuildsByState(List buildInfos, .toList(); } + public void verifyToken(String token) { + try { + String buildKiteToken = "Bearer " + token; + log.info("Start to query token permissions by token"); + BuildKiteTokenInfo buildKiteTokenInfo = buildKiteFeignClient.getTokenInfo(buildKiteToken); + log.info("Successfully query token permissions by token, token info scopes: {}", + buildKiteTokenInfo.getScopes()); + verifyTokenScopes(buildKiteTokenInfo); + } + catch (RuntimeException e) { + Throwable cause = Optional.ofNullable(e.getCause()).orElse(e); + log.error("Failed to call BuildKite, e: {}", cause.getMessage()); + if (cause instanceof BaseException baseException) { + throw baseException; + } + throw new InternalServerErrorException( + String.format("Failed to call BuildKite, cause is %s", cause.getMessage())); + } + } + + public BuildKiteResponseDTO getBuildKiteInfo(PipelineParam pipelineParam) { + try { + String buildKiteToken = "Bearer " + pipelineParam.getToken(); + log.info("Start to query BuildKite organizations by token"); + List buildKiteOrganizationsInfo = buildKiteFeignClient + .getBuildKiteOrganizationsInfo(buildKiteToken); + log.info("Successfully query BuildKite organizations by token, slug: {}", buildKiteOrganizationsInfo); + + log.info("Start to query BuildKite pipelineInfo by organizations slug: {}", buildKiteOrganizationsInfo); + List buildKiteInfoList = buildKiteOrganizationsInfo.stream() + .flatMap(org -> buildKiteFeignClient + .getPipelineInfo(buildKiteToken, org.getSlug(), "1", "100", pipelineParam.getStartTime(), + pipelineParam.getEndTime()) + .stream() + .map(pipeline -> PipelineTransformer.fromBuildKitePipelineDto(pipeline, org.getSlug(), + org.getName()))) + .collect(Collectors.toList()); + log.info("Successfully get BuildKite pipelineInfo, slug:{}, pipelineInfoList size:{}", + buildKiteOrganizationsInfo, buildKiteInfoList.size()); + + return BuildKiteResponseDTO.builder().pipelineList(buildKiteInfoList).build(); + } + catch (RuntimeException e) { + Throwable cause = Optional.ofNullable(e.getCause()).orElse(e); + log.error("Failed to call BuildKite, start time: {}, e: {}", pipelineParam.getStartTime(), + cause.getMessage()); + if (cause instanceof BaseException baseException) { + throw baseException; + } + throw new InternalServerErrorException( + String.format("Failed to call BuildKite, cause is %s", cause.getMessage())); + + } + } + } diff --git a/backend/src/test/java/heartbeat/controller/pipeline/BuildKiteControllerTest.java b/backend/src/test/java/heartbeat/controller/pipeline/BuildKiteControllerTest.java index 62efa0527c..bdefefdf47 100644 --- a/backend/src/test/java/heartbeat/controller/pipeline/BuildKiteControllerTest.java +++ b/backend/src/test/java/heartbeat/controller/pipeline/BuildKiteControllerTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -12,6 +13,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.JsonPath; import heartbeat.controller.pipeline.dto.request.PipelineParam; +import heartbeat.controller.pipeline.dto.request.TokenParam; import heartbeat.controller.pipeline.dto.response.BuildKiteResponseDTO; import heartbeat.controller.pipeline.dto.response.Pipeline; import heartbeat.controller.pipeline.dto.response.PipelineStepsDTO; @@ -19,6 +21,7 @@ import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import lombok.val; @@ -38,6 +41,14 @@ @AutoConfigureJsonTesters public class BuildKiteControllerTest { + public static final String TEST_TOKEN = "test_token"; + + public static final String TEST_START_TIME = "16737733"; + + public static final String TEST_END_TIME = "17657557"; + + public static final String BUILD_KITE = "buildkite"; + @MockBean private BuildKiteService buildKiteService; @@ -53,16 +64,18 @@ void shouldReturnCorrectPipelineInfoWhenCallBuildKiteMockServer() throws Excepti BuildKiteResponseDTO buildKiteResponseDTO = BuildKiteResponseDTO.builder().pipelineList(pipelines).build(); when(buildKiteService.fetchPipelineInfo(any())).thenReturn(buildKiteResponseDTO); PipelineParam pipelineParam = PipelineParam.builder() - .token("test_token") - .startTime("16737733") - .endTime("17657557") + .token(TEST_TOKEN) + .startTime(TEST_START_TIME) + .endTime(TEST_END_TIME) .build(); + MockHttpServletResponse response = mockMvc .perform(post("/pipelines/buildKite").contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(pipelineParam))) .andExpect(status().isOk()) .andReturn() .getResponse(); + final var resultId = JsonPath.parse(response.getContentAsString()).read("$.pipelineList[0].id").toString(); assertThat(resultId).contains("payment-selector-ui"); final var resultName = JsonPath.parse(response.getContentAsString()).read("$.pipelineList[0].name").toString(); @@ -88,6 +101,7 @@ void shouldReturnCorrectPipelineStepsWhenCalBuildKiteMockServer() throws Excepti .andExpect(status().isOk()) .andReturn() .getResponse(); + val resultStep = JsonPath.parse(response.getContentAsString()).read("$.steps[0]"); assertThat(resultStep).isEqualTo(":docker: publish image to cloudsmith"); } @@ -96,7 +110,6 @@ void shouldReturnCorrectPipelineStepsWhenCalBuildKiteMockServer() throws Excepti void shouldReturnNoContentIfNoStepsWhenCallBuildKite() throws Exception { List steps = new ArrayList<>(); PipelineStepsDTO emptyPipelineSteps = PipelineStepsDTO.builder().steps(steps).build(); - when(buildKiteService.fetchPipelineSteps(anyString(), anyString(), anyString(), any())) .thenReturn(emptyPipelineSteps); @@ -116,4 +129,70 @@ void shouldReturnNoContentIfNoStepsWhenCallBuildKite() throws Exception { assertThat(response.getContentAsString()).isEqualTo(""); } + @Test + void shouldReturnNoContentWhenCorrectTokenCallBuildKite() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + TokenParam tokenParam = TokenParam.builder().token(TEST_TOKEN).build(); + doNothing().when(buildKiteService).verifyToken(any()); + + MockHttpServletResponse response = mockMvc + .perform(post("/pipelines/{pipelineType}/verify", BUILD_KITE).contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(tokenParam))) + .andExpect(status().isNoContent()) + .andReturn() + .getResponse(); + + assertThat(response.getContentAsString()).isEqualTo(""); + } + + @Test + void shouldReturnPipelineInfoWhenCorrectTokenCallBuildKite() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + List pipelines = mapper.readValue( + new File("src/test/java/heartbeat/controller/pipeline/pipelineInfoData.json"), new TypeReference<>() { + }); + BuildKiteResponseDTO buildKiteResponseDTO = BuildKiteResponseDTO.builder().pipelineList(pipelines).build(); + PipelineParam pipelineParam = PipelineParam.builder() + .token(TEST_TOKEN) + .startTime(TEST_START_TIME) + .endTime(TEST_END_TIME) + .build(); + when(buildKiteService.getBuildKiteInfo(any())).thenReturn(buildKiteResponseDTO); + + MockHttpServletResponse response = mockMvc + .perform(post("/pipelines/{pipelineType}/info", BUILD_KITE).contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(pipelineParam))) + .andExpect(status().isOk()) + .andReturn() + .getResponse(); + + final var resultId = JsonPath.parse(response.getContentAsString()).read("$.pipelineList[0].id").toString(); + assertThat(resultId).contains("payment-selector-ui"); + final var resultName = JsonPath.parse(response.getContentAsString()).read("$.pipelineList[0].name").toString(); + assertThat(resultName).contains("payment-selector-ui"); + } + + @Test + void shouldReturnNoContentGivenPipelineInfoIsNullWhenCallingBuildKite() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + BuildKiteResponseDTO buildKiteResponseDTO = BuildKiteResponseDTO.builder() + .pipelineList(Collections.emptyList()) + .build(); + PipelineParam pipelineParam = PipelineParam.builder() + .token(TEST_TOKEN) + .startTime(TEST_START_TIME) + .endTime(TEST_END_TIME) + .build(); + when(buildKiteService.getBuildKiteInfo(any())).thenReturn(buildKiteResponseDTO); + + MockHttpServletResponse response = mockMvc + .perform(post("/pipelines/{pipelineType}/info", BUILD_KITE).contentType(MediaType.APPLICATION_JSON) + .content(mapper.writeValueAsString(pipelineParam))) + .andExpect(status().isNoContent()) + .andReturn() + .getResponse(); + + assertThat(response.getContentAsString()).isEqualTo(""); + } + } diff --git a/backend/src/test/java/heartbeat/controller/pipeline/dto/response/PipelineTypeTest.java b/backend/src/test/java/heartbeat/controller/pipeline/dto/response/PipelineTypeTest.java new file mode 100644 index 0000000000..66e1a5957f --- /dev/null +++ b/backend/src/test/java/heartbeat/controller/pipeline/dto/response/PipelineTypeTest.java @@ -0,0 +1,24 @@ +package heartbeat.controller.pipeline.dto.response; + +import heartbeat.controller.pipeline.dto.request.PipelineType; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class PipelineTypeTest { + + @Test + public void shouldConvertValueToType() { + PipelineType buildKiteType = PipelineType.fromValue("buildkite"); + + assertEquals(buildKiteType, PipelineType.BUILDKITE); + } + + @Test + public void shouldThrowExceptionWhenDateTypeNotSupported() { + assertThatThrownBy(() -> PipelineType.fromValue("unknown")).isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining("Pipeline type does not find!"); + } + +} diff --git a/backend/src/test/java/heartbeat/service/pipeline/buildkite/BuildKiteServiceTest.java b/backend/src/test/java/heartbeat/service/pipeline/buildkite/BuildKiteServiceTest.java index be3b88207b..43f3214d93 100644 --- a/backend/src/test/java/heartbeat/service/pipeline/buildkite/BuildKiteServiceTest.java +++ b/backend/src/test/java/heartbeat/service/pipeline/buildkite/BuildKiteServiceTest.java @@ -4,6 +4,7 @@ import heartbeat.exception.InternalServerErrorException; import heartbeat.exception.ServiceUnavailableException; import heartbeat.exception.UnauthorizedException; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.hibernate.validator.internal.util.Contracts.assertNotNull; @@ -12,6 +13,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -78,13 +80,27 @@ class BuildKiteServiceTest { ; rel="next" """; + public static final String MOCK_TOKEN = "mock_token"; + + public static final String TEST_ORG_ID = "test_org_id"; + + public static final String TEST_ORG_NAME = "test_org_name"; + + public static final String TEST_PIPELINE_ID = "test_pipeline_id"; + private static final String PASSED_STATE = "passed"; private static final String FAILED_STATE = "failed"; - private static final String mockStartTime = "1661702400000"; + private static final String MOCK_START_TIME = "1661702400000"; - private static final String mockEndTime = "1662739199000"; + private static final String MOCK_END_TIME = "1662739199000"; + + public static final List PERMISSION_SCOPES = List.of("read_builds", "read_organizations", "read_pipelines"); + + public static final String TEST_JOB_NAME = "testJob"; + + public static final String UNAUTHORIZED_MSG = "unauthorized"; @Mock BuildKiteFeignClient buildKiteFeignClient; @@ -121,17 +137,16 @@ void shouldReturnBuildKiteResponseWhenCallBuildKiteApi() throws IOException { new File("src/test/java/heartbeat/controller/pipeline/buildKitePipelineInfoData.json"), new TypeReference<>() { }); - BuildKiteTokenInfo buildKiteTokenInfo = BuildKiteTokenInfo.builder() - .scopes(List.of("read_builds", "read_organizations", "read_pipelines")) - .build(); + BuildKiteTokenInfo buildKiteTokenInfo = BuildKiteTokenInfo.builder().scopes(PERMISSION_SCOPES).build(); PipelineParam pipelineParam = PipelineParam.builder() - .token("test_token") - .startTime("startTime") - .endTime("endTime") + .token(MOCK_TOKEN) + .startTime(MOCK_START_TIME) + .endTime(MOCK_END_TIME) .build(); when(buildKiteFeignClient.getBuildKiteOrganizationsInfo(any())) - .thenReturn(List.of(BuildKiteOrganizationsInfo.builder().name("XXXX").slug("XXXX").build())); - when(buildKiteFeignClient.getPipelineInfo("Bearer test_token", "XXXX", "1", "100", "startTime", "endTime")) + .thenReturn(List.of(BuildKiteOrganizationsInfo.builder().name(TEST_ORG_NAME).slug(TEST_ORG_ID).build())); + when(buildKiteFeignClient.getPipelineInfo("Bearer mock_token", TEST_ORG_ID, "1", "100", MOCK_START_TIME, + MOCK_END_TIME)) .thenReturn(pipelineDTOS); when(buildKiteFeignClient.getTokenInfo(any())).thenReturn(buildKiteTokenInfo); @@ -141,8 +156,8 @@ void shouldReturnBuildKiteResponseWhenCallBuildKiteApi() throws IOException { Pipeline pipeline = buildKiteResponseDTO.getPipelineList().get(0); assertThat(pipeline.getId()).isEqualTo("payment-selector-ui"); assertThat(pipeline.getName()).isEqualTo("payment-selector-ui"); - assertThat(pipeline.getOrgId()).isEqualTo("XXXX"); - assertThat(pipeline.getOrgName()).isEqualTo("XXXX"); + assertThat(pipeline.getOrgId()).isEqualTo(TEST_ORG_ID); + assertThat(pipeline.getOrgName()).isEqualTo(TEST_ORG_NAME); assertThat(pipeline.getRepository()) .isEqualTo("https://github.com/XXXX-fs/fs-platform-payment-selector-ui.git"); assertThat(pipeline.getSteps().size()).isEqualTo(1); @@ -150,15 +165,13 @@ void shouldReturnBuildKiteResponseWhenCallBuildKiteApi() throws IOException { @Test void shouldThrowRequestFailedExceptionWhenFeignClientCallFailed() { - BuildKiteTokenInfo buildKiteTokenInfo = BuildKiteTokenInfo.builder() - .scopes(List.of("read_builds", "read_organizations", "read_pipelines")) - .build(); + BuildKiteTokenInfo buildKiteTokenInfo = BuildKiteTokenInfo.builder().scopes(PERMISSION_SCOPES).build(); when(buildKiteFeignClient.getBuildKiteOrganizationsInfo(any())) .thenThrow(new CustomFeignClientException(401, "Bad credentials")); when(buildKiteFeignClient.getTokenInfo(any())).thenReturn(buildKiteTokenInfo); assertThatThrownBy(() -> buildKiteService.fetchPipelineInfo( - PipelineParam.builder().token("test_token").startTime("startTime").endTime("endTime").build())) + PipelineParam.builder().token(MOCK_TOKEN).startTime(MOCK_START_TIME).endTime(MOCK_END_TIME).build())) .isInstanceOf(Exception.class) .hasMessageContaining("Bad credentials"); @@ -171,18 +184,15 @@ void shouldThrowNoPermissionExceptionWhenTokenPermissionDeny() { when(buildKiteFeignClient.getTokenInfo(any())).thenReturn(buildKiteTokenInfo); assertThrows(PermissionDenyException.class, () -> buildKiteService.fetchPipelineInfo( - PipelineParam.builder().token("test_token").startTime("startTime").endTime("endTime").build())); + PipelineParam.builder().token(MOCK_TOKEN).startTime(MOCK_START_TIME).endTime(MOCK_END_TIME).build())); } @Test public void shouldReturnResponseWhenFetchPipelineStepsSuccess() { - String token = "test_token"; - String organizationId = "test_org_id"; - String pipelineId = "test_pipeline_id"; PipelineStepsParam stepsParam = new PipelineStepsParam(); - stepsParam.setStartTime(mockStartTime); - stepsParam.setEndTime(mockEndTime); - BuildKiteJob testJob = BuildKiteJob.builder().name("testJob").build(); + stepsParam.setStartTime(MOCK_START_TIME); + stepsParam.setEndTime(MOCK_END_TIME); + BuildKiteJob testJob = BuildKiteJob.builder().name(TEST_JOB_NAME).build(); List buildKiteBuildInfoList = new ArrayList<>(); buildKiteBuildInfoList.add(BuildKiteBuildInfo.builder() .jobs(List.of(testJob)) @@ -194,11 +204,11 @@ public void shouldReturnResponseWhenFetchPipelineStepsSuccess() { anyString(), anyString(), any())) .thenReturn(responseEntity); - PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps(token, organizationId, pipelineId, - stepsParam); + PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, + TEST_PIPELINE_ID, stepsParam); assertNotNull(pipelineStepsDTO); - assertThat(pipelineStepsDTO.getSteps().get(0)).isEqualTo("testJob"); + assertThat(pipelineStepsDTO.getSteps().get(0)).isEqualTo(TEST_JOB_NAME); } @Test @@ -211,22 +221,22 @@ public void shouldThrowRequestFailedExceptionWhenFetchPipelineStepsWithException .thenThrow(mockException); assertThrows(RequestFailedException.class, - () -> buildKiteService.fetchPipelineSteps("test_token", "test_org_id", "test_pipeline_id", - PipelineStepsParam.builder().startTime(mockStartTime).endTime(mockEndTime).build()), + () -> buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, TEST_PIPELINE_ID, + PipelineStepsParam.builder().startTime(MOCK_START_TIME).endTime(MOCK_END_TIME).build()), "Request failed with status code 500, error: exception"); } @Test public void shouldReturnMoreThanOnePageStepsWhenPageFetchPipelineSteps() { PipelineStepsParam stepsParam = new PipelineStepsParam(); - stepsParam.setStartTime(mockStartTime); - stepsParam.setEndTime(mockEndTime); + stepsParam.setStartTime(MOCK_START_TIME); + stepsParam.setEndTime(MOCK_END_TIME); List linkHeader = new ArrayList<>(); linkHeader.add(TOTAL_PAGE_HEADER); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.addAll(HttpHeaders.LINK, linkHeader); List buildKiteBuildInfoList = new ArrayList<>(); - BuildKiteJob testJob = BuildKiteJob.builder().name("testJob").build(); + BuildKiteJob testJob = BuildKiteJob.builder().name(TEST_JOB_NAME).build(); BuildKiteJob testJob2 = BuildKiteJob.builder().name("testJob2").build(); buildKiteBuildInfoList.add(BuildKiteBuildInfo.builder().jobs(List.of(testJob, testJob2)).build()); ResponseEntity> responseEntity = new ResponseEntity<>(buildKiteBuildInfoList, @@ -242,12 +252,12 @@ public void shouldReturnMoreThanOnePageStepsWhenPageFetchPipelineSteps() { anyString(), anyString(), any())) .thenReturn(buildKiteBuildInfoList2); - PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps("test_token", "test_org_id", - "test_pipeline_id", stepsParam); + PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, + TEST_PIPELINE_ID, stepsParam); assertNotNull(pipelineStepsDTO); assertThat(pipelineStepsDTO.getSteps().size()).isEqualTo(3); - assertThat(pipelineStepsDTO.getSteps().get(0)).isEqualTo("testJob"); + assertThat(pipelineStepsDTO.getSteps().get(0)).isEqualTo(TEST_JOB_NAME); assertThat(pipelineStepsDTO.getSteps().get(1)).isEqualTo("testJob2"); assertThat(pipelineStepsDTO.getSteps().get(2)).isEqualTo("testJob3"); } @@ -259,7 +269,7 @@ public void shouldRThrowServerErrorWhenPageFetchPipelineStepsAndFetchNextPage404 HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.addAll(HttpHeaders.LINK, linkHeader); List buildKiteBuildInfoList = new ArrayList<>(); - BuildKiteJob testJob = BuildKiteJob.builder().name("testJob").build(); + BuildKiteJob testJob = BuildKiteJob.builder().name(TEST_JOB_NAME).build(); buildKiteBuildInfoList.add(BuildKiteBuildInfo.builder().jobs(List.of(testJob)).build()); ResponseEntity> responseEntity = new ResponseEntity<>(buildKiteBuildInfoList, httpHeaders, HttpStatus.OK); @@ -270,8 +280,8 @@ public void shouldRThrowServerErrorWhenPageFetchPipelineStepsAndFetchNextPage404 any(), any(), any())) .thenThrow(new CompletionException(new NotFoundException("Client Error"))); - assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps("test_token", "test_org_id", "test_pipeline_id", - PipelineStepsParam.builder().startTime(mockStartTime).endTime(mockEndTime).build())) + assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, TEST_PIPELINE_ID, + PipelineStepsParam.builder().startTime(MOCK_START_TIME).endTime(MOCK_END_TIME).build())) .isInstanceOf(NotFoundException.class) .hasMessageContaining("Client Error"); } @@ -283,7 +293,7 @@ public void shouldRThrowTimeoutExceptionWhenPageFetchPipelineStepsAndFetchNextPa HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.addAll(HttpHeaders.LINK, linkHeader); List buildKiteBuildInfoList = new ArrayList<>(); - BuildKiteJob testJob = BuildKiteJob.builder().name("testJob").build(); + BuildKiteJob testJob = BuildKiteJob.builder().name(TEST_JOB_NAME).build(); buildKiteBuildInfoList.add(BuildKiteBuildInfo.builder().jobs(List.of(testJob)).build()); ResponseEntity> responseEntity = new ResponseEntity<>(buildKiteBuildInfoList, httpHeaders, HttpStatus.OK); @@ -294,8 +304,8 @@ public void shouldRThrowTimeoutExceptionWhenPageFetchPipelineStepsAndFetchNextPa any(), any(), any())) .thenThrow(new CompletionException(new ServiceUnavailableException("Service Unavailable"))); - assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps("test_token", "test_org_id", "test_pipeline_id", - PipelineStepsParam.builder().startTime(mockStartTime).endTime(mockEndTime).build())) + assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, TEST_PIPELINE_ID, + PipelineStepsParam.builder().startTime(MOCK_START_TIME).endTime(MOCK_END_TIME).build())) .isInstanceOf(ServiceUnavailableException.class) .hasMessageContaining("Service Unavailable"); } @@ -307,7 +317,7 @@ public void shouldThrowServerErrorWhenPageFetchPipelineStepsAndFetchNextPage5xxE HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.addAll(HttpHeaders.LINK, linkHeader); List buildKiteBuildInfoList = new ArrayList<>(); - BuildKiteJob testJob = BuildKiteJob.builder().name("testJob").build(); + BuildKiteJob testJob = BuildKiteJob.builder().name(TEST_JOB_NAME).build(); buildKiteBuildInfoList.add(BuildKiteBuildInfo.builder().jobs(List.of(testJob)).build()); ResponseEntity> responseEntity = new ResponseEntity<>(buildKiteBuildInfoList, httpHeaders, HttpStatus.OK); @@ -318,8 +328,8 @@ public void shouldThrowServerErrorWhenPageFetchPipelineStepsAndFetchNextPage5xxE any(), any(), any())) .thenThrow(new RequestFailedException(504, "Server Error")); - assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps("test_token", "test_org_id", "test_pipeline_id", - PipelineStepsParam.builder().startTime(mockStartTime).endTime(mockEndTime).build())) + assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, TEST_PIPELINE_ID, + PipelineStepsParam.builder().startTime(MOCK_START_TIME).endTime(MOCK_END_TIME).build())) .isInstanceOf(RequestFailedException.class) .hasMessageContaining("Server Error"); } @@ -331,11 +341,10 @@ public void shouldThrowInternalServerErrorExceptionWhenPageFetchPipelineStepsAnd HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.addAll(HttpHeaders.LINK, linkHeader); List buildKiteBuildInfoList = new ArrayList<>(); - BuildKiteJob testJob = BuildKiteJob.builder().name("testJob").build(); + BuildKiteJob testJob = BuildKiteJob.builder().name(TEST_JOB_NAME).build(); buildKiteBuildInfoList.add(BuildKiteBuildInfo.builder().jobs(List.of(testJob)).build()); ResponseEntity> responseEntity = new ResponseEntity<>(buildKiteBuildInfoList, httpHeaders, HttpStatus.OK); - when(buildKiteFeignClient.getPipelineSteps(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), any())) .thenReturn(responseEntity); @@ -343,7 +352,7 @@ public void shouldThrowInternalServerErrorExceptionWhenPageFetchPipelineStepsAnd any(), any(), any())) .thenReturn(buildKiteBuildInfoList); - assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps("test_token", "test_org_id", "test_pipeline_id", + assertThatThrownBy(() -> buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, TEST_PIPELINE_ID, PipelineStepsParam.builder().build())) .isInstanceOf(InternalServerErrorException.class) .hasMessageContaining("Failed to get pipeline steps"); @@ -353,14 +362,14 @@ public void shouldThrowInternalServerErrorExceptionWhenPageFetchPipelineStepsAnd @Test public void shouldReturnOnePageStepsWhenPageFetchPipelineStepsAndHeaderParseOnePage() { PipelineStepsParam stepsParam = new PipelineStepsParam(); - stepsParam.setStartTime(mockStartTime); - stepsParam.setEndTime(mockEndTime); + stepsParam.setStartTime(MOCK_START_TIME); + stepsParam.setEndTime(MOCK_END_TIME); List linkHeader = new ArrayList<>(); linkHeader.add(NONE_TOTAL_PAGE_HEADER); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.addAll(HttpHeaders.LINK, linkHeader); List buildKiteBuildInfoList = new ArrayList<>(); - BuildKiteJob testJob = BuildKiteJob.builder().name("testJob").build(); + BuildKiteJob testJob = BuildKiteJob.builder().name(TEST_JOB_NAME).build(); buildKiteBuildInfoList.add(BuildKiteBuildInfo.builder().jobs(List.of(testJob)).build()); ResponseEntity> responseEntity = new ResponseEntity<>(buildKiteBuildInfoList, httpHeaders, HttpStatus.OK); @@ -368,19 +377,19 @@ public void shouldReturnOnePageStepsWhenPageFetchPipelineStepsAndHeaderParseOneP anyString(), anyString(), any())) .thenReturn(responseEntity); - PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps("test_token", "test_org_id", - "test_pipeline_id", stepsParam); + PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, + TEST_PIPELINE_ID, stepsParam); assertNotNull(pipelineStepsDTO); assertThat(pipelineStepsDTO.getSteps().size()).isEqualTo(1); - assertThat(pipelineStepsDTO.getSteps().get(0)).isEqualTo("testJob"); + assertThat(pipelineStepsDTO.getSteps().get(0)).isEqualTo(TEST_JOB_NAME); } @Test public void shouldReturnOnePageStepsWhenPageFetchPipelineStep() { PipelineStepsParam stepsParam = new PipelineStepsParam(); - stepsParam.setStartTime(mockStartTime); - stepsParam.setEndTime(mockEndTime); + stepsParam.setStartTime(MOCK_START_TIME); + stepsParam.setEndTime(MOCK_END_TIME); List linkHeader = new ArrayList<>(); linkHeader.add(NONE_TOTAL_PAGE_HEADER); HttpHeaders httpHeaders = new HttpHeaders(); @@ -391,8 +400,8 @@ public void shouldReturnOnePageStepsWhenPageFetchPipelineStep() { anyString(), anyString(), any())) .thenReturn(responseEntity); - PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps("test_token", "test_org_id", - "test_pipeline_id", stepsParam); + PipelineStepsDTO pipelineStepsDTO = buildKiteService.fetchPipelineSteps(MOCK_TOKEN, TEST_ORG_ID, + TEST_PIPELINE_ID, stepsParam); assertNotNull(pipelineStepsDTO); assertThat(pipelineStepsDTO.getSteps().size()).isEqualTo(0); @@ -400,7 +409,6 @@ public void shouldReturnOnePageStepsWhenPageFetchPipelineStep() { @Test public void shouldReturnBuildKiteBuildInfoWhenFetchPipelineBuilds() { - String mockToken = "xxxxxxxxxx"; DeploymentEnvironment mockDeployment = DeploymentEnvironmentBuilder.withDefault().build(); List linkHeader = new ArrayList<>(); linkHeader.add(NONE_TOTAL_PAGE_HEADER); @@ -408,12 +416,12 @@ public void shouldReturnBuildKiteBuildInfoWhenFetchPipelineBuilds() { httpHeaders.addAll(HttpHeaders.LINK, linkHeader); ResponseEntity> responseEntity = new ResponseEntity<>(null, httpHeaders, HttpStatus.OK); - when(buildKiteFeignClient.getPipelineSteps(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), any())) .thenReturn(responseEntity); - List pipelineBuilds = buildKiteService.fetchPipelineBuilds(mockToken, mockDeployment, - mockStartTime, mockEndTime); + + List pipelineBuilds = buildKiteService.fetchPipelineBuilds(MOCK_TOKEN, mockDeployment, + MOCK_START_TIME, MOCK_END_TIME); assertNotNull(pipelineBuilds); assertThat(pipelineBuilds.size()).isEqualTo(0); @@ -421,23 +429,19 @@ public void shouldReturnBuildKiteBuildInfoWhenFetchPipelineBuilds() { @Test public void shouldThrowUnauthorizedExceptionWhenFetchPipelineBuilds401Exception() { - String mockToken = "xxxxxxxxxx"; DeploymentEnvironment mockDeployment = DeploymentEnvironmentBuilder.withDefault().build(); - when(buildKiteFeignClient.getPipelineSteps(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), any())) - .thenThrow(new UnauthorizedException("unauthorized")); + .thenThrow(new UnauthorizedException(UNAUTHORIZED_MSG)); - Assertions - .assertThatThrownBy( - () -> buildKiteService.fetchPipelineBuilds(mockToken, mockDeployment, mockStartTime, mockEndTime)) + assertThatThrownBy( + () -> buildKiteService.fetchPipelineBuilds(MOCK_TOKEN, mockDeployment, MOCK_START_TIME, MOCK_END_TIME)) .isInstanceOf(UnauthorizedException.class) - .hasMessageContaining("unauthorized"); + .hasMessageContaining(UNAUTHORIZED_MSG); } @Test public void shouldThrowInternalServerErrorExceptionWhenFetchPipelineBuilds500Exception() { - String mockToken = "xxxxxxxxxx"; DeploymentEnvironment mockDeployment = DeploymentEnvironmentBuilder.withDefault().build(); List linkHeader = new ArrayList<>(); linkHeader.add(NONE_TOTAL_PAGE_HEADER); @@ -445,12 +449,11 @@ public void shouldThrowInternalServerErrorExceptionWhenFetchPipelineBuilds500Exc httpHeaders.addAll(HttpHeaders.LINK, linkHeader); ResponseEntity> responseEntity = new ResponseEntity<>(null, httpHeaders, HttpStatus.OK); - when(buildKiteFeignClient.getPipelineSteps(anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), anyString(), any())) .thenReturn(responseEntity); - assertThatThrownBy(() -> buildKiteService.fetchPipelineBuilds(mockToken, mockDeployment, null, mockEndTime)) + assertThatThrownBy(() -> buildKiteService.fetchPipelineBuilds(MOCK_TOKEN, mockDeployment, null, MOCK_END_TIME)) .isInstanceOf(InternalServerErrorException.class) .hasMessageContaining("Failed to get pipeline builds_param"); } @@ -468,7 +471,7 @@ public void shouldReturnDeployTimesWhenCountDeployTimes() { DeployTimes expectedDeployTimes = DeployTimesBuilder.withDefault().build(); DeployTimes deployTimes = buildKiteService.countDeployTimes(mockDeployment, mockBuildKiteBuildInfos, - mockStartTime, mockEndTime); + MOCK_START_TIME, MOCK_END_TIME); assertThat(expectedDeployTimes).isEqualTo(deployTimes); } @@ -479,7 +482,7 @@ public void shouldReturnDeployInfoWhenMappedDeployInfoIsNull() { List mockBuildKiteBuildInfos = List.of(BuildKiteBuildInfoBuilder.withDefault().build()); DeployTimes deployTimes = buildKiteService.countDeployTimes(mockDeployment, mockBuildKiteBuildInfos, - mockStartTime, mockEndTime); + MOCK_START_TIME, MOCK_END_TIME); assertThat(0).isEqualTo(deployTimes.getPassed().size()); assertThat(1).isEqualTo(deployTimes.getFailed().size()); @@ -492,7 +495,7 @@ public void shouldThrowErrorWhenCountDeployTimesGivenOrgIdIsNull() { Assertions .assertThatThrownBy(() -> buildKiteService.countDeployTimes(mockDeployment, mockBuildKiteBuildInfos, - mockStartTime, mockEndTime)) + MOCK_START_TIME, MOCK_END_TIME)) .isInstanceOf(NotFoundException.class) .hasMessageContaining("miss orgId argument"); } @@ -533,22 +536,114 @@ public void shouldReturnDeployTimesWhenCountDeployTimesAtFixedTimeIntervals() { .build(); DeployTimes deployTimes = buildKiteService.countDeployTimes(mockDeployment, mockBuildKiteBuildInfos, - mockStartTime, mockEndTime); + MOCK_START_TIME, MOCK_END_TIME); assertThat(expectedDeployTimes).isEqualTo(deployTimes); } @Test void shouldReturnStepBeforeEndStepsGivenStepsArray() { - String targetStep = "Deploy qa"; - List stepArray = Arrays.asList("Test", "Build", targetStep, "Deploy prod"); + List stepArray = Arrays.asList("Test", "Build", "Deploy qa", "Deploy prod"); - List result = buildKiteService.getStepsBeforeEndStep(targetStep, stepArray); + List result = buildKiteService.getStepsBeforeEndStep("Deploy qa", stepArray); assertEquals(3, result.size()); assertEquals("Test", result.get(0)); assertEquals("Build", result.get(1)); - assertEquals(targetStep, result.get(2)); + assertEquals("Deploy qa", result.get(2)); + } + + @Test + void shouldReturnTrueWhenTokenIsCorrect() { + BuildKiteTokenInfo buildKiteTokenInfo = BuildKiteTokenInfo.builder().scopes(PERMISSION_SCOPES).build(); + when(buildKiteFeignClient.getTokenInfo(any())).thenReturn(buildKiteTokenInfo); + + buildKiteService.verifyToken(MOCK_TOKEN); + + verify(buildKiteFeignClient, times(1)).getTokenInfo(anyString()); + } + + @Test + void shouldThrowUnauthorizedExceptionWhenTokenIsIncorrect() { + when(buildKiteFeignClient.getTokenInfo(any())) + .thenThrow(new UnauthorizedException(UNAUTHORIZED_MSG)); + + assertThatThrownBy( + () -> buildKiteService.verifyToken(MOCK_TOKEN)) + .isInstanceOf(UnauthorizedException.class) + .hasMessageContaining(UNAUTHORIZED_MSG); + } + + @Test + void shouldThrowInternalServerErrorExceptionWhenGetBuildKiteVerify500Exception() { + when(buildKiteFeignClient.getTokenInfo(any())).thenReturn(null); + + assertThatThrownBy(() -> buildKiteService.verifyToken(MOCK_TOKEN)) + .isInstanceOf(InternalServerErrorException.class) + .hasMessageContaining("Failed to call BuildKite, cause is"); + } + + @Test + void shouldReturnBuildKiteResponseWhenGetBuildKiteInfo() throws IOException { + PipelineParam pipelineParam = PipelineParam.builder() + .token(MOCK_TOKEN) + .startTime(MOCK_START_TIME) + .endTime(MOCK_END_TIME) + .build(); + ObjectMapper mapper = new ObjectMapper(); + List pipelineDTOS = mapper.readValue( + new File("src/test/java/heartbeat/controller/pipeline/buildKitePipelineInfoData.json"), + new TypeReference<>() { + }); + when(buildKiteFeignClient.getBuildKiteOrganizationsInfo(any())) + .thenReturn(List.of(BuildKiteOrganizationsInfo.builder().name(TEST_ORG_NAME).slug(TEST_ORG_ID).build())); + when(buildKiteFeignClient.getPipelineInfo("Bearer mock_token", TEST_ORG_ID, "1", "100", MOCK_START_TIME, + MOCK_END_TIME)) + .thenReturn(pipelineDTOS); + + BuildKiteResponseDTO buildKiteResponseDTO = buildKiteService.getBuildKiteInfo(pipelineParam); + + assertThat(buildKiteResponseDTO.getPipelineList().size()).isEqualTo(1); + Pipeline pipeline = buildKiteResponseDTO.getPipelineList().get(0); + assertThat(pipeline.getId()).isEqualTo("payment-selector-ui"); + assertThat(pipeline.getName()).isEqualTo("payment-selector-ui"); + assertThat(pipeline.getOrgId()).isEqualTo(TEST_ORG_ID); + assertThat(pipeline.getOrgName()).isEqualTo(TEST_ORG_NAME); + assertThat(pipeline.getRepository()) + .isEqualTo("https://github.com/XXXX-fs/fs-platform-payment-selector-ui.git"); + assertThat(pipeline.getSteps().size()).isEqualTo(1); + } + + @Test + void shouldThrowInternalServerErrorExceptionWhenGetBuildKiteInfo500Exception() { + PipelineParam pipelineParam = PipelineParam.builder() + .token(MOCK_TOKEN) + .startTime(MOCK_START_TIME) + .endTime(MOCK_END_TIME) + .build(); + when(buildKiteFeignClient.getBuildKiteOrganizationsInfo(any())).thenReturn(null); + when(buildKiteFeignClient.getPipelineInfo("Bearer mock_token", TEST_ORG_ID, "1", "100", MOCK_START_TIME, + MOCK_END_TIME)) + .thenReturn(null); + + assertThatThrownBy(() -> buildKiteService.getBuildKiteInfo(pipelineParam)) + .isInstanceOf(InternalServerErrorException.class) + .hasMessageContaining("Failed to call BuildKite, cause is"); + } + + @Test + void shouldThrowUnauthorizedExceptionWhenGetBuildKiteInfoAndTokenIsIncorrect() { + PipelineParam pipelineParam = PipelineParam.builder() + .token(MOCK_TOKEN) + .startTime(MOCK_START_TIME) + .endTime(MOCK_END_TIME) + .build(); + when(buildKiteFeignClient.getBuildKiteOrganizationsInfo(any())) + .thenThrow(new UnauthorizedException(UNAUTHORIZED_MSG)); + + assertThatThrownBy(() -> buildKiteService.getBuildKiteInfo(pipelineParam)) + .isInstanceOf(UnauthorizedException.class) + .hasMessageContaining(UNAUTHORIZED_MSG); } } diff --git a/docs/src/content/docs/en/spikes/tech-spikes-split-verify-of-buildkite.mdx b/docs/src/content/docs/en/spikes/tech-spikes-split-verify-of-buildkite.mdx index cf8fb48c82..f182d29427 100644 --- a/docs/src/content/docs/en/spikes/tech-spikes-split-verify-of-buildkite.mdx +++ b/docs/src/content/docs/en/spikes/tech-spikes-split-verify-of-buildkite.mdx @@ -93,7 +93,7 @@ request: { token: "your_token" } responses: - Status Code: 200 + Status Code: 204 ``` - Exception Handler @@ -103,18 +103,19 @@ responses: - + - - - - + + + + + @@ -189,6 +190,7 @@ responses:{ ] }] } +When pipelineList is empty, responses 204 ``` - Exception Handler
hintInfo
400400 Token cannot be empty.
Token's pattern is incorrect.
401 Failed to get BuildKite info_status: 401 UNAUTHORIZED, reason: xxx Token is incorrect
403Failed to call BuildKite, because of insufficient permission!Permission deny
500
@@ -198,12 +200,9 @@ responses:{ - + - - - - + @@ -216,6 +215,11 @@ responses:{ + + + + +
hintInfo
400400 Token cannot be empty.
Token's pattern is incorrect.
StartTime cannot be empty.Failed to get BuildKite info_status: 401 UNAUTHORIZED, reason: xxx Token is incorrect
403Failed to call BuildKite, because of insufficient permission!Permission deny
500