diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/api/StartGuideController.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/api/StartGuideController.java new file mode 100644 index 00000000..44c9fe2b --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/api/StartGuideController.java @@ -0,0 +1,31 @@ +package com.consoleconnect.kraken.operator.controller.api; + +import com.consoleconnect.kraken.operator.controller.dto.start.StartGuideInfoDto; +import com.consoleconnect.kraken.operator.controller.service.start.StartGuideService; +import com.consoleconnect.kraken.operator.core.model.HttpResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping(value = StartGuideController.URL, produces = MediaType.APPLICATION_JSON_VALUE) +@RequiredArgsConstructor +@Tag(name = "Start Guide APIs", description = "Portal APIs") +public class StartGuideController { + + public static final String URL = "/start/guide"; + private final StartGuideService service; + + @Operation(summary = "Get start guide info") + @GetMapping("/{productId}") + public HttpResponse getStartGuideInfo( + @PathVariable("productId") String productId, @RequestParam(value = "kind") String kind) { + return HttpResponse.ok(service.getStartGuideInfo(productId, kind)); + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/ApiMappingInfoDto.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/ApiMappingInfoDto.java new file mode 100644 index 00000000..3b8f11c7 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/ApiMappingInfoDto.java @@ -0,0 +1,13 @@ +package com.consoleconnect.kraken.operator.controller.dto.start; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ApiMappingInfoDto { + + private Boolean atLeastOneMappingCompleted; +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/DeploymentInfoDto.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/DeploymentInfoDto.java new file mode 100644 index 00000000..3191675d --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/DeploymentInfoDto.java @@ -0,0 +1,14 @@ +package com.consoleconnect.kraken.operator.controller.dto.start; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class DeploymentInfoDto { + private Boolean atLeastOneApiDeployedToStage; + private Boolean atLeastOneBuyerRegistered; + private Boolean atLeastOneApiDeployedToProduction; +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/SellerApiServerRegistrationInfoDto.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/SellerApiServerRegistrationInfoDto.java new file mode 100644 index 00000000..069d1855 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/SellerApiServerRegistrationInfoDto.java @@ -0,0 +1,13 @@ +package com.consoleconnect.kraken.operator.controller.dto.start; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class SellerApiServerRegistrationInfoDto { + + private Boolean atLeastOneSellerApiRegistered; +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/StartGuideInfoDto.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/StartGuideInfoDto.java new file mode 100644 index 00000000..fde11c58 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/dto/start/StartGuideInfoDto.java @@ -0,0 +1,14 @@ +package com.consoleconnect.kraken.operator.controller.dto.start; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class StartGuideInfoDto { + private SellerApiServerRegistrationInfoDto sellerApiServerRegistrationInfo; + private ApiMappingInfoDto apiMappingInfo; + private DeploymentInfoDto deploymentInfo; +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/start/StartGuideService.java b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/start/StartGuideService.java new file mode 100644 index 00000000..23294271 --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/main/java/com/consoleconnect/kraken/operator/controller/service/start/StartGuideService.java @@ -0,0 +1,107 @@ +package com.consoleconnect.kraken.operator.controller.service.start; + +import static com.consoleconnect.kraken.operator.core.enums.AssetKindEnum.PRODUCT_BUYER; +import static com.consoleconnect.kraken.operator.core.enums.MappingStatusEnum.COMPLETE; +import static com.consoleconnect.kraken.operator.core.service.UnifiedAssetService.getSearchPageRequest; + +import com.consoleconnect.kraken.operator.controller.dto.start.ApiMappingInfoDto; +import com.consoleconnect.kraken.operator.controller.dto.start.DeploymentInfoDto; +import com.consoleconnect.kraken.operator.controller.dto.start.SellerApiServerRegistrationInfoDto; +import com.consoleconnect.kraken.operator.controller.dto.start.StartGuideInfoDto; +import com.consoleconnect.kraken.operator.controller.model.Environment; +import com.consoleconnect.kraken.operator.controller.service.ApiComponentService; +import com.consoleconnect.kraken.operator.controller.service.EnvironmentService; +import com.consoleconnect.kraken.operator.controller.service.ProductDeploymentService; +import com.consoleconnect.kraken.operator.core.enums.DeployStatusEnum; +import com.consoleconnect.kraken.operator.core.enums.EnvNameEnum; +import com.consoleconnect.kraken.operator.core.exception.KrakenException; +import com.consoleconnect.kraken.operator.core.repo.UnifiedAssetRepository; +import com.consoleconnect.kraken.operator.core.service.UnifiedAssetService; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +@RequiredArgsConstructor +@Service +public class StartGuideService { + + public static final int DEFAULT_NUMBER_OF_COMPLETED_MAPPINGS = 2; + public static final String PRODUCT_ID_CAN_NOT_BE_EMPTY_ERROR = "Product id can not be empty."; + public static final String KIND_CAN_NOT_BE_EMPTY_ERROR = "Kind can not be empty."; + + private final ApiComponentService apiComponentService; + private final UnifiedAssetRepository unifiedAssetRepository; + private final UnifiedAssetService unifiedAssetService; + private final EnvironmentService environmentService; + private final ProductDeploymentService productDeploymentService; + + public StartGuideInfoDto getStartGuideInfo(String productId, String kind) { + validateParams(productId, kind); + var atLeastOneSellerApiRegistered = atLeastOneSellerApiRegistered(productId, kind); + var atLeastOneMappingCompleted = atLeastOneMappingCompleted(); + var atLestOnBuyerRegistered = atLestOnBuyerRegistered(productId); + var atLeastOneApiDeployedOnStage = atLeastOneApiDeployedToEvn(productId, EnvNameEnum.STAGE); + var atLeastOneApiDeployedOnProduction = + atLeastOneApiDeployedToEvn(productId, EnvNameEnum.PRODUCTION); + + return new StartGuideInfoDto( + new SellerApiServerRegistrationInfoDto(atLeastOneSellerApiRegistered), + new ApiMappingInfoDto(atLeastOneMappingCompleted), + new DeploymentInfoDto( + atLeastOneApiDeployedOnStage, + atLestOnBuyerRegistered, + atLeastOneApiDeployedOnProduction)); + } + + private void validateParams(String productId, String kind) { + if (StringUtils.isBlank(productId)) { + throw new KrakenException(400, PRODUCT_ID_CAN_NOT_BE_EMPTY_ERROR); + } + if (StringUtils.isBlank(kind)) { + throw new KrakenException(400, KIND_CAN_NOT_BE_EMPTY_ERROR); + } + } + + private boolean atLeastOneSellerApiRegistered(String productId, String kind) { + var parentId = unifiedAssetService.findOne(productId).getId(); + return unifiedAssetRepository.existsByParentIdAndKind(parentId, kind); + } + + private boolean atLeastOneMappingCompleted() { + var completedMappings = + apiComponentService.listAllApiUseCase().stream() + .flatMap(component -> component.getDetails().stream()) + .filter(mapping -> mapping.getMappingStatus().equalsIgnoreCase(COMPLETE.getDesc())) + .toList(); + return completedMappings.size() > DEFAULT_NUMBER_OF_COMPLETED_MAPPINGS; + } + + private boolean atLestOnBuyerRegistered(String productId) { + var parentId = unifiedAssetService.findOneByIdOrKey(productId).getId().toString(); + return unifiedAssetRepository.existsByParentIdAndKind(parentId, PRODUCT_BUYER.getKind()); + } + + private boolean atLeastOneApiDeployedToEvn(String productId, EnvNameEnum envNameEnum) { + var environments = + environmentService + .search(productId, getSearchPageRequest(0, EnvNameEnum.values().length)) + .getData(); + Optional environment = + environments.stream() + .filter(e -> envNameEnum.name().equalsIgnoreCase(e.getName())) + .findFirst(); + return environment + .map( + env -> { + var deployments = + productDeploymentService.retrieveApiMapperDeployments( + environment.get().getId(), + null, + DeployStatusEnum.SUCCESS, + getSearchPageRequest(0, 1)); + return !deployments.getData().isEmpty(); + }) + .orElse(false); + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/api/StartGuideControllerTest.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/api/StartGuideControllerTest.java new file mode 100644 index 00000000..44c23cba --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/api/StartGuideControllerTest.java @@ -0,0 +1,69 @@ +package com.consoleconnect.kraken.operator.controller.api; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.when; + +import com.consoleconnect.kraken.operator.config.TestApplication; +import com.consoleconnect.kraken.operator.controller.WebTestClientHelper; +import com.consoleconnect.kraken.operator.controller.dto.start.ApiMappingInfoDto; +import com.consoleconnect.kraken.operator.controller.dto.start.DeploymentInfoDto; +import com.consoleconnect.kraken.operator.controller.dto.start.SellerApiServerRegistrationInfoDto; +import com.consoleconnect.kraken.operator.controller.dto.start.StartGuideInfoDto; +import com.consoleconnect.kraken.operator.controller.service.start.StartGuideService; +import com.consoleconnect.kraken.operator.core.model.HttpResponse; +import com.consoleconnect.kraken.operator.test.AbstractIntegrationTest; +import com.consoleconnect.kraken.operator.test.MockIntegrationTest; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.web.reactive.server.WebTestClient; + +@ActiveProfiles("test-auth-server-enabled") +@MockIntegrationTest +@ContextConfiguration(classes = TestApplication.class) +class StartGuideControllerTest extends AbstractIntegrationTest { + + @Autowired protected ObjectMapper objectMapper; + + @MockBean private StartGuideService service; + + private final WebTestClientHelper testClientHelper; + + @Autowired + StartGuideControllerTest(WebTestClient webTestClient) { + testClientHelper = new WebTestClientHelper(webTestClient); + } + + @SneakyThrows + @Test + void givenStartingGuideInfo_whenGettingStartGuideInfo_thenReturnsOk() { + // given + var kind = "kind1"; + var productId = "productId1"; + var guideInfoDto = + new StartGuideInfoDto( + new SellerApiServerRegistrationInfoDto(true), + new ApiMappingInfoDto(true), + new DeploymentInfoDto(true, true, false)); + when(service.getStartGuideInfo(productId, kind)).thenReturn(guideInfoDto); + // when + var path = StartGuideController.URL + "/" + productId; + testClientHelper.getAndVerify( + (uriBuilder -> uriBuilder.path(path).queryParam("kind", kind).build()), + bodyStr -> { + // then + var result = content(bodyStr, new TypeReference>() {}); + assertThat(result.getData()).isEqualTo(guideInfoDto); + }); + } + + @SneakyThrows + private T content(String response, TypeReference typeReference) { + return objectMapper.readValue(response, typeReference); + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/service/start/StartGuideServiceTest.java b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/service/start/StartGuideServiceTest.java new file mode 100644 index 00000000..352597fa --- /dev/null +++ b/kraken-java-sdk/kraken-java-sdk-controller/src/test/java/com/consoleconnect/kraken/operator/controller/service/start/StartGuideServiceTest.java @@ -0,0 +1,348 @@ +package com.consoleconnect.kraken.operator.controller.service.start; + +import static com.consoleconnect.kraken.operator.controller.service.start.StartGuideService.KIND_CAN_NOT_BE_EMPTY_ERROR; +import static com.consoleconnect.kraken.operator.controller.service.start.StartGuideService.PRODUCT_ID_CAN_NOT_BE_EMPTY_ERROR; +import static com.consoleconnect.kraken.operator.core.enums.AssetKindEnum.PRODUCT_BUYER; +import static com.consoleconnect.kraken.operator.core.enums.MappingStatusEnum.COMPLETE; +import static com.consoleconnect.kraken.operator.core.enums.MappingStatusEnum.INCOMPLETE; +import static com.consoleconnect.kraken.operator.core.service.UnifiedAssetService.getSearchPageRequest; +import static com.consoleconnect.kraken.operator.core.toolkit.PagingHelper.toPage; +import static java.util.List.of; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import com.consoleconnect.kraken.operator.controller.dto.ApiMapperDeploymentDTO; +import com.consoleconnect.kraken.operator.controller.dto.ComponentExpandDTO; +import com.consoleconnect.kraken.operator.controller.model.Environment; +import com.consoleconnect.kraken.operator.controller.service.ApiComponentService; +import com.consoleconnect.kraken.operator.controller.service.EnvironmentService; +import com.consoleconnect.kraken.operator.controller.service.ProductDeploymentService; +import com.consoleconnect.kraken.operator.core.dto.UnifiedAssetDto; +import com.consoleconnect.kraken.operator.core.entity.UnifiedAssetEntity; +import com.consoleconnect.kraken.operator.core.enums.DeployStatusEnum; +import com.consoleconnect.kraken.operator.core.enums.EnvNameEnum; +import com.consoleconnect.kraken.operator.core.enums.MappingStatusEnum; +import com.consoleconnect.kraken.operator.core.exception.KrakenException; +import com.consoleconnect.kraken.operator.core.repo.UnifiedAssetRepository; +import com.consoleconnect.kraken.operator.core.service.UnifiedAssetService; +import com.consoleconnect.kraken.operator.core.toolkit.PagingHelper; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +class StartGuideServiceTest { + + public static final String STAGE_ENVIRONMENT_ID_1 = "eId1"; + public static final String PRODUCTION_ENVIRONMENT_ID_2 = "eId2"; + public static final String PRODUCT_ID = "productId1"; + public static final String KIND = "kind1"; + public static final String ASSET_PRODUCT_ID_1 = "assetProductId1"; + + private StartGuideService sut; + private ApiComponentService apiComponentServiceMock; + private UnifiedAssetRepository unifiedAssetRepositoryMock; + private UnifiedAssetService unifiedAssetServiceMock; + private EnvironmentService environmentServiceMock; + private ProductDeploymentService productDeploymentServiceMock; + + private UnifiedAssetDto product; + + @BeforeEach + void setUp() { + apiComponentServiceMock = mock(ApiComponentService.class); + unifiedAssetRepositoryMock = mock(UnifiedAssetRepository.class); + unifiedAssetServiceMock = mock(UnifiedAssetService.class); + environmentServiceMock = mock(EnvironmentService.class); + productDeploymentServiceMock = mock(ProductDeploymentService.class); + sut = + new StartGuideService( + apiComponentServiceMock, + unifiedAssetRepositoryMock, + unifiedAssetServiceMock, + environmentServiceMock, + productDeploymentServiceMock); + + product = new UnifiedAssetDto(); + product.setParentId(ASSET_PRODUCT_ID_1); + } + + @Test + void givenNoSellerApiRegistered_whenGettingAtLeastOneSellerApiRegistered_thenReturnsFalse() { + // given + givenNoBuyer(); + givenNoApiDeployedOnEnvs(); + when(unifiedAssetServiceMock.findOne(PRODUCT_ID)).thenReturn(product); + when(unifiedAssetRepositoryMock.existsByParentIdAndKind(product.getId(), KIND)) + .thenReturn(false); + // when + var result = sut.getStartGuideInfo(PRODUCT_ID, KIND); + // then + assertThat(result.getSellerApiServerRegistrationInfo().getAtLeastOneSellerApiRegistered()) + .isFalse(); + } + + @Test + void + givenAtLeastOneSellerApiRegistered_whenGettingAtLeastOneSellerApiRegistered_thenReturnsTrue() { + // given + givenNoBuyer(); + givenNoApiDeployedOnEnvs(); + when(unifiedAssetServiceMock.findOne(StartGuideServiceTest.PRODUCT_ID)).thenReturn(product); + when(unifiedAssetRepositoryMock.existsByParentIdAndKind(product.getId(), KIND)) + .thenReturn(true); + // when + var result = + sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, StartGuideServiceTest.KIND); + // then + assertThat(result.getSellerApiServerRegistrationInfo().getAtLeastOneSellerApiRegistered()) + .isTrue(); + } + + @Test + void givenNoApiMappingCompleted_whenGettingAtLeastOneMappingCompleted_thenReturnsFalse() { + // given + givenNoSellerApiRegistered(product); + givenNoApiDeployedOnEnvs(); + givenNoBuyer(); + when(apiComponentServiceMock.listAllApiUseCase()).thenReturn(Collections.emptyList()); + // when + var result = + sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, StartGuideServiceTest.KIND); + // then + var apiMappingInfo = result.getApiMappingInfo(); + assertThat(apiMappingInfo.getAtLeastOneMappingCompleted()).isFalse(); + } + + @Test + void + givenOnlyDefaultApiMappingCompleted_whenGettingAtLeastOneMappingCompleted_thenReturnsFalse() { + // given + givenNoSellerApiRegistered(product); + givenNoApiDeployedOnEnvs(); + givenNoBuyer(); + + var componentExpandDTO1 = new ComponentExpandDTO(); + componentExpandDTO1.setDetails( + of(targetMappingDetail(COMPLETE), targetMappingDetail(INCOMPLETE))); + var componentExpandDTO2 = new ComponentExpandDTO(); + componentExpandDTO2.setDetails(of(targetMappingDetail(COMPLETE))); + when(apiComponentServiceMock.listAllApiUseCase()) + .thenReturn(of(componentExpandDTO1, componentExpandDTO2)); + // when + var result = sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, KIND); + // then + var apiMappingInfo = result.getApiMappingInfo(); + assertThat(apiMappingInfo.getAtLeastOneMappingCompleted()).isFalse(); + } + + @Test + void + givenDefaultApiMappingAndOneCompleted_whenGettingAtLeastOneMappingCompleted_thenReturnsTrue() { + // given + givenNoSellerApiRegistered(product); + givenNoApiDeployedOnEnvs(); + givenNoBuyer(); + + var componentExpandDTO1 = new ComponentExpandDTO(); + componentExpandDTO1.setDetails( + of( + targetMappingDetail(COMPLETE), + targetMappingDetail(COMPLETE), + targetMappingDetail(INCOMPLETE))); + var componentExpandDTO2 = new ComponentExpandDTO(); + componentExpandDTO2.setDetails(of(targetMappingDetail(COMPLETE))); + when(apiComponentServiceMock.listAllApiUseCase()) + .thenReturn(of(componentExpandDTO1, componentExpandDTO2)); + // when + var result = + sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, StartGuideServiceTest.KIND); + // then + var apiMappingInfo = result.getApiMappingInfo(); + assertThat(apiMappingInfo.getAtLeastOneMappingCompleted()).isTrue(); + } + + @Test + void givenNoBuyerRegistered_whenGettingAtLestOnBuyerRegistered_thenReturnsFalse() { + // given + var assetEntity = new UnifiedAssetEntity(); + var parentId = UUID.randomUUID(); + assetEntity.setId(parentId); + givenNoSellerApiRegistered(product); + givenNoApiDeployedOnEnvs(); + + when(unifiedAssetServiceMock.findOneByIdOrKey(StartGuideServiceTest.PRODUCT_ID)) + .thenReturn(assetEntity); + when(unifiedAssetRepositoryMock.existsByParentIdAndKind( + parentId.toString(), PRODUCT_BUYER.getKind())) + .thenReturn(false); + // when + var result = + sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, StartGuideServiceTest.KIND); + // then + assertThat(result.getDeploymentInfo().getAtLeastOneBuyerRegistered()).isFalse(); + } + + @Test + void givenAtLeastOneBuyerRegistered_whenGettingAtLestOnBuyerRegistered_thenReturnsTrue() { + // given + var parentId = UUID.randomUUID(); + var assetEntity = new UnifiedAssetEntity(); + assetEntity.setId(parentId); + givenNoSellerApiRegistered(product); + givenNoApiDeployedOnEnvs(); + when(unifiedAssetServiceMock.findOneByIdOrKey(StartGuideServiceTest.PRODUCT_ID)) + .thenReturn(assetEntity); + when(unifiedAssetRepositoryMock.existsByParentIdAndKind( + parentId.toString(), PRODUCT_BUYER.getKind())) + .thenReturn(true); + // when + var result = + sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, StartGuideServiceTest.KIND); + // then + assertThat(result.getDeploymentInfo().getAtLeastOneBuyerRegistered()).isTrue(); + } + + @Test + void givenNoApiDeployedToEnvs_whenGettingAtLeastOneApiDeployedToEnv_thenReturnsFalse() { + // given + givenNoSellerApiRegistered(product); + givenNoBuyer(); + + givenNoApiDeployedOnEnvs(); + + // when + var result = + sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, StartGuideServiceTest.KIND); + // then + assertThat(result.getDeploymentInfo().getAtLeastOneApiDeployedToStage()).isFalse(); + assertThat(result.getDeploymentInfo().getAtLeastOneApiDeployedToProduction()).isFalse(); + } + + @Test + void givenAtLeastOneApiDeployedToEnvs_whenGettingAtLeastOneApiDeployedToEnv_thenReturnsTrue() { + // given + givenNoSellerApiRegistered(product); + givenNoBuyer(); + + when(environmentServiceMock.search( + StartGuideServiceTest.PRODUCT_ID, getSearchPageRequest(0, EnvNameEnum.values().length))) + .thenReturn(toPage(environments(), 0, 2)); + when(productDeploymentServiceMock.retrieveApiMapperDeployments( + STAGE_ENVIRONMENT_ID_1, null, DeployStatusEnum.SUCCESS, getSearchPageRequest(0, 1))) + .thenReturn( + PagingHelper.toPage( + of(firstDefaultApiMapper(), secondDefaultApiMapper(), new ApiMapperDeploymentDTO()), + 0, + 3)); + when(productDeploymentServiceMock.retrieveApiMapperDeployments( + PRODUCTION_ENVIRONMENT_ID_2, + null, + DeployStatusEnum.SUCCESS, + getSearchPageRequest(0, 1))) + .thenReturn( + PagingHelper.toPage( + of(firstDefaultApiMapper(), secondDefaultApiMapper(), new ApiMapperDeploymentDTO()), + 0, + 3)); + // when + var result = + sut.getStartGuideInfo(StartGuideServiceTest.PRODUCT_ID, StartGuideServiceTest.KIND); + // then + var deploymentInfo = result.getDeploymentInfo(); + assertThat(deploymentInfo.getAtLeastOneApiDeployedToStage()).isTrue(); + assertThat(deploymentInfo.getAtLeastOneApiDeployedToProduction()).isTrue(); + } + + @Test + void givenNoProductId_whenGetStartGuideInfo_thenReturnsError() { + // given + // when + var ex = + assertThrows( + KrakenException.class, + () -> { + sut.getStartGuideInfo("", KIND); + }); + + // then + assertThat(ex.getCode()).isEqualTo(400); + assertThat(ex.getMessage()).isEqualTo(PRODUCT_ID_CAN_NOT_BE_EMPTY_ERROR); + } + + @Test + void givenNoKind_whenGetStartGuideInfo_thenReturnsError() { + // given + // when + var ex = + assertThrows( + KrakenException.class, + () -> { + sut.getStartGuideInfo(PRODUCT_ID, ""); + }); + + // then + assertThat(ex.getCode()).isEqualTo(400); + assertThat(ex.getMessage()).isEqualTo(KIND_CAN_NOT_BE_EMPTY_ERROR); + } + + private ApiMapperDeploymentDTO secondDefaultApiMapper() { + return new ApiMapperDeploymentDTO(); + } + + private ApiMapperDeploymentDTO firstDefaultApiMapper() { + return new ApiMapperDeploymentDTO(); + } + + private List environments() { + Environment e1 = new Environment(); + e1.setId(STAGE_ENVIRONMENT_ID_1); + e1.setName(EnvNameEnum.STAGE.name()); + Environment e2 = new Environment(); + e2.setName(EnvNameEnum.PRODUCTION.name()); + e2.setId(PRODUCTION_ENVIRONMENT_ID_2); + return of(e1, e2); + } + + private ComponentExpandDTO.TargetMappingDetail targetMappingDetail( + MappingStatusEnum mappingStatus) { + var targetMappingDetail = new ComponentExpandDTO.TargetMappingDetail(); + targetMappingDetail.setMappingStatus(mappingStatus.getDesc()); + return targetMappingDetail; + } + + private void givenNoSellerApiRegistered(UnifiedAssetDto product) { + when(unifiedAssetServiceMock.findOne(StartGuideServiceTest.PRODUCT_ID)).thenReturn(product); + when(unifiedAssetRepositoryMock.existsByParentIdAndKind( + product.getId(), StartGuideServiceTest.KIND)) + .thenReturn(false); + } + + private void givenNoApiDeployedOnEnvs() { + when(environmentServiceMock.search( + StartGuideServiceTest.PRODUCT_ID, getSearchPageRequest(0, EnvNameEnum.values().length))) + .thenReturn(toPage(environments(), 0, 2)); + when(productDeploymentServiceMock.retrieveApiMapperDeployments( + STAGE_ENVIRONMENT_ID_1, null, DeployStatusEnum.SUCCESS, getSearchPageRequest(0, 1))) + .thenReturn(PagingHelper.toPage(Collections.emptyList(), 0, 0)); + when(productDeploymentServiceMock.retrieveApiMapperDeployments( + PRODUCTION_ENVIRONMENT_ID_2, + null, + DeployStatusEnum.SUCCESS, + getSearchPageRequest(0, 1))) + .thenReturn(PagingHelper.toPage(Collections.emptyList(), 0, 0)); + } + + private void givenNoBuyer() { + UnifiedAssetEntity assetEntity = new UnifiedAssetEntity(); + assetEntity.setId(UUID.randomUUID()); + when(unifiedAssetServiceMock.findOneByIdOrKey(StartGuideServiceTest.PRODUCT_ID)) + .thenReturn(assetEntity); + when(unifiedAssetRepositoryMock.existsByParentIdAndKind( + assetEntity.getId().toString(), PRODUCT_BUYER.getKind())) + .thenReturn(false); + } +} diff --git a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/repo/UnifiedAssetRepository.java b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/repo/UnifiedAssetRepository.java index a854d9ad..90da3e5c 100644 --- a/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/repo/UnifiedAssetRepository.java +++ b/kraken-java-sdk/kraken-java-sdk-core/src/main/java/com/consoleconnect/kraken/operator/core/repo/UnifiedAssetRepository.java @@ -93,4 +93,6 @@ Page findBuyers( Pageable pageable); boolean existsByKey(String key); + + boolean existsByParentIdAndKind(String parentId, String kind); }