Merged in feature/integration_test_v2 (pull request #54)

Integration tests for v2
This commit is contained in:
Sebastian Sdorra
2018-08-07 14:14:43 +00:00
51 changed files with 1234 additions and 4349 deletions

4
Jenkinsfile vendored
View File

@@ -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)

View File

@@ -73,6 +73,7 @@
<module>scm-ui</module>
<module>scm-webapp</module>
<module>scm-server</module>
<module>scm-it</module>
</modules>
<repositories>

View File

@@ -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.");
}
}

View File

@@ -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<Repository> getByNamespace(String namespace, String name) {
return getAll()
.stream()
.filter(r -> r.getName().equals(name) && r.getNamespace().equals(namespace))
.findFirst();
}
}

240
scm-it/pom.xml Normal file
View File

@@ -0,0 +1,240 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>2.0.0-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-it</artifactId>
<packaging>jar</packaging>
<version>2.0.0-SNAPSHOT</version>
<name>scm-it</name>
<dependencies>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>2.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>2.0.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>2.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>2.0.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>2.0.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>2.0.0-SNAPSHOT</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>3.1.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.mycila.maven-license-plugin</groupId>
<artifactId>maven-license-plugin</artifactId>
<version>1.9.0</version>
<configuration>
<header>http://download.scm-manager.org/licenses/mvn-license.txt</header>
<includes>
<include>src/**</include>
<include>**/test/**</include>
</includes>
<excludes>
<exclude>target/**</exclude>
<exclude>.hg/**</exclude>
</excludes>
<strictCheck>true</strictCheck>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>it</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<configuration>
<includes>
<include>sonia/scm/it/*ITCase.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>integration-test</id>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>verify</id>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<configuration>
<artifactItems>
<artifactItem>
<groupId>sonia.scm</groupId>
<artifactId>scm-webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<destFileName>scm-webapp.war</destFileName>
</artifactItem>
</artifactItems>
</configuration>
<executions>
<execution>
<id>copy-war</id>
<phase>pre-integration-test</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<version>${jetty.maven.version}</version>
<configuration>
<stopPort>8085</stopPort>
<stopKey>STOP</stopKey>
<systemProperties>
<systemProperty>
<name>scm.home</name>
<value>${scm.home}</value>
</systemProperty>
<systemProperty>
<name>scm.stage</name>
<value>${scm.stage}</value>
</systemProperty>
<systemProperty>
<name>java.awt.headless</name>
<value>true</value>
</systemProperty>
</systemProperties>
<webApp>
<contextPath>/scm</contextPath>
</webApp>
<jettyXml>${project.basedir}/src/main/conf/jetty.xml</jettyXml>
<war>${project.build.outputDirectory}/scm-webapp.war</war>
<scanIntervalSeconds>0</scanIntervalSeconds>
<daemon>true</daemon>
</configuration>
<executions>
<execution>
<id>start-jetty</id>
<phase>pre-integration-test</phase>
<goals>
<goal>deploy-war</goal>
</goals>
</execution>
<execution>
<id>stop-jetty</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<properties>
<scm.stage>DEVELOPMENT</scm.stage>
<scm.home>target/scm-it</scm.home>
</properties>
</profile>
</profiles>
</project>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_0.dtd">
<!--*
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
-->
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<New id="httpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
<!-- increase header size for mercurial -->
<Set name="requestHeaderSize">16384</Set>
<Set name="responseHeaderSize">16384</Set>
</New>
<Call id="httpConnector" name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.ServerConnector">
<Arg name="server">
<Ref refid="Server" />
</Arg>
<Arg name="factories">
<Array type="org.eclipse.jetty.server.ConnectionFactory">
<Item>
<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config">
<Ref refid="httpConfig" />
</Arg>
</New>
</Item>
</Array>
</Arg>
<Set name="host">
<Property name="jetty.host" />
</Set>
<Set name="port">
<Property name="jetty.port" default="8081" />
</Set>
<Set name="idleTimeout">
<Property name="http.timeout" default="30000"/>
</Set>
</New>
</Arg>
</Call>
</Configure>

View File

@@ -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<String> {
public static Matcher<String> 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();
}
}

View File

@@ -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<String> 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");
}
}

View File

@@ -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");
}
}

View File

@@ -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<String> availableScmTypes() {
Collection<String> params = new ArrayList<>();
params.add("git");
params.add("svn");
if (IOUtil.search("hg") != null) {
params.add("hg");
}
return params;
}
}

View File

@@ -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<String> PROTECTED_USERS = asList("scmadmin", "anonymous");
private static Map<String, String> 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<String> 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<String> 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<String> 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();
}
}

View File

@@ -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<Optional<Repository>> loadBy(String namespace, String name) {
return () -> manager.getByNamespace(namespace, name);
return () -> Optional.ofNullable(manager.get(new NamespaceAndName(namespace, name)));
}
private Predicate<Repository> nameAndNamespaceStaysTheSame(String namespace, String name) {

View File

@@ -25,6 +25,7 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper<Reposit
@AfterMapping
void appendLinks(Repository repository, @MappingTarget RepositoryDto target) {
Links.Builder linksBuilder = linkingTo().self(resourceLinks.repository().self(target.getNamespace(), target.getName()));
linksBuilder.single(link("httpProtocol", resourceLinks.repository().clone(target.getType(), target.getNamespace(), target.getName())));
if (RepositoryPermissions.delete(repository).isPermitted()) {
linksBuilder.single(link("delete", resourceLinks.repository().delete(target.getNamespace(), target.getName())));
}

View File

@@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources;
import javax.inject.Inject;
import javax.ws.rs.core.UriInfo;
import java.net.URI;
class ResourceLinks {
@@ -127,15 +128,21 @@ class ResourceLinks {
static class RepositoryLinks {
private final LinkBuilder repositoryLinkBuilder;
private final UriInfo uriInfo;
RepositoryLinks(UriInfo uriInfo) {
repositoryLinkBuilder = new LinkBuilder(uriInfo, RepositoryRootResource.class, RepositoryResource.class);
this.uriInfo = uriInfo;
}
String self(String namespace, String name) {
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("get").parameters().href();
}
String clone(String type, String namespace, String name) {
return uriInfo.getBaseUri().resolve(URI.create("../../" + type + "/" + namespace + "/" + name)).toASCIIString();
}
String delete(String namespace, String name) {
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("delete").parameters().href();
}

View File

@@ -34,13 +34,14 @@ import com.github.legman.ReferenceType;
import com.github.legman.Subscribe;
import com.google.common.base.Function;
import com.google.common.collect.Collections2;
import javax.inject.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.EagerSingleton;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.PostReceiveRepositoryHookEvent;
import javax.inject.Inject;
/**
* {@link PostReceiveRepositoryHookEvent} which stores receives data and passes it to the {@link DebugService}.
*
@@ -78,7 +79,7 @@ public final class DebugHook
LOG.trace("store changeset ids from repository", event.getRepository().getId());
debugService.put(
event.getRepository().getId(),
event.getRepository().getNamespaceAndName(),
new DebugHookData(Collections2.transform(
event.getContext().getChangesetProvider().getChangesetList(), IDEXTRACTOR)
));

View File

@@ -30,20 +30,22 @@
*/
package sonia.scm.debug;
import java.util.Collection;
import sonia.scm.repository.NamespaceAndName;
import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.Collection;
/**
* Rest api resource for the {@link DebugService}.
*
* @author Sebastian Sdorra
*/
@Path("debug/{repository}/post-receive")
@Path("debug/{namespace}/{name}/post-receive")
public final class DebugResource
{
private final DebugService debugService;
@@ -62,28 +64,30 @@ public final class DebugResource
/**
* Returns all received hook data for the given repository.
*
* @param repository repository id
*
* @param namespace repository namespace
* @param name repository name
*
* @return all received hook data for the given repository
*/
@GET
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Collection<DebugHookData> getAll(@PathParam("repository") String repository){
return debugService.getAll(repository);
public Collection<DebugHookData> 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));
}
}

View File

@@ -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<String,DebugHookData> receivedHooks = LinkedListMultimap.create();
private final Multimap<NamespaceAndName,DebugHookData> 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<DebugHookData> receivedHookData = receivedHooks.get(repository);
Collection<DebugHookData> 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<DebugHookData> getAll(String repository){
public Collection<DebugHookData> getAll(NamespaceAndName namespaceAndName){
SecurityUtils.getSubject().checkRole(Role.ADMIN);
return receivedHooks.get(repository);
return receivedHooks.get(namespaceAndName);
}
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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<T>
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<Credentials[]> createParameters()
@Parameters(name = "{1}")
public static Collection<Object[]> createParameters()
{
Collection<Credentials[]> params = new ArrayList<>();
params.add(new Credentials[] { new Credentials() });
params.add(new Credentials[] {
new Credentials("trillian", "a.trillian124") });
return params;
return asList(
new Object[] {new Credentials(), "anonymous"},
new Object[] {new Credentials("trillian", "a.trillian124"), "trillian" }
);
}
/**
@@ -111,18 +106,13 @@ public abstract class AbstractPermissionITCaseBase<T>
trillian.setPassword("a.trillian124");
Client client = createClient();
ScmClient client = createAdminClient();
authenticateAdmin(client);
WebResource wr = createResource(client, "users");
ClientResponse response = wr.post(ClientResponse.class, trillian);
ClientResponse response = UserITUtil.postUser(client, trillian);
assertNotNull(response);
assertEquals(201, response.getStatus());
response.close();
logoutClient(client);
client.destroy();
}
/**
@@ -132,15 +122,12 @@ public abstract class AbstractPermissionITCaseBase<T>
@AfterClass
public static void removeTestUser()
{
Client client = createClient();
authenticateAdmin(client);
ScmClient client = createAdminClient();
createResource(client, "users/trillian").delete();
client.destroy();
}
//~--- get methods ----------------------------------------------------------
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
@@ -189,30 +176,10 @@ public abstract class AbstractPermissionITCaseBase<T>
*/
protected abstract String getModifyPath();
protected abstract String getMediaType();
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@After
public void after()
{
client = createClient();
logout();
}
/**
* Method description
*
*/
@Before
public void before()
{
client = createClient();
login();
}
/**
* Method description
*
@@ -220,9 +187,7 @@ public abstract class AbstractPermissionITCaseBase<T>
@Test
public void create()
{
WebResource wr = createResource(client, getBasePath());
checkResponse(wr.post(ClientResponse.class, getCreateItem()));
checkResponse(post(client, getBasePath(), getMediaType(), getCreateItem()));
}
/**
@@ -232,7 +197,7 @@ public abstract class AbstractPermissionITCaseBase<T>
@Test
public void delete()
{
WebResource wr = createResource(client, getDeletePath());
WebResource.Builder wr = createResource(client, getDeletePath());
checkResponse(wr.delete(ClientResponse.class));
}
@@ -244,9 +209,9 @@ public abstract class AbstractPermissionITCaseBase<T>
@Test
public void modify()
{
WebResource wr = createResource(client, getModifyPath());
WebResource.Builder wr = createResource(client, getModifyPath());
checkResponse(wr.put(ClientResponse.class, getModifyItem()));
checkResponse(wr.type(getMediaType()).put(ClientResponse.class, getModifyItem()));
}
//~--- get methods ----------------------------------------------------------
@@ -258,7 +223,7 @@ public abstract class AbstractPermissionITCaseBase<T>
@Test
public void get()
{
WebResource wr = createResource(client, getGetPath());
WebResource.Builder wr = createResource(client, getGetPath());
checkGetResponse(wr.get(ClientResponse.class));
}
@@ -270,7 +235,7 @@ public abstract class AbstractPermissionITCaseBase<T>
@Test
public void getAll()
{
WebResource wr = createResource(client, getBasePath());
WebResource.Builder wr = createResource(client, getBasePath());
checkGetAllResponse(wr.get(ClientResponse.class));
}
@@ -321,36 +286,9 @@ public abstract class AbstractPermissionITCaseBase<T>
response.close();
}
/**
* Method description
*
*/
private void login()
{
if (!credentials.isAnonymous())
{
authenticate(client, credentials.getUsername(),
credentials.getPassword());
}
}
/**
* Method description
*
*/
private void logout()
{
if (!credentials.isAnonymous())
{
logoutClient(client);
}
}
//~--- fields ---------------------------------------------------------------
/** Field description */
protected Client client;
protected ScmClient client;
/** Field description */
protected Credentials credentials;
}

