diff --git a/pom.xml b/pom.xml index c6dd5bf74155ef462e9651f936f630f4036dbcb9..8b07c04fd106d9f2924c3335f1a4205d506de890 100644 --- a/pom.xml +++ b/pom.xml @@ -34,6 +34,14 @@ <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-security</artifactId> + </dependency> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-validation</artifactId> + </dependency> <!-- Dev --> <dependency> diff --git a/src/main/java/de/ozgcloud/admin/web/error/ExceptionTranslator.java b/src/main/java/de/ozgcloud/admin/errorhandling/ExceptionTranslator.java similarity index 54% rename from src/main/java/de/ozgcloud/admin/web/error/ExceptionTranslator.java rename to src/main/java/de/ozgcloud/admin/errorhandling/ExceptionTranslator.java index 4e0b50f5c3423a52967f107732eaae4a24e0df30..17a5d236a9de7be52ae9cdd10ed42535ae92219b 100644 --- a/src/main/java/de/ozgcloud/admin/web/error/ExceptionTranslator.java +++ b/src/main/java/de/ozgcloud/admin/errorhandling/ExceptionTranslator.java @@ -19,11 +19,14 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.ozgcloud.admin.web.error; +package de.ozgcloud.admin.errorhandling; -import java.nio.file.AccessDeniedException; import java.util.Map; +import jakarta.validation.ConstraintViolationException; + +import org.springframework.http.HttpStatus; +import org.springframework.security.access.AccessDeniedException; import org.springframework.web.ErrorResponse; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; @@ -34,13 +37,26 @@ import de.ozgcloud.common.errorhandling.TechnicalException; @RestControllerAdvice public class ExceptionTranslator extends ResponseEntityExceptionHandler { - @ExceptionHandler({ RuntimeException.class, AccessDeniedException.class, TechnicalException.class }) - public ErrorResponse handleAccessDeniedException(Exception ex) { - var errorType = Map.of( - AccessDeniedException.class, ErrorType.AUTHORIZATION, - TechnicalException.class, ErrorType.TECHNICAL - ).getOrDefault(ex.getClass(), ErrorType.UNKNOWN); + static final Map<Class<? extends Exception>, HttpStatus> EXCEPTION_STATUS = Map.of( + RuntimeException.class, HttpStatus.INTERNAL_SERVER_ERROR, + AccessDeniedException.class, HttpStatus.FORBIDDEN, + ConstraintViolationException.class, HttpStatus.UNPROCESSABLE_ENTITY, + ResourceNotFoundException.class, HttpStatus.NOT_FOUND, + FunctionalException.class, HttpStatus.BAD_REQUEST, + TechnicalException.class, HttpStatus.INTERNAL_SERVER_ERROR + ); + + @ExceptionHandler({ + RuntimeException.class, + AccessDeniedException.class, + ConstraintViolationException.class, + ResourceNotFoundException.class, + FunctionalException.class, + TechnicalException.class + }) + public ErrorResponse handleRuntimeExceptionGeneric(RuntimeException ex) { + var errorStatus = EXCEPTION_STATUS.getOrDefault(ex.getClass(), HttpStatus.INTERNAL_SERVER_ERROR); - return ErrorResponse.builder(ex, errorType.getStatus(), ex.getLocalizedMessage()).build(); + return ErrorResponse.builder(ex, errorStatus, ex.getLocalizedMessage()).build(); } } diff --git a/src/main/java/de/ozgcloud/admin/errorhandling/FunctionalException.java b/src/main/java/de/ozgcloud/admin/errorhandling/FunctionalException.java new file mode 100644 index 0000000000000000000000000000000000000000..e0e57b3feb65073674c0645aac9fc997af8dbfed --- /dev/null +++ b/src/main/java/de/ozgcloud/admin/errorhandling/FunctionalException.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.errorhandling; + +import java.io.Serial; +import java.util.UUID; + +import de.ozgcloud.common.errorhandling.ExceptionUtil; +import de.ozgcloud.common.errorhandling.FunctionalErrorCode; +import de.ozgcloud.common.errorhandling.IdentifiableException; + +public class FunctionalException extends RuntimeException implements IdentifiableException { + + @Serial + private static final long serialVersionUID = 1L; + + private final FunctionalErrorCode errorCode; + private final String exceptionId; + + public FunctionalException(FunctionalErrorCode errorCode) { + super("Functional error: " + errorCode.getErrorCode()); + + this.errorCode = errorCode; + this.exceptionId = UUID.randomUUID().toString(); + } + + public String getErrorCode() { + return errorCode.getErrorCode(); + } + + @Override + public String getMessage() { + return ExceptionUtil.formatMessageWithExceptionId(super.getMessage(), exceptionId); + } + + @Override + public String getExceptionId() { + return exceptionId; + } +} diff --git a/src/main/java/de/ozgcloud/admin/web/error/ErrorType.java b/src/main/java/de/ozgcloud/admin/errorhandling/ResourceNotFoundException.java similarity index 59% rename from src/main/java/de/ozgcloud/admin/web/error/ErrorType.java rename to src/main/java/de/ozgcloud/admin/errorhandling/ResourceNotFoundException.java index a374b0c636bc8ff945d07bf5bceff30ac8235633..376a5679d4a5927e8c38a6c3e1d12439e3eb1e38 100644 --- a/src/main/java/de/ozgcloud/admin/web/error/ErrorType.java +++ b/src/main/java/de/ozgcloud/admin/errorhandling/ResourceNotFoundException.java @@ -19,21 +19,26 @@ * Die sprachspezifischen Genehmigungen und Beschränkungen * unter der Lizenz sind dem Lizenztext zu entnehmen. */ -package de.ozgcloud.admin.web.error; +package de.ozgcloud.admin.errorhandling; -import org.springframework.http.HttpStatus; +import java.io.Serial; -import lombok.AllArgsConstructor; +import de.ozgcloud.common.errorhandling.FunctionalErrorCode; import lombok.Getter; -@AllArgsConstructor @Getter -public enum ErrorType { - UNKNOWN(HttpStatus.INTERNAL_SERVER_ERROR), - AUTHORIZATION(HttpStatus.UNAUTHORIZED), - FUNCTIONAL(HttpStatus.BAD_REQUEST), - TECHNICAL(HttpStatus.INTERNAL_SERVER_ERROR), - ; +public class ResourceNotFoundException extends FunctionalException { - private final HttpStatus status; + @Serial + private static final long serialVersionUID = 1L; + + private static final String MESSAGE_TEMPLATE = "Resource '%s' with id '%s' not found."; + + public ResourceNotFoundException(Class<?> resource, Object id) { + super(buildErrorCode(resource, id)); + } + + private static FunctionalErrorCode buildErrorCode(Class<?> resource, Object id) { + return () -> String.format(MESSAGE_TEMPLATE, resource.getSimpleName(), id.toString()); + } } diff --git a/src/main/java/de/ozgcloud/admin/service/BasicAppInfoService.java b/src/main/java/de/ozgcloud/admin/service/BasicAppInfoService.java deleted file mode 100644 index dd46122602744f939b77bb1486f473a3dbef23f5..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/admin/service/BasicAppInfoService.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur - * Zentrales IT-Management - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.admin.service; - -import java.time.Instant; -import java.util.Optional; - -import org.springframework.boot.info.BuildProperties; -import org.springframework.stereotype.Service; - -import lombok.AllArgsConstructor; - -@Service -@AllArgsConstructor -public class BasicAppInfoService { - private Optional<BuildProperties> buildProperties; - - public String getVersion() { - return buildProperties.map(BuildProperties::getVersion).orElse("--"); - } - - public Instant getBuildTime() { - return buildProperties.map(BuildProperties::getTime).orElse(Instant.now()); - } - - public String getJavaVersion() { - return System.getProperty("java.version", "?"); - } - - public String getBuildNumber() { - return buildProperties.map(p -> p.get("number")).orElse("?"); - } - - public String getBuildUrl() { - return buildProperties.map(p -> p.get("url")).orElse("?"); - } -} diff --git a/src/main/java/de/ozgcloud/admin/web/controller/BasicAppInfoController.java b/src/main/java/de/ozgcloud/admin/web/controller/BasicAppInfoController.java deleted file mode 100644 index b5b14ca25c9f29d70f1de5b3b8ebdcdec499e526..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/admin/web/controller/BasicAppInfoController.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur - * Zentrales IT-Management - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.admin.web.controller; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; - -import de.ozgcloud.admin.service.BasicAppInfoService; -import de.ozgcloud.admin.web.dto.BasicAppInfo; -import lombok.AllArgsConstructor; - -@RestController -@AllArgsConstructor -@RequestMapping(BasicAppInfoController.PATH) -public class BasicAppInfoController { - static final String PATH = "/api"; // NOSONAR - - private BasicAppInfoService basicAppInfoService; - - @GetMapping - public BasicAppInfo getInfo() { - return buildInfo(); - } - - private BasicAppInfo buildInfo() { - return BasicAppInfo.builder() - .javaVersion(basicAppInfoService.getJavaVersion()) - .buildTime(basicAppInfoService.getBuildTime()) - .buildVersion(basicAppInfoService.getVersion()) - .buildNumber(basicAppInfoService.getBuildNumber()) - .buildUrl(basicAppInfoService.getBuildUrl()) - .build(); - } - -} diff --git a/src/main/java/de/ozgcloud/admin/web/dto/BasicAppInfo.java b/src/main/java/de/ozgcloud/admin/web/dto/BasicAppInfo.java deleted file mode 100644 index f6d3fa4cdb5a01dce28c15ceb18394ef81f1245e..0000000000000000000000000000000000000000 --- a/src/main/java/de/ozgcloud/admin/web/dto/BasicAppInfo.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur - * Zentrales IT-Management - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.admin.web.dto; - -import java.time.Instant; - -import lombok.Builder; -import lombok.Getter; - -@Builder -@Getter -public class BasicAppInfo { - private String javaVersion; - private String buildVersion; - private Instant buildTime; - private String buildNumber; - private String buildUrl; -} diff --git a/src/test/java/de/ozgcloud/admin/errorhandling/ExceptionTranslatorITCase.java b/src/test/java/de/ozgcloud/admin/errorhandling/ExceptionTranslatorITCase.java new file mode 100644 index 0000000000000000000000000000000000000000..39e99928f05638c35e551f0a91f8160128d31732 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/errorhandling/ExceptionTranslatorITCase.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.errorhandling; + +import static de.ozgcloud.admin.errorhandling.ExceptionTranslator.*; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; + +import java.util.stream.Stream; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.HttpStatus; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.ResultActions; +import org.springframework.test.web.servlet.setup.MockMvcBuilders; + +import lombok.SneakyThrows; + +@ExtendWith(MockitoExtension.class) +class ExceptionTranslatorITCase { + + private MockMvc mockMvc; + + @BeforeEach + void setup() { + mockMvc = MockMvcBuilders + .standaloneSetup(new TestErrorController()) + .setControllerAdvice(new ExceptionTranslator()).build(); + } + + @DisplayName("Error handler") + @Nested + class TestErrorHandler { + + private static Stream<Arguments> exceptionAndExpectedStatus() { + return EXCEPTION_STATUS.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue())); + } + + @ParameterizedTest + @MethodSource("exceptionAndExpectedStatus") + @SneakyThrows + void shouldHandleExceptionWithStatus(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) { + var result = doPerformWithError(exceptionClass); + + result.andExpect(status().is(expectedStatus.value())); + } + + @SneakyThrows + private ResultActions doPerformWithError(Class<? extends Exception> exceptionClass) { + return mockMvc.perform(get("/test-error").param("errorClassName", exceptionClass.getName())); + } + } +} diff --git a/src/test/java/de/ozgcloud/admin/errorhandling/TestErrorController.java b/src/test/java/de/ozgcloud/admin/errorhandling/TestErrorController.java new file mode 100644 index 0000000000000000000000000000000000000000..6b822e91935025bfba3f15564b4be2c39099cbb1 --- /dev/null +++ b/src/test/java/de/ozgcloud/admin/errorhandling/TestErrorController.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur + * Zentrales IT-Management + * + * Lizenziert unter der EUPL, Version 1.2 oder - sobald + * diese von der Europäischen Kommission genehmigt wurden - + * Folgeversionen der EUPL ("Lizenz"); + * Sie dürfen dieses Werk ausschließlich gemäß + * dieser Lizenz nutzen. + * Eine Kopie der Lizenz finden Sie hier: + * + * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 + * + * Sofern nicht durch anwendbare Rechtsvorschriften + * gefordert oder in schriftlicher Form vereinbart, wird + * die unter der Lizenz verbreitete Software "so wie sie + * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - + * ausdrücklich oder stillschweigend - verbreitet. + * Die sprachspezifischen Genehmigungen und Beschränkungen + * unter der Lizenz sind dem Lizenztext zu entnehmen. + */ +package de.ozgcloud.admin.errorhandling; + +import static org.junit.Assert.*; + +import java.util.Collections; +import java.util.Map; +import java.util.Objects; + +import jakarta.validation.ConstraintViolationException; + +import org.springframework.data.repository.query.Param; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import de.ozgcloud.common.errorhandling.TechnicalException; + +@RestController +@RequestMapping("/test-error") +public class TestErrorController { + + @FunctionalInterface + interface ExceptionProducer { + Exception produceException(); + } + + static Map<Class<? extends Exception>, ExceptionProducer> EXCEPTION_PRODUCER = Map.of( + RuntimeException.class, () -> new RuntimeException("x"), + AccessDeniedException.class, () -> new AccessDeniedException("x"), + ConstraintViolationException.class, () -> new ConstraintViolationException("x", Collections.emptySet()), + ResourceNotFoundException.class, () -> new ResourceNotFoundException(Object.class, "x"), + FunctionalException.class, () -> new FunctionalException(() -> "x"), + TechnicalException.class, () -> new TechnicalException("x") + ); + + @GetMapping + String throwException(@Param("error") String errorClassName) throws Exception { + Objects.requireNonNull(errorClassName); + + var clazz = Class.forName(errorClassName); + + var exception = EXCEPTION_PRODUCER.get(clazz).produceException(); + assertEquals(clazz, exception.getClass()); + throw exception; + } +} + diff --git a/src/test/java/de/ozgcloud/admin/web/AdministrationApplicationTests.java b/src/test/java/de/ozgcloud/admin/web/AdministrationApplicationTests.java deleted file mode 100644 index 7fb5cbbac22552834056322150b2b2908ca80f11..0000000000000000000000000000000000000000 --- a/src/test/java/de/ozgcloud/admin/web/AdministrationApplicationTests.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur - * Zentrales IT-Management - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.admin.web; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.test.context.SpringBootTest; - -@SpringBootTest -class AdministrationApplicationTest { - - @Test - void shouldSpringContextLoad() { // NOSONAR - } -} diff --git a/src/test/java/de/ozgcloud/admin/web/controller/BasicAppInfoControllerTest.java b/src/test/java/de/ozgcloud/admin/web/controller/BasicAppInfoControllerTest.java deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/src/test/java/de/ozgcloud/admin/web/error/ExceptionTranslatorITCase.java b/src/test/java/de/ozgcloud/admin/web/error/ExceptionTranslatorITCase.java deleted file mode 100644 index 2fe91262de2dc4119a4b0fa414165cd74aead18b..0000000000000000000000000000000000000000 --- a/src/test/java/de/ozgcloud/admin/web/error/ExceptionTranslatorITCase.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2024. Das Land Schleswig-Holstein vertreten durch das Ministerium für Energiewende, Klimaschutz, Umwelt und Natur - * Zentrales IT-Management - * - * Lizenziert unter der EUPL, Version 1.2 oder - sobald - * diese von der Europäischen Kommission genehmigt wurden - - * Folgeversionen der EUPL ("Lizenz"); - * Sie dürfen dieses Werk ausschließlich gemäß - * dieser Lizenz nutzen. - * Eine Kopie der Lizenz finden Sie hier: - * - * https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12 - * - * Sofern nicht durch anwendbare Rechtsvorschriften - * gefordert oder in schriftlicher Form vereinbart, wird - * die unter der Lizenz verbreitete Software "so wie sie - * ist", OHNE JEGLICHE GEWÄHRLEISTUNG ODER BEDINGUNGEN - - * ausdrücklich oder stillschweigend - verbreitet. - * Die sprachspezifischen Genehmigungen und Beschränkungen - * unter der Lizenz sind dem Lizenztext zu entnehmen. - */ -package de.ozgcloud.admin.web.error; - -import static org.mockito.Mockito.*; -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; - -import java.nio.file.AccessDeniedException; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.Spy; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.setup.MockMvcBuilders; - -import de.ozgcloud.admin.service.BasicAppInfoService; -import de.ozgcloud.admin.web.controller.BasicAppInfoController; -import de.ozgcloud.common.errorhandling.TechnicalException; - -@SpringBootTest -class ExceptionTranslatorITCase { - - @Spy - @InjectMocks - private BasicAppInfoController basicAppInfoController; - - @Mock - private BasicAppInfoService basicAppInfoService; - - private MockMvc mockMvc; - - @BeforeEach - void mock() { - mockMvc = MockMvcBuilders - .standaloneSetup(basicAppInfoController) - .setControllerAdvice(new ExceptionTranslator()) - .build(); - } - - @DisplayName("Error handler") - @Nested - class TestErrorHandler { - - private void throwWhenApiCalled(Exception ex) { - when(basicAppInfoService.getJavaVersion()) - .thenAnswer(invocation -> { - throw ex; - }); - } - - @Test - void shouldHandleAccessDenied() throws Exception { - throwWhenApiCalled(new AccessDeniedException("test no access")); - - mockMvc.perform(get("/api")) - .andExpect(status().is(ErrorType.AUTHORIZATION.getStatus().value())); - } - - @Test - void shouldHandleTechnicalError() throws Exception { - throwWhenApiCalled(new TechnicalException("test technical error")); - - mockMvc.perform(get("/api")) - .andExpect(status().is(ErrorType.TECHNICAL.getStatus().value())); - } - - @Test - void shouldRuntimeError() throws Exception { - throwWhenApiCalled(new RuntimeException("test unknown error")); - - mockMvc.perform(get("/api")) - .andExpect(status().is(ErrorType.UNKNOWN.getStatus().value())); - } - } -}