mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-17 04:52:10 +01:00
Fix unit test for import resource
This commit is contained in:
@@ -49,7 +49,6 @@ import sonia.scm.importexport.FullScmRepositoryImporter;
|
||||
import sonia.scm.importexport.RepositoryImportExportEncryption;
|
||||
import sonia.scm.importexport.RepositoryImportLoggerFactory;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.api.Command;
|
||||
import sonia.scm.repository.api.ImportFailedException;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
@@ -206,7 +205,6 @@ public class RepositoryImportResource {
|
||||
@Pattern(regexp = "\\w{1,10}") @PathParam("type") String type,
|
||||
MultipartFormDataInput input,
|
||||
@QueryParam("compressed") @DefaultValue("false") boolean compressed) {
|
||||
RepositoryPermissions.create().check();
|
||||
Repository repository = doImportFromBundle(type, input, compressed);
|
||||
|
||||
return Response.created(URI.create(resourceLinks.repository().self(repository.getNamespace(), repository.getName()))).build();
|
||||
@@ -256,7 +254,6 @@ public class RepositoryImportResource {
|
||||
public Response importFullRepository(@Context UriInfo uriInfo,
|
||||
@Pattern(regexp = "\\w{1,10}") @PathParam("type") String type,
|
||||
MultipartFormDataInput input) {
|
||||
RepositoryPermissions.create().check();
|
||||
Repository createdRepository = importFullRepositoryFromInput(input);
|
||||
return Response.created(URI.create(resourceLinks.repository().self(createdRepository.getNamespace(), createdRepository.getName()))).build();
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import sonia.scm.ContextEntry;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
import sonia.scm.repository.api.ImportFailedException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -74,6 +75,7 @@ public class FullScmRepositoryImporter {
|
||||
}
|
||||
|
||||
public Repository importFromStream(Repository repository, InputStream inputStream, String password) {
|
||||
RepositoryPermissions.create().check();
|
||||
RepositoryImportLogger logger = startLogger(repository);
|
||||
try {
|
||||
if (inputStream.available() > 0) {
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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 com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
class MultiPartRequestBuilder {
|
||||
|
||||
/**
|
||||
* This method is a slightly adapted copy of Lin Zaho's gist at https://gist.github.com/lin-zhao/9985191
|
||||
*/
|
||||
static void multipartRequest(MockHttpRequest request, Map<String, InputStream> files, RepositoryDto repository) throws IOException {
|
||||
String boundary = UUID.randomUUID().toString();
|
||||
request.contentType("multipart/form-data; boundary=" + boundary);
|
||||
|
||||
//Make sure this is deleted in afterTest()
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
try (OutputStreamWriter formWriter = new OutputStreamWriter(buffer)) {
|
||||
formWriter.append("--").append(boundary);
|
||||
|
||||
for (Map.Entry<String, InputStream> entry : files.entrySet()) {
|
||||
formWriter.append("\n");
|
||||
formWriter.append(String.format("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"",
|
||||
entry.getKey(), entry.getKey())).append("\n");
|
||||
formWriter.append("Content-Type: application/octet-stream").append("\n\n");
|
||||
|
||||
InputStream stream = entry.getValue();
|
||||
int b = stream.read();
|
||||
while (b >= 0) {
|
||||
formWriter.write(b);
|
||||
b = stream.read();
|
||||
}
|
||||
stream.close();
|
||||
formWriter.append("\n").append("--").append(boundary);
|
||||
}
|
||||
|
||||
if (repository != null) {
|
||||
formWriter.append("\n");
|
||||
formWriter.append("Content-Disposition: form-data; name=\"repository\"").append("\n\n");
|
||||
StringWriter repositoryWriter = new StringWriter();
|
||||
new JsonFactory().createGenerator(repositoryWriter).setCodec(new ObjectMapper()).writeObject(repository);
|
||||
formWriter.append(repositoryWriter.getBuffer().toString()).append("\n");
|
||||
formWriter.append("--").append(boundary);
|
||||
}
|
||||
|
||||
formWriter.append("--");
|
||||
formWriter.flush();
|
||||
}
|
||||
request.setInputStream(new ByteArrayInputStream(buffer.toByteArray()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,304 @@
|
||||
/*
|
||||
* 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 com.google.common.io.Resources;
|
||||
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||
import org.jboss.resteasy.mock.MockHttpResponse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.api.v2.resources.RepositoryImportResource.RepositoryImportFromFileDto;
|
||||
import sonia.scm.importexport.FromBundleImporter;
|
||||
import sonia.scm.importexport.FromUrlImporter;
|
||||
import sonia.scm.importexport.FullScmRepositoryImporter;
|
||||
import sonia.scm.importexport.RepositoryImportExportEncryption;
|
||||
import sonia.scm.importexport.RepositoryImportLoggerFactory;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryTestData;
|
||||
import sonia.scm.web.RestDispatcher;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_CREATED;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isNull;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RepositoryImportResourceTest extends RepositoryTestBase {
|
||||
|
||||
private final RestDispatcher dispatcher = new RestDispatcher();
|
||||
|
||||
@Mock
|
||||
private FullScmRepositoryImporter fullScmRepositoryImporter;
|
||||
@Mock
|
||||
private FromUrlImporter fromUrlImporter;
|
||||
@Mock
|
||||
private FromBundleImporter fromBundleImporter;
|
||||
@Mock
|
||||
private RepositoryImportLoggerFactory importLoggerFactory;
|
||||
@Mock
|
||||
private RepositoryImportExportEncryption repositoryImportExportEncryption;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<FromUrlImporter.RepositoryImportParameters> parametersCaptor;
|
||||
@Captor
|
||||
private ArgumentCaptor<Repository> repositoryCaptor;
|
||||
|
||||
private final URI baseUri = URI.create("/");
|
||||
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
|
||||
|
||||
@InjectMocks
|
||||
private RepositoryDtoToRepositoryMapperImpl dtoToRepositoryMapper;
|
||||
|
||||
private final MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
@Before
|
||||
public void prepareEnvironment() {
|
||||
super.repositoryImportResource = new RepositoryImportResource(dtoToRepositoryMapper, resourceLinks, fullScmRepositoryImporter, new RepositoryImportDtoToRepositoryImportParametersMapperImpl(), repositoryImportExportEncryption, fromUrlImporter, fromBundleImporter, importLoggerFactory);
|
||||
dispatcher.addSingletonResource(getRepositoryRootResource());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImportRepositoryFromUrl() throws Exception {
|
||||
when(fromUrlImporter.importFromUrl(parametersCaptor.capture(), repositoryCaptor.capture()))
|
||||
.thenReturn(RepositoryTestData.createHeartOfGold());
|
||||
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/import-repo.json");
|
||||
byte[] importRequest = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/git/url")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(importRequest);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(SC_CREATED);
|
||||
assertThat(response.getOutputHeaders().get("Location")).asString().contains("/v2/repositories/hitchhiker/HeartOfGold");
|
||||
|
||||
assertThat(parametersCaptor.getValue().getImportUrl()).isEqualTo("https://scm-manager-org/scm/repo/secret/puzzle42");
|
||||
assertThat(parametersCaptor.getValue().getUsername()).isNull();
|
||||
assertThat(parametersCaptor.getValue().getPassword()).isNull();
|
||||
|
||||
assertThat(repositoryCaptor.getValue().getName()).isEqualTo("HeartOfGold");
|
||||
assertThat(repositoryCaptor.getValue().getNamespace()).isEqualTo("hitchhiker");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImportRepositoryFromUrlWithCredentials() throws Exception {
|
||||
when(fromUrlImporter.importFromUrl(parametersCaptor.capture(), repositoryCaptor.capture()))
|
||||
.thenReturn(RepositoryTestData.createHeartOfGold());
|
||||
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/import-repo-with-credentials.json");
|
||||
byte[] importRequest = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/git/url")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(importRequest);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(SC_CREATED);
|
||||
|
||||
assertThat(parametersCaptor.getValue().getUsername()).isEqualTo("trillian");
|
||||
assertThat(parametersCaptor.getValue().getPassword()).isEqualTo("secret");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailOnImportFromUrlWithDifferentTypes() throws Exception {
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/import-repo.json");
|
||||
byte[] importRequest = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/svn/url")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(importRequest);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isNotEqualTo(SC_CREATED);
|
||||
|
||||
verify(fromUrlImporter, never()).importFromUrl(any(), any());
|
||||
}
|
||||
|
||||
@Nested
|
||||
class WithCorrectBundle {
|
||||
|
||||
@BeforeEach
|
||||
void mockImporter() {
|
||||
when(
|
||||
fromBundleImporter.importFromBundle(
|
||||
eq(false),
|
||||
argThat(argument -> streamHasContent(argument, "svn-dump")),
|
||||
argThat(repository -> repository.getName().equals("HeartOfGold"))
|
||||
)
|
||||
).thenReturn(RepositoryTestData.createHeartOfGold());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImportRepositoryFromBundle() throws Exception {
|
||||
RepositoryImportFromFileDto importDto = createBasicImportDto();
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/svn/bundle");
|
||||
|
||||
MultiPartRequestBuilder.multipartRequest(request, singletonMap("bundle", new ByteArrayInputStream("svn-dump".getBytes(UTF_8))), importDto);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(SC_CREATED);
|
||||
assertThat(response.getOutputHeaders().get("Location")).asString().contains("/v2/repositories/hitchhiker/HeartOfGold");
|
||||
verify(repositoryImportExportEncryption, never()).decrypt(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImportRepositoryFromEncryptedBundle() throws Exception {
|
||||
when(repositoryImportExportEncryption.decrypt(any(), eq("hgt2g")))
|
||||
.thenAnswer(invocation -> invocation.getArgument(0));
|
||||
|
||||
RepositoryImportFromFileDto importDto = createBasicImportDto();
|
||||
importDto.setPassword("hgt2g");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/svn/bundle");
|
||||
|
||||
MultiPartRequestBuilder.multipartRequest(request, singletonMap("bundle", new ByteArrayInputStream("svn-dump".getBytes(UTF_8))), importDto);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(SC_CREATED);
|
||||
assertThat(response.getOutputHeaders().get("Location")).asString().contains("/v2/repositories/hitchhiker/HeartOfGold");
|
||||
}
|
||||
|
||||
private RepositoryImportFromFileDto createBasicImportDto() {
|
||||
RepositoryImportFromFileDto importDto = new RepositoryImportFromFileDto();
|
||||
importDto.setName("HeartOfGold");
|
||||
importDto.setNamespace("hitchhiker");
|
||||
importDto.setType("svn");
|
||||
return importDto;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailOnImportFromBundleWithDifferentTypes() throws Exception {
|
||||
RepositoryDto repositoryDto = new RepositoryDto();
|
||||
repositoryDto.setName("HeartOfGold");
|
||||
repositoryDto.setNamespace("hitchhiker");
|
||||
repositoryDto.setType("svn");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/git/bundle");
|
||||
|
||||
MultiPartRequestBuilder.multipartRequest(request, Collections.singletonMap("bundle", new ByteArrayInputStream("svn-dump".getBytes(StandardCharsets.UTF_8))), repositoryDto);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isNotEqualTo(SC_CREATED);
|
||||
verify(fromBundleImporter, never()).importFromBundle(any(Boolean.class), any(InputStream.class), any(Repository.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImportFullRepository() throws Exception {
|
||||
when(
|
||||
fullScmRepositoryImporter.importFromStream(
|
||||
argThat(repository -> repository.getName().equals("HeartOfGold")),
|
||||
argThat(argument -> streamHasContent(argument, "svn-dump")),
|
||||
isNull()
|
||||
)
|
||||
).thenReturn(RepositoryTestData.createHeartOfGold());
|
||||
|
||||
RepositoryDto repositoryDto = new RepositoryDto();
|
||||
repositoryDto.setName("HeartOfGold");
|
||||
repositoryDto.setNamespace("hitchhiker");
|
||||
repositoryDto.setType("svn");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/svn/full");
|
||||
|
||||
MultiPartRequestBuilder.multipartRequest(request, singletonMap("bundle", new ByteArrayInputStream("svn-dump".getBytes(UTF_8))), repositoryDto);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(SC_CREATED);
|
||||
assertThat(response.getOutputHeaders().get("Location")).asString().contains("/v2/repositories/hitchhiker/HeartOfGold");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindImportLog() throws Exception {
|
||||
doAnswer(
|
||||
invocation -> {
|
||||
invocation.getArgument(1, OutputStream.class).write("some log".getBytes(UTF_8));
|
||||
return null;
|
||||
}
|
||||
).when(importLoggerFactory).getLog(eq("42"), any(OutputStream.class));
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/log/42");
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(SC_OK);
|
||||
assertThat(response.getContentAsString()).isEqualTo("some log");
|
||||
}
|
||||
|
||||
private boolean streamHasContent(InputStream argument, String expectedContent) {
|
||||
try {
|
||||
byte[] data = new byte[expectedContent.length()];
|
||||
argument.read(data);
|
||||
return new String(data).equals(expectedContent);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonFactory;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.github.sdorra.shiro.ShiroRule;
|
||||
import com.github.sdorra.shiro.SubjectAware;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
@@ -37,14 +35,15 @@ import org.jboss.resteasy.mock.MockHttpResponse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import sonia.scm.NotFoundException;
|
||||
import sonia.scm.PageResult;
|
||||
import sonia.scm.config.ScmConfiguration;
|
||||
import sonia.scm.event.ScmEventBus;
|
||||
import sonia.scm.importexport.ExportFileExtensionResolver;
|
||||
import sonia.scm.importexport.ExportService;
|
||||
import sonia.scm.importexport.ExportStatus;
|
||||
@@ -59,14 +58,11 @@ import sonia.scm.repository.NamespaceAndName;
|
||||
import sonia.scm.repository.NamespaceStrategy;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryHandler;
|
||||
import sonia.scm.repository.RepositoryImportEvent;
|
||||
import sonia.scm.repository.RepositoryInitializer;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.repository.RepositoryTestData;
|
||||
import sonia.scm.repository.RepositoryType;
|
||||
import sonia.scm.repository.api.BundleCommandBuilder;
|
||||
import sonia.scm.repository.api.Command;
|
||||
import sonia.scm.repository.api.ImportFailedException;
|
||||
import sonia.scm.repository.api.RepositoryService;
|
||||
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||
import sonia.scm.user.User;
|
||||
@@ -76,21 +72,14 @@ import sonia.scm.web.VndMediaType;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.time.Instant;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
@@ -98,7 +87,6 @@ import static java.util.stream.Stream.of;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_ACCEPTED;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_CONFLICT;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_CREATED;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
@@ -115,7 +103,6 @@ import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.openMocks;
|
||||
|
||||
@SubjectAware(
|
||||
username = "trillian",
|
||||
@@ -123,6 +110,7 @@ import static org.mockito.MockitoAnnotations.openMocks;
|
||||
configuration = "classpath:sonia/scm/repository/shiro.ini"
|
||||
)
|
||||
@SuppressWarnings("UnstableApiUsage")
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
|
||||
private static final String REALM = "AdminRealm";
|
||||
@@ -151,8 +139,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
@Mock
|
||||
private Set<NamespaceStrategy> strategies;
|
||||
@Mock
|
||||
private ScmEventBus eventBus;
|
||||
@Mock
|
||||
private FullScmRepositoryExporter fullScmRepositoryExporter;
|
||||
@Mock
|
||||
private RepositoryExportInformationToDtoMapper exportInformationToDtoMapper;
|
||||
@@ -182,9 +168,10 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
@InjectMocks
|
||||
private RepositoryDtoToRepositoryMapperImpl dtoToRepositoryMapper;
|
||||
|
||||
private final MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
@Before
|
||||
public void prepareEnvironment() throws IOException {
|
||||
openMocks(this);
|
||||
super.repositoryToDtoMapper = repositoryToDtoMapper;
|
||||
super.dtoToRepositoryMapper = dtoToRepositoryMapper;
|
||||
super.manager = repositoryManager;
|
||||
@@ -194,8 +181,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
super.repositoryExportResource = new RepositoryExportResource(repositoryManager, serviceFactory, fullScmRepositoryExporter, repositoryImportExportEncryption, exportService, exportInformationToDtoMapper, fileExtensionResolver, resourceLinks);
|
||||
dispatcher.addSingletonResource(getRepositoryRootResource());
|
||||
when(serviceFactory.create(any(Repository.class))).thenReturn(service);
|
||||
when(scmPathInfoStore.get()).thenReturn(uriInfo);
|
||||
when(uriInfo.getApiRestUri()).thenReturn(URI.create("/x/y"));
|
||||
doReturn(ImmutableSet.of(new CustomNamespaceStrategy()).iterator()).when(strategies).iterator();
|
||||
SimplePrincipalCollection trillian = new SimplePrincipalCollection("trillian", REALM);
|
||||
trillian.add(new User("trillian"), REALM);
|
||||
@@ -213,7 +198,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
createRepository("space", "repo");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/other");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -226,7 +210,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -241,7 +224,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -256,7 +238,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "?q=Rep");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -273,7 +254,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -290,7 +270,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space?q=Rep");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -310,7 +289,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repository);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -328,7 +306,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repository);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -347,7 +324,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repository);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -367,7 +343,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "wrong/repo")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repository);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -380,7 +355,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
createRepository("space", "repo");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.delete("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -403,7 +377,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2)
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repositoryJson);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -424,7 +397,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "?initialize=true")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repositoryJson);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -454,7 +426,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2)
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repositoryJson);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -473,7 +444,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(configuration.getNamespaceStrategy()).thenReturn("CustomNamespaceStrategy");
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -495,7 +465,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/rename")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repository);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -503,82 +472,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
verify(repositoryManager).rename(repository1, "space", "x");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldImportRepositoryFromUrl() throws URISyntaxException, IOException {
|
||||
ArgumentCaptor<RepositoryImportEvent> captor = ArgumentCaptor.forClass(RepositoryImportEvent.class);
|
||||
when(manager.getHandler("git")).thenReturn(repositoryHandler);
|
||||
when(repositoryHandler.getType()).thenReturn(new RepositoryType("git", "git", ImmutableSet.of(Command.PULL)));
|
||||
when(manager.create(any(Repository.class), any())).thenReturn(RepositoryTestData.create42Puzzle());
|
||||
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/import-repo.json");
|
||||
byte[] importRequest = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/git/url")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(importRequest);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(SC_CREATED, response.getStatus());
|
||||
verify(eventBus).post(captor.capture());
|
||||
|
||||
assertThat(captor.getValue().isFailed()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFailOnImportRepositoryFromUrl() throws URISyntaxException, IOException {
|
||||
ArgumentCaptor<RepositoryImportEvent> captor = ArgumentCaptor.forClass(RepositoryImportEvent.class);
|
||||
when(manager.getHandler("git")).thenReturn(repositoryHandler);
|
||||
when(repositoryHandler.getType()).thenReturn(new RepositoryType("git", "git", ImmutableSet.of(Command.PULL)));
|
||||
doThrow(ImportFailedException.class).when(manager).create(any(Repository.class), any());
|
||||
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/import-repo.json");
|
||||
byte[] importRequest = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/git/url")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(importRequest);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(500, response.getStatus());
|
||||
verify(eventBus).post(captor.capture());
|
||||
|
||||
assertThat(captor.getValue().isFailed()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldThrowFailedEventOnImportRepositoryFromBundle() throws IOException, URISyntaxException {
|
||||
when(manager.getHandler("svn")).thenReturn(repositoryHandler);
|
||||
when(repositoryHandler.getType()).thenReturn(new RepositoryType("svn", "svn", ImmutableSet.of(Command.UNBUNDLE)));
|
||||
doThrow(ImportFailedException.class).when(repositoryManager).create(any(), any());
|
||||
|
||||
RepositoryDto repositoryDto = new RepositoryDto();
|
||||
repositoryDto.setName("HeartOfGold");
|
||||
repositoryDto.setNamespace("hitchhiker");
|
||||
repositoryDto.setType("svn");
|
||||
|
||||
URL dumpUrl = Resources.getResource("sonia/scm/api/v2/svn.dump");
|
||||
byte[] svnDump = Resources.toByteArray(dumpUrl);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "import/svn/bundle");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
multipartRequest(request, Collections.singletonMap("bundle", new ByteArrayInputStream(svnDump)), repositoryDto);
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, response.getStatus());
|
||||
ArgumentCaptor<RepositoryImportEvent> event = ArgumentCaptor.forClass(RepositoryImportEvent.class);
|
||||
verify(eventBus).post(event.capture());
|
||||
assertTrue(event.getValue().isFailed());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMarkRepositoryAsArchived() throws Exception {
|
||||
String namespace = "space";
|
||||
@@ -589,7 +482,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/archive")
|
||||
.content(new byte[]{});
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -608,7 +500,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.post("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/unarchive")
|
||||
.content(new byte[]{});
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -630,7 +521,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/export/svn");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -653,7 +543,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/export/svn?compressed=true");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -670,12 +559,8 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(manager.get(new NamespaceAndName(namespace, name))).thenReturn(repository);
|
||||
mockRepositoryHandler(ImmutableSet.of(Command.BUNDLE));
|
||||
|
||||
BundleCommandBuilder bundleCommandBuilder = mock(BundleCommandBuilder.class);
|
||||
when(service.getBundleCommand()).thenReturn(bundleCommandBuilder);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/export/full");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
@@ -891,7 +776,6 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(repositoryType.getSupportedCommands()).thenReturn(cmds);
|
||||
}
|
||||
|
||||
|
||||
private PageResult<Repository> createSingletonPageResult(Repository repository) {
|
||||
return new PageResult<>(singletonList(repository), 0);
|
||||
}
|
||||
@@ -919,48 +803,4 @@ public class RepositoryRootResourceTest extends RepositoryTestBase {
|
||||
when(repositoryManager.get(id)).thenReturn(repository);
|
||||
return repository;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is a slightly adapted copy of Lin Zaho's gist at https://gist.github.com/lin-zhao/9985191
|
||||
*/
|
||||
private void multipartRequest(MockHttpRequest request, Map<String, InputStream> files, RepositoryDto repository) throws IOException {
|
||||
String boundary = UUID.randomUUID().toString();
|
||||
request.contentType("multipart/form-data; boundary=" + boundary);
|
||||
|
||||
//Make sure this is deleted in afterTest()
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||
try (OutputStreamWriter formWriter = new OutputStreamWriter(buffer)) {
|
||||
formWriter.append("--").append(boundary);
|
||||
|
||||
for (Map.Entry<String, InputStream> entry : files.entrySet()) {
|
||||
formWriter.append("\n");
|
||||
formWriter.append(String.format("Content-Disposition: form-data; name=\"%s\"; filename=\"%s\"",
|
||||
entry.getKey(), entry.getKey())).append("\n");
|
||||
formWriter.append("Content-Type: application/octet-stream").append("\n\n");
|
||||
|
||||
InputStream stream = entry.getValue();
|
||||
int b = stream.read();
|
||||
while (b >= 0) {
|
||||
formWriter.write(b);
|
||||
b = stream.read();
|
||||
}
|
||||
stream.close();
|
||||
formWriter.append("\n").append("--").append(boundary);
|
||||
}
|
||||
|
||||
if (repository != null) {
|
||||
formWriter.append("\n");
|
||||
formWriter.append("Content-Disposition: form-data; name=\"repository\"").append("\n\n");
|
||||
StringWriter repositoryWriter = new StringWriter();
|
||||
new JsonFactory().createGenerator(repositoryWriter).setCodec(new ObjectMapper()).writeObject(repository);
|
||||
formWriter.append(repositoryWriter.getBuffer().toString()).append("\n");
|
||||
formWriter.append("--").append(boundary);
|
||||
}
|
||||
|
||||
formWriter.append("--");
|
||||
formWriter.flush();
|
||||
}
|
||||
request.setInputStream(new ByteArrayInputStream(buffer.toByteArray()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
package sonia.scm.importexport;
|
||||
|
||||
import com.google.common.io.Resources;
|
||||
import org.apache.shiro.authz.AuthorizationException;
|
||||
import org.apache.shiro.subject.Subject;
|
||||
import org.apache.shiro.util.ThreadContext;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -64,6 +67,7 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -98,6 +102,8 @@ class FullScmRepositoryImporterTest {
|
||||
private RepositoryImportLogger logger;
|
||||
@Mock
|
||||
private RepositoryImportLoggerFactory loggerFactory;
|
||||
@Mock
|
||||
private Subject subject;
|
||||
|
||||
@InjectMocks
|
||||
private EnvironmentCheckStep environmentCheckStep;
|
||||
@@ -140,6 +146,16 @@ class FullScmRepositoryImporterTest {
|
||||
lenient().when(loggerFactory.createLogger()).thenReturn(logger);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void initSubject() {
|
||||
ThreadContext.bind(subject);
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
void cleanupSubject() {
|
||||
ThreadContext.unbindSubject();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotImportRepositoryIfFileNotExists(@TempDir Path temp) throws IOException {
|
||||
Path emptyFile = temp.resolve("empty");
|
||||
@@ -162,6 +178,18 @@ class FullScmRepositoryImporterTest {
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotImportRepositoryWithoutPermission() throws IOException {
|
||||
doThrow(AuthorizationException.class).when(subject).checkPermission("repository:create");
|
||||
|
||||
InputStream stream = Resources.getResource("sonia/scm/repository/import/scm-import.tar.gz").openStream();
|
||||
|
||||
assertThrows(AuthorizationException.class, () -> fullImporter.importFromStream(REPOSITORY, stream, null));
|
||||
|
||||
verify(storeImporter, never()).importFromTarArchive(any(Repository.class), any(InputStream.class), any(RepositoryImportLogger.class));
|
||||
verify(repositoryManager, never()).modify(any());
|
||||
}
|
||||
|
||||
@Nested
|
||||
class WithValidEnvironment {
|
||||
|
||||
@@ -214,6 +242,7 @@ class FullScmRepositoryImporterTest {
|
||||
|
||||
assertThat(repository).isEqualTo(REPOSITORY);
|
||||
verify(storeImporter).importFromTarArchive(eq(REPOSITORY), any(InputStream.class), eq(logger));
|
||||
verify(repositoryManager).create(REPOSITORY);
|
||||
verify(repositoryManager).modify(REPOSITORY);
|
||||
verify(unbundleCommandBuilder).unbundle((InputStream) argThat(argument -> argument.getClass().equals(NoneClosingInputStream.class)));
|
||||
verify(workdirProvider, never()).createNewWorkdir(REPOSITORY.getId());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{
|
||||
"namespace": "hitchhiker",
|
||||
"name": "HeartOfGold",
|
||||
"type": "git",
|
||||
"importUrl": "https://scm-manager-org/scm/repo/secret/puzzle42",
|
||||
"username": "trillian",
|
||||
"password": "secret"
|
||||
|
||||
Reference in New Issue
Block a user