diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/SnapshotPostbackRequestInvalidFiles.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/SnapshotPostbackRequestInvalidFiles.java index f0b1ba9b06..4b17d3eca3 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/SnapshotPostbackRequestInvalidFiles.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/SnapshotPostbackRequestInvalidFiles.java @@ -1,9 +1,11 @@ package uk.ac.ic.wlgitbridge.snapshot.servermock.response.push.postback; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import uk.ac.ic.wlgitbridge.snapshot.servermock.response.push.postback.invalidfile.InvalidFileError; +import java.util.ArrayList; import java.util.List; /** @@ -18,6 +20,13 @@ public class SnapshotPostbackRequestInvalidFiles extends SnapshotPostbackRequest this.errors = errors; } + public SnapshotPostbackRequestInvalidFiles(JsonArray errors) { + this(new ArrayList()); + for (JsonElement error : errors) { + this.errors.add(InvalidFileError.buildFromJsonError(error.getAsJsonObject())); + } + } + @Override public JsonObject toJson() { JsonObject jsonThis = super.toJson(); diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/invalidfile/InvalidFileError.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/invalidfile/InvalidFileError.java index ab7c52cb4f..7d773609c2 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/invalidfile/InvalidFileError.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/response/push/postback/invalidfile/InvalidFileError.java @@ -22,4 +22,18 @@ public abstract class InvalidFileError { protected abstract String getState(); + public static InvalidFileError buildFromJsonError(JsonObject error) { + String state = error.get("state").getAsString(); + String file = error.get("file").getAsString(); + if (state.equals("error")) { + return new InvalidFileErrorDefault(file); + } else if (state.equals("disallowed")) { + return new InvalidFileErrorDisallowed(file); + } else if (state.equals("unclean_name")) { + return new InvalidFileErrorUnclean(file, error.get("cleanFile").getAsString()); + } else { + throw new IllegalArgumentException("bad invalid file state: " + state); + } + } + } diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/state/SnapshotAPIStateBuilder.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/state/SnapshotAPIStateBuilder.java index 5e6a44561c..acf25682a4 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/state/SnapshotAPIStateBuilder.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/snapshot/servermock/state/SnapshotAPIStateBuilder.java @@ -4,18 +4,17 @@ import com.google.gson.Gson; import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; +import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult; +import uk.ac.ic.wlgitbridge.snapshot.getforversion.GetForVersionResult; +import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotAttachment; +import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotData; +import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotFile; +import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.GetSavedVersResult; +import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.SnapshotInfo; import uk.ac.ic.wlgitbridge.snapshot.servermock.response.push.data.SnapshotPushResult; import uk.ac.ic.wlgitbridge.snapshot.servermock.response.push.data.SnapshotPushResultOutOfDate; import uk.ac.ic.wlgitbridge.snapshot.servermock.response.push.data.SnapshotPushResultSuccess; import uk.ac.ic.wlgitbridge.snapshot.servermock.response.push.postback.*; -import uk.ac.ic.wlgitbridge.snapshot.servermock.response.push.postback.invalidfile.InvalidFileError; -import uk.ac.ic.wlgitbridge.snapshot.getdoc.GetDocResult; -import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotAttachment; -import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotData; -import uk.ac.ic.wlgitbridge.snapshot.getforversion.SnapshotFile; -import uk.ac.ic.wlgitbridge.snapshot.getforversion.GetForVersionResult; -import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.GetSavedVersResult; -import uk.ac.ic.wlgitbridge.snapshot.getsavedvers.SnapshotInfo; import java.io.InputStream; import java.io.InputStreamReader; @@ -139,7 +138,7 @@ public class SnapshotAPIStateBuilder { } else if (type.equals("outOfDate")) { p = new SnapshotPostbackRequestOutOfDate(); } else if (type.equals("invalidFiles")) { - p = new SnapshotPostbackRequestInvalidFiles(new LinkedList()); + p = new SnapshotPostbackRequestInvalidFiles(jsonPostback.get("errors").getAsJsonArray()); } else if (type.equals("invalidProject")) { p = new SnapshotPostbackRequestInvalidProject(new LinkedList()); } else if (type.equals("error")) { diff --git a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java index 0e9962ad03..d36b36fb09 100644 --- a/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java +++ b/services/git-bridge/src/main/java/uk/ac/ic/wlgitbridge/util/Util.java @@ -3,10 +3,7 @@ package uk.ac.ic.wlgitbridge.util; import java.io.*; import java.text.DateFormat; import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.HashSet; -import java.util.Set; +import java.util.*; /** * Created by Winston on 19/11/14. @@ -152,6 +149,25 @@ public class Util { } } + public static List linesFromStream(InputStream stream, int skip, String trimSuffix) throws IOException { + List lines = new ArrayList(); + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + String line; + for (int i = 0; i < skip; i++) { + reader.readLine(); + } + while ((line = reader.readLine()) != null) { + String trim = line.trim(); + trim = trim.replaceAll("\\p{C}", ""); + int endIndex = trim.lastIndexOf(trimSuffix); + if (endIndex >= 0) { + trim = trim.substring(0, endIndex); + } + lines.add(trim); + } + return lines; + } + public static String fromStream(InputStream stream, int skip) throws IOException { BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); StringBuilder out = new StringBuilder(); diff --git a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest.java b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest.java index 29e731770e..23288ae495 100644 --- a/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest.java +++ b/services/git-bridge/src/test/java/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest.java @@ -14,7 +14,9 @@ import uk.ac.ic.wlgitbridge.util.Util; import java.io.*; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import static org.junit.Assert.assertEquals; @@ -71,6 +73,9 @@ public class WLGitBridgeIntegrationTest { put("pushFailsOnSecondStageOutOfDate", new HashMap() {{ put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/pushFailsOnSecondStageOutOfDate/state/state.json")).build()); }}); + put("pushFailsOnInvalidFiles", new HashMap() {{ + put("state", new SnapshotAPIStateBuilder(getResourceAsStream("/pushFailsOnInvalidFiles/state/state.json")).build()); + }}); }}; @Rule @@ -371,6 +376,46 @@ public class WLGitBridgeIntegrationTest { assertEquals(EXPECTED_OUT_PUSH_OUT_OF_DATE_SECOND, Util.fromStream(gitPush.getErrorStream(), 2)); } + + private static final List EXPECTED_OUT_PUSH_INVALID_FILES = + Arrays.asList( + "remote: error: invalid files", + "remote: hint: You have 4 invalid files in your Overleaf project:", + "remote: hint: file1.invalid (error)", + "remote: hint: file2.exe (invalid file extension)", + "remote: hint: hello world.png (rename to: hello_world.png)", + "remote: hint: an image.jpg (rename to: an_image.jpg)", + "To http://127.0.0.1:33869/testproj.git", + "! [remote rejected] master -> master (invalid files)", + "error: failed to push some refs to 'http://127.0.0.1:33869/testproj.git'" + ); + + @Test + public void pushFailsOnInvalidFiles() throws IOException, GitAPIException, InterruptedException { + MockSnapshotServer server = new MockSnapshotServer(3869, getResource("/pushFailsOnInvalidFiles").toFile()); + server.start(); + server.setState(states.get("pushFailsOnInvalidFiles").get("state")); + GitBridgeApp wlgb = new GitBridgeApp(new String[] { + makeConfigFile(33869, 3869) + }); + wlgb.run(); + File dir = folder.newFolder(); + Process git = runtime.exec("git clone http://127.0.0.1:33869/testproj.git", null, dir); + int exitCode = git.waitFor(); + File testprojDir = new File(dir, "testproj"); + assertEquals(0, exitCode); + assertTrue(FileUtil.gitDirectoriesAreEqual(getResource("/pushFailsOnInvalidFiles/state/testproj"), testprojDir.toPath())); + runtime.exec("touch push.tex", null, testprojDir).waitFor(); + runtime.exec("git add -A", null, testprojDir).waitFor(); + runtime.exec("git commit -m \"push\"", null, testprojDir).waitFor(); + Process gitPush = runtime.exec("git push", null, testprojDir); + int pushExitCode = gitPush.waitFor(); + wlgb.stop(); + assertEquals(1, pushExitCode); + List actual = Util.linesFromStream(gitPush.getErrorStream(), 2, "[K"); + assertEquals(EXPECTED_OUT_PUSH_INVALID_FILES, actual); + } + private String makeConfigFile(int port, int apiPort) throws IOException { File wlgb = folder.newFolder(); File config = folder.newFile(); @@ -400,4 +445,8 @@ public class WLGitBridgeIntegrationTest { } } + private static String withoutWhitespace(String s) { + return s.replaceAll("\\s",""); + } + } diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnInvalidFiles/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnInvalidFiles/state/state.json index cfefd00f8a..b1ce038fb6 100644 --- a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnInvalidFiles/state/state.json +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnInvalidFiles/state/state.json @@ -31,15 +31,35 @@ ], "atts": [ { - "url": "http://127.0.0.1:3868/state/testproj/min_mean_wait_evm_7_eps_150dpi.png", + "url": "http://127.0.0.1:3869/state/testproj/min_mean_wait_evm_7_eps_150dpi.png", "path": "min_mean_wait_evm_7_eps_150dpi.png" } ] } ], - "push": "outOfDate", + "push": "success", "postback": { - "type": "outOfDate" + "type": "invalidFiles", + "errors": [ + { + "file": "file1.invalid", + "state": "error" + }, + { + "file": "file2.exe", + "state": "disallowed" + }, + { + "file": "hello world.png", + "state": "unclean_name", + "cleanFile": "hello_world.png" + }, + { + "file": "an image.jpg", + "state": "unclean_name", + "cleanFile": "an_image.jpg" + } + ] } } ] \ No newline at end of file diff --git a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnSecondStageOutOfDate/state/state.json b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnSecondStageOutOfDate/state/state.json index cfefd00f8a..cead6f6bbe 100644 --- a/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnSecondStageOutOfDate/state/state.json +++ b/services/git-bridge/src/test/resources/uk/ac/ic/wlgitbridge/WLGitBridgeIntegrationTest/pushFailsOnSecondStageOutOfDate/state/state.json @@ -37,7 +37,7 @@ ] } ], - "push": "outOfDate", + "push": "success", "postback": { "type": "outOfDate" }