diff --git a/scm-it/src/test/java/sonia/scm/it/AutoCompleteITCase.java b/scm-it/src/test/java/sonia/scm/it/AutoCompleteITCase.java index f15acdb6f4..f343f322a3 100644 --- a/scm-it/src/test/java/sonia/scm/it/AutoCompleteITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/AutoCompleteITCase.java @@ -24,67 +24,33 @@ public class AutoCompleteITCase { } @Test - public void adminShouldAutoCompleteUsers() { - createUsers(); - ScmRequests.start() - .given() - .requestIndexResource(TestData.USER_SCM_ADMIN,TestData.USER_SCM_ADMIN) - .assertStatusCode(200) - .usingIndexResponse() - .requestAutoCompleteUsers("user*") - .assertStatusCode(200) - .usingAutoCompleteResponse() - .assertAutoCompleteResults(assertAutoCompleteResult(CREATED_USER_PREFIX)); + public void adminShouldAutoComplete() { + shouldAutocomplete(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN); } @Test - public void userShouldAutoCompleteUsersWithoutAdminPermission() { + public void userShouldAutoComplete() { String username = "nonAdmin"; String password = "pass"; TestData.createUser(username, password, false, "xml", "email@e.de"); + shouldAutocomplete(username, password); + } + + public void shouldAutocomplete(String username, String password) { createUsers(); + createGroups(); ScmRequests.start() - .given() - .requestIndexResource(username,password) + .requestIndexResource(username, password) .assertStatusCode(200) - .usingIndexResponse() + .requestAutoCompleteGroups("group*") + .assertStatusCode(200) + .assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX)) + .returnToPrevious() .requestAutoCompleteUsers("user*") .assertStatusCode(200) - .usingAutoCompleteResponse() .assertAutoCompleteResults(assertAutoCompleteResult(CREATED_USER_PREFIX)); } - @Test - public void adminShouldAutoCompleteGroups() { - createGroups(); - ScmRequests.start() - .given() - .requestIndexResource(TestData.USER_SCM_ADMIN,TestData.USER_SCM_ADMIN) - .assertStatusCode(200) - .usingIndexResponse() - .applyAutoCompleteGroups("group*") - .assertStatusCode(200) - .usingAutoCompleteResponse() - .assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX)); - } - - @Test - public void userShouldAutoCompleteGroupsWithoutAdminPermission() { - String username = "nonAdminUser"; - String password = "pass"; - TestData.createNotAdminUser(username, password); - createGroups(); - ScmRequests.start() - .given() - .requestIndexResource(username,password) - .assertStatusCode(200) - .usingIndexResponse() - .applyAutoCompleteGroups("group*") - .assertStatusCode(200) - .usingAutoCompleteResponse() - .assertAutoCompleteResults(assertAutoCompleteResult(CREATED_GROUP_PREFIX)); - } - @SuppressWarnings("unchecked") private Consumer> assertAutoCompleteResult(String id) { return autoCompleteDtos -> { diff --git a/scm-it/src/test/java/sonia/scm/it/MeITCase.java b/scm-it/src/test/java/sonia/scm/it/MeITCase.java index 5a1df060c8..5809f883ca 100644 --- a/scm-it/src/test/java/sonia/scm/it/MeITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/MeITCase.java @@ -20,12 +20,9 @@ public class MeITCase { 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() + .requestIndexResource(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN) + .requestMe() .assertStatusCode(200) - .usingMeResponse() .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE)) .assertPassword(Assert::assertNull) .assertType(s -> assertThat(s).isEqualTo("xml")) @@ -33,12 +30,9 @@ public class MeITCase { .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() + .requestIndexResource(TestData.USER_SCM_ADMIN, newPassword) + .requestMe() .assertStatusCode(200) - .usingMeResponse() .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE))// still admin .requestChangePassword(newPassword, TestData.USER_SCM_ADMIN) .assertStatusCode(204); @@ -51,12 +45,9 @@ public class MeITCase { String type = "not XML Type"; TestData.createUser(newUser, password, true, type, "user@scm-manager.org"); ScmRequests.start() - .given() - .url(TestData.getMeUrl()) - .usernameAndPassword(newUser, password) - .getMeResource() + .requestIndexResource(newUser, password) + .requestMe() .assertStatusCode(200) - .usingMeResponse() .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE)) .assertPassword(Assert::assertNull) .assertType(s -> assertThat(s).isEqualTo(type)) 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 3f8832a3f5..334274b7b0 100644 --- a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java @@ -44,7 +44,7 @@ public class RepositoryAccessITCase { private final String repositoryType; private File folder; - private ScmRequests.AppliedRepositoryRequest repositoryGetRequest; + private ScmRequests.RepositoryResponse repositoryResponse; public RepositoryAccessITCase(String repositoryType) { this.repositoryType = repositoryType; @@ -59,17 +59,13 @@ public class RepositoryAccessITCase { public void init() { TestData.createDefault(); folder = tempFolder.getRoot(); - repositoryGetRequest = ScmRequests.start() - .given() - .url(TestData.getDefaultRepositoryUrl(repositoryType)) - .usernameAndPassword(ADMIN_USERNAME, ADMIN_PASSWORD) - .getRepositoryResource() + String namespace = ADMIN_USERNAME; + String repo = TestData.getDefaultRepoName(repositoryType); + repositoryResponse = + ScmRequests.start() + .requestIndexResource(ADMIN_USERNAME, ADMIN_PASSWORD) + .requestRepository(namespace, repo) .assertStatusCode(HttpStatus.SC_OK); - ScmRequests.AppliedMeRequest meGetRequest = ScmRequests.start() - .given() - .url(TestData.getMeUrl()) - .usernameAndPassword(ADMIN_USERNAME, ADMIN_PASSWORD) - .getMeResource(); } @Test @@ -306,17 +302,12 @@ public class RepositoryAccessITCase { public void shouldFindFileHistory() throws IOException { RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder); Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "folder/subfolder/a.txt", "a"); - repositoryGetRequest - .usingRepositoryResponse() + repositoryResponse .requestSources() - .usingSourcesResponse() .requestSelf("folder") - .usingSourcesResponse() .requestSelf("subfolder") - .usingSourcesResponse() .requestFileHistory("a.txt") .assertStatusCode(HttpStatus.SC_OK) - .usingChangesetsResponse() .assertChangesets(changesets -> { assertThat(changesets).hasSize(1); assertThat(changesets.get(0)).containsEntry("id", changeset.getId()); @@ -332,14 +323,11 @@ public class RepositoryAccessITCase { String fileName = "a.txt"; Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "a"); String revision = changeset.getId(); - repositoryGetRequest - .usingRepositoryResponse() + repositoryResponse .requestChangesets() .assertStatusCode(HttpStatus.SC_OK) - .usingChangesetsResponse() .requestModifications(revision) .assertStatusCode(HttpStatus.SC_OK) - .usingModificationsResponse() .assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision)) .assertAdded(addedFiles -> assertThat(addedFiles) .hasSize(1) @@ -359,14 +347,11 @@ public class RepositoryAccessITCase { Changeset changeset = RepositoryUtil.removeAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName); String revision = changeset.getId(); - repositoryGetRequest - .usingRepositoryResponse() + repositoryResponse .requestChangesets() .assertStatusCode(HttpStatus.SC_OK) - .usingChangesetsResponse() .requestModifications(revision) .assertStatusCode(HttpStatus.SC_OK) - .usingModificationsResponse() .assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision)) .assertRemoved(removedFiles -> assertThat(removedFiles) .hasSize(1) @@ -386,14 +371,11 @@ public class RepositoryAccessITCase { Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "new Content"); String revision = changeset.getId(); - repositoryGetRequest - .usingRepositoryResponse() + repositoryResponse .requestChangesets() .assertStatusCode(HttpStatus.SC_OK) - .usingChangesetsResponse() .requestModifications(revision) .assertStatusCode(HttpStatus.SC_OK) - .usingModificationsResponse() .assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision)) .assertModified(modifiedFiles -> assertThat(modifiedFiles) .hasSize(1) @@ -423,14 +405,11 @@ public class RepositoryAccessITCase { Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles); String revision = changeset.getId(); - repositoryGetRequest - .usingRepositoryResponse() + repositoryResponse .requestChangesets() .assertStatusCode(HttpStatus.SC_OK) - .usingChangesetsResponse() .requestModifications(revision) .assertStatusCode(HttpStatus.SC_OK) - .usingModificationsResponse() .assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision)) .assertAdded(a -> assertThat(a) .hasSize(1) @@ -463,14 +442,11 @@ public class RepositoryAccessITCase { Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles); String revision = changeset.getId(); - repositoryGetRequest - .usingRepositoryResponse() + repositoryResponse .requestChangesets() .assertStatusCode(HttpStatus.SC_OK) - .usingChangesetsResponse() .requestModifications(revision) .assertStatusCode(HttpStatus.SC_OK) - .usingModificationsResponse() .assertRevision(actualRevision -> assertThat(actualRevision).isEqualTo(revision)) .assertAdded(a -> assertThat(a) .hasSize(3) diff --git a/scm-it/src/test/java/sonia/scm/it/UserITCase.java b/scm-it/src/test/java/sonia/scm/it/UserITCase.java index 3b220da00c..a4bc4e412f 100644 --- a/scm-it/src/test/java/sonia/scm/it/UserITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/UserITCase.java @@ -23,27 +23,21 @@ public class UserITCase { String newPassword = "new_password"; // admin change the own password ScmRequests.start() - .given() - .url(TestData.getUserUrl(newUser)) - .usernameAndPassword(newUser, password) - .getUserResource() + .requestIndexResource(newUser, password) + .assertStatusCode(200) + .requestUser(newUser) .assertStatusCode(200) - .usingUserResponse() .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE)) .assertPassword(Assert::assertNull) .requestChangePassword(newPassword) // the oldPassword is not needed in the user resource .assertStatusCode(204); // assert password is changed -> login with the new Password ScmRequests.start() - .given() - .url(TestData.getUserUrl(newUser)) - .usernameAndPassword(newUser, newPassword) - .getUserResource() + .requestIndexResource(newUser, newPassword) .assertStatusCode(200) - .usingUserResponse() + .requestUser(newUser) .assertAdmin(isAdmin -> assertThat(isAdmin).isEqualTo(Boolean.TRUE)) .assertPassword(Assert::assertNull); - } @Test @@ -54,22 +48,19 @@ public class UserITCase { String newPassword = "new_password"; // admin change the password of the user ScmRequests.start() - .given() - .url(TestData.getUserUrl(newUser))// the admin get the user object - .usernameAndPassword(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN) - .getUserResource() + .requestIndexResource(TestData.USER_SCM_ADMIN, TestData.USER_SCM_ADMIN) + .assertStatusCode(200) + .requestUser(newUser) .assertStatusCode(200) - .usingUserResponse() .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE)) // the user anonymous is not an admin .assertPassword(Assert::assertNull) .requestChangePassword(newPassword) // the oldPassword is not needed in the user resource .assertStatusCode(204); // assert password is changed ScmRequests.start() - .given() - .url(TestData.getUserUrl(newUser)) - .usernameAndPassword(newUser, newPassword) - .getUserResource() + .requestIndexResource(newUser, newPassword) + .assertStatusCode(200) + .requestUser(newUser) .assertStatusCode(200); } @@ -82,12 +73,10 @@ public class UserITCase { String type = "not XML Type"; TestData.createUser(newUser, password, true, type, "user@scm-manager.org"); ScmRequests.start() - .given() - .url(TestData.getMeUrl()) - .usernameAndPassword(newUser, password) - .getUserResource() + .requestIndexResource(newUser, password) + .assertStatusCode(200) + .requestUser(newUser) .assertStatusCode(200) - .usingUserResponse() .assertAdmin(aBoolean -> assertThat(aBoolean).isEqualTo(Boolean.TRUE)) .assertPassword(Assert::assertNull) .assertType(s -> assertThat(s).isEqualTo(type)) diff --git a/scm-it/src/test/java/sonia/scm/it/utils/ScmRequests.java b/scm-it/src/test/java/sonia/scm/it/utils/ScmRequests.java index 6abbc6f2bd..bcfbe93b3e 100644 --- a/scm-it/src/test/java/sonia/scm/it/utils/ScmRequests.java +++ b/scm-it/src/test/java/sonia/scm/it/utils/ScmRequests.java @@ -4,7 +4,6 @@ import io.restassured.RestAssured; import io.restassured.response.Response; import sonia.scm.web.VndMediaType; -import java.net.URI; import java.util.List; import java.util.Map; import java.util.function.Consumer; @@ -33,8 +32,10 @@ public class ScmRequests { return new ScmRequests(); } - public Given given() { - return new Given(); + public IndexResponse requestIndexResource(String username, String password) { + setUsername(username); + setPassword(password); + return new IndexResponse(applyGETRequest(RestUtil.REST_BASE_URL.toString())); } @@ -54,28 +55,28 @@ public class ScmRequests { * * @param linkPropertyName the property name of link * @param response the response containing the link - * @param queryParams query params eg. ?q=xyz&count=12 + * @param params query params eg. ?q=xyz&count=12 or path params eg. namespace/name * @return the response of the GET request using the given link */ - private Response applyGETRequestFromLinkWithParams(Response response, String linkPropertyName, String queryParams) { + private Response applyGETRequestFromLinkWithParams(Response response, String linkPropertyName, String params) { return applyGETRequestWithQueryParams(response .then() .extract() - .path(linkPropertyName), queryParams); + .path(linkPropertyName), params); } /** * Apply a GET Request to the given url and return the response. * - * @param url the url of the GET request - * @param htmlQueryParams query params eg. ?q=xyz&count=12 + * @param url the url of the GET request + * @param params query params eg. ?q=xyz&count=12 or path params eg. namespace/name * @return the response of the GET request using the given url */ - private Response applyGETRequestWithQueryParams(String url, String htmlQueryParams) { + private Response applyGETRequestWithQueryParams(String url, String params) { return RestAssured.given() .auth().preemptive().basic(username, password) .when() - .get(url + htmlQueryParams); + .get(url + params); } /** @@ -123,11 +124,6 @@ public class ScmRequests { .put(url); } - - private void setUrl(String url) { - this.url = url; - } - private void setUsername(String username) { this.username = username; } @@ -136,308 +132,185 @@ public class ScmRequests { this.password = password; } - private String getUrl() { - return url; - } - private String getUsername() { - return username; - } + public class IndexResponse extends ModelResponse { + public static final String LINK_AUTOCOMPLETE_USERS = "_links.autocomplete.find{it.name=='users'}.href"; + public static final String LINK_AUTOCOMPLETE_GROUPS = "_links.autocomplete.find{it.name=='groups'}.href"; + public static final String LINK_REPOSITORIES = "_links.repositories.href"; + private static final String LINK_ME = "_links.me.href"; + private static final String LINK_USERS = "_links.users.href"; - private String getPassword() { - return password; - } - - public class Given { - - public GivenUrl url(String url) { - setUrl(url); - return new GivenUrl(); + public IndexResponse(Response response) { + super(response, null); } - public AppliedIndexResource requestIndexResource(String username, String password) { - setUsername(username); - setPassword(password); - return new AppliedIndexResource(applyGETRequest(RestUtil.REST_BASE_URL.toString())); + public AutoCompleteResponse requestAutoCompleteUsers(String q) { + return new AutoCompleteResponse<>(applyGETRequestFromLinkWithParams(response, LINK_AUTOCOMPLETE_USERS, "?q=" + q), this); } - public GivenUrl url(URI url) { - setUrl(url.toString()); - return new GivenUrl(); + public AutoCompleteResponse requestAutoCompleteGroups(String q) { + return new AutoCompleteResponse<>(applyGETRequestFromLinkWithParams(response, LINK_AUTOCOMPLETE_GROUPS, "?q=" + q), this); + } + + public RepositoryResponse requestRepository(String namespace, String name) { + return new RepositoryResponse<>(applyGETRequestFromLinkWithParams(response, LINK_REPOSITORIES, namespace + "/" + name), this); + } + + public MeResponse requestMe() { + return new MeResponse<>(applyGETRequestFromLink(response, LINK_ME), this); + } + + public UserResponse requestUser(String username) { + return new UserResponse<>(applyGETRequestFromLinkWithParams(response, LINK_USERS, username), this); } } - public class GivenWithUrlAndAuth { - public AppliedMeRequest getMeResource() { - return new AppliedMeRequest(applyGETRequest(url)); + public class RepositoryResponse extends ModelResponse, PREV> { + + + public static final String LINKS_SOURCES = "_links.sources.href"; + public static final String LINKS_CHANGESETS = "_links.changesets.href"; + + public RepositoryResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } - public AppliedUserRequest getUserResource() { - return new AppliedUserRequest(applyGETRequest(url)); + public SourcesResponse requestSources() { + return new SourcesResponse<>(applyGETRequestFromLink(response, LINKS_SOURCES), this); } - public AppliedRepositoryRequest getRepositoryResource() { - return new AppliedRepositoryRequest( - applyGETRequest(url) - ); - } - - public AppliedAutoCompleteRequest getAutoCompleteResource() { - return new AppliedAutoCompleteRequest( - applyGETRequest(url) - ); - } - } - - public class AppliedRequest { - private Response response; - - public AppliedRequest(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 - */ - public 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 - */ - public SELF assertStatusCode(int expectedStatusCode) { - this.response.then().assertThat().statusCode(expectedStatusCode); - return (SELF) this; + public ChangesetsResponse requestChangesets() { + return new ChangesetsResponse<>(applyGETRequestFromLink(response, LINKS_CHANGESETS), this); } } - public class AppliedRepositoryRequest extends AppliedRequest { + public class ChangesetsResponse extends ModelResponse, PREV> { - public AppliedRepositoryRequest(Response response) { - super(response); - } - - public RepositoryResponse usingRepositoryResponse() { - return new RepositoryResponse(super.response); - } - } - - public class RepositoryResponse { - - private Response repositoryResponse; - - public RepositoryResponse(Response repositoryResponse) { - this.repositoryResponse = repositoryResponse; - } - - public AppliedSourcesRequest requestSources() { - return new AppliedSourcesRequest(applyGETRequestFromLink(repositoryResponse, "_links.sources.href")); - } - - public AppliedChangesetsRequest requestChangesets() { - return new AppliedChangesetsRequest(applyGETRequestFromLink(repositoryResponse, "_links.changesets.href")); - } - } - - public class AppliedChangesetsRequest extends AppliedRequest { - - public AppliedChangesetsRequest(Response response) { - super(response); - } - - public ChangesetsResponse usingChangesetsResponse() { - return new ChangesetsResponse(super.response); - } - } - - public class ChangesetsResponse { - private Response changesetsResponse; - - public ChangesetsResponse(Response changesetsResponse) { - this.changesetsResponse = changesetsResponse; + public ChangesetsResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } public ChangesetsResponse assertChangesets(Consumer> changesetsConsumer) { - List changesets = changesetsResponse.then().extract().path("_embedded.changesets"); + List changesets = response.then().extract().path("_embedded.changesets"); changesetsConsumer.accept(changesets); return this; } - public AppliedDiffRequest requestDiff(String revision) { - return new AppliedDiffRequest(applyGETRequestFromLink(changesetsResponse, "_embedded.changesets.find{it.id=='" + revision + "'}._links.diff.href")); + public DiffResponse requestDiff(String revision) { + return new DiffResponse<>(applyGETRequestFromLink(response, "_embedded.changesets.find{it.id=='" + revision + "'}._links.diff.href"), this); } - public AppliedModificationsRequest requestModifications(String revision) { - return new AppliedModificationsRequest(applyGETRequestFromLink(changesetsResponse, "_embedded.changesets.find{it.id=='" + revision + "'}._links.modifications.href")); + public ModificationsResponse requestModifications(String revision) { + return new ModificationsResponse<>(applyGETRequestFromLink(response, "_embedded.changesets.find{it.id=='" + revision + "'}._links.modifications.href"), this); } } - public class AppliedSourcesRequest extends AppliedRequest { - public AppliedSourcesRequest(Response sourcesResponse) { - super(sourcesResponse); - } + public class SourcesResponse extends ModelResponse, PREV> { - public SourcesResponse usingSourcesResponse() { - return new SourcesResponse(super.response); - } - } - - public class SourcesResponse { - - private Response sourcesResponse; - - public SourcesResponse(Response sourcesResponse) { - this.sourcesResponse = sourcesResponse; + public SourcesResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } public SourcesResponse assertRevision(Consumer assertRevision) { - String revision = sourcesResponse.then().extract().path("revision"); + String revision = response.then().extract().path("revision"); assertRevision.accept(revision); return this; } public SourcesResponse assertFiles(Consumer assertFiles) { - List files = sourcesResponse.then().extract().path("files"); + List files = response.then().extract().path("files"); assertFiles.accept(files); return this; } - public AppliedChangesetsRequest requestFileHistory(String fileName) { - return new AppliedChangesetsRequest(applyGETRequestFromLink(sourcesResponse, "_embedded.files.find{it.name=='" + fileName + "'}._links.history.href")); + public ChangesetsResponse requestFileHistory(String fileName) { + return new ChangesetsResponse<>(applyGETRequestFromLink(response, "_embedded.files.find{it.name=='" + fileName + "'}._links.history.href"), this); } - public AppliedSourcesRequest requestSelf(String fileName) { - return new AppliedSourcesRequest(applyGETRequestFromLink(sourcesResponse, "_embedded.files.find{it.name=='" + fileName + "'}._links.self.href")); + public SourcesResponse requestSelf(String fileName) { + return new SourcesResponse<>(applyGETRequestFromLink(response, "_embedded.files.find{it.name=='" + fileName + "'}._links.self.href"), this); } } - public class AppliedDiffRequest extends AppliedRequest { + public class ModificationsResponse extends ModelResponse, PREV> { - public AppliedDiffRequest(Response response) { - super(response); - } - } - - public class GivenUrl { - - public GivenWithUrlAndAuth usernameAndPassword(String username, String password) { - setUsername(username); - setPassword(password); - return new GivenWithUrlAndAuth(); - } - } - - public class AppliedModificationsRequest extends AppliedRequest { - public AppliedModificationsRequest(Response response) { - super(response); + public ModificationsResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } - public ModificationsResponse usingModificationsResponse() { - return new ModificationsResponse(super.response); - } - - } - - public class ModificationsResponse { - private Response resource; - - public ModificationsResponse(Response resource) { - this.resource = resource; - } - - public ModificationsResponse assertRevision(Consumer assertRevision) { - String revision = resource.then().extract().path("revision"); + public ModificationsResponse assertRevision(Consumer assertRevision) { + String revision = response.then().extract().path("revision"); assertRevision.accept(revision); return this; } - public ModificationsResponse assertAdded(Consumer> assertAdded) { - List added = resource.then().extract().path("added"); + public ModificationsResponse assertAdded(Consumer> assertAdded) { + List added = response.then().extract().path("added"); assertAdded.accept(added); return this; } - public ModificationsResponse assertRemoved(Consumer> assertRemoved) { - List removed = resource.then().extract().path("removed"); + public ModificationsResponse assertRemoved(Consumer> assertRemoved) { + List removed = response.then().extract().path("removed"); assertRemoved.accept(removed); return this; } - public ModificationsResponse assertModified(Consumer> assertModified) { - List modified = resource.then().extract().path("modified"); + public ModificationsResponse assertModified(Consumer> assertModified) { + List modified = response.then().extract().path("modified"); assertModified.accept(modified); return this; } } - public class AppliedMeRequest extends AppliedRequest { - - public AppliedMeRequest(Response response) { - super(response); - } - - public MeResponse usingMeResponse() { - return new MeResponse(super.response); - } - - } - - public class MeResponse extends UserResponse { + public class MeResponse extends UserResponse { - public MeResponse(Response response) { - super(response); - } - - public AppliedChangePasswordRequest requestChangePassword(String oldPassword, String newPassword) { - return new AppliedChangePasswordRequest(applyPUTRequestFromLink(super.response, "_links.password.href", VndMediaType.PASSWORD_CHANGE, createPasswordChangeJson(oldPassword, newPassword))); + public MeResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } } - public class UserResponse extends ModelResponse { + public class UserResponse extends ModelResponse, PREV> { public static final String LINKS_PASSWORD_HREF = "_links.password.href"; - public UserResponse(Response response) { - super(response); + public UserResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } - public SELF assertPassword(Consumer assertPassword) { + public UserResponse assertPassword(Consumer assertPassword) { return super.assertSingleProperty(assertPassword, "password"); } - public SELF assertType(Consumer assertType) { + public UserResponse assertType(Consumer assertType) { return assertSingleProperty(assertType, "type"); } - public SELF assertAdmin(Consumer assertAdmin) { + public UserResponse assertAdmin(Consumer assertAdmin) { return assertSingleProperty(assertAdmin, "admin"); } - public SELF assertPasswordLinkDoesNotExists() { + public UserResponse assertPasswordLinkDoesNotExists() { return assertPropertyPathDoesNotExists(LINKS_PASSWORD_HREF); } - public SELF assertPasswordLinkExists() { + public UserResponse assertPasswordLinkExists() { return assertPropertyPathExists(LINKS_PASSWORD_HREF); } - public AppliedChangePasswordRequest requestChangePassword(String newPassword) { - return new AppliedChangePasswordRequest(applyPUTRequestFromLink(super.response, LINKS_PASSWORD_HREF, VndMediaType.PASSWORD_CHANGE, createPasswordChangeJson(null, newPassword))); + public ChangePasswordResponse requestChangePassword(String newPassword) { + return requestChangePassword(null, newPassword); + } + + public ChangePasswordResponse requestChangePassword(String oldPassword, String newPassword) { + return new ChangePasswordResponse<>(applyPUTRequestFromLink(super.response, LINKS_PASSWORD_HREF, VndMediaType.PASSWORD_CHANGE, createPasswordChangeJson(oldPassword, newPassword)), this); } } @@ -446,12 +319,18 @@ public class ScmRequests { /** * encapsulate standard assertions over model properties */ - public class ModelResponse { + public class ModelResponse, PREV extends ModelResponse> { + protected PREV previousResponse; protected Response response; - public ModelResponse(Response response) { + public ModelResponse(Response response, PREV previousResponse) { this.response = response; + this.previousResponse = previousResponse; + } + + public PREV returnToPrevious() { + return previousResponse; } public SELF assertSingleProperty(Consumer assertSingleProperty, String propertyJsonPath) { @@ -475,46 +354,26 @@ public class ScmRequests { assertProperties.accept(properties); return (SELF) this; } + + /** + * special assertion of the status code + * + * @param expectedStatusCode the expected status code + * @return the self object + */ + public SELF assertStatusCode(int expectedStatusCode) { + this.response.then().assertThat().statusCode(expectedStatusCode); + return (SELF) this; + } } - public class AppliedChangePasswordRequest extends AppliedRequest { + public class AutoCompleteResponse extends ModelResponse, PREV> { - public AppliedChangePasswordRequest(Response response) { - super(response); + public AutoCompleteResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } - } - - public class AppliedUserRequest extends AppliedRequest { - - public AppliedUserRequest(Response response) { - super(response); - } - - public UserResponse usingUserResponse() { - return new UserResponse(super.response); - } - - } - - public class AppliedAutoCompleteRequest extends AppliedRequest { - public AppliedAutoCompleteRequest(Response response) { - super(response); - } - - public AutoCompleteResponse usingAutoCompleteResponse() { - return new AutoCompleteResponse(super.response); - } - - } - - public class AutoCompleteResponse extends ModelResponse { - - public AutoCompleteResponse(Response response) { - super(response); - } - - public AutoCompleteResponse assertAutoCompleteResults(Consumer> checker) { + public AutoCompleteResponse assertAutoCompleteResults(Consumer> checker) { List result = response.then().extract().path(""); checker.accept(result); return this; @@ -522,31 +381,18 @@ public class ScmRequests { } - public class AppliedIndexResource extends AppliedRequest { - public AppliedIndexResource(Response response) { - super(response); - } - public IndexResponse usingIndexResponse() { - return new IndexResponse(super.response); - } + public class DiffResponse extends ModelResponse, PREV> { + public DiffResponse(Response response, PREV previousResponse) { + super(response, previousResponse); + } } - public class IndexResponse extends ModelResponse { - public static final String AUTOCOMPLETE_USERS = "_links.autocomplete.find{it.name=='users'}.href"; - public static final String AUTOCOMPLETE_GROUPS = "_links.autocomplete.find{it.name=='groups'}.href"; + public class ChangePasswordResponse extends ModelResponse, PREV> { - public IndexResponse(Response response) { - super(response); - } - - public AppliedAutoCompleteRequest requestAutoCompleteUsers(String q) { - return new AppliedAutoCompleteRequest(applyGETRequestFromLinkWithParams(response, AUTOCOMPLETE_USERS, "?q="+q)); - } - - public AppliedAutoCompleteRequest applyAutoCompleteGroups(String q) { - return new AppliedAutoCompleteRequest(applyGETRequestFromLinkWithParams(response, AUTOCOMPLETE_GROUPS, "?q="+q)); + public ChangePasswordResponse(Response response, PREV previousResponse) { + super(response, previousResponse); } } } diff --git a/scm-it/src/test/java/sonia/scm/it/utils/TestData.java b/scm-it/src/test/java/sonia/scm/it/utils/TestData.java index af9032e62e..a164fc6649 100644 --- a/scm-it/src/test/java/sonia/scm/it/utils/TestData.java +++ b/scm-it/src/test/java/sonia/scm/it/utils/TestData.java @@ -203,12 +203,16 @@ public class TestData { return JSON_BUILDER .add("contact", "zaphod.beeblebrox@hitchhiker.com") .add("description", "Heart of Gold") - .add("name", "HeartOfGold-" + repositoryType) + .add("name", getDefaultRepoName(repositoryType)) .add("archived", false) .add("type", repositoryType) .build().toString(); } + public static String getDefaultRepoName(String repositoryType) { + return "HeartOfGold-" + repositoryType; + } + public static String getGroupJson(String groupname , String desc) { return JSON_BUILDER .add("name", groupname) @@ -216,10 +220,6 @@ public class TestData { .build().toString(); } - public static URI getMeUrl() { - return RestUtil.createResourceUrl("me/"); - } - public static URI getGroupsUrl() { return RestUtil.createResourceUrl("groups/"); } @@ -228,18 +228,6 @@ public class TestData { return RestUtil.createResourceUrl("users/"); } - public static URI getUserUrl(String username) { - return getUsersUrl().resolve(username); - } - - public static URI getUsersAutoCompleteUrl(String query ) { - return RestUtil.createResourceUrl("autocomplete/users?q="+query); - } - - public static URI getGroupsAutoCompleteUrl(String query ) { - return RestUtil.createResourceUrl("autocomplete/groups?q="+query); - } - public static String createPasswordChangeJson(String oldPassword, String newPassword) { return JSON_BUILDER .add("oldPassword", oldPassword) diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java index 68bb165140..2cab41bfbf 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/AutoCompleteResourceTest.java @@ -1,16 +1,16 @@ package sonia.scm.api.v2.resources; import com.fasterxml.jackson.databind.ObjectMapper; -import org.apache.shiro.subject.Subject; -import org.apache.shiro.subject.support.SubjectThreadState; +import com.github.sdorra.shiro.ShiroRule; +import com.github.sdorra.shiro.SubjectAware; import org.apache.shiro.util.ThreadContext; -import org.apache.shiro.util.ThreadState; import org.assertj.core.util.Lists; import org.jboss.resteasy.core.Dispatcher; import org.jboss.resteasy.mock.MockHttpRequest; import org.jboss.resteasy.mock.MockHttpResponse; import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.junit.MockitoJUnitRunner; @@ -43,16 +43,17 @@ import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher; +@SubjectAware(configuration = "classpath:sonia/scm/shiro-002.ini") @RunWith(MockitoJUnitRunner.Silent.class) public class AutoCompleteResourceTest { + @Rule + public final ShiroRule shiroRule = new ShiroRule(); + public static final String URL = "/" + AutoCompleteResource.PATH; private final Integer defaultLimit = Manager.DEFAULT_LIMIT; private Dispatcher dispatcher; - private final Subject subject = mock(Subject.class); - private final ThreadState subjectThreadState = new SubjectThreadState(subject); - private XmlUserDAO userDao; private XmlGroupDAO groupDao; private XmlDatabase xmlDB; @@ -75,9 +76,6 @@ public class AutoCompleteResourceTest { GroupManager groupManager = new DefaultGroupManager(groupDao); AutoCompleteResource autoCompleteResource = new AutoCompleteResource(mapper, userManager, groupManager); dispatcher = createDispatcher(autoCompleteResource); - subjectThreadState.bind(); - ThreadContext.bind(subject); - when(subject.isPermitted(any(String.class))).thenReturn(true); } @After @@ -85,19 +83,6 @@ public class AutoCompleteResourceTest { ThreadContext.unbindSubject(); } - @Test - public void shouldGet400OnFailedParameterForUserSearch() throws Exception { - MockHttpRequest request = MockHttpRequest - .get("/" + AutoCompleteResource.PATH + "users") - .contentType(VndMediaType.AUTOCOMPLETE) - .accept(VndMediaType.AUTOCOMPLETE); - MockHttpResponse response = new MockHttpResponse(); - - dispatcher.invoke(request, response); - - assertEquals(400, response.getStatus()); - } - @Test public void shouldGet400IfParameterLengthLessThan2CharsForUserSearch() throws Exception { MockHttpRequest request = MockHttpRequest @@ -112,6 +97,21 @@ public class AutoCompleteResourceTest { } @Test + @SubjectAware(username = "trillian", password = "secret") + public void shouldGet400OnFailedParameterForUserSearch() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "users") + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(400, response.getStatus()); + } + + @Test + @SubjectAware(username = "trillian", password = "secret") public void shouldSearchUsers() throws Exception { ArrayList users = Lists.newArrayList(createMockUser("YuCantFindMe", "ha ha"), createMockUser("user1", "User 1"), createMockUser("user2", "User 2")); String searched = "user"; @@ -134,6 +134,22 @@ public class AutoCompleteResourceTest { } @Test + @SubjectAware(username = "user_without_autocomplete_permission", password = "secret") + public void shouldGet403OnAutoCompleteUsers() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "users?q=user" ) + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + + + @Test + @SubjectAware(username = "trillian", password = "secret") public void shouldSearchUsersWithDefaultLimitLength() throws Exception { List userList = IntStream.range(0, 10).boxed().map(i -> createMockUser("user" + i, "User " + i)).collect(Collectors.toList()); when(xmlDB.values()).thenReturn(userList); @@ -150,6 +166,7 @@ public class AutoCompleteResourceTest { } @Test + @SubjectAware(username = "trillian", password = "secret") public void shouldGet400OnFailedParameterForGroupSearch() throws Exception { MockHttpRequest request = MockHttpRequest .get("/" + AutoCompleteResource.PATH + "groups") @@ -163,6 +180,7 @@ public class AutoCompleteResourceTest { } @Test + @SubjectAware(username = "trillian", password = "secret") public void shouldGet400IfParameterLengthLessThan2CharsForGroupSearch() throws Exception { MockHttpRequest request = MockHttpRequest .get("/" + AutoCompleteResource.PATH + "groups?q=a") @@ -176,6 +194,7 @@ public class AutoCompleteResourceTest { } @Test + @SubjectAware(username = "trillian", password = "secret") public void shouldSearchGroups() throws Exception { ArrayList groups = Lists.newArrayList(createMockGroup("YuCantFindMe"), createMockGroup("group_1"), createMockGroup("group_2")); String searched = "group"; @@ -197,6 +216,21 @@ public class AutoCompleteResourceTest { } @Test + @SubjectAware(username = "user_without_autocomplete_permission", password = "secret") + public void shouldGet403OnAutoCompleteGroups() throws Exception { + MockHttpRequest request = MockHttpRequest + .get("/" + AutoCompleteResource.PATH + "groups?q=user" ) + .contentType(VndMediaType.AUTOCOMPLETE) + .accept(VndMediaType.AUTOCOMPLETE); + MockHttpResponse response = new MockHttpResponse(); + + dispatcher.invoke(request, response); + + assertEquals(HttpServletResponse.SC_FORBIDDEN, response.getStatus()); + } + + @Test + @SubjectAware(username = "trillian", password = "secret") public void shouldSearchGroupsWithDefaultLimitLength() throws Exception { List groups = IntStream.range(0, 10).boxed().map(i -> createMockGroup("group_" + i)).collect(Collectors.toList()); when(xmlDB.values()).thenReturn(groups);