diff --git a/Jenkinsfile b/Jenkinsfile
index aa6cd6b33b..6694b2eb7c 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -34,6 +34,10 @@ node() { // No specific label
mvn 'test -Dsonia.scm.test.skip.hg=true -Dmaven.test.failure.ignore=true'
}
+ stage('Integration Test') {
+ mvn 'verify -Pit -pl :scm-webapp,:scm-it -Dmaven.test.failure.ignore=true'
+ }
+
stage('SonarQube') {
analyzeWith(mvn)
diff --git a/pom.xml b/pom.xml
index af38d5175a..788abaca36 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,6 +73,7 @@
scm-ui
scm-webapp
scm-server
+ scm-it
diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryIsNotArchivedException.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryIsNotArchivedException.java
index 775e4714d8..3742512622 100644
--- a/scm-core/src/main/java/sonia/scm/repository/RepositoryIsNotArchivedException.java
+++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryIsNotArchivedException.java
@@ -38,51 +38,11 @@ package sonia.scm.repository;
*
* @since 1.14
*/
-public class RepositoryIsNotArchivedException extends RepositoryException
-{
+public class RepositoryIsNotArchivedException extends RepositoryException {
- /** Field description */
private static final long serialVersionUID = 7728748133123987511L;
- //~--- constructors ---------------------------------------------------------
-
- /**
- * Constructs ...
- *
- */
- public RepositoryIsNotArchivedException() {}
-
- /**
- * Constructs ...
- *
- *
- * @param message
- */
- public RepositoryIsNotArchivedException(String message)
- {
- super(message);
- }
-
- /**
- * Constructs ...
- *
- *
- * @param cause
- */
- public RepositoryIsNotArchivedException(Throwable cause)
- {
- super(cause);
- }
-
- /**
- * Constructs ...
- *
- *
- * @param message
- * @param cause
- */
- public RepositoryIsNotArchivedException(String message, Throwable cause)
- {
- super(message, cause);
+ public RepositoryIsNotArchivedException() {
+ super("Repository could not be deleted, because it is not archived.");
}
}
diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java
index 493d8f6dbb..172108aa1b 100644
--- a/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java
+++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryManager.java
@@ -41,7 +41,6 @@ import sonia.scm.TypeManager;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Collection;
-import java.util.Optional;
//~--- JDK imports ------------------------------------------------------------
@@ -135,11 +134,4 @@ public interface RepositoryManager
*/
@Override
public RepositoryHandler getHandler(String type);
-
- default Optional getByNamespace(String namespace, String name) {
- return getAll()
- .stream()
- .filter(r -> r.getName().equals(name) && r.getNamespace().equals(namespace))
- .findFirst();
- }
}
diff --git a/scm-it/pom.xml b/scm-it/pom.xml
new file mode 100644
index 0000000000..251fe4d957
--- /dev/null
+++ b/scm-it/pom.xml
@@ -0,0 +1,240 @@
+
+
+
+ 4.0.0
+
+
+ sonia.scm
+ scm
+ 2.0.0-SNAPSHOT
+
+
+ sonia.scm
+ scm-it
+ jar
+ 2.0.0-SNAPSHOT
+ scm-it
+
+
+
+ sonia.scm
+ scm-core
+ 2.0.0-SNAPSHOT
+
+
+
+ sonia.scm
+ scm-test
+ 2.0.0-SNAPSHOT
+
+
+
+ sonia.scm.plugins
+ scm-git-plugin
+ 2.0.0-SNAPSHOT
+ test
+
+
+
+ sonia.scm.plugins
+ scm-git-plugin
+ 2.0.0-SNAPSHOT
+ tests
+ test
+
+
+
+ sonia.scm.plugins
+ scm-hg-plugin
+ 2.0.0-SNAPSHOT
+ test
+
+
+
+ sonia.scm.plugins
+ scm-hg-plugin
+ 2.0.0-SNAPSHOT
+ tests
+ test
+
+
+
+ sonia.scm.plugins
+ scm-svn-plugin
+ 2.0.0-SNAPSHOT
+ test
+
+
+
+ sonia.scm.plugins
+ scm-svn-plugin
+ 2.0.0-SNAPSHOT
+ tests
+ test
+
+
+
+ io.rest-assured
+ rest-assured
+ 3.1.0
+ test
+
+
+
+ javax
+ javaee-api
+ 7.0
+ test
+
+
+
+ org.glassfish
+ javax.json
+ 1.0.4
+ runtime
+
+
+
+
+
+
+
+ com.mycila.maven-license-plugin
+ maven-license-plugin
+ 1.9.0
+
+ http://download.scm-manager.org/licenses/mvn-license.txt
+
+ src/**
+ **/test/**
+
+
+ target/**
+ .hg/**
+
+ true
+
+
+
+
+
+
+
+
+ it
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+ 2.12
+
+
+ sonia/scm/it/*ITCase.java
+
+
+
+
+ integration-test
+
+ integration-test
+
+
+
+ verify
+
+ verify
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 2.10
+
+
+
+ sonia.scm
+ scm-webapp
+ ${project.version}
+ war
+ ${project.build.outputDirectory}
+ scm-webapp.war
+
+
+
+
+
+ copy-war
+ pre-integration-test
+
+ copy
+
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-maven-plugin
+ ${jetty.maven.version}
+
+ 8085
+ STOP
+
+
+ scm.home
+ ${scm.home}
+
+
+ scm.stage
+ ${scm.stage}
+
+
+ java.awt.headless
+ true
+
+
+
+ /scm
+
+ ${project.basedir}/src/main/conf/jetty.xml
+ ${project.build.outputDirectory}/scm-webapp.war
+ 0
+ true
+
+
+
+ start-jetty
+ pre-integration-test
+
+ deploy-war
+
+
+
+ stop-jetty
+ post-integration-test
+
+ stop
+
+
+
+
+
+
+
+
+
+ DEVELOPMENT
+ target/scm-it
+
+
+
+
+
+
+
diff --git a/scm-it/src/main/conf/jetty.xml b/scm-it/src/main/conf/jetty.xml
new file mode 100644
index 0000000000..ec7ac555c8
--- /dev/null
+++ b/scm-it/src/main/conf/jetty.xml
@@ -0,0 +1,72 @@
+
+
+
+
+
+
+
+
+ 16384
+ 16384
+
+
+
+
+
+
+
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/scm-it/src/test/java/sonia/scm/it/RegExMatcher.java b/scm-it/src/test/java/sonia/scm/it/RegExMatcher.java
new file mode 100644
index 0000000000..e5dc7931d3
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/RegExMatcher.java
@@ -0,0 +1,29 @@
+package sonia.scm.it;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+
+import java.util.regex.Pattern;
+
+class RegExMatcher extends BaseMatcher {
+ public static Matcher matchesPattern(String pattern) {
+ return new RegExMatcher(pattern);
+ }
+
+ private final String pattern;
+
+ private RegExMatcher(String pattern) {
+ this.pattern = pattern;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("matching to regex pattern \"" + pattern + "\"");
+ }
+
+ @Override
+ public boolean matches(Object o) {
+ return Pattern.compile(pattern).matcher(o.toString()).matches();
+ }
+}
diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoriesITCase.java b/scm-it/src/test/java/sonia/scm/it/RepositoriesITCase.java
new file mode 100644
index 0000000000..cd791cb013
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/RepositoriesITCase.java
@@ -0,0 +1,198 @@
+/**
+ * Copyright (c) 2010, Sebastian Sdorra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of SCM-Manager; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://bitbucket.org/sdorra/scm-manager
+ */
+
+
+package sonia.scm.it;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import org.apache.http.HttpStatus;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import sonia.scm.repository.Person;
+import sonia.scm.repository.client.api.ClientCommand;
+import sonia.scm.repository.client.api.RepositoryClient;
+import sonia.scm.repository.client.api.RepositoryClientFactory;
+import sonia.scm.web.VndMediaType;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.UUID;
+
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertEquals;
+import static sonia.scm.it.RegExMatcher.matchesPattern;
+import static sonia.scm.it.RestUtil.createResourceUrl;
+import static sonia.scm.it.RestUtil.given;
+import static sonia.scm.it.ScmTypes.availableScmTypes;
+import static sonia.scm.it.TestData.repositoryJson;
+
+@RunWith(Parameterized.class)
+public class RepositoriesITCase {
+
+ public static final Person AUTHOR = new Person("SCM Administrator", "scmadmin@scm-manager.org");
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ private final String repositoryType;
+
+ private String repositoryUrl;
+
+ public RepositoriesITCase(String repositoryType) {
+ this.repositoryType = repositoryType;
+ this.repositoryUrl = TestData.getDefaultRepositoryUrl(repositoryType);
+ }
+
+ @Parameters(name = "{0}")
+ public static Collection createParameters() {
+ return availableScmTypes();
+ }
+
+ @Before
+ public void createRepository() {
+ TestData.createDefault();
+ }
+
+ @Test
+ public void shouldCreateSuccessfully() {
+ given(VndMediaType.REPOSITORY)
+
+ .when()
+ .get(repositoryUrl)
+
+ .then()
+ .statusCode(HttpStatus.SC_OK)
+ .body(
+ "name", equalTo("HeartOfGold-" + repositoryType),
+ "type", equalTo(repositoryType),
+ "creationDate", matchesPattern("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d+Z"),
+ "lastModified", is(nullValue()),
+ "_links.self.href", equalTo(repositoryUrl)
+ );
+ }
+
+ @Test
+ public void shouldDeleteSuccessfully() {
+ given(VndMediaType.REPOSITORY)
+
+ .when()
+ .delete(repositoryUrl)
+
+ .then()
+ .statusCode(HttpStatus.SC_NO_CONTENT);
+
+ given(VndMediaType.REPOSITORY)
+
+ .when()
+ .get(repositoryUrl)
+
+ .then()
+ .statusCode(HttpStatus.SC_NOT_FOUND);
+ }
+
+ @Test
+ public void shouldRejectMultipleCreations() {
+ String repositoryJson = repositoryJson(repositoryType);
+ given(VndMediaType.REPOSITORY)
+ .body(repositoryJson)
+
+ .when()
+ .post(createResourceUrl("repositories"))
+
+ .then()
+ .statusCode(HttpStatus.SC_CONFLICT);
+ }
+
+ @Test
+ public void shouldCloneRepository() throws IOException {
+ RepositoryClient client = createRepositoryClient();
+ assertEquals("expected metadata dir", 1, client.getWorkingCopy().list().length);
+ }
+
+ @Test
+ public void shouldCommitFiles() throws IOException {
+ RepositoryClient client = createRepositoryClient();
+
+ for (int i = 0; i < 5; i++) {
+ createRandomFile(client);
+ }
+
+ commit(client);
+
+ RepositoryClient checkClient = createRepositoryClient();
+ assertEquals("expected 5 files and metadata dir", 6, checkClient.getWorkingCopy().list().length);
+ }
+
+ private static void createRandomFile(RepositoryClient client) throws IOException {
+ String uuid = UUID.randomUUID().toString();
+ String name = "file-" + uuid + ".uuid";
+
+ File file = new File(client.getWorkingCopy(), name);
+ try (FileOutputStream out = new FileOutputStream(file)) {
+ out.write(uuid.getBytes());
+ }
+
+ client.getAddCommand().add(name);
+ }
+
+ private static void commit(RepositoryClient repositoryClient) throws IOException {
+ repositoryClient.getCommitCommand().commit(AUTHOR, "commit");
+ if ( repositoryClient.isCommandSupported(ClientCommand.PUSH) ) {
+ repositoryClient.getPushCommand().push();
+ }
+ }
+
+ private RepositoryClient createRepositoryClient() throws IOException {
+ RepositoryClientFactory clientFactory = new RepositoryClientFactory();
+ String cloneUrl = readCloneUrl();
+ return clientFactory.create(repositoryType, cloneUrl, "scmadmin", "scmadmin", temporaryFolder.newFolder());
+ }
+
+ private String readCloneUrl() {
+ return given(VndMediaType.REPOSITORY)
+
+ .when()
+ .get(repositoryUrl)
+
+ .then()
+ .extract()
+ .path("_links.httpProtocol.href");
+ }
+}
diff --git a/scm-it/src/test/java/sonia/scm/it/RestUtil.java b/scm-it/src/test/java/sonia/scm/it/RestUtil.java
new file mode 100644
index 0000000000..1458ab6d0b
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/RestUtil.java
@@ -0,0 +1,25 @@
+package sonia.scm.it;
+
+import io.restassured.RestAssured;
+import io.restassured.specification.RequestSpecification;
+
+import java.net.URI;
+
+import static java.net.URI.create;
+
+public class RestUtil {
+
+ public static final URI BASE_URL = create("http://localhost:8081/scm/");
+ public static final URI REST_BASE_URL = BASE_URL.resolve("api/rest/v2/");
+
+ public static URI createResourceUrl(String path) {
+ return REST_BASE_URL.resolve(path);
+ }
+
+ public static RequestSpecification given(String mediaType) {
+ return RestAssured.given()
+ .contentType(mediaType)
+ .accept(mediaType)
+ .auth().preemptive().basic("scmadmin", "scmadmin");
+ }
+}
diff --git a/scm-it/src/test/java/sonia/scm/it/ScmTypes.java b/scm-it/src/test/java/sonia/scm/it/ScmTypes.java
new file mode 100644
index 0000000000..e8ba67e561
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/ScmTypes.java
@@ -0,0 +1,21 @@
+package sonia.scm.it;
+
+import sonia.scm.util.IOUtil;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+class ScmTypes {
+ static Collection availableScmTypes() {
+ Collection params = new ArrayList<>();
+
+ params.add("git");
+ params.add("svn");
+
+ if (IOUtil.search("hg") != null) {
+ params.add("hg");
+ }
+
+ return params;
+ }
+}
diff --git a/scm-it/src/test/java/sonia/scm/it/TestData.java b/scm-it/src/test/java/sonia/scm/it/TestData.java
new file mode 100644
index 0000000000..b2785b2051
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/TestData.java
@@ -0,0 +1,116 @@
+package sonia.scm.it;
+
+import org.apache.http.HttpStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sonia.scm.web.VndMediaType;
+
+import javax.json.Json;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static java.util.Arrays.asList;
+import static sonia.scm.it.RestUtil.createResourceUrl;
+import static sonia.scm.it.RestUtil.given;
+import static sonia.scm.it.ScmTypes.availableScmTypes;
+
+public class TestData {
+
+ private static final Logger LOG = LoggerFactory.getLogger(TestData.class);
+
+ private static final List PROTECTED_USERS = asList("scmadmin", "anonymous");
+
+ private static Map DEFAULT_REPOSITORIES = new HashMap<>();
+
+ public static void createDefault() {
+ cleanup();
+ createDefaultRepositories();
+ }
+
+ public static void cleanup() {
+ cleanupRepositories();
+ cleanupGroups();
+ cleanupUsers();
+ }
+
+ public static String getDefaultRepositoryUrl(String repositoryType) {
+ return DEFAULT_REPOSITORIES.get(repositoryType);
+ }
+
+ private static void cleanupRepositories() {
+ List repositories = given(VndMediaType.REPOSITORY_COLLECTION)
+ .when()
+ .get(createResourceUrl("repositories"))
+ .then()
+ .statusCode(HttpStatus.SC_OK)
+ .extract()
+ .body().jsonPath().getList("_embedded.repositories._links.self.href");
+ LOG.info("about to delete {} repositories", repositories.size());
+ repositories.forEach(TestData::delete);
+ DEFAULT_REPOSITORIES.clear();
+ }
+
+ private static void cleanupGroups() {
+ List groups = given(VndMediaType.GROUP_COLLECTION)
+ .when()
+ .get(createResourceUrl("groups"))
+ .then()
+ .statusCode(HttpStatus.SC_OK)
+ .extract()
+ .body().jsonPath().getList("_embedded.groups._links.self.href");
+ LOG.info("about to delete {} groups", groups.size());
+ groups.forEach(TestData::delete);
+ }
+
+ private static void cleanupUsers() {
+ List users = given(VndMediaType.USER_COLLECTION)
+ .when()
+ .get(createResourceUrl("users"))
+ .then()
+ .statusCode(HttpStatus.SC_OK)
+ .extract()
+ .body().jsonPath().getList("_embedded.users._links.self.href");
+ LOG.info("about to delete {} users", users.size());
+ users.stream().filter(url -> PROTECTED_USERS.stream().noneMatch(url::contains)).forEach(TestData::delete);
+ }
+
+ private static void delete(String url) {
+ given(VndMediaType.REPOSITORY)
+ .when()
+ .delete(url)
+ .then()
+ .statusCode(HttpStatus.SC_NO_CONTENT);
+ LOG.info("deleted {}", url);
+ }
+
+ private static void createDefaultRepositories() {
+ for (String repositoryType : availableScmTypes()) {
+ String url = given(VndMediaType.REPOSITORY)
+ .body(repositoryJson(repositoryType))
+
+ .when()
+ .post(createResourceUrl("repositories"))
+
+ .then()
+ .statusCode(HttpStatus.SC_CREATED)
+ .extract()
+ .header("location");
+ DEFAULT_REPOSITORIES.put(repositoryType, url);
+ }
+ }
+
+ public static String repositoryJson(String repositoryType) {
+ return Json.createObjectBuilder()
+ .add("contact", "zaphod.beeblebrox@hitchhiker.com")
+ .add("description", "Heart of Gold")
+ .add("name", "HeartOfGold-" + repositoryType)
+ .add("archived", false)
+ .add("type", repositoryType)
+ .build().toString();
+ }
+
+ public static void main(String[] args) {
+ cleanup();
+ }
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java
index 255f08f295..2c227f78f2 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryResource.java
@@ -3,6 +3,7 @@ package sonia.scm.api.v2.resources;
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint;
+import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryException;
import sonia.scm.repository.RepositoryIsNotArchivedException;
@@ -164,7 +165,7 @@ public class RepositoryResource {
}
private Supplier> loadBy(String namespace, String name) {
- return () -> manager.getByNamespace(namespace, name);
+ return () -> Optional.ofNullable(manager.get(new NamespaceAndName(namespace, name)));
}
private Predicate nameAndNamespaceStaysTheSame(String namespace, String name) {
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
index 2f13723d39..cb89f0ea63 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
@@ -25,6 +25,7 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper getAll(@PathParam("repository") String repository){
- return debugService.getAll(repository);
+ public Collection getAll(@PathParam("namespace") String namespace, @PathParam("name") String name){
+ return debugService.getAll(new NamespaceAndName(namespace, name));
}
/**
* Returns the last received hook data for the given repository.
- *
- * @param repository repository id
+ *
+ * @param namespace repository namespace
+ * @param name repository name
*
* @return the last received hook data for the given repository
*/
@GET
@Path("last")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
- public DebugHookData getLast(@PathParam("repository") String repository){
- return debugService.getLast(repository);
+ public DebugHookData getLast(@PathParam("namespace") String namespace, @PathParam("name") String name){
+ return debugService.getLast(new NamespaceAndName(namespace, name));
}
}
diff --git a/scm-webapp/src/main/java/sonia/scm/debug/DebugService.java b/scm-webapp/src/main/java/sonia/scm/debug/DebugService.java
index 31282b6b08..8e2475d802 100644
--- a/scm-webapp/src/main/java/sonia/scm/debug/DebugService.java
+++ b/scm-webapp/src/main/java/sonia/scm/debug/DebugService.java
@@ -34,10 +34,12 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import com.google.inject.Singleton;
-import java.util.Collection;
import org.apache.shiro.SecurityUtils;
+import sonia.scm.repository.NamespaceAndName;
import sonia.scm.security.Role;
+import java.util.Collection;
+
/**
* The DebugService stores and returns received data from repository hook events.
*
@@ -47,30 +49,23 @@ import sonia.scm.security.Role;
public final class DebugService
{
- private final Multimap receivedHooks = LinkedListMultimap.create();
+ private final Multimap receivedHooks = LinkedListMultimap.create();
/**
* Stores {@link DebugHookData} for the given repository.
- *
- * @param repository repository id
- * @param hookData received hook data
*/
- void put(String repository, DebugHookData hookData)
+ void put(NamespaceAndName namespaceAndName, DebugHookData hookData)
{
- receivedHooks.put(repository, hookData);
+ receivedHooks.put(namespaceAndName, hookData);
}
/**
* Returns the last received hook data for the given repository.
- *
- * @param repository repository id
- *
- * @return the last received hook data for the given repository
*/
- public DebugHookData getLast(String repository){
+ public DebugHookData getLast(NamespaceAndName namespaceAndName){
SecurityUtils.getSubject().checkRole(Role.ADMIN);
DebugHookData hookData = null;
- Collection receivedHookData = receivedHooks.get(repository);
+ Collection receivedHookData = receivedHooks.get(namespaceAndName);
if (receivedHookData != null && ! receivedHookData.isEmpty()){
hookData = Iterables.getLast(receivedHookData);
}
@@ -79,14 +74,9 @@ public final class DebugService
/**
* Returns all received hook data for the given repository.
- *
- * @param repository repository id
- *
- * @return all received hook data for the given repository
*/
- public Collection getAll(String repository){
+ public Collection getAll(NamespaceAndName namespaceAndName){
SecurityUtils.getSubject().checkRole(Role.ADMIN);
- return receivedHooks.get(repository);
+ return receivedHooks.get(namespaceAndName);
}
-
}
diff --git a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java
index 69e969f9cb..e380979d3c 100644
--- a/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java
+++ b/scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java
@@ -172,7 +172,7 @@ public class DefaultRepositoryManager extends AbstractRepositoryManager {
private void preDelete(Repository toDelete) throws RepositoryException {
if (configuration.isEnableRepositoryArchive() && !toDelete.isArchived()) {
- throw new RepositoryIsNotArchivedException("Repository could not deleted, because it is not archived.");
+ throw new RepositoryIsNotArchivedException();
}
fireEvent(HandlerEventType.BEFORE_DELETE, toDelete);
getHandler(toDelete).delete(toDelete);
diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java
index f0e875e650..888d4d6f25 100644
--- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java
+++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/RepositoryRootResourceTest.java
@@ -13,6 +13,7 @@ import org.junit.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import sonia.scm.PageResult;
+import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryException;
import sonia.scm.repository.RepositoryIsNotArchivedException;
@@ -26,8 +27,6 @@ import java.net.URISyntaxException;
import java.net.URL;
import static java.util.Collections.singletonList;
-import static java.util.Optional.empty;
-import static java.util.Optional.of;
import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
@@ -37,7 +36,6 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
-import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.never;
@@ -80,7 +78,7 @@ public class RepositoryRootResourceTest {
@Test
public void shouldFailForNotExistingRepository() throws URISyntaxException {
- when(repositoryManager.getByNamespace(anyString(), anyString())).thenReturn(empty());
+ when(repositoryManager.get(any(NamespaceAndName.class))).thenReturn(null);
mockRepository("space", "repo");
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/other");
@@ -135,7 +133,7 @@ public class RepositoryRootResourceTest {
public void shouldHandleUpdateForNotExistingRepository() throws URISyntaxException, IOException {
URL url = Resources.getResource("sonia/scm/api/v2/repository-test-update.json");
byte[] repository = Resources.toByteArray(url);
- when(repositoryManager.getByNamespace(anyString(), anyString())).thenReturn(empty());
+ when(repositoryManager.get(any(NamespaceAndName.class))).thenReturn(null);
MockHttpRequest request = MockHttpRequest
.put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo")
@@ -247,7 +245,7 @@ public class RepositoryRootResourceTest {
repository.setName(name);
String id = namespace + "-" + name;
repository.setId(id);
- when(repositoryManager.getByNamespace(namespace, name)).thenReturn(of(repository));
+ when(repositoryManager.get(new NamespaceAndName(namespace, name))).thenReturn(repository);
when(repositoryManager.get(id)).thenReturn(repository);
return repository;
}
diff --git a/scm-webapp/src/test/java/sonia/scm/it/AbstractAdminITCaseBase.java b/scm-webapp/src/test/java/sonia/scm/it/AbstractAdminITCaseBase.java
index f8ec4d2d10..45a24585e3 100644
--- a/scm-webapp/src/test/java/sonia/scm/it/AbstractAdminITCaseBase.java
+++ b/scm-webapp/src/test/java/sonia/scm/it/AbstractAdminITCaseBase.java
@@ -35,45 +35,22 @@ package sonia.scm.it;
//~--- non-JDK imports --------------------------------------------------------
-import org.junit.After;
-import org.junit.Before;
-
-import static sonia.scm.it.IntegrationTestUtil.*;
+import static sonia.scm.it.IntegrationTestUtil.createAdminClient;
//~--- JDK imports ------------------------------------------------------------
-import com.sun.jersey.api.client.Client;
-
/**
*
* @author Sebastian Sdorra
*/
public class AbstractAdminITCaseBase
{
-
- /**
- * Method description
- *
- */
- @Before
- public void login()
- {
- client = createClient();
- authenticateAdmin(client);
- }
-
- /**
- * Method description
- *
- */
- @After
- public void logout()
- {
- logoutClient(client);
+ public AbstractAdminITCaseBase() {
+ client = createAdminClient();
}
//~--- fields ---------------------------------------------------------------
/** Field description */
- protected Client client;
+ protected final ScmClient client;
}
diff --git a/scm-webapp/src/test/java/sonia/scm/it/AbstractPermissionITCaseBase.java b/scm-webapp/src/test/java/sonia/scm/it/AbstractPermissionITCaseBase.java
index cd655c78b5..d72f952876 100644
--- a/scm-webapp/src/test/java/sonia/scm/it/AbstractPermissionITCaseBase.java
+++ b/scm-webapp/src/test/java/sonia/scm/it/AbstractPermissionITCaseBase.java
@@ -35,29 +35,26 @@ package sonia.scm.it;
//~--- non-JDK imports --------------------------------------------------------
-import org.junit.After;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
import org.junit.AfterClass;
-import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runners.Parameterized.Parameters;
-
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
-import static org.junit.Assert.*;
+import java.util.Collection;
-import static sonia.scm.it.IntegrationTestUtil.*;
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static sonia.scm.it.IntegrationTestUtil.createAdminClient;
+import static sonia.scm.it.IntegrationTestUtil.createResource;
+import static sonia.scm.it.IntegrationTestUtil.post;
//~--- JDK imports ------------------------------------------------------------
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-
-import java.util.ArrayList;
-import java.util.Collection;
-
/**
*
* @author Sebastian Sdorra
@@ -77,26 +74,24 @@ public abstract class AbstractPermissionITCaseBase
public AbstractPermissionITCaseBase(Credentials credentials)
{
this.credentials = credentials;
+ this.client = credentials.isAnonymous()? ScmClient.anonymous(): new ScmClient(credentials.getUsername(), credentials.getPassword());
}
- //~--- methods --------------------------------------------------------------
+ //~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
- @Parameters
- public static Collection createParameters()
+ @Parameters(name = "{1}")
+ public static Collection