From 188d2d8cefbdba9ac8044711a49da47c176ad918 Mon Sep 17 00:00:00 2001 From: Mohamed Karray Date: Thu, 13 Sep 2018 17:29:52 +0200 Subject: [PATCH] integration tests for modifications --- .../sonia/scm/it/RepositoryAccessITCase.java | 163 ++++++++++++++++++ .../java/sonia/scm/it/RepositoryRequests.java | 46 ++++- .../java/sonia/scm/it/RepositoryUtil.java | 46 ++++- .../spi/GitModificationsCommandTest.java | 2 +- .../spi/HgRepositoryServiceProvider.java | 11 ++ .../spi/SvnRepositoryServiceProvider.java | 4 + .../client/spi/SvnChangeWorker.java | 14 +- 7 files changed, 277 insertions(+), 9 deletions(-) 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 fc095828b3..398921a692 100644 --- a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java @@ -3,6 +3,8 @@ package sonia.scm.it; 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; @@ -17,8 +19,11 @@ import sonia.scm.web.VndMediaType; import java.io.File; import java.io.IOException; +import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static java.lang.Thread.sleep; import static org.assertj.core.api.Assertions.assertThat; @@ -312,5 +317,163 @@ public class RepositoryAccessITCase { } ); } + + @Test + @SuppressWarnings("unchecked") + public void shouldFindAddedModifications() throws IOException { + RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder); + String fileName = "a.txt"; + Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "a"); + String revision = changeset.getId(); + repositoryGetRequest + .usingRepositoryResponse() + .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) + .containsExactly(fileName)) + .assertRemoved(removedFiles -> assertThat(removedFiles) + .hasSize(0)) + .assertModified(files -> assertThat(files) + .hasSize(0)); + } + + @Test + @SuppressWarnings("unchecked") + public void shouldFindRemovedModifications() throws IOException { + RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder); + String fileName = "a.txt"; + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "a"); + Changeset changeset = RepositoryUtil.removeAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName); + + String revision = changeset.getId(); + repositoryGetRequest + .usingRepositoryResponse() + .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) + .containsExactly(fileName)) + .assertAdded(addedFiles -> assertThat(addedFiles) + .hasSize(0)) + .assertModified(files -> assertThat(files) + .hasSize(0)); + } + + @Test + @SuppressWarnings("unchecked") + public void shouldFindUpdateModifications() throws IOException { + RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder); + String fileName = "a.txt"; + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "a"); + Changeset changeset = RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, fileName, "new Content"); + + String revision = changeset.getId(); + repositoryGetRequest + .usingRepositoryResponse() + .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) + .containsExactly(fileName)) + .assertRemoved(removedFiles -> assertThat(removedFiles) + .hasSize(0)) + .assertAdded(addedFiles -> assertThat(addedFiles) + .hasSize(0)); + } + + @Test + @SuppressWarnings("unchecked") + public void shouldFindMultipleModifications() throws IOException { + RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder); + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "b.txt", "b"); + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "c.txt", "c"); + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "d.txt", "d"); + Map addedFiles = new HashMap() + {{ + put("a.txt", "bla bla"); + }}; + Map modifiedFiles = new HashMap() + {{ + put("b.txt", "new content"); + }}; + ArrayList removedFiles = Lists.newArrayList("c.txt", "d.txt"); + Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles); + + String revision = changeset.getId(); + repositoryGetRequest + .usingRepositoryResponse() + .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) + .containsExactly("a.txt")) + .assertModified(m-> assertThat(m) + .hasSize(1) + .containsExactly("b.txt")) + .assertRemoved(r -> assertThat(r) + .hasSize(2) + .containsExactly("c.txt", "d.txt")); + } + + @Test + @SuppressWarnings("unchecked") + public void svnShouldCreateOneModificationPerFolder() throws IOException { + Assume.assumeThat(repositoryType, equalTo("svn")); + RepositoryClient repositoryClient = RepositoryUtil.createRepositoryClient(repositoryType, folder); + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "bbb/bb/b.txt", "b"); + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "ccc/cc/c.txt", "c"); + RepositoryUtil.createAndCommitFile(repositoryClient, ADMIN_USERNAME, "ddd/dd/d.txt", "d"); + Map addedFiles = new HashMap() + {{ + put("aaa/aa/a.txt", "bla bla"); + }}; + Map modifiedFiles = new HashMap() + {{ + put("bbb/bb/b.txt", "new content"); + }}; + ArrayList removedFiles = Lists.newArrayList("ccc/cc/c.txt", "ddd/dd/d.txt"); + Changeset changeset = RepositoryUtil.commitMultipleFileModifications(repositoryClient, ADMIN_USERNAME, addedFiles, modifiedFiles, removedFiles); + + String revision = changeset.getId(); + repositoryGetRequest + .usingRepositoryResponse() + .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) + .containsExactly("aaa/aa/a.txt", "aaa", "aaa/aa")) + .assertModified(m-> assertThat(m) + .hasSize(1) + .containsExactly("bbb/bb/b.txt")) + .assertRemoved(r -> assertThat(r) + .hasSize(2) + .containsExactly("ccc/cc/c.txt", "ddd/dd/d.txt")); + } } diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoryRequests.java b/scm-it/src/test/java/sonia/scm/it/RepositoryRequests.java index 41fa2a6a3d..79300d7b45 100644 --- a/scm-it/src/test/java/sonia/scm/it/RepositoryRequests.java +++ b/scm-it/src/test/java/sonia/scm/it/RepositoryRequests.java @@ -156,7 +156,7 @@ public class RepositoryRequests { return new AppliedGetSourcesRequest(getResponseFromLink(repositoryResponse, "_links.sources.href")); } - AppliedGetChangesetsRequest requestChangesets(String fileName) { + AppliedGetChangesetsRequest requestChangesets() { return new AppliedGetChangesetsRequest(getResponseFromLink(repositoryResponse, "_links.changesets.href")); } } @@ -189,6 +189,9 @@ public class RepositoryRequests { return new AppliedGetDiffRequest(getResponseFromLink(changesetsResponse, "_embedded.changesets.find{it.id=='" + revision + "'}._links.diff.href")); } + public AppliedGetModificationsRequest requestModifications(String revision) { + return new AppliedGetModificationsRequest(getResponseFromLink(changesetsResponse, "_embedded.changesets.find{it.id=='" + revision + "'}._links.modifications.href")); + } } class AppliedGetSourcesRequest extends AppliedGetRequest { @@ -246,4 +249,45 @@ public class RepositoryRequests { return new GivenWithUrlAndAuth(); } } + + class AppliedGetModificationsRequest extends AppliedGetRequest { + public AppliedGetModificationsRequest(Response response) { super(response); } + ModificationsResponse usingModificationsResponse() { + return new ModificationsResponse(super.response); + } + + } + + class ModificationsResponse { + private Response resource; + + public ModificationsResponse(Response resource) { + this.resource = resource; + } + + ModificationsResponse assertRevision(Consumer assertRevision) { + String revision = resource.then().extract().path("revision"); + assertRevision.accept(revision); + return this; + } + + ModificationsResponse assertAdded(Consumer> assertAdded) { + List added = resource.then().extract().path("added"); + assertAdded.accept(added); + return this; + } + + ModificationsResponse assertRemoved(Consumer> assertRemoved) { + List removed = resource.then().extract().path("removed"); + assertRemoved.accept(removed); + return this; + } + + ModificationsResponse assertModified(Consumer> assertModified) { + List modified = resource.then().extract().path("modified"); + assertModified.accept(modified); + return this; + } + + } } diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoryUtil.java b/scm-it/src/test/java/sonia/scm/it/RepositoryUtil.java index 0e2eb24ca9..96b92a0bed 100644 --- a/scm-it/src/test/java/sonia/scm/it/RepositoryUtil.java +++ b/scm-it/src/test/java/sonia/scm/it/RepositoryUtil.java @@ -14,6 +14,8 @@ import sonia.scm.repository.client.api.RepositoryClientFactory; import java.io.File; import java.io.IOException; +import java.util.List; +import java.util.Map; import java.util.UUID; public class RepositoryUtil { @@ -42,11 +44,53 @@ public class RepositoryUtil { } static Changeset createAndCommitFile(RepositoryClient repositoryClient, String username, String fileName, String content) throws IOException { + writeAndAddFile(repositoryClient, fileName, content); + return commit(repositoryClient, username, "added " + fileName); + } + + /** + * Bundle multiple File modification in one changeset + * + * @param repositoryClient + * @param username + * @param addedFiles map.key: path of the file, value: the file content + * @param modifiedFiles map.key: path of the file, value: the file content + * @param removedFiles list of file paths to be removed + * @return the changeset with all modifications + * @throws IOException + */ + static Changeset commitMultipleFileModifications(RepositoryClient repositoryClient, String username, Map addedFiles, Map modifiedFiles, List removedFiles) throws IOException { + for (String fileName : addedFiles.keySet()) { + writeAndAddFile(repositoryClient, fileName, addedFiles.get(fileName)); + } + for (String fileName : modifiedFiles.keySet()) { + writeAndAddFile(repositoryClient, fileName, modifiedFiles.get(fileName)); + } + for (String fileName : removedFiles) { + deleteFileAndApplyRemoveCommand(repositoryClient, fileName); + } + return commit(repositoryClient, username, "multiple file modifications" ); + } + + private static File writeAndAddFile(RepositoryClient repositoryClient, String fileName, String content) throws IOException { File file = new File(repositoryClient.getWorkingCopy(), fileName); Files.createParentDirs(file); Files.write(content, file, Charsets.UTF_8); addWithParentDirectories(repositoryClient, file); - return commit(repositoryClient, username, "added " + fileName); + return file; + } + + static Changeset removeAndCommitFile(RepositoryClient repositoryClient, String username, String fileName) throws IOException { + deleteFileAndApplyRemoveCommand(repositoryClient, fileName); + return commit(repositoryClient, username, "removed " + fileName); + } + + private static void deleteFileAndApplyRemoveCommand(RepositoryClient repositoryClient, String fileName) throws IOException { + File file = new File(repositoryClient.getWorkingCopy(), fileName); + if (repositoryClient.isCommandSupported(ClientCommand.REMOVE)) { + repositoryClient.getRemoveCommand().remove(fileName); + } + file.delete(); } private static String addWithParentDirectories(RepositoryClient repositoryClient, File file) throws IOException { diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModificationsCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModificationsCommandTest.java index de90d5a393..fb982f6f0c 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModificationsCommandTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitModificationsCommandTest.java @@ -53,7 +53,7 @@ public class GitModificationsCommandTest extends AbstractRemoteCommandTestBase { commit(outgoing, "add file"); File file = new File(outgoingDirectory, fileName); file.delete(); - outgoing.add().setUpdate(true).addFilepattern(".").call(); + outgoing.rm().addFilepattern(fileName).call(); RevCommit removedFileCommit = commit(outgoing, "remove file"); String revision = removedFileCommit.getName(); Consumer assertModifications = assertRemovedFiles(fileName); diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java index 4295bf45e4..7749b7e40a 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/spi/HgRepositoryServiceProvider.java @@ -42,6 +42,7 @@ import sonia.scm.repository.HgHookManager; import sonia.scm.repository.HgRepositoryHandler; import sonia.scm.repository.Repository; import sonia.scm.repository.api.Command; +import sonia.scm.repository.api.CommandNotSupportedException; //~--- JDK imports ------------------------------------------------------------ @@ -201,6 +202,16 @@ public class HgRepositoryServiceProvider extends RepositoryServiceProvider return new HgLogCommand(context, repository); } + /** + * Get the corresponding {@link ModificationsCommand} implemented from the Plugins + * + * @return the corresponding {@link ModificationsCommand} implemented from the Plugins + * @throws CommandNotSupportedException if there is no Implementation + */ + public ModificationsCommand getModificationsCommand() { + return new HgModificationsCommand(context,repository); + } + /** * Method description * diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java index 24180bfe9e..1fda21f0d8 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/spi/SvnRepositoryServiceProvider.java @@ -167,6 +167,10 @@ public class SvnRepositoryServiceProvider extends RepositoryServiceProvider return new SvnLogCommand(context, repository); } + public ModificationsCommand getModificationsCommand() { + return new SvnModificationsCommand(context, repository); + } + /** * Method description * diff --git a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/client/spi/SvnChangeWorker.java b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/client/spi/SvnChangeWorker.java index b54e51c4d6..302ef3e8aa 100644 --- a/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/client/spi/SvnChangeWorker.java +++ b/scm-plugins/scm-svn-plugin/src/test/java/sonia/scm/repository/client/spi/SvnChangeWorker.java @@ -70,13 +70,15 @@ class SvnChangeWorker { SVNWCClient wClient = client.getWCClient(); // add files - try { - wClient.doAdd(addedFiles.toArray(new File[0]), true, false, false, - SVNDepth.INFINITY, false, false, false); - addedFiles.clear(); + if (!addedFiles.isEmpty()){ + try { + wClient.doAdd(addedFiles.toArray(new File[0]), true, false, false, + SVNDepth.INFINITY, false, false, false); + addedFiles.clear(); - } catch (SVNException ex) { - throw new RepositoryClientException("failed to add files", ex); + } catch (SVNException ex) { + throw new RepositoryClientException("failed to add files", ex); + } } // remove files