mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-07-08 14:31:52 +02:00
Merge pull request #1324 from scm-manager/feature/template_plugin
Feature/template plugin
This commit is contained in:
@@ -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<String> 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";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -74,6 +74,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyMap;
|
||||
import static org.mockito.ArgumentMatchers.anyObject;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
@@ -315,7 +316,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
assertEquals(HttpServletResponse.SC_CREATED, response.getStatus());
|
||||
assertEquals("/v2/repositories/otherspace/repo", response.getOutputHeaders().get("Location").get(0).toString());
|
||||
verify(repositoryManager).create(any(Repository.class));
|
||||
verify(repositoryInitializer, never()).initialize(any(Repository.class));
|
||||
verify(repositoryInitializer, never()).initialize(any(Repository.class), anyMap());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -336,7 +337,7 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
assertEquals(HttpServletResponse.SC_CREATED, response.getStatus());
|
||||
|
||||
ArgumentCaptor<Repository> captor = ArgumentCaptor.forClass(Repository.class);
|
||||
verify(repositoryInitializer).initialize(captor.capture());
|
||||
verify(repositoryInitializer).initialize(captor.capture(), anyMap());
|
||||
|
||||
Repository repository = captor.getValue();
|
||||
assertEquals("space", repository.getNamespace());
|
||||
|
||||
@@ -48,7 +48,7 @@ class ReadmeRepositoryContentInitializerTest {
|
||||
|
||||
private Repository repository;
|
||||
|
||||
private ReadmeRepositoryContentInitializer initializer = new ReadmeRepositoryContentInitializer();
|
||||
private final ReadmeRepositoryContentInitializer initializer = new ReadmeRepositoryContentInitializer();
|
||||
|
||||
@BeforeEach
|
||||
void setUpContext() {
|
||||
|
||||
@@ -21,15 +21,16 @@
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
package sonia.scm.repository;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.io.ByteSource;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestTemplate;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -44,6 +45,9 @@ import java.io.ByteArrayInputStream;
|
||||
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;
|
||||
|
||||
@@ -51,15 +55,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class RepositoryInitializerTest {
|
||||
|
||||
private final ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
@Mock
|
||||
private RepositoryServiceFactory repositoryServiceFactory;
|
||||
|
||||
@@ -88,7 +90,7 @@ class RepositoryInitializerTest {
|
||||
);
|
||||
|
||||
RepositoryInitializer initializer = new RepositoryInitializer(repositoryServiceFactory, repositoryContentInitializers);
|
||||
initializer.initialize(repository);
|
||||
initializer.initialize(repository, Collections.emptyMap());
|
||||
|
||||
verifyFileCreation(readmeContentLoader, "# HeartOfGold");
|
||||
verifyFileCreation(licenseContentLoader, "MIT");
|
||||
@@ -108,7 +110,7 @@ class RepositoryInitializerTest {
|
||||
);
|
||||
|
||||
RepositoryInitializer initializer = new RepositoryInitializer(repositoryServiceFactory, repositoryContentInitializers);
|
||||
initializer.initialize(repository);
|
||||
initializer.initialize(repository, Collections.emptyMap());
|
||||
|
||||
verifyFileCreationWithStream(contentLoader, "awesome");
|
||||
|
||||
@@ -138,7 +140,7 @@ class RepositoryInitializerTest {
|
||||
);
|
||||
|
||||
RepositoryInitializer initializer = new RepositoryInitializer(repositoryServiceFactory, repositoryContentInitializers);
|
||||
initializer.initialize(repository);
|
||||
initializer.initialize(repository, Collections.emptyMap());
|
||||
|
||||
assertThat(reference.get()).isEqualTo("MIT");
|
||||
}
|
||||
@@ -149,7 +151,45 @@ 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));
|
||||
Map<String, JsonNode> contextEntries = Collections.emptyMap();
|
||||
assertThrows(InternalRepositoryException.class, () -> initializer.initialize(repository, contextEntries));
|
||||
|
||||
verify(repositoryService).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCallRepositoryContentInitializerWithContext() throws IOException {
|
||||
ModifyCommandBuilder.WithOverwriteFlagContentLoader slartiContentLoader = mockContentLoader("Slarti.md");
|
||||
|
||||
Set<RepositoryContentInitializer> repositoryContentInitializers = ImmutableSet.of(
|
||||
new NamedFileInitializer()
|
||||
);
|
||||
|
||||
RepositoryInitializer initializer = new RepositoryInitializer(repositoryServiceFactory, repositoryContentInitializers);
|
||||
Named named = new Named();
|
||||
named.setName("Slarti");
|
||||
initializer.initialize(repository, Collections.singletonMap("named", mapper.valueToTree(named)));
|
||||
|
||||
verifyFileCreation(slartiContentLoader, "# Named file");
|
||||
|
||||
verify(modifyCommand).setCommitMessage("initialize repository");
|
||||
verify(modifyCommand).execute();
|
||||
|
||||
verify(repositoryService).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDoNoInitializationWithoutContextType() {
|
||||
Set<RepositoryContentInitializer> repositoryContentInitializers = ImmutableSet.of(
|
||||
new NamedFileInitializer()
|
||||
);
|
||||
|
||||
RepositoryInitializer initializer = new RepositoryInitializer(repositoryServiceFactory, repositoryContentInitializers);
|
||||
initializer.initialize(repository, Collections.emptyMap());
|
||||
|
||||
verify(modifyCommand, never()).createFile(any());
|
||||
verify(modifyCommand).setCommitMessage("initialize repository");
|
||||
verify(modifyCommand).execute();
|
||||
|
||||
verify(repositoryService).close();
|
||||
}
|
||||
@@ -175,6 +215,29 @@ class RepositoryInitializerTest {
|
||||
assertThat(new String(bytes, StandardCharsets.UTF_8)).isEqualTo(expectedContent);
|
||||
}
|
||||
|
||||
private static class NamedFileInitializer implements RepositoryContentInitializer {
|
||||
|
||||
@Override
|
||||
public void initialize(InitializerContext context) throws IOException {
|
||||
Optional<Named> named = context.getEntry("named", Named.class);
|
||||
if (named.isPresent()) {
|
||||
context.create(named.get().getName() + ".md").from("# Named file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class Named {
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
@Priority(1)
|
||||
private static class ReadmeContentInitializer implements RepositoryContentInitializer {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user