View File

@@ -1,308 +0,0 @@
/**
* 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.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import sonia.scm.group.Group;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import sonia.scm.util.IOUtil;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import java.util.ArrayList;
import java.util.Collection;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class AdminPermissionITCase
{
/**
* Constructs ...
*
*
* @param credentials
*/
public AdminPermissionITCase(Credentials credentials)
{
this.credentials = credentials;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@AfterClass
public static void cleanup()
{
Client client = createAdminClient();
createResource(client, "users/marvin").delete();
createResource(client, "groups/test-group").delete();
client.destroy();
}
/**
* Method description
*
*
* @return
*/
@Parameters
public static Collection<Object[]> createParameters()
{
Collection<Object[]> params = new ArrayList<>();
// params.add(new Object[] { new Credentials() });
User u = UserTestData.createMarvin();
u.setPassword("secret");
Client client = createAdminClient();
createResource(client, "users").post(u);
client.destroy();
params.add(new Object[] { new Credentials(u.getName(), u.getPassword()) });
return params;
}
/**
* Method description
*
*/
@BeforeClass
public static void setup()
{
Group group = new Group("xml", "test-group");
Client client = createAdminClient();
createResource(client, "groups").post(group);
client.destroy();
}
/**
* Method description
*
*/
@Before
public void login()
{
client = createClient();
if (!credentials.isAnonymous())
{
authenticate(client, credentials.getUsername(),
credentials.getPassword());
}
}
/**
* Method description
*
*/
@After
public void logout()
{
if (!credentials.isAnonymous())
{
logoutClient(client);
}
}
/**
* Method description
*
*/
@Test
public void testConfig()
{
checkResponse(createResource(client, "config").get(ClientResponse.class));
checkResponse(createResource(client, "config").post(ClientResponse.class));
}
/**
* Method description
*
*/
@Test
public void testGitConfig()
{
checkResponse(
createResource(client, "config/repositories/git").get(
ClientResponse.class));
checkResponse(
createResource(client, "config/repositories/git").post(
ClientResponse.class));
}
/**
* Method description
*
*/
@Test
public void testGroups()
{
checkResponse(createResource(client, "groups").get(ClientResponse.class));
checkResponse(createResource(client, "groups").post(ClientResponse.class));
checkResponse(
createResource(client, "groups/test-group").get(ClientResponse.class));
checkResponse(
createResource(client, "groups/test-group").put(ClientResponse.class));
checkResponse(
createResource(client, "groups/test-group").delete(
ClientResponse.class));
}
/**
* Method description
*
*/
@Test
public void testHgConfig()
{
checkResponse(
createResource(client, "config/repositories/hg").get(
ClientResponse.class));
checkResponse(
createResource(client, "config/repositories/hg").post(
ClientResponse.class));
}
/**
* Method description
*
*/
@Test
public void testPlugins()
{
checkResponse(createResource(client, "plugins").get(ClientResponse.class));
checkResponse(createResource(client,
"plugins/overview").get(ClientResponse.class));
checkResponse(
createResource(client, "plugins/installed").get(ClientResponse.class));
checkResponse(createResource(client,
"plugins/updates").get(ClientResponse.class));
checkResponse(
createResource(client, "plugins/available").get(ClientResponse.class));
}
/**
* Method description
*
*/
@Test
public void testSvnConfig()
{
checkResponse(
createResource(client, "config/repositories/svn").get(
ClientResponse.class));
checkResponse(
createResource(client, "config/repositories/svn").post(
ClientResponse.class));
}
/**
* Method description
*
*/
@Test
public void testUsers()
{
checkResponse(createResource(client, "users").get(ClientResponse.class));
checkResponse(createResource(client, "users").post(ClientResponse.class));
checkResponse(createResource(client,
"users/scmadmin").get(ClientResponse.class));
checkResponse(createResource(client,
"users/scmadmin").put(ClientResponse.class));
checkResponse(
createResource(client, "users/scmadmin").delete(ClientResponse.class));
}
/**
* Method description
*
*
* @param response
*/
private void checkResponse(ClientResponse response)
{
assertNotNull(response);
if (credentials.isAnonymous())
{
assertEquals(401, response.getStatus());
}
else
{
assertEquals(403, response.getStatus());
}
// fix jersey-client bug
IOUtil.close(response.getEntityInputStream());
response.close();
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Client client;
/** Field description */
private Credentials credentials;
}

View File

@@ -1,285 +0,0 @@
/**
* 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.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
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.config.ScmConfiguration;
import sonia.scm.repository.Permission;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
//~--- 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.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import org.junit.Ignore;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.repository.client.api.RepositoryClientFactory;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class AnonymousAccessITCase
{
/** Field description */
private static final Permission PERMISSION_ANONYMOUS_WRITE =
new Permission("anonymous", PermissionType.WRITE);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param repositoryType
*/
public AnonymousAccessITCase(String repositoryType)
{
this.repositoryType = repositoryType;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Parameters
public static Collection<String[]> createParameters()
{
return createRepositoryTypeParameters();
}
/**
* Method description
*
*/
@AfterClass
public static void unsetAnonymousAccess()
{
toggleAnonymousAccess(false);
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*/
@BeforeClass
public static void setAnonymousAccess()
{
toggleAnonymousAccess(true);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param anonymousAccess
*/
private static void toggleAnonymousAccess(boolean anonymousAccess)
{
Client client = createAdminClient();
WebResource resource = createResource(client, "config");
ScmConfiguration config = resource.get(ScmConfiguration.class);
assertNotNull(config);
config.setAnonymousAccessEnabled(anonymousAccess);
ClientResponse response = resource.post(ClientResponse.class, config);
assertNotNull(response);
assertEquals(201, response.getStatus());
logoutClient(client);
}
/**
* Method description
*
*/
@Before
public void createTestRepository()
{
Client client = createAdminClient();
repository = RepositoryTestData.createHeartOfGold(repositoryType);
repository.setPublicReadable(true);
repository = createRepository(client, repository);
logoutClient(client);
}
/**
* Method description
*
*/
@After
public void removeTestRepository()
{
Client client = createAdminClient();
deleteRepository(client, repository.getId());
logoutClient(client);
}
/**
* Method description
*
* @throws IOException
*/
@Test
@Ignore
public void testAllowedAnonymousPush() throws IOException
{
Client client = createAdminClient();
WebResource resource = createResource(client,
"repository/".concat(repository.getId()));
repository.setPermissions(Arrays.asList(PERMISSION_ANONYMOUS_WRITE));
resource.post(ClientResponse.class, repository);
RepositoryClient repositoryClient = createAnonymousRepositoryClient();
createRandomFile(repositoryClient);
commit(repositoryClient, "added test files");
}
/**
* Method description
*
* TODO fix test case
*
* @throws IOException
*/
@Test @Ignore
public void testAnonymousClone() throws IOException
{
testSimpleAdminPush();
RepositoryClient client = createAnonymousRepositoryClient();
// client.checkout();
}
/**
* Method description
*
* @throws IOException
*/
@Ignore
@Test(expected = IOException.class)
public void testDeniedAnonymousPush() throws IOException
{
RepositoryClient repositoryClient = createAnonymousRepositoryClient();
createRandomFile(repositoryClient);
commit(repositoryClient, "added anonymous test file");
}
/**
* Method description
*
*
* @throws IOException
*/
@Test
public void testSimpleAdminPush() throws IOException
{
RepositoryClient repositoryClient = createAdminRepositoryClient();
createRandomFile(repositoryClient);
commit(repositoryClient, "added random file");
}
private RepositoryClient createAdminRepositoryClient() throws IOException {
return createRepositoryClient(ADMIN_USERNAME, ADMIN_PASSWORD);
}
private RepositoryClient createAnonymousRepositoryClient() throws IOException {
return createRepositoryClient(null, null);
}
private RepositoryClient createRepositoryClient(String username, String password) throws IOException {
File directory = temporaryFolder.newFolder();
String remoteUrl = repository.createUrl(BASE_URL);
RepositoryClientFactory factory = new RepositoryClientFactory();
return factory.create(repositoryType, remoteUrl, username, password, directory);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
/** Field description */
private Repository repository;
/** Field description */
private final String repositoryType;
}

View File

@@ -1,96 +0,0 @@
/**
* 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.junit.Test;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
/**
*
* @author Sebastian Sdorra
*/
public class AuthenticationITCase
{
/**
* Method description
*
*
*/
@Test
public void testLogin()
{
Client client = createClient();
authenticateAdmin(client);
}
/**
* Method description
*
*/
@Test
public void testLoginFailed()
{
Client client = createClient();
ClientResponse response = authenticate(client, "dent", "trillian");
assertNotNull(response);
assertEquals(401, response.getStatus());
response.close();
}
/**
* Method description
*
*/
@Test
public void testLogout()
{
Client client = createClient();
authenticateAdmin(client);
logoutClient(client);
}
}

View File

@@ -1,131 +0,0 @@
/**
* Copyright (c) 2014, 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;
import com.google.common.base.Strings;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import java.util.List;
import javax.ws.rs.core.MultivaluedMap;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import sonia.scm.ScmState;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
import static sonia.scm.it.RepositoryITUtil.createRepository;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
/**
* Integration test for authorization with scope.
*
* @author Sebastian Sdorra
*/
public class AuthorizationScopeITCase {
private Repository heartOfGold;
private Repository puzzle42;
/**
* Create test repositories.
*/
@Before
public void createTestRepositories(){
Client adminClient = createAdminClient();
this.heartOfGold = createRepository(adminClient, RepositoryTestData.createHeartOfGold("git"));
this.puzzle42 = createRepository(adminClient, RepositoryTestData.create42Puzzle("git"));
}
/**
* Delete test repositories.
*/
@After
public void deleteTestRepositories(){
Client adminClient = createAdminClient();
deleteRepository(adminClient, heartOfGold.getId());
deleteRepository(adminClient, puzzle42.getId());
}
/**
* Read all available repositories without scope.
*/
@Test
public void testAuthenticateWithoutScope() {
Assert.assertEquals(2, getRepositories(createAuthenticationToken()).size());
}
/**
* Read all available repositories with a scope for only one of them.
*/
@Test
public void testAuthenticateWithScope() {
String scope = "repository:read:".concat(heartOfGold.getId());
Assert.assertEquals(1, getRepositories(createAuthenticationToken(scope)).size());
}
private List<Repository> getRepositories(String token) {
Client client = createClient();
WebResource wr = client.resource(createResourceUrl("repositories"));
return wr.header("Authorization", "Bearer ".concat(token)).get(new GenericType<List<Repository>>(){});
}
private String createAuthenticationToken() {
return createAuthenticationToken("");
}
private String createAuthenticationToken(String scope) {
Client client = createClient();
String url = createResourceUrl("auth/access_token");
WebResource wr = client.resource(url);
MultivaluedMap<String, String> formData = new MultivaluedMapImpl();
formData.add("username", ADMIN_USERNAME);
formData.add("password", ADMIN_PASSWORD);
formData.add("grant_type", "password");
if (!Strings.isNullOrEmpty(scope)) {
formData.add("scope", scope);
}
ClientResponse response = wr.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);
if (response.getStatus() >= 300 ){
Assert.fail("authentication failed with status code " + response.getStatus());
}
return response.getEntity(ScmState.class).getToken();
}
}

View File

@@ -1,296 +0,0 @@
/**
* 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.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.Modifications;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.util.IOUtil;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.repository.client.api.RepositoryClientFactory;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class ChangesetViewerITCase extends AbstractAdminITCaseBase
{
/**
* Constructs ...
*
*
* @param repositoryType
*/
public ChangesetViewerITCase(String repositoryType)
{
this.repositoryType = repositoryType;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Parameters
public static Collection<String[]> createParameters()
{
return createRepositoryTypeParameters();
}
/**
* Method description
*
*
* @throws IOException
* @throws InterruptedException
*/
@Test
public void cachingTest() throws IOException, InterruptedException
{
RepositoryClient rc = createRepositoryClient();
// rc.checkout();
addTestFile(rc, "a", 1, false);
addTestFile(rc, "b", 2, true);
}
/**
* Method description
*
*
* @throws IOException
*/
@After
public void cleanup() throws IOException
{
IOUtil.delete(localDirectory, true);
deleteRepository(client, repository.getId());
}
/**
* Method description
*
*
* @throws IOException
*/
@Before
public void setup() throws IOException
{
repository = RepositoryTestData.createHeartOfGold(repositoryType);
repository = createRepository(client, repository);
localDirectory = File.createTempFile("scm-", ".unittest");
IOUtil.delete(localDirectory);
IOUtil.mkdirs(localDirectory);
}
/**
* Method description
*
*
* @throws IOException
* @throws InterruptedException
*/
@Test
public void simpleTest() throws IOException, InterruptedException
{
RepositoryClient rc = createRepositoryClient();
// rc.init();
addTestFile(rc, "a", 1, false);
}
/**
* Method description
*
*
* @param rc
* @param name
* @param count
* @param sleep
*
* @throws IOException
* @throws InterruptedException
* @throws RepositoryClientException
*/
private void addTestFile(RepositoryClient rc, String name, int count,
boolean sleep)
throws IOException, InterruptedException
{
File file = new File(localDirectory, name.concat(".txt"));
writeRandomContent(file);
rc.getAddCommand().add(name.concat(".txt"));
IntegrationTestUtil.commit(rc, "added-".concat(name).concat(".txt"));
if (sleep) {
// cache clear is async
Thread.sleep(500l);
}
ChangesetPagingResult cpr = getChangesets(repository);
if ("svn".equals(repositoryType)) {
assertEquals((count + 1), cpr.getTotal());
} else {
assertEquals(count, cpr.getTotal());
}
List<Changeset> changesets = cpr.getChangesets();
assertNotNull(changesets);
if ("svn".equals(repositoryType)) {
assertEquals((count + 1), changesets.size());
} else {
assertEquals(count, changesets.size());
}
Changeset c = changesets.get(0);
assertNotNull(c);
assertEquals("added-".concat(name).concat(".txt"), c.getDescription());
assertTrue(c.isValid());
Modifications m = c.getModifications();
assertNotNull(m);
List<String> added = m.getAdded();
assertNotNull(added);
assertFalse(added.isEmpty());
assertEquals(1, added.size());
//J-
assertThat(
added.get(0),
anyOf(
equalTo(name.concat(".txt")),
equalTo("/".concat(name).concat(".txt"))
)
);
//J+
}
private RepositoryClient createRepositoryClient() throws IOException {
RepositoryClientFactory factory = new RepositoryClientFactory();
return factory.create(
repositoryType, repository.createUrl(BASE_URL),
IntegrationTestUtil.ADMIN_USERNAME, IntegrationTestUtil.ADMIN_PASSWORD,
localDirectory
);
}
private void writeRandomContent(File file) throws IOException {
Random random = new Random();
byte[] data = new byte[random.nextInt(1024)];
try (FileOutputStream output = new FileOutputStream(file)) {
random.nextBytes(data);
output.write(data);
}
}
//~--- get methods ----------------------------------------------------------
private String getChangesetViewerUri(Repository repository) {
return "repositories/".concat(repository.getId()).concat("/changesets");
}
private ChangesetPagingResult getChangesets(Repository repository) {
WebResource resource = createResource(client,
getChangesetViewerUri(repository));
assertNotNull(resource);
ClientResponse response = resource.get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
ChangesetPagingResult cpr = response.getEntity(ChangesetPagingResult.class);
assertNotNull(cpr);
return cpr;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private File localDirectory;
/** Field description */
private Repository repository;
/** Field description */
private final String repositoryType;
}

View File

@@ -1,191 +0,0 @@
/**
* 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.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.util.IOUtil;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class CreateRepositoriesITCase extends AbstractAdminITCaseBase
{
/**
* Constructs ...
*
*
* @param repositoryType
*/
public CreateRepositoriesITCase(String repositoryType)
{
this.repositoryType = repositoryType;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Parameters
public static Collection<String[]> createParameters()
{
Collection<String[]> params = new ArrayList<>();
params.add(new String[] { "git" });
params.add(new String[] { "svn" });
if (IOUtil.search("hg") != null)
{
params.add(new String[] { "hg" });
}
return params;
}
/**
* Method description
*
*
* @throws IOException
*/
@After
public void cleanup() throws IOException
{
deleteRepository(client, repository.getId());
}
/**
* Method description
*
*/
@Test
public void testCreate()
{
repository = RepositoryTestData.createHeartOfGold(repositoryType);
repository = createRepository(client, repository);
}
/**
* Method description
*
*/
@Test
public void testCreateAllreadyExists()
{
repository = RepositoryTestData.create42Puzzle(repositoryType);
repository = createRepository(client, repository);
WebResource wr = createResource(client, "repositories");
ClientResponse response =
wr.post(ClientResponse.class,
RepositoryTestData.create42Puzzle(repositoryType));
assertNotNull(response);
assertEquals(500, response.getStatus());
response.close();
}
/**
* Method description
*
*/
@Test
public void testCreateAllreadyExistsWithStructure()
{
repository = RepositoryTestData.create42Puzzle(repositoryType);
repository = createRepository(client, repository);
Repository r = RepositoryTestData.create42Puzzle(repositoryType);
r.setName(r.getName() + "/" + r.getName());
WebResource wr = createResource(client, "repositories");
ClientResponse response = wr.post(ClientResponse.class, r);
assertNotNull(response);
System.out.println( response.getStatus() );
assertEquals(500, response.getStatus());
response.close();
}
/**
* Method description
*
*/
@Test
public void testCreateWithStructure()
{
repository = RepositoryTestData.createHeartOfGold(repositoryType);
repository.setName("test/".concat(repository.getName()));
repository = createRepository(client, repository);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Repository repository;
/** Field description */
private String repositoryType;
}

View File

@@ -1,137 +0,0 @@
/**
* 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.junit.After;
import org.junit.Before;
import org.junit.Test;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.core.MediaType;
/**
*
* @author Sebastian Sdorra
*/
public class DeactivatedUserITCase
{
/**
* Method description
*
*/
@Before
public void createDeactivatedUser()
{
Client client = createAdminClient();
try
{
WebResource wr = createResource(client, "users");
slarti = UserTestData.createSlarti();
slarti.setPassword("slart123");
slarti.setActive(false);
ClientResponse response =
wr.type(MediaType.APPLICATION_XML).post(ClientResponse.class, slarti);
assertNotNull(response);
assertEquals(201, response.getStatus());
response.close();
}
finally
{
client.destroy();
}
}
/**
* Method description
*
*/
@After
public void destroyDeactivatedUser()
{
Client client = createAdminClient();
try
{
WebResource wr = createResource(client,
"users/".concat(slarti.getName()));
ClientResponse response =
wr.type(MediaType.APPLICATION_XML).delete(ClientResponse.class);
assertNotNull(response);
assertEquals(204, response.getStatus());
response.close();
}
finally
{
client.destroy();
}
}
/**
* Method description
*
*/
@Test
public void testFailedAuthentication()
{
Client client = createClient();
ClientResponse response = authenticate(client, slarti.getName(), "slart123");
assertNotNull(response);
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private User slarti;
}

View File

@@ -1,196 +0,0 @@
/**
* 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.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.util.IOUtil;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class GetRepositoriesITCase extends AbstractAdminITCaseBase
{
/**
* Constructs ...
*
*
* @param repositoryType
*/
public GetRepositoriesITCase(String repositoryType)
{
this.repositoryType = repositoryType;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Parameters
public static Collection<String[]> createParameters()
{
Collection<String[]> params = new ArrayList<String[]>();
params.add(new String[] { "git" });
params.add(new String[] { "svn" });
if (IOUtil.search("hg") != null)
{
params.add(new String[] { "hg" });
}
return params;
}
/**
* Method description
*
*
* @throws IOException
*/
@After
public void cleanup() throws IOException
{
deleteRepository(client, repository.getId());
}
/**
* Method description
*
*/
@Test
public void testGetById()
{
repository = RepositoryTestData.createHeartOfGold(repositoryType);
repository = createRepository(client, repository);
String id = repository.getId();
assertNotNull(id);
Repository r = getRepositoryById(client, id);
assertEquals(id, r.getId());
}
/**
* Method description
*
*/
@Test
public void testGetByTypeAndName()
{
repository = RepositoryTestData.create42Puzzle(repositoryType);
testGetByTypeAndName(repository);
}
/**
* Method description
*
*/
@Test
public void testGetByTypeAndNameWithDirectoryStructure()
{
repository =
RepositoryTestData.createRestaurantAtTheEndOfTheUniverse(repositoryType);
repository.setName("test/".concat(repository.getName()));
testGetByTypeAndName(repository);
}
/**
* Method description
*
*
* @param repository
*/
private void testGetByTypeAndName(Repository repo)
{
repository = createRepository(client, repo);
String name = repository.getName();
WebResource wr = createResource(
client,
"repositories/".concat(repositoryType).concat(
"/").concat(name));
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
Repository r = response.getEntity(Repository.class);
response.close();
assertNotNull(r);
assertEquals(repository.getId(), r.getId());
assertEquals(repository.getName(), r.getName());
assertEquals(repository.getType(), r.getType());
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Repository repository;
/** Field description */
private String repositoryType;
}

View File

@@ -36,251 +36,259 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
import com.google.common.base.Charsets;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.UniformInterfaceException;
import java.io.IOException;
import java.util.UUID;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.hamcrest.Matchers;
import org.junit.After;
import org.junit.Test;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import static org.junit.Assert.*;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
import sonia.scm.repository.Permission;
import org.junit.rules.TemporaryFolder;
import sonia.scm.api.rest.ObjectMapperProvider;
import sonia.scm.api.v2.resources.RepositoryDto;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.IOException;
import java.util.UUID;
import static org.junit.Assert.assertArrayEquals;
import static sonia.scm.it.IntegrationTestUtil.BASE_URL;
import static sonia.scm.it.IntegrationTestUtil.REST_BASE_URL;
import static sonia.scm.it.IntegrationTestUtil.createAdminClient;
import static sonia.scm.it.IntegrationTestUtil.readJson;
import static sonia.scm.it.RepositoryITUtil.createRepository;
import static sonia.scm.it.RepositoryITUtil.deleteRepository;
/**
* Integration tests for git lfs.
*
*
* @author Sebastian Sdorra
*/
public class GitLfsITCase {
@Rule
public ExpectedException expectedException = ExpectedException.none();
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private final ObjectMapper mapper = new ObjectMapper();
private Client adminClient;
private Repository repository;
private ScmClient adminClient;
private RepositoryDto repository;
public GitLfsITCase() {
mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()));
}
// lifecycle methods
@Before
public void setUpTestDependencies() {
adminClient = createAdminClient();
repository = createRepository(adminClient, RepositoryTestData.createHeartOfGold("git"));
repository = createRepository(adminClient, readJson("repository-git.json"));
}
@After
public void tearDownTestDependencies() {
deleteRepository(adminClient, repository.getId());
adminClient.destroy();
deleteRepository(adminClient, repository);
}
// tests
@Test
public void testLfsAPIWithAdminPermissions() throws IOException {
uploadAndDownload(adminClient);
}
@Test
@Ignore("permissions not yet implemented")
public void testLfsAPIWithOwnerPermissions() throws IOException {
uploadAndDownloadAsUser(PermissionType.OWNER);
}
private void uploadAndDownloadAsUser(PermissionType permissionType) throws IOException {
User trillian = UserTestData.createTrillian();
trillian.setPassword("secret123");
createUser(trillian);
try {
repository.getPermissions().add(new Permission(trillian.getId(), permissionType));
modifyRepository(repository);
Client client = createClient();
authenticate(client, trillian.getId(), "secret123");
try {
// TODO enable when permissions are implemented in v2
// repository.getPermissions().add(new Permission(trillian.getId(), permissionType));
// modifyRepository(repository);
ScmClient client = new ScmClient(trillian.getId(), "secret123");
uploadAndDownload(client);
} finally {
removeUser(trillian);
}
}
@Test
@Ignore("permissions not yet implemented")
public void testLfsAPIWithWritePermissions() throws IOException {
uploadAndDownloadAsUser(PermissionType.WRITE);
}
private void createUser(User user) {
adminClient.resource(REST_BASE_URL + "users.json").post(user);
}
private void modifyRepository(Repository repository) {
adminClient.resource(REST_BASE_URL + "repositories/" + repository.getId() + ".json").put(repository);
}
private void removeUser(User user) {
adminClient.resource(REST_BASE_URL + "users/" + user.getId() + ".json").delete();
}
@Test
@Ignore("permissions not yet implemented")
public void testLfsAPIWithoutWritePermissions() throws IOException {
User trillian = UserTestData.createTrillian();
trillian.setPassword("secret123");
createUser(trillian);
expectedException.expect(UniformInterfaceException.class);
expectedException.expectMessage(Matchers.containsString("403"));
try {
repository.getPermissions().add(new Permission(trillian.getId(), PermissionType.READ));
modifyRepository(repository);
Client client = createClient();
authenticate(client, trillian.getId(), "secret123");
try {
// TODO enable when permissions are implemented in v2
// repository.getPermissions().add(new Permission(trillian.getId(), PermissionType.READ));
// modifyRepository(repository);
ScmClient client = new ScmClient(trillian.getId(), "secret123");
uploadAndDownload(client);
} finally {
removeUser(trillian);
}
}
@Test
@Ignore("permissions not yet implemented")
public void testLfsDownloadWithReadPermissions() throws IOException {
User trillian = UserTestData.createTrillian();
trillian.setPassword("secret123");
createUser(trillian);
try {
repository.getPermissions().add(new Permission(trillian.getId(), PermissionType.READ));
modifyRepository(repository);
try {
// TODO enable when permissions are implemented in v2
// repository.getPermissions().add(new Permission(trillian.getId(), PermissionType.READ));
// modifyRepository(repository);
// upload data as admin
String data = UUID.randomUUID().toString();
byte[] dataAsBytes = data.getBytes(Charsets.UTF_8);
LfsObject lfsObject = upload(adminClient, dataAsBytes);
Client client = createClient();
authenticate(client, trillian.getId(), "secret123");
ScmClient client = new ScmClient(trillian.getId(), "secret123");
// download as user
byte[] downloadedData = download(client, lfsObject);
// assert both are equal
assertArrayEquals(dataAsBytes, downloadedData);
} finally {
removeUser(trillian);
}
}
// lfs api
private void uploadAndDownload(Client client) throws IOException {
private void uploadAndDownload(ScmClient client) throws IOException {
String data = UUID.randomUUID().toString();
byte[] dataAsBytes = data.getBytes(Charsets.UTF_8);
LfsObject lfsObject = upload(client, dataAsBytes);
byte[] downloadedData = download(client, lfsObject);
assertArrayEquals(dataAsBytes, downloadedData);
}
private LfsObject upload(Client client, byte[] data) throws IOException {
private LfsObject upload(ScmClient client, byte[] data) throws IOException {
LfsObject lfsObject = createLfsObject(data);
LfsRequestBody request = LfsRequestBody.createUploadRequest(lfsObject);
LfsResponseBody response = request(client, request);
String uploadURL = response.objects[0].actions.upload.href;
client.resource(uploadURL).put(data);
return lfsObject;
}
private LfsResponseBody request(Client client, LfsRequestBody request) throws IOException {
}
private LfsResponseBody request(ScmClient client, LfsRequestBody request) throws IOException {
String batchUrl = createBatchUrl();
String requestAsString = mapper.writeValueAsString(request);
return client
.resource(batchUrl)
.accept("application/vnd.git-lfs+json")
.header("Content-Type", "application/vnd.git-lfs+json")
.post(LfsResponseBody.class, requestAsString);
String json = client
.resource(batchUrl)
.accept("application/vnd.git-lfs+json")
.header("Content-Type", "application/vnd.git-lfs+json")
.post(String.class, requestAsString);
return new ObjectMapperProvider().get().readValue(json, LfsResponseBody.class);
}
private String createBatchUrl() {
String url = repository.createUrl(BASE_URL);
String url = BASE_URL + "git/" + repository.getNamespace() + "/" + repository.getName();
return url + "/info/lfs/objects/batch";
}
private byte[] download(Client client, LfsObject lfsObject) throws IOException {
private byte[] download(ScmClient client, LfsObject lfsObject) throws IOException {
LfsRequestBody request = LfsRequestBody.createDownloadRequest(lfsObject);
LfsResponseBody response = request(client, request);
String downloadUrl = response.objects[0].actions.download.href;
return client.resource(downloadUrl).get(byte[].class);
}
private LfsObject createLfsObject(byte[] data) {
Sha256Hash hash = new Sha256Hash(data);
String oid = hash.toHex();
return new LfsObject(oid, data.length);
}
// LFS DTO objects
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
private static class LfsRequestBody {
private String operation;
private String[] transfers = new String[]{ "basic" };
private LfsObject[] objects;
public LfsRequestBody() {
}
private LfsRequestBody(String operation, LfsObject[] objects) {
this.operation = operation;
this.objects = objects;
}
public static LfsRequestBody createUploadRequest(LfsObject object) {
return new LfsRequestBody("upload", new LfsObject[]{object});
}
public static LfsRequestBody createDownloadRequest(LfsObject object) {
return new LfsRequestBody("download", new LfsObject[]{object});
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
private static class LfsResponseBody {
private LfsObject[] objects;
public LfsResponseBody() {
@@ -290,11 +298,11 @@ public class GitLfsITCase {
this.objects = objects;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
private static class LfsObject {
private String oid;
private long size;
private LfsActions actions;
@@ -312,24 +320,24 @@ public class GitLfsITCase {
this.size = size;
this.actions = actions;
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
private static class LfsActions {
private LfsAction upload;
private LfsAction download;
public LfsActions() {
}
}
@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
private static class LfsAction {
private String href;
public LfsAction() {
@@ -338,7 +346,7 @@ public class GitLfsITCase {
public LfsAction(String href) {
this.href = href;
}
}
}

View File

@@ -32,103 +32,108 @@ package sonia.scm.it;
import com.google.common.base.Charsets;
import com.google.common.io.Files;
import com.sun.jersey.api.client.Client;
import java.io.File;
import java.io.IOException;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
import sonia.scm.api.v2.resources.RepositoryDto;
import sonia.scm.repository.Person;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.repository.client.api.ClientCommand;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.repository.client.api.RepositoryClientFactory;
import java.io.File;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static sonia.scm.it.IntegrationTestUtil.ADMIN_PASSWORD;
import static sonia.scm.it.IntegrationTestUtil.ADMIN_USERNAME;
import static sonia.scm.it.IntegrationTestUtil.BASE_URL;
import static sonia.scm.it.IntegrationTestUtil.createAdminClient;
import static sonia.scm.it.IntegrationTestUtil.readJson;
import static sonia.scm.it.RepositoryITUtil.createRepository;
import static sonia.scm.it.RepositoryITUtil.deleteRepository;
/**
* Integration test for RepositoryPathMatching with ".git" and without ".git".
*
*
* @author Sebastian Sdorra
* @since 1.54
*/
public class GitRepositoryPathMatcherITCase {
private static final RepositoryClientFactory REPOSITORY_CLIENT_FACTORY = new RepositoryClientFactory();
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
private Client apiClient;
private Repository repository;
private ScmClient apiClient;
private RepositoryDto repository;
@Before
public void setUp() {
apiClient = createAdminClient();
Repository testRepository = RepositoryTestData.createHeartOfGold("git");
this.repository = createRepository(apiClient, testRepository);
this.repository = createRepository(apiClient, readJson("repository-git.json"));
}
@After
public void tearDown() {
deleteRepository(apiClient, repository.getId());
deleteRepository(apiClient, repository);
}
// tests begin
@Test
public void testWithoutDotGit() throws IOException {
String urlWithoutDotGit = createUrl();
cloneAndPush(urlWithoutDotGit);
}
@Test
public void testWithDotGit() throws IOException {
String urlWithDotGit = createUrl() + ".git";
cloneAndPush(urlWithDotGit);
}
// tests end
private String createUrl() {
return BASE_URL + "git/" + repository.getName();
return BASE_URL + "git/" + repository.getNamespace() + "/" + repository.getName();
}
private void cloneAndPush( String url ) throws IOException {
cloneRepositoryAndPushFiles(url);
cloneRepositoryAndCheckFiles(url);
}
private void cloneRepositoryAndPushFiles(String url) throws IOException {
RepositoryClient repositoryClient = createRepositoryClient(url);
Files.write("a", new File(repositoryClient.getWorkingCopy(), "a.txt"), Charsets.UTF_8);
repositoryClient.getAddCommand().add("a.txt");
commit(repositoryClient, "added a");
Files.write("b", new File(repositoryClient.getWorkingCopy(), "b.txt"), Charsets.UTF_8);
repositoryClient.getAddCommand().add("b.txt");
commit(repositoryClient, "added b");
}
private void cloneRepositoryAndCheckFiles(String url) throws IOException {
RepositoryClient repositoryClient = createRepositoryClient(url);
File workingCopy = repositoryClient.getWorkingCopy();
File a = new File(workingCopy, "a.txt");
assertTrue(a.exists());
assertEquals("a", Files.toString(a, Charsets.UTF_8));
File b = new File(workingCopy, "b.txt");
assertTrue(b.exists());
assertEquals("b", Files.toString(b, Charsets.UTF_8));
}
private void commit(RepositoryClient repositoryClient, String message) throws IOException {
private void commit(RepositoryClient repositoryClient, String message) throws IOException {
repositoryClient.getCommitCommand().commit(
new Person("scmadmin", "scmadmin@scm-manager.org"), message
);
@@ -136,7 +141,7 @@ public class GitRepositoryPathMatcherITCase {
repositoryClient.getPushCommand().push();
}
}
private RepositoryClient createRepositoryClient(String url) throws IOException {
return REPOSITORY_CLIENT_FACTORY.create("git", url, ADMIN_USERNAME, ADMIN_PASSWORD, tempFolder.newFolder());
}

View File

@@ -1,265 +0,0 @@
/**
* 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.junit.AfterClass;
import org.junit.Test;
import sonia.scm.group.Group;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
*
* @author Sebastian Sdorra
*/
public class GroupITCase extends AbstractAdminITCaseBase
{
/**
* Method description
*
*/
@AfterClass
public static void cleanup()
{
Client client = createClient();
authenticateAdmin(client);
createResource(client, "groups/group-a").delete();
createResource(client, "groups/group-c").delete();
client.destroy();
}
/**
* Method description
*
*/
@Test
public void create()
{
Group group = new Group();
group.setName("group-a");
group.setDescription("group a");
List<String> members = new ArrayList<String>();
members.add("slarti");
members.add("marvin");
members.add("dent");
group.setMembers(members);
createGroup(group);
}
/**
* Method description
*
*/
@Test
public void delete()
{
Group group = new Group();
group.setName("group-b");
group.setDescription("group b");
List<String> members = new ArrayList<String>();
members.add("slarti");
members.add("dent");
group.setMembers(members);
createGroup(group);
deleteGroup(group.getName());
}
/**
* Method description
*
*/
@Test
public void modify()
{
Group group = new Group();
group.setName("group-d");
group.setDescription("group d");
createGroup(group);
group = getGroup(group.getName());
group.setDescription("GROUP D");
WebResource wr = createResource(client, "groups/group-d");
ClientResponse response = wr.put(ClientResponse.class, group);
assertNotNull(response);
assertEquals(204, response.getStatus());
response.close();
Group other = getGroup("group-d");
assertEquals(group.getName(), other.getName());
assertEquals(group.getDescription(), other.getDescription());
assertNotNull(other.getLastModified());
deleteGroup(other.getName());
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*/
@Test
public void getAll()
{
Group group = new Group();
group.setName("group-c");
createGroup(group);
WebResource wr = createResource(client, "groups");
ClientResponse response = wr.get(ClientResponse.class);
Collection<Group> groups =
response.getEntity(new GenericType<Collection<Group>>() {}
);
response.close();
assertNotNull(groups);
assertFalse(groups.isEmpty());
Group groupC = null;
for (Group g : groups)
{
if (g.getName().equals("group-c"))
{
groupC = g;
}
}
assertNotNull(groupC);
assertNotNull(groupC.getCreationDate());
assertNotNull(groupC.getType());
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param group
*/
private void createGroup(Group group)
{
WebResource wr = createResource(client, "groups");
ClientResponse response = wr.post(ClientResponse.class, group);
assertNotNull(response);
assertEquals(201, response.getStatus());
response.close();
Group other = getGroup(group.getName());
assertNotNull(other);
assertNotNull(other.getType());
assertEquals(group.getName(), other.getName());
assertEquals(group.getDescription(), other.getDescription());
assertArrayEquals(other.getMembers().toArray(new String[0]),
group.getMembers().toArray(new String[0]));
assertNotNull(other.getCreationDate());
}
/**
* Method description
*
*
* @param name
*/
private void deleteGroup(String name)
{
WebResource wr = createResource(client, "groups/".concat(name));
ClientResponse response = wr.delete(ClientResponse.class);
assertNotNull(response);
assertEquals(204, response.getStatus());
response.close();
wr = createResource(client, "groups/".concat(name));
response = wr.get(ClientResponse.class);
assertNotNull(response);
assertEquals(404, response.getStatus());
response.close();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param groupname
*
* @return
*/
private Group getGroup(String groupname)
{
WebResource wr = createResource(client, "groups/".concat(groupname));
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
Group group = response.getEntity(Group.class);
response.close();
assertNotNull(group);
assertEquals(groupname, group.getName());
return group;
}
}

View File

@@ -1,185 +0,0 @@
/**
* 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.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import sonia.scm.group.Group;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class GroupPermissionITCase extends AbstractPermissionITCaseBase<Group>
{
/**
* Constructs ...
*
*
* @param credentials
*/
public GroupPermissionITCase(Credentials credentials)
{
super(credentials);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@AfterClass
public static void cleanup()
{
Client client = createClient();
authenticateAdmin(client);
createResource(client, "groups/test-group").delete();
client.destroy();
}
/**
* Method description
*
*/
@BeforeClass
public static void createTestGroup()
{
Group testGroup = new Group("xml", "test-group");
Client client = createClient();
authenticateAdmin(client);
WebResource wr = createResource(client, "groups");
ClientResponse response = wr.post(ClientResponse.class, testGroup);
assertNotNull(response);
assertEquals(201, response.getStatus());
response.close();
logoutClient(client);
client.destroy();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
protected String getBasePath()
{
return "groups";
}
/**
* Method description
*
*
* @return
*/
@Override
protected Group getCreateItem()
{
return new Group("xml", "create-test-group");
}
/**
* Method description
*
*
* @return
*/
@Override
protected String getDeletePath()
{
return "groups/test-group";
}
/**
* Method description
*
*
* @return
*/
@Override
protected String getGetPath()
{
return "groups/test-group";
}
/**
* Method description
*
*
* @return
*/
@Override
protected Group getModifyItem()
{
return new Group("xml", "test-group", "dent", "zaphod", "trillian");
}
/**
* Method description
*
*
* @return
*/
@Override
protected String getModifyPath()
{
return "groups/test-group";
}
}

View File

@@ -1,243 +0,0 @@
/**
* 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.junit.After;
import org.junit.Test;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- 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.Date;
import javax.ws.rs.core.EntityTag;
/**
*
* @author Sebastian Sdorra
*
* @param <T>
*/
public abstract class HttpCacheITCaseBase<T>
{
/**
* Method description
*
*
* @return
*/
protected abstract T createSampleItem();
/**
* Method description
*
*
* @param item
*/
protected abstract void destroy(T item);
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
protected abstract String getCollectionUrlPart();
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Test
public void changingCollectionETagTest()
{
ClientResponse response = getCollectionResponse();
String etag = getETag(response);
item = createSampleItem();
response = getCollectionResponse();
String otherEtag = getETag(response);
assertThat(etag, not(equalTo(otherEtag)));
}
/**
* Method description
*
*
* @throws InterruptedException
*/
@Test
public void changingCollectionLastModifiedTest() throws InterruptedException
{
ClientResponse response = getCollectionResponse();
long lastModified = getLastModified(response);
// wait 1 second because http date is not millisecond precision
Thread.sleep(1000l);
item = createSampleItem();
response = getCollectionResponse();
long otherLastModified = getLastModified(response);
assertNotEquals(lastModified, otherLastModified);
}
/**
* Method description
*
*/
@After
public void cleanup()
{
if (item != null)
{
destroy(item);
}
}
/**
* Method description
*
*/
@Test
public void simpleCollectionETagTest()
{
ClientResponse response = getCollectionResponse();
String etag = getETag(response);
response = getCollectionResponse();
String otherEtag = getETag(response);
assertEquals(etag, otherEtag);
}
/**
* Method description
*
*/
@Test
public void simpleCollectionLastModifiedTest()
{
ClientResponse response = getCollectionResponse();
long lastModified = getLastModified(response);
response = getCollectionResponse();
long otherLastModified = getLastModified(response);
assertEquals(lastModified, otherLastModified);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
private ClientResponse getCollectionResponse()
{
Client client = createAdminClient();
WebResource resource = createResource(client, getCollectionUrlPart());
ClientResponse response = resource.get(ClientResponse.class);
assertEquals(200, response.getStatus());
return response;
}
/**
* Method description
*
*
* @param response
*
* @return
*/
private String getETag(ClientResponse response)
{
EntityTag e = response.getEntityTag();
assertNotNull(e);
String value = e.getValue();
assertNotNull(value);
assertTrue(value.length() > 0);
return value;
}
/**
* Method description
*
*
* @param response
*
* @return
*/
private long getLastModified(ClientResponse response)
{
Date lastModified = response.getLastModified();
assertNotNull(lastModified);
return lastModified.getTime();
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private T item;
}

View File

@@ -35,32 +35,27 @@ package sonia.scm.it;
//~--- non-JDK imports --------------------------------------------------------
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.Resources;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.client.apache.ApacheHttpClient;
import com.sun.jersey.client.apache.config.ApacheHttpClientConfig;
import com.sun.jersey.client.apache.config.DefaultApacheHttpClientConfig;
import com.sun.jersey.core.util.MultivaluedMapImpl;
import sonia.scm.ScmState;
import sonia.scm.Type;
import de.otto.edison.hal.HalRepresentation;
import sonia.scm.api.rest.JSONContextResolver;
import sonia.scm.api.rest.ObjectMapperProvider;
import sonia.scm.repository.Person;
import sonia.scm.repository.client.api.ClientCommand;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.user.User;
import sonia.scm.util.IOUtil;
import javax.ws.rs.core.MultivaluedMap;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.UUID;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
@@ -83,7 +78,7 @@ public final class IntegrationTestUtil
public static final String BASE_URL = "http://localhost:8081/scm/";
/** scm-manager base url for the rest api */
public static final String REST_BASE_URL = BASE_URL.concat("api/rest/");
public static final String REST_BASE_URL = BASE_URL.concat("api/rest/v2/");
//~--- constructors ---------------------------------------------------------
@@ -95,72 +90,10 @@ public final class IntegrationTestUtil
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param client
* @param username
* @param password
*
* @return
*/
public static ClientResponse authenticate(Client client, String username, String password) {
WebResource wr = client.resource(createResourceUrl("auth/access_token"));
MultivaluedMap<String, String> formData = new MultivaluedMapImpl();
formData.add("username", username);
formData.add("password", password);
formData.add("cookie", "true");
formData.add("grant_type", "password");
return wr.type("application/x-www-form-urlencoded").post(ClientResponse.class, formData);
}
/**
* Method description
*
*
* @param client
*
* @return
*/
public static ScmState authenticateAdmin(Client client)
public static ScmClient createAdminClient()
{
ClientResponse cr = authenticate(client, ADMIN_USERNAME, ADMIN_PASSWORD);
ScmState state = cr.getEntity(ScmState.class);
cr.close();
assertNotNull(state);
assertTrue(state.isSuccess());
User user = state.getUser();
assertNotNull(user);
assertEquals("scmadmin", user.getName());
assertTrue(user.isAdmin());
Collection<Type> types = state.getRepositoryTypes();
assertNotNull(types);
assertFalse(types.isEmpty());
return state;
}
/**
* Method description
*
*
* @return
*/
public static Client createAdminClient()
{
Client client = createClient();
authenticateAdmin(client);
return client;
return new ScmClient("scmadmin", "scmadmin");
}
/**
@@ -178,76 +111,44 @@ public final class IntegrationTestUtil
return ApacheHttpClient.create(config);
}
/**
* Commit and push changes.
*
* @param repositoryClient repository client
* @param message commit message
*
* @throws IOException
*
* @since 1.51
*/
public static void commit(RepositoryClient repositoryClient, String message) throws IOException {
repositoryClient.getCommitCommand().commit(IntegrationTestUtil.AUTHOR, message);
if ( repositoryClient.isCommandSupported(ClientCommand.PUSH) ) {
repositoryClient.getPushCommand().push();
public static String serialize(Object o) {
ObjectMapper mapper = new ObjectMapperProvider().get();
try {
return mapper.writeValueAsString(o);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
/**
* Method description
*
* @param client
*
* @throws IOException
*/
public 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());
}
public static Collection<String> createRepositoryTypeParameters() {
Collection<String> params = new ArrayList<>();
client.getAddCommand().add(name);
}
/**
* Method description
*
*
* @return
*/
public static Collection<String[]> createRepositoryTypeParameters()
{
Collection<String[]> params = new ArrayList<>();
params.add(new String[] { "git" });
params.add(new String[] { "svn" });
params.add("git");
params.add("svn" );
if (IOUtil.search("hg") != null)
{
params.add(new String[] { "hg" });
params.add("hg");
}
return params;
}
/**
* Method description
*
*
* @param client
* @param url
*
* @return
*/
public static WebResource createResource(Client client, String url)
{
return client.resource(createResourceUrl(url));
public static URI getLink(HalRepresentation object, String linkName) {
return URI.create(object.getLinks().getLinkBy("delete").get().getHref());
}
public static WebResource.Builder createResource(ScmClient client, String url) {
return createResource(client, createResourceUrl(url));
}
public static WebResource.Builder createResource(ScmClient client, URI url) {
return client.resource(url.toString());
}
public static ClientResponse post(ScmClient client, String path, String mediaType, Object o) {
return createResource(client, path)
.type(mediaType)
.post(ClientResponse.class, serialize(o));
}
/**
@@ -258,41 +159,17 @@ public final class IntegrationTestUtil
*
* @return
*/
public static String createResourceUrl(String url)
public static URI createResourceUrl(String url)
{
return REST_BASE_URL.concat(url);
return URI.create(REST_BASE_URL).resolve(url);
}
/**
* Method description
*
*
* @return
*/
public static File createTempDirectory()
{
File directory = new File(System.getProperty("java.io.tmpdir"),
UUID.randomUUID().toString());
IOUtil.mkdirs(directory);
return directory;
}
/**
* Method description
*
*
* @param client
*/
public static void logoutClient(Client client)
{
WebResource wr = createResource(client, "auth/logout");
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
response.close();
client.destroy();
public static String readJson(String jsonFileName) {
URL url = Resources.getResource(jsonFileName);
try {
return Resources.toString(url, Charset.forName("UTF-8"));
} catch (IOException e) {
throw new RuntimeException("could not read json file " + jsonFileName, e);
}
}
}

View File

@@ -33,36 +33,38 @@
package sonia.scm.it;
//~--- non-JDK imports --------------------------------------------------------
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import sonia.scm.api.v2.resources.ConfigDto;
import sonia.scm.api.v2.resources.RepositoryDto;
import sonia.scm.web.VndMediaType;
import sonia.scm.config.ScmConfiguration;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import javax.ws.rs.core.MediaType;
import java.net.URI;
import java.util.Collection;
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.getLink;
import static sonia.scm.it.IntegrationTestUtil.readJson;
import static sonia.scm.it.IntegrationTestUtil.serialize;
import static sonia.scm.it.RepositoryITUtil.createRepository;
import static sonia.scm.it.RepositoryITUtil.deleteRepository;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class RepositoryArchiveITCase extends RepositoryTypeITCaseBase
public class RepositoryArchiveITCase
{
/**
@@ -78,16 +80,19 @@ public class RepositoryArchiveITCase extends RepositoryTypeITCaseBase
//~--- methods --------------------------------------------------------------
@Parameterized.Parameters(name = "{0}")
public static Collection<String> createParameters() {
return IntegrationTestUtil.createRepositoryTypeParameters();
}
/**
* Method description
*
*/
@Before
public void createTestRepository()
{
repository = RepositoryTestData.createHeartOfGold(type);
public void createTestRepository() {
client = createAdminClient();
repository = createRepository(client, repository);
repository = createRepository(client, readJson("repository-" + type + ".json"));
}
/**
@@ -101,10 +106,8 @@ public class RepositoryArchiveITCase extends RepositoryTypeITCaseBase
if (repository != null)
{
deleteRepository(client, repository.getId());
deleteRepository(client, repository);
}
logoutClient(client);
}
/**
@@ -112,20 +115,19 @@ public class RepositoryArchiveITCase extends RepositoryTypeITCaseBase
*
*/
@Test
public void testDeleteAllowed()
{
public void testDeleteAllowed() {
setArchiveMode(true);
WebResource resource = createResource(client,
"repositories/".concat(repository.getId()));
repository.setArchived(true);
ClientResponse response = resource.put(ClientResponse.class, repository);
ClientResponse response = createResource(client,
"repositories/" + repository.getNamespace() + "/" + repository.getName())
.type(VndMediaType.REPOSITORY).put(ClientResponse.class, serialize(repository));
assertNotNull(response);
assertEquals(204, response.getStatus());
response = resource.delete(ClientResponse.class);
response = createResource(client,
"repositories/" + repository.getNamespace() + "/" + repository.getName()).delete(ClientResponse.class);
assertNotNull(response);
assertEquals(204, response.getStatus());
repository = null;
@@ -140,16 +142,14 @@ public class RepositoryArchiveITCase extends RepositoryTypeITCaseBase
{
setArchiveMode(true);
WebResource resource = createResource(client,
"repositories/".concat(repository.getId()));
ClientResponse response = resource.delete(ClientResponse.class);
URI deleteUrl = getLink(repository, "delete");
ClientResponse response = createResource(client, deleteUrl).delete(ClientResponse.class);
assertNotNull(response);
assertEquals(412, response.getStatus());
response.close();
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
@@ -158,25 +158,23 @@ public class RepositoryArchiveITCase extends RepositoryTypeITCaseBase
*/
private void setArchiveMode(boolean archive)
{
WebResource resource = createResource(client, "config");
ScmConfiguration config = resource.get(ScmConfiguration.class);
WebResource.Builder resource = createResource(client, "config").type(MediaType.APPLICATION_JSON);
ConfigDto config = resource.get(ConfigDto.class);
assertNotNull(config);
config.setEnableRepositoryArchive(archive);
ClientResponse resp = resource.post(ClientResponse.class, config);
ClientResponse resp = createResource(client, "config").type(VndMediaType.CONFIG).put(ClientResponse.class, config);
assertNotNull(resp);
assertEquals(201, resp.getStatus());
assertEquals(204, resp.getStatus());
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private ScmClient client;
/** Field description */
private Client client;
/** Field description */
private Repository repository;
private RepositoryDto repository;
/** Field description */
private String type;

View File

@@ -1,184 +0,0 @@
/**
* 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.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import sonia.scm.repository.Repository;
import sonia.scm.user.User;
import sonia.scm.util.IOUtil;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.repository.client.api.RepositoryClientException;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class RepositoryExtendedITCase extends RepositoryITCaseBase
{
/**
* Constructs ...
*
*
* @param repository
* @param owner
* @param write
* @param read
* @param noperm
* @param password
*/
public RepositoryExtendedITCase(Repository repository, User owner,
User write, User read, User noperm,
String password)
{
super(repository, owner, write, read, noperm, password);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @throws IOException
*/
@After
public void cleanupTest() throws IOException
{
IOUtil.delete(directory);
}
/**
* Method description
*
*
* @throws IOException
*/
@Test(expected = RepositoryClientException.class)
public void readFailed() throws IOException
{
RepositoryClient rc = createRepositoryClient(nopermUser, directory);
// rc.checkout();
// ugly workaround
if (repository.getType().equals("git"))
{
for (File f : directory.listFiles())
{
if (!".git".equals(f.getName()))
{
fail("checkout works");
}
}
throw new IOException("checkout failed");
}
}
/**
* Method description
*
*/
@Before
public void setupTest()
{
directory = createTempDirectory();
}
/**
* Method description
*
*
* @throws IOException
*/
@Test
public void simpleRead() throws IOException
{
RepositoryClient rc = createRepositoryClient(readUser, directory);
// rc.checkout();
}
/**
* Method description
*
* @throws IOException
*/
@Test
public void simpleWrite() throws IOException
{
RepositoryClient rc = createRepositoryClient(writeUser, directory);
// rc.checkout();
addTestFiles(rc);
}
/**
* Method description
*
* @throws IOException
*/
@Test(expected = IOException.class)
public void writeFailed() throws IOException
{
RepositoryClient rc = createRepositoryClient(readUser, directory);
// rc.checkout();
addTestFiles(rc);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private File directory;
}

View File

@@ -31,7 +31,6 @@
package sonia.scm.it;
import com.google.common.base.Charsets;
import com.google.common.collect.Lists;
import com.google.common.io.Files;
import com.sun.jersey.api.client.WebResource;
import org.junit.After;
@@ -43,26 +42,25 @@ import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import sonia.scm.api.v2.resources.RepositoryDto;
import sonia.scm.debug.DebugHookData;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.Person;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.repository.client.api.ClientCommand;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.repository.client.api.RepositoryClientFactory;
import sonia.scm.util.IOUtil;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.core.AllOf.allOf;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static sonia.scm.it.IntegrationTestUtil.createResource;
import static sonia.scm.it.IntegrationTestUtil.readJson;
import static sonia.scm.it.RepositoryITUtil.createRepository;
import static sonia.scm.it.RepositoryITUtil.deleteRepository;
@@ -83,7 +81,7 @@ public class RepositoryHookITCase extends AbstractAdminITCaseBase
public TemporaryFolder tempFolder = new TemporaryFolder();
private final String repositoryType;
private Repository repository;
private RepositoryDto repository;
private File workingCopy;
private RepositoryClient repositoryClient;
@@ -105,8 +103,7 @@ public class RepositoryHookITCase extends AbstractAdminITCaseBase
@Before
public void setUpTestRepository() throws IOException
{
repository = RepositoryTestData.createHeartOfGold(repositoryType);
repository = createRepository(client, repository);
repository = createRepository(client, readJson("repository-" + repositoryType + ".json"));
workingCopy = tempFolder.newFolder();
repositoryClient = createRepositoryClient();
}
@@ -117,7 +114,9 @@ public class RepositoryHookITCase extends AbstractAdminITCaseBase
@After
public void removeTestRepository()
{
deleteRepository(client, repository.getId());
if (repository != null) {
deleteRepository(client, repository);
}
}
/**
@@ -138,7 +137,7 @@ public class RepositoryHookITCase extends AbstractAdminITCaseBase
Thread.sleep(WAIT_TIME);
// check debug servlet for pushed commit
WebResource wr = createResource(client, "debug/" + repository.getId() + "/post-receive/last");
WebResource.Builder wr = createResource(client, "../debug/" + repository.getNamespace() + "/" + repository.getName() + "/post-receive/last");
DebugHookData data = wr.get(DebugHookData.class);
assertNotNull(data);
assertThat(data.getChangesets(), contains(changeset.getId()));
@@ -173,7 +172,7 @@ public class RepositoryHookITCase extends AbstractAdminITCaseBase
Thread.sleep(WAIT_TIME);
// check debug servlet that only one commit is present
WebResource wr = createResource(client, "debug/" + repository.getId() + "/post-receive/last");
WebResource.Builder wr = createResource(client, "../debug/" + repository.getNamespace() + "/" + repository.getName() + "/post-receive/last");
DebugHookData data = wr.get(DebugHookData.class);
assertNotNull(data);
assertThat(data.getChangesets(), allOf(
@@ -197,7 +196,7 @@ public class RepositoryHookITCase extends AbstractAdminITCaseBase
private RepositoryClient createRepositoryClient() throws IOException
{
return REPOSITORY_CLIENT_FACTORY.create(repositoryType,
IntegrationTestUtil.BASE_URL + repositoryType + "/" + repository.getName(),
IntegrationTestUtil.BASE_URL + repositoryType + "/" + repository.getNamespace() + "/" + repository.getName(),
IntegrationTestUtil.ADMIN_USERNAME, IntegrationTestUtil.ADMIN_PASSWORD, workingCopy
);
}
@@ -208,16 +207,10 @@ public class RepositoryHookITCase extends AbstractAdminITCaseBase
*
* @return repository types test parameter
*/
@Parameters
public static Collection<String[]> createParameters()
@Parameters(name = "{0}")
public static Collection<String> createParameters()
{
Collection<String[]> params = Lists.newArrayList();
params.add(new String[] { "git" });
params.add(new String[] { "svn" });
if (IOUtil.search("hg") != null) {
params.add(new String[] { "hg" });
}
return params;
return IntegrationTestUtil.createRepositoryTypeParameters();
}
}

View File

@@ -1,119 +0,0 @@
/**
* 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 sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
/**
*
* @author Sebastian Sdorra
*/
public class RepositoryHttpCacheITCase extends HttpCacheITCaseBase<Repository>
{
/**
* Method description
*
*
* @return
*/
@Override
protected Repository createSampleItem()
{
Repository repository = RepositoryTestData.createHeartOfGold("git");
Client client = createAdminClient();
WebResource resource = createResource(client, "repositories");
ClientResponse response = resource.post(ClientResponse.class, repository);
assertNotNull(response);
assertEquals(201, response.getStatus());
String location = response.getHeaders().get("Location").get(0);
assertNotNull(location);
resource = client.resource(location);
response = resource.get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
repository = response.getEntity(Repository.class);
assertNotNull(repository);
assertNotNull(repository.getId());
return repository;
}
/**
* Method description
*
*
* @param item
*/
@Override
protected void destroy(Repository item)
{
Client client = createAdminClient();
WebResource resource = createResource(client,
"repositories/".concat(item.getId()));
ClientResponse response = resource.delete(ClientResponse.class);
assertNotNull(response);
assertEquals(204, response.getStatus());
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
protected String getCollectionUrlPart()
{
return "repositories";
}
}

View File

@@ -1,259 +0,0 @@
/**
* 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 com.google.common.collect.Lists;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import sonia.scm.repository.Permission;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import java.util.Arrays;
import java.util.Collection;
import org.junit.After;
import sonia.scm.util.IOUtil;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class RepositoryITCase extends AbstractAdminITCaseBase
{
/**
* Constructs ...
*
*
* @param repositoryType
*/
public RepositoryITCase(String repositoryType)
{
this.repositoryType = repositoryType;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@After
public void cleanup()
{
Collection<Repository> repositories =
createResource(client,
"repositories").get(new GenericType<Collection<Repository>>() {}
);
if (repositories != null)
{
for (Repository r : repositories)
{
createResource(client, "repositories/" + r.getId()).delete();
}
}
client.destroy();
}
/**
* Method description
*
*
* @return
*/
@Parameters
public static Collection<String[]> createParameters()
{
Collection<String[]> params = Lists.newArrayList();
params.add(new String[] { "git" });
params.add(new String[] { "svn" });
if (IOUtil.search("hg") != null)
{
params.add(new String[] { "hg" });
}
return params;
}
/**
* Method description
*
>>>>>>> merge rev
*/
@Test
public void create()
{
Repository repository =
RepositoryTestData.createHeartOfGold(repositoryType);
createRepository(client, repository);
}
/**
* Method description
*
*/
@Test
public void delete()
{
Repository repository =
RepositoryTestData.createHappyVerticalPeopleTransporter(repositoryType);
repository = createRepository(client, repository);
deleteRepository(client, repository.getId());
}
/**
* Method description
*
*/
@Test
public void doubleCreate()
{
Repository repository = RepositoryTestData.create42Puzzle(repositoryType);
repository = createRepository(client, repository);
WebResource wr = createResource(client, "repositories");
ClientResponse response = wr.post(ClientResponse.class, repository);
assertNotNull(response);
assertThat(response.getStatus(), not(lessThanOrEqualTo(400)));
}
/**
* Method description
*
*/
@Test
public void modify()
{
Repository repository =
RepositoryTestData.createHappyVerticalPeopleTransporter(repositoryType);
repository = createRepository(client, repository);
repository.setPermissions(Arrays.asList(new Permission("dent",
PermissionType.READ), new Permission("slarti", PermissionType.WRITE)));
WebResource wr = createResource(client,
"repositories/".concat(repository.getId()));
ClientResponse response = wr.put(ClientResponse.class, repository);
assertNotNull(response);
assertEquals(204, response.getStatus());
response.close();
Repository other = getRepositoryById(client, repository.getId());
assertRepositoriesEquals(repository, other);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*/
@Test
public void getAll()
{
Repository repository =
RepositoryTestData.createHappyVerticalPeopleTransporter(repositoryType);
repository = createRepository(client, repository);
WebResource wr = createResource(client, "repositories");
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
Collection<Repository> repositories =
response.getEntity(new GenericType<Collection<Repository>>() {}
);
response.close();
assertNotNull(repositories);
assertFalse(repositories.isEmpty());
Repository hvpt = null;
for (Repository other : repositories)
{
// fix equals check
other.getPermissions();
if (repository.equals(other))
{
hvpt = other;
break;
}
}
assertNotNull(hvpt);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final String repositoryType;
}

View File

@@ -1,359 +0,0 @@
/**
* 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.junit.AfterClass;
import org.junit.runners.Parameterized.Parameters;
import sonia.scm.ScmState;
import sonia.scm.Type;
import sonia.scm.repository.Permission;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryTestData;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import sonia.scm.util.IOUtil;
import sonia.scm.util.Util;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static sonia.scm.it.RepositoryITUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.GenericType;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.repository.client.api.RepositoryClientFactory;
/**
*
* @author Sebastian Sdorra
*/
public class RepositoryITCaseBase
{
/**
* Constructs ...
*
*
* @param repository
* @param owner
* @param write
* @param read
* @param noperm
* @param password
*/
public RepositoryITCaseBase(Repository repository, User owner, User write,
User read, User noperm, String password)
{
this.repository = repository;
this.ownerUser = owner;
this.writeUser = write;
this.readUser = read;
this.nopermUser = noperm;
this.password = password;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param client
*
* @throws IOException
*/
public static void addTestFiles(RepositoryClient client) throws IOException
{
for (int i = 0; i < 5; i++)
{
createRandomFile(client);
}
commit(client, "added some test files");
}
/**
* Method description
*
* @param repository
* @param username
* @param password
*
* @throws IOException
*/
public static void addTestFiles(Repository repository, String username,
String password)
throws IOException
{
File directory = createTempDirectory();
try
{
RepositoryClientFactory clientFactory = new RepositoryClientFactory();
RepositoryClient client = clientFactory.create(
repository.getType(), repository.createUrl(BASE_URL), username, password, directory
);
addTestFiles(client);
}
finally
{
IOUtil.delete(directory);
}
}
/**
* Method description
*
*/
@AfterClass
public static void cleanup()
{
Client client = createAdminClient();
deleteUser(client, UserTestData.createTrillian());
deleteUser(client, UserTestData.createZaphod());
deleteUser(client, UserTestData.createMarvin());
deleteUser(client, UserTestData.createPerfect());
Collection<Repository> repositories =
createResource(client, "repositories").get(
new GenericType<Collection<Repository>>() {}
);
if (repositories != null)
{
for (Repository r : repositories)
{
createResource(client, "repositories/" + r.getId()).delete();
}
}
client.destroy();
}
/**
* Method description
*
*
* @return
*
* @throws IOException
*/
@Parameters
public static Collection<Object[]> createParameters() throws IOException
{
Client client = createClient();
ScmState state = authenticateAdmin(client);
assertNotNull(state);
assertTrue(state.isSuccess());
Collection<Object[]> params = new ArrayList<>();
User owner = UserTestData.createTrillian();
createUser(owner);
User write = UserTestData.createZaphod();
createUser(write);
User read = UserTestData.createMarvin();
createUser(read);
User noperm = UserTestData.createPerfect();
createUser(noperm);
for (Type t : state.getRepositoryTypes())
{
appendTestParemeter(params, t.getName(), owner, write, read, noperm);
}
return params;
}
/**
* Method description
*
*
* @param params
* @param type
* @param owner
* @param write
* @param read
* @param noperm
*
* @throws IOException
* @throws RepositoryClientException
*/
private static void appendTestParemeter(Collection<Object[]> params,
String type, User owner, User write, User read, User noperm) throws IOException
{
Repository repository = createTestRepository(null, type, owner, write, read);
params.add(new Object[]
{
repository, owner, write, read, noperm, "secret"
});
repository = createTestRepository("test", type, owner, write, read);
params.add(new Object[]
{
repository, owner, write, read, noperm, "secret"
});
}
/**
* Method description
*
*
*
* @param prefix
* @param type
* @param owner
* @param write
* @param read
*
* @return
*
* @throws IOException
* @throws RepositoryClientException
*/
private static Repository createTestRepository(String prefix, String type,
User owner, User write, User read) throws IOException
{
Client client = createAdminClient();
Repository repository = RepositoryTestData.createHeartOfGold(type);
if (Util.isNotEmpty(prefix))
{
repository.setName(prefix.concat("/").concat(repository.getName()));
}
//J-
repository.setPermissions(Arrays.asList(
new Permission(owner.getName(), PermissionType.OWNER),
new Permission(write.getName(), PermissionType.WRITE),
new Permission(read.getName(), PermissionType.READ))
);
//J+
repository = createRepository(client, repository);
client.destroy();
addTestFiles(repository, ADMIN_USERNAME, ADMIN_PASSWORD);
return repository;
}
/**
* Method description
*
*
* @param user
*/
private static void createUser(User user)
{
Client client = createAdminClient();
user.setPassword("secret");
createResource(client, "users").post(user);
client.destroy();
}
/**
* Method description
*
*
* @param client
* @param user
*/
private static void deleteUser(Client client, User user)
{
createResource(client, "users/".concat(user.getName())).delete();
}
/**
* Method description
*
*
* @param user
* @param directory
*
* @return
*
* @throws IOException
*/
protected RepositoryClient createRepositoryClient(User user, File directory) throws IOException
{
RepositoryClientFactory clientFactory = new RepositoryClientFactory();
return clientFactory.create(repository.getType(), repository.createUrl(BASE_URL),
user.getName(), password, directory);
}
//~--- fields ---------------------------------------------------------------
/** Field description */
protected User nopermUser;
/** Field description */
protected User ownerUser;
/** Field description */
protected String password;
/** Field description */
protected User readUser;
/** Field description */
protected Repository repository;
/** Field description */
protected User writeUser;
}

View File

@@ -35,119 +35,84 @@ package sonia.scm.it;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.repository.Repository;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import sonia.scm.api.rest.ObjectMapperProvider;
import sonia.scm.api.v2.resources.RepositoryDto;
import sonia.scm.web.VndMediaType;
import static org.junit.Assert.*;
import java.io.IOException;
import java.net.URI;
import static sonia.scm.it.IntegrationTestUtil.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static sonia.scm.it.IntegrationTestUtil.BASE_URL;
import static sonia.scm.it.IntegrationTestUtil.createResource;
import static sonia.scm.it.IntegrationTestUtil.getLink;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
/**
*
* @author Sebastian Sdorra
*/
public final class RepositoryITUtil
{
/**
* Constructs ...
*
*/
private RepositoryITUtil() {}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
* @param repository
* @param other
*/
public static void assertRepositoriesEquals(Repository repository, Repository other)
{
assertEquals(repository.getName(), other.getName());
assertEquals(repository.getDescription(), other.getDescription());
assertEquals(repository.getContact(), other.getContact());
assertEquals(repository.getPermissions(), other.getPermissions());
assertEquals(repository.getType(), other.getType());
}
/**
* Method description
*
* @param client
* @param repository
*
* @return
*/
public static Repository createRepository(Client client,
Repository repository)
{
WebResource wr = createResource(client, "repositories");
ClientResponse response = wr.post(ClientResponse.class, repository);
public static RepositoryDto createRepository(ScmClient client, String repositoryJson) {
ClientResponse response =
createResource(client, "repositories")
.accept("*/*")
.type(VndMediaType.REPOSITORY)
.post(ClientResponse.class, repositoryJson);
assertNotNull(response);
assertEquals(201, response.getStatus());
String url = response.getHeaders().get("Location").get(0);
URI url = URI.create(response.getHeaders().get("Location").get(0));
response.close();
Repository other = getRepository(client, url);
RepositoryDto other = getRepository(client, url);
assertNotNull(other);
assertNotNull(other.getType());
assertRepositoriesEquals(repository, other);
assertNotNull(other.getId());
assertNotNull(other.getNamespace());
assertNotNull(other.getCreationDate());
return other;
}
/**
* Method description
*
* @param client
* @param id
*/
public static void deleteRepository(Client client, String id)
public static void deleteRepository(ScmClient client, RepositoryDto repository)
{
WebResource wr = createResource(client, "repositories/".concat(id));
ClientResponse response = wr.delete(ClientResponse.class);
URI deleteUrl = getLink(repository, "delete");
ClientResponse response = createResource(client, deleteUrl).delete(ClientResponse.class);
assertNotNull(response);
assertEquals(204, response.getStatus());
response.close();
wr = createResource(client, "repositories/".concat(id));
response = wr.get(ClientResponse.class);
URI selfUrl = getLink(repository, "self");
response = createResource(client, selfUrl).get(ClientResponse.class);
assertNotNull(response);
assertEquals(404, response.getStatus());
response.close();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
* @param client
* @param url
*
* @return
*/
public static Repository getRepository(Client client, String url)
public static RepositoryDto getRepository(ScmClient client, URI url)
{
WebResource wr = client.resource(url);
WebResource.Builder wr = createResource(client, url);
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
Repository repository = response.getEntity(Repository.class);
String json = response.getEntity(String.class);
RepositoryDto repository = null;
try {
repository = new ObjectMapperProvider().get().readerFor(RepositoryDto.class).readValue(json);
} catch (IOException e) {
fail("could not read json:\n" + json);
}
response.close();
assertNotNull(repository);
@@ -155,26 +120,7 @@ public final class RepositoryITUtil
return repository;
}
/**
* Method description
*
* @param client
* @param id
*
* @return
*/
public static Repository getRepositoryById(Client client, String id)
{
WebResource wr = createResource(client, "repositories/".concat(id));
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
Repository repository = response.getEntity(Repository.class);
response.close();
assertNotNull(repository);
return repository;
public static String createUrl(RepositoryDto repository) {
return BASE_URL + repository.getType() + "/" + repository.getNamespace() + "/" + repository.getName();
}
}

View File

@@ -35,37 +35,39 @@ package sonia.scm.it;
//~--- non-JDK imports --------------------------------------------------------
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import de.otto.edison.hal.HalRepresentation;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import sonia.scm.api.rest.ObjectMapperProvider;
import sonia.scm.api.v2.resources.RepositoryDto;
import sonia.scm.web.VndMediaType;
import sonia.scm.repository.Repository;
import java.io.IOException;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static sonia.scm.it.IntegrationTestUtil.createAdminClient;
import static sonia.scm.it.IntegrationTestUtil.createResource;
import static sonia.scm.it.IntegrationTestUtil.serialize;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import java.util.Collection;
/**
*
* @author Sebastian Sdorra
*/
@RunWith(Parameterized.class)
public class RepositorySimplePermissionITCase
extends AbstractPermissionITCaseBase<Repository>
extends AbstractPermissionITCaseBase<RepositoryDto>
{
/** Field description */
private static String REPOSITORY_UUID;
private static String REPOSITORY_PATH;
//~--- constructors ---------------------------------------------------------
@@ -75,7 +77,7 @@ public class RepositorySimplePermissionITCase
*
* @param credentials
*/
public RepositorySimplePermissionITCase(Credentials credentials)
public RepositorySimplePermissionITCase(Credentials credentials, String ignore_testCaseName)
{
super(credentials);
}
@@ -87,20 +89,17 @@ public class RepositorySimplePermissionITCase
*
*/
@BeforeClass
public static void createTestRepository()
{
Repository repository = new Repository();
public static void createTestRepository() throws IOException {
RepositoryDto repository = new RepositoryDto();
repository.setName("test-repo");
repository.setType("git");
repository.setPublicReadable(false);
// repository.setPublicReadable(false);
Client client = createClient();
ScmClient client = createAdminClient();
authenticateAdmin(client);
WebResource wr = createResource(client, "repositories");
ClientResponse response = wr.post(ClientResponse.class, repository);
WebResource.Builder wr = createResource(client, "repositories");
ClientResponse response = wr.type(VndMediaType.REPOSITORY).post(ClientResponse.class, serialize(repository));
assertNotNull(response);
assertEquals(201, response.getStatus());
@@ -109,17 +108,13 @@ public class RepositorySimplePermissionITCase
assertNotNull(repositoryUrl);
response.close();
wr = client.resource(repositoryUrl);
response = wr.get(ClientResponse.class);
response = client.resource(repositoryUrl).get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
repository = response.getEntity(Repository.class);
assertNotNull(repository);
REPOSITORY_UUID = repository.getId();
assertNotNull(REPOSITORY_UUID);
repository = new ObjectMapperProvider().get().readValue(response.getEntity(String.class), RepositoryDto.class);
REPOSITORY_PATH = repository.getNamespace() + "/" + repository.getName();
assertNotNull(REPOSITORY_PATH);
response.close();
logoutClient(client);
client.destroy();
}
/**
@@ -127,13 +122,9 @@ public class RepositorySimplePermissionITCase
*
*/
@AfterClass
public static void removeTestRepoistory()
public static void removeTestRepository()
{
Client client = createClient();
authenticateAdmin(client);
createResource(client, "repositories/" + REPOSITORY_UUID).delete();
client.destroy();
createResource(createAdminClient(), "repositories/" + REPOSITORY_PATH).delete();
}
/**
@@ -150,12 +141,16 @@ public class RepositorySimplePermissionITCase
assertNotNull(response);
assertEquals(200, response.getStatus());
Collection<Repository> repositories =
response.getEntity(new GenericType<Collection<Repository>>() {}
);
HalRepresentation repositories =
null;
try {
repositories = new ObjectMapperProvider().get().readValue(response.getEntity(String.class), HalRepresentation.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
assertNotNull(repositories);
assertTrue(repositories.isEmpty());
assertTrue(repositories.getEmbedded().getItemsBy("repositories").isEmpty());
response.close();
}
}
@@ -198,9 +193,9 @@ public class RepositorySimplePermissionITCase
* @return
*/
@Override
protected Repository getCreateItem()
protected RepositoryDto getCreateItem()
{
Repository repository = new Repository();
RepositoryDto repository = new RepositoryDto();
repository.setName("create-test-repo");
repository.setType("svn");
@@ -217,7 +212,7 @@ public class RepositorySimplePermissionITCase
@Override
protected String getDeletePath()
{
return "repositories/".concat(REPOSITORY_UUID);
return "repositories/".concat(REPOSITORY_PATH);
}
/**
@@ -229,7 +224,7 @@ public class RepositorySimplePermissionITCase
@Override
protected String getGetPath()
{
return "repositories/".concat(REPOSITORY_UUID);
return "repositories/".concat(REPOSITORY_PATH);
}
/**
@@ -239,11 +234,12 @@ public class RepositorySimplePermissionITCase
* @return
*/
@Override
protected Repository getModifyItem()
protected RepositoryDto getModifyItem()
{
Repository repository = new Repository();
RepositoryDto repository = new RepositoryDto();
repository.setName("test-repo");
repository.setNamespace("scmadmin");
repository.setType("git");
repository.setDescription("Test Repository");
@@ -259,6 +255,11 @@ public class RepositorySimplePermissionITCase
@Override
protected String getModifyPath()
{
return "repositories/".concat(REPOSITORY_UUID);
return "repositories/".concat(REPOSITORY_PATH);
}
@Override
protected String getMediaType() {
return VndMediaType.REPOSITORY;
}
}

View File

@@ -1,74 +0,0 @@
/**
* 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.junit.runners.Parameterized.Parameters;
import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------
import java.util.ArrayList;
import java.util.Collection;
/**
*
* @author Sebastian Sdorra
*/
public class RepositoryTypeITCaseBase
{
/**
* Method description
*
*
* @return
*/
@Parameters
public static Collection<String[]> createParameters()
{
Collection<String[]> params = new ArrayList<String[]>();
params.add(new String[] { "git" });
params.add(new String[] { "svn" });
if (IOUtil.search("hg") != null)
{
params.add(new String[] { "hg" });
}
return params;
}
}

View File

@@ -0,0 +1,37 @@
package sonia.scm.it;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import java.util.Base64;
import static sonia.scm.it.IntegrationTestUtil.createClient;
public class ScmClient {
private final String user;
private final String password;
private final Client client;
public static ScmClient anonymous() {
return new ScmClient(null, null);
}
public ScmClient(String user, String password) {
this.user = user;
this.password = password;
this.client = createClient();
}
public WebResource.Builder resource(String url) {
if (user == null) {
return client.resource(url).getRequestBuilder();
} else {
return client.resource(url).header("Authorization", createAuthHeaderValue());
}
}
public String createAuthHeaderValue() {
return "Basic " + Base64.getEncoder().encodeToString((user +":"+ password).getBytes());
}
}

View File

@@ -1,297 +0,0 @@
/**
* 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.junit.AfterClass;
import org.junit.Test;
import sonia.scm.ScmState;
import sonia.scm.Type;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import static org.junit.Assert.*;
import static sonia.scm.it.IntegrationTestUtil.*;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.GenericType;
import com.sun.jersey.api.client.WebResource;
import java.util.Collection;
import javax.ws.rs.core.MediaType;
/**
*
* @author Sebastian Sdorra
*/
public class UserITCase extends AbstractAdminITCaseBase
{
/**
* Method description
*
*/
@AfterClass
public static void cleanup()
{
Client client = createClient();
authenticateAdmin(client);
createResource(client, "users/slarti").delete();
client.destroy();
}
/**
* Method description
*
*/
@Test
public void create()
{
User slarti = UserTestData.createSlarti();
slarti.setPassword("slarti123");
createUser(slarti);
}
/**
* Method description
*
*/
@Test
public void delete()
{
User dent = UserTestData.createDent();
createUser(dent);
deleteUser(dent);
}
/**
* Method description
*
*/
@Test
public void modify()
{
User marvin = UserTestData.createMarvin();
createUser(marvin);
marvin = getUser(marvin.getName());
marvin.setDisplayName("Paranoid Android");
WebResource wr = createResource(client, "users/".concat(marvin.getName()));
ClientResponse response =
wr.type(MediaType.APPLICATION_XML).put(ClientResponse.class, marvin);
assertNotNull(response);
assertEquals(204, response.getStatus());
response.close();
User other = getUser(marvin.getName());
assertEquals(marvin.getDisplayName(), other.getDisplayName());
assertNotNull(other.getLastModified());
deleteUser(marvin);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*/
@Test
public void get()
{
User scmadmin = getUser("scmadmin");
testAdmin(scmadmin);
}
/**
* Method description
*
*/
@Test
public void getAll()
{
WebResource wr = createResource(client, "users");
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
Collection<User> users =
response.getEntity(new GenericType<Collection<User>>() {}
);
response.close();
assertNotNull(users);
assertFalse(users.isEmpty());
User admin = null;
for (User user : users)
{
if (user.getName().equals("scmadmin"))
{
admin = user;
}
}
testAdmin(admin);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param client
*/
protected void adminLogin(Client client)
{
ClientResponse cr = authenticate(client, "scmadmin", "scmadmin");
ScmState state = cr.getEntity(ScmState.class);
cr.close();
assertNotNull(state);
assertTrue(state.isSuccess());
User user = state.getUser();
assertNotNull(user);
assertEquals("scmadmin", user.getName());
assertTrue(user.isAdmin());
Collection<Type> types = state.getRepositoryTypes();
assertNotNull(types);
assertFalse(types.isEmpty());
}
/**
* Method description
*
*
* @param user
*/
private void createUser(User user)
{
WebResource wr = createResource(client, "users");
ClientResponse response =
wr.type(MediaType.APPLICATION_XML).post(ClientResponse.class, user);
assertNotNull(response);
assertEquals(201, response.getStatus());
response.close();
User other = getUser(user.getName());
assertEquals(user.getName(), other.getName());
assertEquals(user.getDisplayName(), other.getDisplayName());
assertEquals(user.getMail(), other.getMail());
assertNotNull(other.getType());
assertNotNull(other.getCreationDate());
}
/**
* Method description
*
*
* @param user
*/
private void deleteUser(User user)
{
WebResource wr = createResource(client, "users/".concat(user.getName()));
ClientResponse response = wr.delete(ClientResponse.class);
assertNotNull(response);
assertEquals(204, response.getStatus());
response.close();
wr = createResource(client, "users/".concat(user.getName()));
response = wr.get(ClientResponse.class);
assertNotNull(response);
assertEquals(404, response.getStatus());
response.close();
}
/**
* Method description
*
*
* @param user
*/
private void testAdmin(User user)
{
assertNotNull(user);
assertEquals(user.getName(), "scmadmin");
assertTrue(user.isAdmin());
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param username
*
* @return
*/
private User getUser(String username)
{
WebResource wr = createResource(client, "users/".concat(username));
ClientResponse response = wr.get(ClientResponse.class);
assertNotNull(response);
assertEquals(200, response.getStatus());
User user = response.getEntity(User.class);
response.close();
assertNotNull(user);
return user;
}
}

View File

@@ -0,0 +1,13 @@
package sonia.scm.it;
import com.sun.jersey.api.client.ClientResponse;
import sonia.scm.user.User;
import sonia.scm.web.VndMediaType;
import static sonia.scm.it.IntegrationTestUtil.post;
public class UserITUtil {
public static ClientResponse postUser(ScmClient client, User user) {
return post(client, "users", VndMediaType.USER, user);
}
}

View File

@@ -35,11 +35,20 @@ package sonia.scm.it;
//~--- non-JDK imports --------------------------------------------------------
import com.sun.jersey.api.client.ClientResponse;
import de.otto.edison.hal.HalRepresentation;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import sonia.scm.api.rest.ObjectMapperProvider;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import sonia.scm.web.VndMediaType;
import java.io.IOException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
/**
*
@@ -55,7 +64,7 @@ public class UserPermissionITCase extends AbstractPermissionITCaseBase<User>
*
* @param credentials
*/
public UserPermissionITCase(Credentials credentials)
public UserPermissionITCase(Credentials credentials, String ignore_testCaseName)
{
super(credentials);
}
@@ -140,4 +149,31 @@ public class UserPermissionITCase extends AbstractPermissionITCaseBase<User>
{
return "users/scmadmin";
}
@Override
protected String getMediaType() {
return VndMediaType.USER;
}
@Override
protected void checkGetAllResponse(ClientResponse response)
{
if (!credentials.isAnonymous())
{
assertNotNull(response);
assertEquals(200, response.getStatus());
HalRepresentation repositories =
null;
try {
repositories = new ObjectMapperProvider().get().readValue(response.getEntity(String.class), HalRepresentation.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
assertNotNull(repositories);
assertTrue(repositories.getEmbedded().getItemsBy("users").isEmpty());
response.close();
}
}
}

View File

@@ -0,0 +1,7 @@
{
"contact": "zaphod.beeblebrox@hitchhiker.com",
"description": "Heart of Gold is the first prototype ship to successfully utilise the revolutionary Infinite Improbability Drive",
"name": "HeartOfGold-git",
"archived": false,
"type": "git"
}

View File

@@ -0,0 +1,7 @@
{
"contact": "zaphod.beeblebrox@hitchhiker.com",
"description": "Heart of Gold is the first prototype ship to successfully utilise the revolutionary Infinite Improbability Drive",
"name": "HeartOfGold-hg",
"archived": false,
"type": "hg"
}

View File

@@ -0,0 +1,7 @@
{
"contact": "zaphod.beeblebrox@hitchhiker.com",
"description": "Heart of Gold is the first prototype ship to successfully utilise the revolutionary Infinite Improbability Drive",
"name": "HeartOfGold-svn",
"archived": false,
"type": "svn"
}