From aa76af4d41f5f304d56c8edc895a39de9c8c4f5f Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 9 Sep 2020 15:08:23 +0200 Subject: [PATCH] Add optional url to ExceptionWithContext --- .../java/sonia/scm/ExceptionWithContext.java | 14 +++- .../ExceptionWithContextToErrorDtoMapper.java | 10 ++- ...eptionWithContextToErrorDtoMapperTest.java | 81 +++++++++++++++++++ .../repository/RepositoryInitializerTest.java | 4 +- 4 files changed, 105 insertions(+), 4 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapperTest.java diff --git a/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java b/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java index 6d7b31693d..1631aea178 100644 --- a/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java +++ b/scm-core/src/main/java/sonia/scm/ExceptionWithContext.java @@ -21,10 +21,11 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm; import java.util.List; +import java.util.Optional; import static java.util.Collections.unmodifiableList; @@ -49,4 +50,15 @@ public abstract class ExceptionWithContext extends RuntimeException { } public abstract String getCode(); + + /** + * Returns an url which gives more information about the exception or an empty optional. + * The methods returns an empty optional by default and can be overwritten. + * + * @return information url or empty + * @since 2.5.0 + */ + public Optional getUrl() { + return Optional.empty(); + } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapper.java index 3c62fe2b0d..bdf14e5bd5 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapper.java @@ -21,7 +21,7 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ - + package sonia.scm.api.v2.resources; import org.mapstruct.AfterMapping; @@ -31,15 +31,21 @@ import org.mapstruct.MappingTarget; import org.slf4j.MDC; import sonia.scm.ExceptionWithContext; +import java.util.Optional; + @Mapper public abstract class ExceptionWithContextToErrorDtoMapper { @Mapping(target = "errorCode", source = "code") @Mapping(target = "transactionId", ignore = true) @Mapping(target = "violations", ignore = true) - @Mapping(target = "url", ignore = true) public abstract ErrorDto map(ExceptionWithContext exception); + @SuppressWarnings("OptionalUsedAsFieldOrParameterType") // is ok for mapping + public String mapOptional(Optional optionalString) { + return optionalString.orElse(null); + } + @AfterMapping void setTransactionId(@MappingTarget ErrorDto dto) { dto.setTransactionId(MDC.get("transaction_id")); diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapperTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapperTest.java new file mode 100644 index 0000000000..649493b7e8 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/ExceptionWithContextToErrorDtoMapperTest.java @@ -0,0 +1,81 @@ +/* + * MIT License + * + * Copyright (c) 2020-present Cloudogu GmbH and Contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package sonia.scm.api.v2.resources; + +import org.junit.jupiter.api.Test; +import org.mapstruct.factory.Mappers; +import sonia.scm.ContextEntry; +import sonia.scm.ExceptionWithContext; + +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; + +class ExceptionWithContextToErrorDtoMapperTest { + + private final ExceptionWithContextToErrorDtoMapper mapper = Mappers.getMapper(ExceptionWithContextToErrorDtoMapper.class); + + @Test + void shouldMapUrl() { + ExceptionWithUrl exception = new ExceptionWithUrl(); + ErrorDto dto = mapper.map(exception); + assertThat(dto.getUrl()).isEqualTo("https://scm-manager.org"); + } + + @Test + void shouldMapUrlToNull() { + ExceptionWithoutUrl exception = new ExceptionWithoutUrl(); + ErrorDto dto = mapper.map(exception); + assertThat(dto.getUrl()).isNull(); + } + + private static class ExceptionWithUrl extends ExceptionWithContext { + public ExceptionWithUrl() { + super(ContextEntry.ContextBuilder.noContext(), "With Url"); + } + + @Override + public String getCode() { + return "42"; + } + + @Override + public Optional getUrl() { + return Optional.of("https://scm-manager.org"); + } + } + + private static class ExceptionWithoutUrl extends ExceptionWithContext { + public ExceptionWithoutUrl() { + super(ContextEntry.ContextBuilder.noContext(), "Without Url"); + } + + @Override + public String getCode() { + return "21"; + } + } + +} diff --git a/scm-webapp/src/test/java/sonia/scm/repository/RepositoryInitializerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/RepositoryInitializerTest.java index a8cd0986aa..ba97478bdc 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/RepositoryInitializerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/RepositoryInitializerTest.java @@ -46,6 +46,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.Collections; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; @@ -150,7 +151,8 @@ class RepositoryInitializerTest { doThrow(new IOException("epic fail")).when(contentLoader).withData(any(ByteSource.class)); RepositoryInitializer initializer = new RepositoryInitializer(repositoryServiceFactory, ImmutableSet.of(new ReadmeContentInitializer())); - assertThrows(InternalRepositoryException.class, () -> initializer.initialize(repository, Collections.emptyMap())); + Map creationContext = Collections.emptyMap(); + assertThrows(InternalRepositoryException.class, () -> initializer.initialize(repository, creationContext)); verify(repositoryService).close(); }