mockSetPathInfo() {
- return when(pathInfoStore.get()).thenReturn(() -> URI.create("http://example.com/scm/api/rest/"));
+ return when(pathInfoStore.get()).thenReturn(() -> URI.create("http://example.com/scm/api/"));
}
}
diff --git a/scm-core/src/test/java/sonia/scm/web/JsonEnricherBaseTest.java b/scm-core/src/test/java/sonia/scm/web/JsonEnricherBaseTest.java
new file mode 100644
index 0000000000..43ed4940fa
--- /dev/null
+++ b/scm-core/src/test/java/sonia/scm/web/JsonEnricherBaseTest.java
@@ -0,0 +1,51 @@
+package sonia.scm.web;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import org.junit.Test;
+
+import javax.ws.rs.core.MediaType;
+
+import static java.util.Collections.singletonMap;
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class JsonEnricherBaseTest {
+
+ private ObjectMapper objectMapper = new ObjectMapper();
+ private TestJsonEnricher enricher = new TestJsonEnricher(objectMapper);
+
+ @Test
+ public void testResultHasMediaType() {
+ JsonEnricherContext context = new JsonEnricherContext(null, MediaType.APPLICATION_JSON_TYPE, null);
+
+ assertThat(enricher.resultHasMediaType(MediaType.APPLICATION_JSON, context)).isTrue();
+ assertThat(enricher.resultHasMediaType(MediaType.APPLICATION_XML, context)).isFalse();
+ }
+
+ @Test
+ public void testAppendLink() {
+ ObjectNode root = objectMapper.createObjectNode();
+ ObjectNode links = objectMapper.createObjectNode();
+ root.set("_links", links);
+ JsonEnricherContext context = new JsonEnricherContext(null, MediaType.APPLICATION_JSON_TYPE, root);
+ enricher.enrich(context);
+
+ assertThat(links.get("awesome").get("href").asText()).isEqualTo("/my/awesome/link");
+ }
+
+ private static class TestJsonEnricher extends JsonEnricherBase {
+
+ public TestJsonEnricher(ObjectMapper objectMapper) {
+ super(objectMapper);
+ }
+
+ @Override
+ public void enrich(JsonEnricherContext context) {
+ JsonNode gitConfigRefNode = createObject(singletonMap("href", value("/my/awesome/link")));
+
+ addPropertyNode(context.getResponseEntity().get("_links"), "awesome", gitConfigRefNode);
+ }
+ }
+
+}
diff --git a/scm-it/src/test/java/sonia/scm/it/IndexITCase.java b/scm-it/src/test/java/sonia/scm/it/IndexITCase.java
new file mode 100644
index 0000000000..4a621d962f
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/IndexITCase.java
@@ -0,0 +1,48 @@
+package sonia.scm.it;
+
+import io.restassured.RestAssured;
+import org.apache.http.HttpStatus;
+import org.junit.Test;
+import sonia.scm.it.utils.RestUtil;
+import sonia.scm.web.VndMediaType;
+
+import static sonia.scm.it.utils.RegExMatcher.matchesPattern;
+import static sonia.scm.it.utils.RestUtil.given;
+
+public class IndexITCase {
+
+ @Test
+ public void shouldLinkEverythingForAdmin() {
+ given(VndMediaType.INDEX)
+
+ .when()
+ .get(RestUtil.createResourceUrl(""))
+
+ .then()
+ .statusCode(HttpStatus.SC_OK)
+ .body(
+ "_links.repositories.href", matchesPattern(".+/repositories/"),
+ "_links.users.href", matchesPattern(".+/users/"),
+ "_links.groups.href", matchesPattern(".+/groups/"),
+ "_links.config.href", matchesPattern(".+/config"),
+ "_links.gitConfig.href", matchesPattern(".+/config/git"),
+ "_links.hgConfig.href", matchesPattern(".+/config/hg"),
+ "_links.svnConfig.href", matchesPattern(".+/config/svn")
+ );
+ }
+
+ @Test
+ public void shouldCreateLoginLinksForAnonymousAccess() {
+ RestAssured.given() // do not specify user credentials
+
+ .when()
+ .get(RestUtil.createResourceUrl(""))
+
+ .then()
+ .statusCode(HttpStatus.SC_OK)
+ .body(
+ "_links.login.href", matchesPattern(".+/auth/.+")
+ );
+ }
+
+}
diff --git a/scm-it/src/test/java/sonia/scm/it/MeITCase.java b/scm-it/src/test/java/sonia/scm/it/MeITCase.java
new file mode 100644
index 0000000000..64f06765ea
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/MeITCase.java
@@ -0,0 +1,65 @@
+package sonia.scm.it;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import sonia.scm.it.utils.ScmRequests;
+import sonia.scm.it.utils.TestData;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MeITCase {
+
+ @Before
+ public void init() {
+ TestData.cleanup();
+ }
+
+ @Test
+ public void adminShouldChangeOwnPassword() {
+ String newPassword = TestData.USER_SCM_ADMIN + "1";
+ // admin change the own password
+ ScmRequests.start()
+ .given()
+ .url(TestData.getMeUrl())
+ .usernameAndPassword(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN)
+ .getMeResource()
+ .assertStatusCode(200)
+ .usingMeResponse()
+ .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
+ .assertPassword(Assert::assertNull)
+ .assertType(s -> assertThat(s).isEqualTo("xml"))
+ .requestChangePassword(TestData.USER_SCM_ADMIN, newPassword)
+ .assertStatusCode(204);
+ // assert password is changed -> login with the new Password than undo changes
+ ScmRequests.start()
+ .given()
+ .url(TestData.getUserUrl(TestData.USER_SCM_ADMIN))
+ .usernameAndPassword(TestData.USER_SCM_ADMIN, newPassword)
+ .getMeResource()
+ .assertStatusCode(200)
+ .usingMeResponse()
+ .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))// still admin
+ .requestChangePassword(newPassword, TestData.USER_SCM_ADMIN)
+ .assertStatusCode(204);
+ }
+
+ @Test
+ public void shouldHidePasswordLinkIfUserTypeIsNotXML() {
+ String newUser = "user";
+ String password = "pass";
+ String type = "not XML Type";
+ TestData.createUser(newUser, password, true, type);
+ ScmRequests.start()
+ .given()
+ .url(TestData.getMeUrl())
+ .usernameAndPassword(newUser, password)
+ .getMeResource()
+ .assertStatusCode(200)
+ .usingMeResponse()
+ .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))
+ .assertPassword(Assert::assertNull)
+ .assertType(s -> assertThat(s).isEqualTo(type))
+ .assertPasswordLinkDoesNotExists();
+ }
+}
diff --git a/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java b/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java
index 63d8b46d47..f288d4891c 100644
--- a/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java
+++ b/scm-it/src/test/java/sonia/scm/it/PermissionsITCase.java
@@ -39,6 +39,8 @@ import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+import sonia.scm.it.utils.RepositoryUtil;
+import sonia.scm.it.utils.TestData;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.repository.client.api.RepositoryClientException;
@@ -51,11 +53,11 @@ import java.util.Objects;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
-import static sonia.scm.it.RepositoryUtil.addAndCommitRandomFile;
-import static sonia.scm.it.RestUtil.given;
-import static sonia.scm.it.ScmTypes.availableScmTypes;
-import static sonia.scm.it.TestData.USER_SCM_ADMIN;
-import static sonia.scm.it.TestData.callRepository;
+import static sonia.scm.it.utils.RepositoryUtil.addAndCommitRandomFile;
+import static sonia.scm.it.utils.RestUtil.given;
+import static sonia.scm.it.utils.ScmTypes.availableScmTypes;
+import static sonia.scm.it.utils.TestData.USER_SCM_ADMIN;
+import static sonia.scm.it.utils.TestData.callRepository;
@RunWith(Parameterized.class)
public class PermissionsITCase {
diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoriesITCase.java b/scm-it/src/test/java/sonia/scm/it/RepositoriesITCase.java
index 21d4d97b1b..3c67ca3dc3 100644
--- a/scm-it/src/test/java/sonia/scm/it/RepositoriesITCase.java
+++ b/scm-it/src/test/java/sonia/scm/it/RepositoriesITCase.java
@@ -36,12 +36,15 @@ package sonia.scm.it;
import org.apache.http.HttpStatus;
import org.assertj.core.api.Assertions;
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.it.utils.RepositoryUtil;
+import sonia.scm.it.utils.TestData;
import sonia.scm.repository.client.api.RepositoryClient;
import sonia.scm.web.VndMediaType;
@@ -53,11 +56,11 @@ 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;
+import static sonia.scm.it.utils.RegExMatcher.matchesPattern;
+import static sonia.scm.it.utils.RestUtil.createResourceUrl;
+import static sonia.scm.it.utils.RestUtil.given;
+import static sonia.scm.it.utils.ScmTypes.availableScmTypes;
+import static sonia.scm.it.utils.TestData.repositoryJson;
@RunWith(Parameterized.class)
public class RepositoriesITCase {
diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java
index 398921a692..3f8832a3f5 100644
--- a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java
+++ b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java
@@ -4,7 +4,6 @@ import io.restassured.response.ExtractableResponse;
import io.restassured.response.Response;
import org.apache.http.HttpStatus;
import org.assertj.core.util.Lists;
-import org.assertj.core.util.Maps;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Rule;
@@ -12,6 +11,9 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
+import sonia.scm.it.utils.RepositoryUtil;
+import sonia.scm.it.utils.ScmRequests;
+import sonia.scm.it.utils.TestData;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.client.api.ClientCommand;
import sonia.scm.repository.client.api.RepositoryClient;
@@ -29,10 +31,10 @@ import static java.lang.Thread.sleep;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertNotNull;
-import static sonia.scm.it.RestUtil.ADMIN_PASSWORD;
-import static sonia.scm.it.RestUtil.ADMIN_USERNAME;
-import static sonia.scm.it.RestUtil.given;
-import static sonia.scm.it.ScmTypes.availableScmTypes;
+import static sonia.scm.it.utils.RestUtil.ADMIN_PASSWORD;
+import static sonia.scm.it.utils.RestUtil.ADMIN_USERNAME;
+import static sonia.scm.it.utils.RestUtil.given;
+import static sonia.scm.it.utils.ScmTypes.availableScmTypes;
@RunWith(Parameterized.class)
public class RepositoryAccessITCase {
@@ -42,7 +44,7 @@ public class RepositoryAccessITCase {
private final String repositoryType;
private File folder;
- private RepositoryRequests.AppliedRepositoryGetRequest repositoryGetRequest;
+ private ScmRequests.AppliedRepositoryRequest repositoryGetRequest;
public RepositoryAccessITCase(String repositoryType) {
this.repositoryType = repositoryType;
@@ -57,12 +59,17 @@ public class RepositoryAccessITCase {
public void init() {
TestData.createDefault();
folder = tempFolder.getRoot();
- repositoryGetRequest = RepositoryRequests.start()
+ repositoryGetRequest = ScmRequests.start()
.given()
.url(TestData.getDefaultRepositoryUrl(repositoryType))
.usernameAndPassword(ADMIN_USERNAME, ADMIN_PASSWORD)
- .get()
+ .getRepositoryResource()
.assertStatusCode(HttpStatus.SC_OK);
+ ScmRequests.AppliedMeRequest meGetRequest = ScmRequests.start()
+ .given()
+ .url(TestData.getMeUrl())
+ .usernameAndPassword(ADMIN_USERNAME, ADMIN_PASSWORD)
+ .getMeResource();
}
@Test
@@ -165,7 +172,7 @@ public class RepositoryAccessITCase {
.isNotNull()
.contains(String.format("%s/sources/%s", repositoryUrl, changeset.getId()));
- assertThat(response.body().jsonPath().getString("_embedded.tags.find{it.name=='" + tagName + "'}._links.changesets.href"))
+ assertThat(response.body().jsonPath().getString("_embedded.tags.find{it.name=='" + tagName + "'}._links.changeset.href"))
.as("assert single tag changesets link")
.isNotNull()
.contains(String.format("%s/changesets/%s", repositoryUrl, changeset.getId()));
diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoryRequests.java b/scm-it/src/test/java/sonia/scm/it/RepositoryRequests.java
deleted file mode 100644
index 79300d7b45..0000000000
--- a/scm-it/src/test/java/sonia/scm/it/RepositoryRequests.java
+++ /dev/null
@@ -1,293 +0,0 @@
-package sonia.scm.it;
-
-import io.restassured.RestAssured;
-import io.restassured.response.Response;
-
-import java.util.List;
-import java.util.Map;
-import java.util.function.Consumer;
-
-
-/**
- * Encapsulate rest requests of a repository in builder pattern
- *
- * A Get Request can be applied with the methods request*()
- * These methods return a AppliedGet*Request object
- * This object can be used to apply general assertions over the rest Assured response
- * In the AppliedGet*Request classes there is a using*Response() method
- * that return the *Response class containing specific operations related to the specific response
- * the *Response class contains also the request*() method to apply the next GET request from a link in the response.
- */
-public class RepositoryRequests {
-
- private String url;
- private String username;
- private String password;
-
- static RepositoryRequests start() {
- return new RepositoryRequests();
- }
-
- Given given() {
- return new Given();
- }
-
-
- /**
- * Apply a GET Request to the extracted url from the given link
- *
- * @param linkPropertyName the property name of link
- * @param response the response containing the link
- * @return the response of the GET request using the given link
- */
- private Response getResponseFromLink(Response response, String linkPropertyName) {
- return getResponse(response
- .then()
- .extract()
- .path(linkPropertyName));
- }
-
-
- /**
- * Apply a GET Request to the given url and return the response.
- *
- * @param url the url of the GET request
- * @return the response of the GET request using the given url
- */
- private Response getResponse(String url) {
- return RestAssured.given()
- .auth().preemptive().basic(username, password)
- .when()
- .get(url);
- }
-
- private void setUrl(String url) {
- this.url = url;
- }
-
- private void setUsername(String username) {
- this.username = username;
- }
-
- private void setPassword(String password) {
- this.password = password;
- }
-
- private String getUrl() {
- return url;
- }
-
- private String getUsername() {
- return username;
- }
-
- private String getPassword() {
- return password;
- }
-
- class Given {
-
- GivenUrl url(String url) {
- setUrl(url);
- return new GivenUrl();
- }
-
- }
-
- class GivenWithUrlAndAuth {
- AppliedRepositoryGetRequest get() {
- return new AppliedRepositoryGetRequest(
- getResponse(url)
- );
- }
- }
-
- class AppliedGetRequest {
- private Response response;
-
- public AppliedGetRequest(Response response) {
- this.response = response;
- }
-
- /**
- * apply custom assertions to the actual response
- *
- * @param consumer consume the response in order to assert the content. the header, the payload etc..
- * @return the self object
- */
- SELF assertResponse(Consumer consumer) {
- consumer.accept(response);
- return (SELF) this;
- }
-
- /**
- * special assertion of the status code
- *
- * @param expectedStatusCode the expected status code
- * @return the self object
- */
- SELF assertStatusCode(int expectedStatusCode) {
- this.response.then().assertThat().statusCode(expectedStatusCode);
- return (SELF) this;
- }
-
- }
-
- class AppliedRepositoryGetRequest extends AppliedGetRequest {
-
- AppliedRepositoryGetRequest(Response response) {
- super(response);
- }
-
- RepositoryResponse usingRepositoryResponse() {
- return new RepositoryResponse(super.response);
- }
- }
-
- class RepositoryResponse {
-
- private Response repositoryResponse;
-
- public RepositoryResponse(Response repositoryResponse) {
- this.repositoryResponse = repositoryResponse;
- }
-
- AppliedGetSourcesRequest requestSources() {
- return new AppliedGetSourcesRequest(getResponseFromLink(repositoryResponse, "_links.sources.href"));
- }
-
- AppliedGetChangesetsRequest requestChangesets() {
- return new AppliedGetChangesetsRequest(getResponseFromLink(repositoryResponse, "_links.changesets.href"));
- }
- }
-
- class AppliedGetChangesetsRequest extends AppliedGetRequest {
-
- AppliedGetChangesetsRequest(Response response) {
- super(response);
- }
-
- ChangesetsResponse usingChangesetsResponse() {
- return new ChangesetsResponse(super.response);
- }
- }
-
- class ChangesetsResponse {
- private Response changesetsResponse;
-
- public ChangesetsResponse(Response changesetsResponse) {
- this.changesetsResponse = changesetsResponse;
- }
-
- ChangesetsResponse assertChangesets(Consumer> changesetsConsumer) {
- List