diff --git a/src/main/java/org/tkit/onecx/shell/bff/rs/controllers/WorkspaceConfigRestController.java b/src/main/java/org/tkit/onecx/shell/bff/rs/controllers/WorkspaceConfigRestController.java index 85118fb..dbdf5d4 100644 --- a/src/main/java/org/tkit/onecx/shell/bff/rs/controllers/WorkspaceConfigRestController.java +++ b/src/main/java/org/tkit/onecx/shell/bff/rs/controllers/WorkspaceConfigRestController.java @@ -123,33 +123,36 @@ public Response getWorkspaceConfig(GetWorkspaceConfigRequestDTO getWorkspaceConf @Override public Response loadWorkspaceConfig(LoadWorkspaceConfigRequestDTO loadWorkspaceConfigRequestDTO) { - try (Response response = workspaceClient.loadWorkspaceByRequest(mapper.createRequest(loadWorkspaceConfigRequestDTO))) { - var wrapper = response.readEntity(WorkspaceWrapper.class); - if (wrapper == null) { - return Response.status(Response.Status.NOT_FOUND).build(); - } - var result = mapper.createResponse(wrapper); + WorkspaceWrapper wrapper; + try (Response response = workspaceClient.loadWorkspaceByRequest(mapper.createRequest(loadWorkspaceConfigRequestDTO))) { + wrapper = response.readEntity(WorkspaceWrapper.class); + } - // load products and create corresponding module and components - if (wrapper.getProducts() != null) { - try (Response psResponse = productStoreClient.loadProductsByNames(mapper.create(wrapper))) { - var productResponse = psResponse.readEntity(LoadProductResponsePSV1.class); - mapper.createMfeAndComponents(result, wrapper, productResponse); - } - } + if (wrapper == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } - // create slots - result.setSlots(mapper.createSlots(wrapper.getSlots())); + var result = mapper.createResponse(wrapper); - //get theme info - try (Response themeResponse = themeClient.getThemeByName(wrapper.getTheme())) { - var theme = themeResponse.readEntity(Theme.class); - result.setTheme(mapper.createTheme(theme, uriInfo.getPath())); + // load products and create corresponding module and components + if (wrapper.getProducts() != null) { + try (Response psResponse = productStoreClient.loadProductsByNames(mapper.create(wrapper))) { + var productResponse = psResponse.readEntity(LoadProductResponsePSV1.class); + mapper.createMfeAndComponents(result, wrapper, productResponse); } + } - return Response.ok(result).build(); + // create slots + result.setSlots(mapper.createSlots(wrapper.getSlots())); + + //get theme info + try (Response themeResponse = themeClient.getThemeByName(wrapper.getTheme())) { + var theme = themeResponse.readEntity(Theme.class); + result.setTheme(mapper.createTheme(theme, uriInfo.getPath())); } + + return Response.ok(result).build(); } @Override diff --git a/src/main/java/org/tkit/onecx/shell/bff/rs/mappers/WorkspaceConfigMapper.java b/src/main/java/org/tkit/onecx/shell/bff/rs/mappers/WorkspaceConfigMapper.java index 577ef09..0d2e3f7 100644 --- a/src/main/java/org/tkit/onecx/shell/bff/rs/mappers/WorkspaceConfigMapper.java +++ b/src/main/java/org/tkit/onecx/shell/bff/rs/mappers/WorkspaceConfigMapper.java @@ -1,5 +1,7 @@ package org.tkit.onecx.shell.bff.rs.mappers; +import static gen.org.tkit.onecx.product.store.client.model.MicrofrontendTypePSV1.MODULE; + import java.util.List; import java.util.Map; import java.util.stream.Collectors; @@ -108,9 +110,8 @@ default SlotDTO createSlot(WorkspaceWrapperSlot slot) { SlotDTO result = new SlotDTO().name(slot.getName()); if (slot.getComponents() != null) { - slot.getComponents().forEach(c -> { - result.addComponentsItem(componentName(c.getProductName(), c.getAppId(), c.getName())); - }); + slot.getComponents() + .forEach(c -> result.addComponentsItem(componentName(c.getProductName(), c.getAppId(), c.getName()))); } return result; } @@ -153,10 +154,10 @@ default void createMfeAndComponents(LoadWorkspaceConfigResponseDTO result, Works if (product.getMicrofrontends() != null) { product.getMicrofrontends().forEach(mfe -> { - switch (mfe.getType()) { - case MODULE -> result - .addRoutesItem(createRoute(product, mfe, pathMapping, wrapper)); - case COMPONENT -> result.addComponentsItem(createComponent(product, mfe)); + if (mfe.getType() == MODULE) { + result.addRoutesItem(createRoute(product, mfe, pathMapping, wrapper)); + } else if (mfe.getType() == MicrofrontendTypePSV1.COMPONENT) { + result.addComponentsItem(createComponent(product, mfe)); } }); } diff --git a/src/test/java/org/tkit/onecx/shell/bff/rs/WorkspaceConfigRestControllerTest.java b/src/test/java/org/tkit/onecx/shell/bff/rs/WorkspaceConfigRestControllerTest.java index 3ac1ec2..5c7cb9a 100644 --- a/src/test/java/org/tkit/onecx/shell/bff/rs/WorkspaceConfigRestControllerTest.java +++ b/src/test/java/org/tkit/onecx/shell/bff/rs/WorkspaceConfigRestControllerTest.java @@ -746,4 +746,167 @@ void loadWorkspaceConfig_WorkspaceNotFoundTest() { mockServerClient.clear("mockWS"); } + @Test + void loadWorkspaceConfigByEmptyProductsTest() { + + var workspace = new WorkspaceWrapper(); + workspace.name("w1").theme("theme1") + .addSlotsItem( + new WorkspaceWrapperSlot().name("slot1") + .addComponentsItem( + new WorkspaceWrapperComponent().productName("product1").appId("app1") + .name("App1Component"))); + + // create mock rest endpoint for workspace search + mockServerClient.when(request().withPath("/v1/workspaces/load").withMethod(HttpMethod.POST) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(new WorkspaceLoadRequest().path("/w1Url")))) + .withId("mockWS") + .respond(httpRequest -> response().withStatusCode(Response.Status.OK.getStatusCode()) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(workspace))); + + Theme themeResponse = new Theme(); + themeResponse.name("theme1").cssFile("cssfile").properties(new Object()).logoUrl("someLogoUrl") + .faviconUrl("someFavIconUrl"); + // create mock rest endpoint for get theme by name from theme-svc + mockServerClient.when(request().withPath("/v1/themes/theme1").withMethod(HttpMethod.GET)) + .withId("mockTheme") + .respond(httpRequest -> response().withStatusCode(Response.Status.OK.getStatusCode()) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(themeResponse))); + + var output = given() + .when() + .auth().oauth2(keycloakClient.getAccessToken(ADMIN)) + .header(APM_HEADER_PARAM, ADMIN) + .contentType(APPLICATION_JSON) + .body(new LoadWorkspaceConfigRequestDTO().path("/w1Url")) + .post("load") + .then() + .statusCode(Response.Status.OK.getStatusCode()) + .contentType(APPLICATION_JSON) + .extract().as(LoadWorkspaceConfigResponseDTO.class); + + Assertions.assertNotNull(output); + Assertions.assertEquals("w1", output.getWorkspace().getName()); + Assertions.assertEquals("theme1", output.getTheme().getName()); + Assertions.assertEquals(0, output.getRoutes().size()); + + mockServerClient.clear("mockWS"); + mockServerClient.clear("mockTheme"); + } + + @Test + void loadWorkspaceConfig_ErrorTest() { + + // create mock rest endpoint for workspace search + mockServerClient.when(request().withPath("/v1/workspaces/load").withMethod(HttpMethod.POST) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(new WorkspaceLoadRequest().path("/w1Url")))) + .withId("mockWS") + .respond(httpRequest -> response().withStatusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .withContentType(MediaType.APPLICATION_JSON)); + + var output = given() + .when() + .auth().oauth2(keycloakClient.getAccessToken(ADMIN)) + .header(APM_HEADER_PARAM, ADMIN) + .contentType(APPLICATION_JSON) + .body(new LoadWorkspaceConfigRequestDTO().path("/w1Url")) + .post("load") + .then() + .statusCode(BAD_REQUEST.getStatusCode()); + Assertions.assertNotNull(output); + mockServerClient.clear("mockWS"); + } + + @Test + void loadWorkspaceConfig_errorThemeTest() { + + var workspace = new WorkspaceWrapper(); + workspace.name("w1").theme("theme1") + .addSlotsItem( + new WorkspaceWrapperSlot().name("slot1") + .addComponentsItem( + new WorkspaceWrapperComponent().productName("product1").appId("app1") + .name("App1Component"))); + + // create mock rest endpoint for workspace search + mockServerClient.when(request().withPath("/v1/workspaces/load").withMethod(HttpMethod.POST) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(new WorkspaceLoadRequest().path("/w1Url")))) + .withId("mockWS") + .respond(httpRequest -> response().withStatusCode(Response.Status.OK.getStatusCode()) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(workspace))); + + // create mock rest endpoint for get theme by name from theme-svc + mockServerClient.when(request().withPath("/v1/themes/theme1").withMethod(HttpMethod.GET)) + .withId("mockTheme") + .respond(httpRequest -> response().withStatusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .withContentType(MediaType.APPLICATION_JSON)); + + given() + .when() + .auth().oauth2(keycloakClient.getAccessToken(ADMIN)) + .header(APM_HEADER_PARAM, ADMIN) + .contentType(APPLICATION_JSON) + .body(new LoadWorkspaceConfigRequestDTO().path("/w1Url")) + .post("load") + .then() + .statusCode(BAD_REQUEST.getStatusCode()); + + mockServerClient.clear("mockWS"); + mockServerClient.clear("mockTheme"); + } + + @Test + void loadWorkspace_errorProductTest() { + + var workspace = new WorkspaceWrapper(); + workspace.name("w1").theme("theme1") + .addProductsItem( + new Product().productName("product1").baseUrl("/product1") + .addMicrofrontendsItem(new Microfrontend().basePath("/app1").mfeId("app1"))) + .addSlotsItem( + new WorkspaceWrapperSlot().name("slot1") + .addComponentsItem( + new WorkspaceWrapperComponent().productName("product1").appId("app1") + .name("App1Component")) + .addComponentsItem( + new WorkspaceWrapperComponent().productName("product1").appId("app1") + .name("App2Component")) + .addComponentsItem( + new WorkspaceWrapperComponent().productName("product1").appId("app1") + .name("App3Component"))); + + // create mock rest endpoint for workspace search + mockServerClient.when(request().withPath("/v1/workspaces/load").withMethod(HttpMethod.POST) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(new WorkspaceLoadRequest().path("/w1Url")))) + .withId("mockWS") + .respond(httpRequest -> response().withStatusCode(Response.Status.OK.getStatusCode()) + .withContentType(MediaType.APPLICATION_JSON) + .withBody(JsonBody.json(workspace))); + + // create mock rest endpoint for get product by name from product-store + mockServerClient.when(request().withPath("/v1/products/load/shell").withMethod(HttpMethod.POST)) + .withId("mockPS") + .respond(httpRequest -> response().withStatusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .withContentType(MediaType.APPLICATION_JSON)); + + given() + .when() + .auth().oauth2(keycloakClient.getAccessToken(ADMIN)) + .header(APM_HEADER_PARAM, ADMIN) + .contentType(APPLICATION_JSON) + .body(new LoadWorkspaceConfigRequestDTO().path("/w1Url")) + .post("load") + .then() + .statusCode(BAD_REQUEST.getStatusCode()); + + mockServerClient.clear("mockWS"); + mockServerClient.clear("mockPS"); + } }