From 8ecfc78d36dee303983b81b1601c305c66ef9e5c Mon Sep 17 00:00:00 2001 From: Andrej Petras Date: Mon, 13 Nov 2023 11:55:43 +0100 Subject: [PATCH] feat: add external v1 api --- pom.xml | 13 ++ .../onecx/theme/domain/daos/ThemeDAO.java | 29 ++- .../onecx/theme/domain/models/ThemeInfo.java | 4 + .../controllers/ThemesRestControllerV1.java | 52 +++++ .../external/v1/mappers/ExceptionMapper.java | 47 ++++ .../rs/external/v1/mappers/ThemeMapper.java | 29 +++ .../controllers/ThemesRestController.java | 12 +- .../rs/internal/mappers/ThemeMapper.java | 13 ++ .../openapi/onecx-theme-internal-openapi.yaml | 74 +++++- src/main/openapi/onecx-theme-v1.yaml | 216 ++++++++++++++++++ .../onecx/theme/domain/daos/ThemeDAOTest.java | 4 + .../ThemesRestControllerV1ExceptionTest.java | 59 +++++ .../controllers/ThemesRestControllerV1IT.java | 7 + .../ThemesRestControllerV1Test.java | 59 +++++ .../controllers/ThemesRestControllerTest.java | 32 ++- src/test/resources/data/testdata-external.xml | 9 + 16 files changed, 643 insertions(+), 16 deletions(-) create mode 100644 src/main/java/io/github/onecx/theme/domain/models/ThemeInfo.java create mode 100644 src/main/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1.java create mode 100644 src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ExceptionMapper.java create mode 100644 src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ThemeMapper.java create mode 100644 src/main/openapi/onecx-theme-v1.yaml create mode 100644 src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1ExceptionTest.java create mode 100644 src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1IT.java create mode 100644 src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1Test.java create mode 100644 src/test/resources/data/testdata-external.xml diff --git a/pom.xml b/pom.xml index 959f179..116bcf2 100644 --- a/pom.xml +++ b/pom.xml @@ -197,6 +197,19 @@ DTOV1 + + v1 + + generate + + + src/main/openapi/onecx-theme-v1.yaml + gen.io.github.onecx.theme.rs.external.v1 + gen.io.github.onecx.theme.rs.external.v1.model + DTOV1 + V1Api + + diff --git a/src/main/java/io/github/onecx/theme/domain/daos/ThemeDAO.java b/src/main/java/io/github/onecx/theme/domain/daos/ThemeDAO.java index cca50ba..4eacd99 100644 --- a/src/main/java/io/github/onecx/theme/domain/daos/ThemeDAO.java +++ b/src/main/java/io/github/onecx/theme/domain/daos/ThemeDAO.java @@ -8,9 +8,12 @@ import jakarta.transaction.Transactional; import org.tkit.quarkus.jpa.daos.AbstractDAO; +import org.tkit.quarkus.jpa.daos.Page; +import org.tkit.quarkus.jpa.daos.PageResult; import org.tkit.quarkus.jpa.exceptions.DAOException; import io.github.onecx.theme.domain.models.Theme; +import io.github.onecx.theme.domain.models.ThemeInfo; import io.github.onecx.theme.domain.models.Theme_; @ApplicationScoped @@ -27,7 +30,6 @@ public Stream findThemeByNames(Set themeNames) { if (themeNames != null && !themeNames.isEmpty()) { cq.where(root.get(Theme_.name).in(themeNames)); } - return this.getEntityManager().createQuery(cq).getResultStream(); } catch (Exception ex) { @@ -35,6 +37,29 @@ public Stream findThemeByNames(Set themeNames) { } } + public PageResult findAll(Integer pageNumber, Integer pageSize) { + try { + var cb = this.getEntityManager().getCriteriaBuilder(); + var cq = cb.createQuery(Theme.class); + cq.from(Theme.class); + return createPageQuery(cq, Page.of(pageNumber, pageSize)).getPageResult(); + } catch (Exception ex) { + throw new DAOException(ErrorKeys.ERROR_FIND_ALL_THEME_PAGE, ex); + } + } + + public Stream findAllInfos() { + try { + var cb = this.getEntityManager().getCriteriaBuilder(); + var cq = cb.createQuery(ThemeInfo.class); + var root = cq.from(Theme.class); + cq.select(cb.construct(ThemeInfo.class, root.get(Theme_.NAME), root.get(Theme_.DESCRIPTION))); + return this.getEntityManager().createQuery(cq).getResultStream(); + } catch (Exception ex) { + throw new DAOException(ErrorKeys.ERROR_FIND_ALL_THEME_INFO, ex); + } + } + public Theme findThemeByName(String themeName) { try { var cb = this.getEntityManager().getCriteriaBuilder(); @@ -53,6 +78,8 @@ public Theme findThemeByName(String themeName) { public enum ErrorKeys { + ERROR_FIND_ALL_THEME_INFO, + ERROR_FIND_ALL_THEME_PAGE, ERROR_FIND_THEME_BY_NAMES, ERROR_FIND_THEME_BY_NAME, } diff --git a/src/main/java/io/github/onecx/theme/domain/models/ThemeInfo.java b/src/main/java/io/github/onecx/theme/domain/models/ThemeInfo.java new file mode 100644 index 0000000..8b98878 --- /dev/null +++ b/src/main/java/io/github/onecx/theme/domain/models/ThemeInfo.java @@ -0,0 +1,4 @@ +package io.github.onecx.theme.domain.models; + +public record ThemeInfo(String name, String description) { +} diff --git a/src/main/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1.java b/src/main/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1.java new file mode 100644 index 0000000..0e21567 --- /dev/null +++ b/src/main/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1.java @@ -0,0 +1,52 @@ +package io.github.onecx.theme.rs.external.v1.controllers; + +import jakarta.enterprise.context.ApplicationScoped; +import jakarta.inject.Inject; +import jakarta.transaction.Transactional; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.core.Response; + +import org.jboss.resteasy.reactive.RestResponse; +import org.jboss.resteasy.reactive.server.ServerExceptionMapper; + +import gen.io.github.onecx.theme.rs.external.v1.ThemesV1Api; +import gen.io.github.onecx.theme.rs.external.v1.model.RestExceptionDTOV1; +import io.github.onecx.theme.domain.daos.ThemeDAO; +import io.github.onecx.theme.rs.external.v1.mappers.ExceptionMapper; +import io.github.onecx.theme.rs.external.v1.mappers.ThemeMapper; + +@Path("/v1/themes") +@ApplicationScoped +@Transactional(Transactional.TxType.NOT_SUPPORTED) +public class ThemesRestControllerV1 implements ThemesV1Api { + + @Inject + ThemeDAO dao; + + @Inject + ExceptionMapper exceptionMapper; + + @Inject + ThemeMapper mapper; + + @Override + public Response getThemeByThemeDefinitionName(String name) { + var theme = dao.findThemeByName(name); + if (theme == null) { + return Response.status(Response.Status.NOT_FOUND).build(); + } + return Response.ok(mapper.map(theme)).build(); + } + + @Override + public Response getThemeInfoList() { + var items = dao.findAllInfos(); + return Response.ok(mapper.mapInfoList(items)).build(); + } + + @ServerExceptionMapper + public RestResponse exception(Exception ex) { + return exceptionMapper.exception(ex); + } + +} diff --git a/src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ExceptionMapper.java b/src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ExceptionMapper.java new file mode 100644 index 0000000..ea38cb3 --- /dev/null +++ b/src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ExceptionMapper.java @@ -0,0 +1,47 @@ +package io.github.onecx.theme.rs.external.v1.mappers; + +import java.util.List; + +import jakarta.ws.rs.core.Response; + +import org.jboss.resteasy.reactive.RestResponse; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.tkit.quarkus.jpa.exceptions.DAOException; +import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper; + +import gen.io.github.onecx.theme.rs.external.v1.model.RestExceptionDTOV1; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Mapper(uses = { OffsetDateTimeMapper.class }) +public abstract class ExceptionMapper { + + public RestResponse exception(Exception ex) { + log.error("Processing theme external v1 rest controller error: {}", ex.getMessage()); + + if (ex instanceof DAOException de) { + return RestResponse.status(Response.Status.BAD_REQUEST, + exception(de.getMessageKey().name(), ex.getMessage(), de.parameters)); + } + return RestResponse.status(Response.Status.INTERNAL_SERVER_ERROR, + exception("UNDEFINED_ERROR_CODE", ex.getMessage())); + + } + + @Mapping(target = "removeParametersItem", ignore = true) + @Mapping(target = "namedParameters", ignore = true) + @Mapping(target = "removeNamedParametersItem", ignore = true) + @Mapping(target = "parameters", ignore = true) + @Mapping(target = "validations", ignore = true) + @Mapping(target = "removeValidationsItem", ignore = true) + public abstract RestExceptionDTOV1 exception(String errorCode, String message); + + @Mapping(target = "removeParametersItem", ignore = true) + @Mapping(target = "namedParameters", ignore = true) + @Mapping(target = "removeNamedParametersItem", ignore = true) + @Mapping(target = "validations", ignore = true) + @Mapping(target = "removeValidationsItem", ignore = true) + public abstract RestExceptionDTOV1 exception(String errorCode, String message, List parameters); + +} diff --git a/src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ThemeMapper.java b/src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ThemeMapper.java new file mode 100644 index 0000000..2fbaf8d --- /dev/null +++ b/src/main/java/io/github/onecx/theme/rs/external/v1/mappers/ThemeMapper.java @@ -0,0 +1,29 @@ +package io.github.onecx.theme.rs.external.v1.mappers; + +import java.util.List; +import java.util.stream.Stream; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper; + +import gen.io.github.onecx.theme.rs.external.v1.model.ThemeDTOV1; +import gen.io.github.onecx.theme.rs.external.v1.model.ThemeInfoDTOV1; +import gen.io.github.onecx.theme.rs.external.v1.model.ThemeInfoListDTOV1; +import io.github.onecx.theme.domain.models.Theme; +import io.github.onecx.theme.domain.models.ThemeInfo; + +@Mapper(uses = { OffsetDateTimeMapper.class }) +public abstract class ThemeMapper { + + @Mapping(target = "version", source = "modificationCount") + public abstract ThemeDTOV1 map(Theme theme); + + public ThemeInfoListDTOV1 mapInfoList(Stream data) { + var result = new ThemeInfoListDTOV1(); + result.setThemes(mapInfo(data)); + return result; + } + + public abstract List mapInfo(Stream page); +} diff --git a/src/main/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestController.java b/src/main/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestController.java index df24137..a319bbe 100644 --- a/src/main/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestController.java +++ b/src/main/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestController.java @@ -57,6 +57,12 @@ public Response deleteTheme(String id) { return Response.noContent().build(); } + @Override + public Response getThemeInfoList() { + var items = dao.findAllInfos(); + return Response.ok(mapper.mapInfoList(items)).build(); + } + @Override public Response getThemeById(String id) { var theme = dao.findById(id); @@ -76,9 +82,9 @@ public Response getThemeByThemeDefinitionName(String name) { } @Override - public Response getThemes() { - var items = dao.findAll(); - return Response.ok(mapper.map(items)).build(); + public Response getThemes(Integer pageNumber, Integer pageSize) { + var items = dao.findAll(pageNumber, pageSize); + return Response.ok(mapper.mapPage(items)).build(); } @Override diff --git a/src/main/java/io/github/onecx/theme/rs/internal/mappers/ThemeMapper.java b/src/main/java/io/github/onecx/theme/rs/internal/mappers/ThemeMapper.java index ac333a1..aee8891 100644 --- a/src/main/java/io/github/onecx/theme/rs/internal/mappers/ThemeMapper.java +++ b/src/main/java/io/github/onecx/theme/rs/internal/mappers/ThemeMapper.java @@ -9,6 +9,7 @@ import org.mapstruct.Mapping; import org.mapstruct.MappingTarget; import org.mapstruct.Named; +import org.tkit.quarkus.jpa.daos.PageResult; import org.tkit.quarkus.rs.mappers.OffsetDateTimeMapper; import com.fasterxml.jackson.core.JsonProcessingException; @@ -16,6 +17,7 @@ import gen.io.github.onecx.theme.rs.internal.model.*; import io.github.onecx.theme.domain.models.Theme; +import io.github.onecx.theme.domain.models.ThemeInfo; @Mapper(uses = { OffsetDateTimeMapper.class }) public abstract class ThemeMapper { @@ -23,6 +25,17 @@ public abstract class ThemeMapper { @Inject ObjectMapper mapper; + public ThemeInfoListDTO mapInfoList(Stream data) { + ThemeInfoListDTO result = new ThemeInfoListDTO(); + result.setThemes(mapInfo(data)); + return result; + } + + public abstract List mapInfo(Stream page); + + @Mapping(target = "removeStreamItem", ignore = true) + public abstract ThemePageResultDTO mapPage(PageResult page); + @Mapping(target = "id", ignore = true) @Mapping(target = "controlTraceabilityManual", ignore = true) @Mapping(target = "modificationCount", ignore = true) diff --git a/src/main/openapi/onecx-theme-internal-openapi.yaml b/src/main/openapi/onecx-theme-internal-openapi.yaml index a17c940..2665fab 100644 --- a/src/main/openapi/onecx-theme-internal-openapi.yaml +++ b/src/main/openapi/onecx-theme-internal-openapi.yaml @@ -14,6 +14,21 @@ paths: - themesInternal description: Return list of themes operationId: getThemes + parameters: + - name: pageNumber + in: query + schema: + format: int32 + description: The number of page. + default: 0 + type: integer + - name: pageSize + in: query + schema: + format: int32 + description: The size of page + default: 10 + type: integer responses: "200": description: OK @@ -22,7 +37,7 @@ paths: schema: type: array items: - $ref: '#/components/schemas/Theme' + $ref: '#/components/schemas/ThemePageResult' "403": description: Forbidden "500": @@ -148,6 +163,27 @@ paths: application/json: schema: $ref: '#/components/schemas/RestException' + /internal/themes/info: + get: + tags: + - themesInternal + description: Get list of all themes + operationId: getThemeInfoList + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ThemeInfoList' + "404": + description: Not found + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/RestException' /internal/themes/name/{name}: get: tags: @@ -175,9 +211,43 @@ paths: application/json: schema: $ref: '#/components/schemas/RestException' - deprecated: true components: schemas: + ThemeInfoList: + type: object + properties: + themes: + type: array + items: + $ref: '#/components/schemas/ThemeInfo' + ThemeInfo: + type: object + properties: + name: + minLength: 2 + type: string + description: + type: string + ThemePageResult: + type: object + properties: + totalElements: + format: int64 + description: The total elements in the resource. + type: integer + number: + format: int32 + type: integer + size: + format: int32 + type: integer + totalPages: + format: int64 + type: integer + stream: + type: array + items: + $ref: '#/components/schemas/Theme' Theme: required: - name diff --git a/src/main/openapi/onecx-theme-v1.yaml b/src/main/openapi/onecx-theme-v1.yaml new file mode 100644 index 0000000..89ec476 --- /dev/null +++ b/src/main/openapi/onecx-theme-v1.yaml @@ -0,0 +1,216 @@ +--- +openapi: 3.0.3 +info: + title: onecx-theme internal service + version: 1.0.0 +servers: + - url: "http://onecx-portal:8080" +tags: + - name: themes +paths: + /v1/themes/info: + get: + tags: + - themes + description: Get list of all themes + operationId: getThemeInfoList + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/ThemeInfoList' + "404": + description: Not found + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/RestException' + /v1/themes/name/{name}: + get: + tags: + - themes + description: Load a single theme definition + operationId: getThemeByThemeDefinitionName + parameters: + - name: name + in: path + required: true + schema: + type: string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/Theme' + "404": + description: Not found + "500": + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/RestException' +components: + schemas: + ThemeInfoList: + type: object + properties: + themes: + type: array + items: + $ref: '#/components/schemas/ThemeInfo' + ThemeInfo: + type: object + properties: + name: + minLength: 2 + type: string + description: + type: string + Theme: + required: + - name + type: object + properties: + version: + format: int32 + type: integer + creationDate: + $ref: '#/components/schemas/OffsetDateTime' + creationUser: + type: string + modificationDate: + $ref: '#/components/schemas/OffsetDateTime' + modificationUser: + type: string + id: + type: string + name: + minLength: 2 + type: string + cssFile: + type: string + description: + type: string + assetsUrl: + type: string + logoUrl: + type: string + faviconUrl: + type: string + previewImageUrl: + type: string + assetsUpdateDate: + type: string + properties: + type: object + OffsetDateTime: + format: date-time + type: string + example: 2022-03-10T12:15:50-04:00 + RestException: + type: object + properties: + errorCode: + type: string + message: + type: string + parameters: + type: array + items: + type: object + namedParameters: + type: object + additionalProperties: + type: object + validations: + type: array + items: + $ref: '#/components/schemas/ValidationConstraint' + ValidationConstraint: + type: object + properties: + parameter: + type: string + message: + type: string + CreateTheme: + required: + - name + type: object + properties: + version: + format: int32 + type: integer + creationDate: + $ref: '#/components/schemas/OffsetDateTime' + creationUser: + type: string + modificationDate: + $ref: '#/components/schemas/OffsetDateTime' + modificationUser: + type: string + id: + type: string + name: + minLength: 2 + type: string + cssFile: + type: string + description: + type: string + assetsUrl: + type: string + logoUrl: + type: string + faviconUrl: + type: string + previewImageUrl: + type: string + assetsUpdateDate: + type: string + properties: + type: object + UpdateTheme: + required: + - name + type: object + properties: + version: + format: int32 + type: integer + creationDate: + $ref: '#/components/schemas/OffsetDateTime' + creationUser: + type: string + modificationDate: + $ref: '#/components/schemas/OffsetDateTime' + modificationUser: + type: string + id: + type: string + name: + minLength: 2 + type: string + cssFile: + type: string + description: + type: string + assetsUrl: + type: string + logoUrl: + type: string + faviconUrl: + type: string + previewImageUrl: + type: string + assetsUpdateDate: + type: string + properties: + type: object \ No newline at end of file diff --git a/src/test/java/io/github/onecx/theme/domain/daos/ThemeDAOTest.java b/src/test/java/io/github/onecx/theme/domain/daos/ThemeDAOTest.java index 9052a4d..5c78920 100644 --- a/src/test/java/io/github/onecx/theme/domain/daos/ThemeDAOTest.java +++ b/src/test/java/io/github/onecx/theme/domain/daos/ThemeDAOTest.java @@ -32,6 +32,10 @@ void methodExceptionTests() { ThemeDAO.ErrorKeys.ERROR_FIND_THEME_BY_NAME); methodExceptionTests(() -> dao.findThemeByNames(null), ThemeDAO.ErrorKeys.ERROR_FIND_THEME_BY_NAMES); + methodExceptionTests(() -> dao.findAll(0, 2), + ThemeDAO.ErrorKeys.ERROR_FIND_ALL_THEME_PAGE); + methodExceptionTests(() -> dao.findAllInfos(), + ThemeDAO.ErrorKeys.ERROR_FIND_ALL_THEME_INFO); } void methodExceptionTests(Executable fn, Enum key) { diff --git a/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1ExceptionTest.java b/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1ExceptionTest.java new file mode 100644 index 0000000..381fccb --- /dev/null +++ b/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1ExceptionTest.java @@ -0,0 +1,59 @@ +package io.github.onecx.theme.rs.external.v1.controllers; + +import static io.restassured.RestAssured.given; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; +import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; +import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.tkit.quarkus.jpa.exceptions.DAOException; + +import gen.io.github.onecx.theme.rs.external.v1.model.RestExceptionDTOV1; +import io.github.onecx.theme.domain.daos.ThemeDAO; +import io.github.onecx.theme.test.AbstractTest; +import io.quarkus.test.InjectMock; +import io.quarkus.test.common.http.TestHTTPEndpoint; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@TestHTTPEndpoint(ThemesRestControllerV1.class) +class ThemesRestControllerV1ExceptionTest extends AbstractTest { + + @InjectMock + ThemeDAO dao; + + @BeforeEach + void beforeAll() { + Mockito.when(dao.findAllInfos()) + .thenThrow(new RuntimeException("Test technical error exception")) + .thenThrow(new DAOException(ErrorKey.ERROR_TEST, new RuntimeException("Test"))); + } + + @Test + void exceptionTest() { + var exception = given() + .contentType(APPLICATION_JSON) + .get("info") + .then() + .statusCode(INTERNAL_SERVER_ERROR.getStatusCode()) + .extract().as(RestExceptionDTOV1.class); + + assertThat(exception.getErrorCode()).isEqualTo("UNDEFINED_ERROR_CODE"); + + exception = given() + .contentType(APPLICATION_JSON) + .get("info") + .then() + .statusCode(BAD_REQUEST.getStatusCode()) + .extract().as(RestExceptionDTOV1.class); + + assertThat(exception.getErrorCode()).isEqualTo(ErrorKey.ERROR_TEST.name()); + } + + public enum ErrorKey { + ERROR_TEST; + } +} diff --git a/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1IT.java b/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1IT.java new file mode 100644 index 0000000..c837dcf --- /dev/null +++ b/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1IT.java @@ -0,0 +1,7 @@ +package io.github.onecx.theme.rs.external.v1.controllers; + +import io.quarkus.test.junit.QuarkusIntegrationTest; + +@QuarkusIntegrationTest +class ThemesRestControllerV1IT extends ThemesRestControllerV1Test { +} diff --git a/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1Test.java b/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1Test.java new file mode 100644 index 0000000..bb1d4f6 --- /dev/null +++ b/src/test/java/io/github/onecx/theme/rs/external/v1/controllers/ThemesRestControllerV1Test.java @@ -0,0 +1,59 @@ +package io.github.onecx.theme.rs.external.v1.controllers; + +import static io.restassured.RestAssured.given; +import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; +import static jakarta.ws.rs.core.Response.Status.NOT_FOUND; +import static jakarta.ws.rs.core.Response.Status.OK; +import static org.assertj.core.api.Assertions.assertThat; + +import org.junit.jupiter.api.Test; +import org.tkit.quarkus.test.WithDBData; + +import gen.io.github.onecx.theme.rs.external.v1.model.ThemeDTOV1; +import gen.io.github.onecx.theme.rs.external.v1.model.ThemeInfoListDTOV1; +import io.github.onecx.theme.test.AbstractTest; +import io.quarkus.test.common.http.TestHTTPEndpoint; +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +@TestHTTPEndpoint(ThemesRestControllerV1.class) +@WithDBData(value = "data/testdata-external.xml", deleteBeforeInsert = true, deleteAfterTest = true, rinseAndRepeat = true) +class ThemesRestControllerV1Test extends AbstractTest { + + @Test + void getThemeByThemeDefinitionNameTest() { + var dto = given() + .contentType(APPLICATION_JSON) + .pathParam("name", "themeWithoutPortal") + .get("/name/{name}") + .then().statusCode(OK.getStatusCode()) + .contentType(APPLICATION_JSON) + .extract() + .body().as(ThemeDTOV1.class); + + assertThat(dto).isNotNull(); + assertThat(dto.getName()).isEqualTo("themeWithoutPortal"); + assertThat(dto.getId()).isEqualTo("22-222"); + + given() + .contentType(APPLICATION_JSON) + .pathParam("name", "none-exists") + .get("/name/{name}") + .then().statusCode(NOT_FOUND.getStatusCode()); + } + + @Test + void getThemeInfoListTest() { + var data = given() + .contentType(APPLICATION_JSON) + .get("info") + .then() + .statusCode(OK.getStatusCode()) + .contentType(APPLICATION_JSON) + .extract() + .as(ThemeInfoListDTOV1.class); + + assertThat(data).isNotNull(); + assertThat(data.getThemes()).isNotNull().hasSize(3); + } +} diff --git a/src/test/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestControllerTest.java b/src/test/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestControllerTest.java index 84df1c0..3c7004b 100644 --- a/src/test/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestControllerTest.java +++ b/src/test/java/io/github/onecx/theme/rs/internal/controllers/ThemesRestControllerTest.java @@ -6,8 +6,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.from; -import java.util.List; - import jakarta.ws.rs.core.HttpHeaders; import jakarta.ws.rs.core.Response; @@ -15,13 +13,10 @@ import org.junit.jupiter.api.Test; import org.tkit.quarkus.test.WithDBData; -import gen.io.github.onecx.theme.rs.internal.model.RestExceptionDTO; -import gen.io.github.onecx.theme.rs.internal.model.ThemeDTO; -import gen.io.github.onecx.theme.rs.internal.model.UpdateThemeDTO; +import gen.io.github.onecx.theme.rs.internal.model.*; import io.github.onecx.theme.test.AbstractTest; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; -import io.restassured.common.mapper.TypeRef; @QuarkusTest @TestHTTPEndpoint(ThemesRestController.class) @@ -180,14 +175,31 @@ void getThemesTest() { var data = given() .contentType(APPLICATION_JSON) .get() - .then().statusCode(OK.getStatusCode()) + .then() + .statusCode(OK.getStatusCode()) .contentType(APPLICATION_JSON) .extract() - .as(new TypeRef>() { - }); + .as(ThemePageResultDTO.class); + + assertThat(data).isNotNull(); + assertThat(data.getTotalElements()).isEqualTo(3); + assertThat(data.getStream()).isNotNull().hasSize(3); + + } - assertThat(data).hasSize(3); + @Test + void getThemeInfoListTest() { + var data = given() + .contentType(APPLICATION_JSON) + .get("info") + .then() + .statusCode(OK.getStatusCode()) + .contentType(APPLICATION_JSON) + .extract() + .as(ThemeInfoListDTO.class); + assertThat(data).isNotNull(); + assertThat(data.getThemes()).isNotNull().hasSize(3); } @Test diff --git a/src/test/resources/data/testdata-external.xml b/src/test/resources/data/testdata-external.xml new file mode 100644 index 0000000..47813f2 --- /dev/null +++ b/src/test/resources/data/testdata-external.xml @@ -0,0 +1,9 @@ + + + + + + + + +