diff --git a/main/ui/pom.xml b/main/ui/pom.xml
index 4e26f7590..e09ff0db5 100644
--- a/main/ui/pom.xml
+++ b/main/ui/pom.xml
@@ -86,5 +86,13 @@
slf4j-simple
test
+
+
+
+ com.google.jimfs
+ jimfs
+ 1.1
+ test
+
diff --git a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java
index 421eda002..eefb5990c 100644
--- a/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java
+++ b/main/ui/src/main/java/org/cryptomator/ui/model/UpgradeVersion3to4.java
@@ -121,7 +121,7 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
if (m.find(0)) {
String base32 = m.group(1);
String suffix = name.substring(m.end());
- String renamed = NEW_FOLDER_PREFIX + base32 + StringUtils.prependIfMissing(suffix, " ");
+ String renamed = NEW_FOLDER_PREFIX + base32 + suffix;
renameWithoutOverwriting(file, renamed);
}
}
@@ -163,7 +163,8 @@ class UpgradeVersion3to4 extends UpgradeStrategy {
Files.move(path, newPath);
Files.createDirectories(newMetadataFile.getParent());
Files.write(newMetadataFile, newLongName.getBytes(UTF_8));
- LOG.info("Renaming {} to {}\nCreating {}", path, newName, newMetadataFile);
+ LOG.info("Renaming {} to {}.", path, newName);
+ LOG.info("Creating {}.", newMetadataFile);
}
}
}
diff --git a/main/ui/src/test/java/org/cryptomator/ui/l10n/LocalizationMock.java b/main/ui/src/test/java/org/cryptomator/ui/l10n/LocalizationMock.java
new file mode 100644
index 000000000..67f95cbbf
--- /dev/null
+++ b/main/ui/src/test/java/org/cryptomator/ui/l10n/LocalizationMock.java
@@ -0,0 +1,10 @@
+package org.cryptomator.ui.l10n;
+
+public class LocalizationMock extends Localization {
+
+ @Override
+ public String handleGetObject(String key) {
+ return key;
+ }
+
+}
diff --git a/main/ui/src/test/java/org/cryptomator/ui/model/UpgradeVersion3to4Test.java b/main/ui/src/test/java/org/cryptomator/ui/model/UpgradeVersion3to4Test.java
new file mode 100644
index 000000000..8b1f18e88
--- /dev/null
+++ b/main/ui/src/test/java/org/cryptomator/ui/model/UpgradeVersion3to4Test.java
@@ -0,0 +1,164 @@
+package org.cryptomator.ui.model;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.cryptomator.ui.l10n.Localization;
+import org.cryptomator.ui.l10n.LocalizationMock;
+import org.cryptomator.ui.model.UpgradeStrategy.UpgradeFailedException;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.Mockito;
+
+import com.google.common.jimfs.Configuration;
+import com.google.common.jimfs.Jimfs;
+
+public class UpgradeVersion3to4Test {
+
+ private static final Localization L10N = new LocalizationMock();
+ private static final String NULL_KEY_CONTENTS = "{" //
+ + " \"version\": 3," //
+ + " \"scryptSalt\": \"AAAAAAAAAAA=\"," //
+ + " \"scryptCostParam\": 16384," //
+ + " \"scryptBlockSize\": 8," //
+ + " \"primaryMasterKey\": \"BJPIq5pvhN24iDtPJLMFPLaVJWdGog9k4n0P03j4ru+ivbWY9OaRGQ==\"," //
+ + " \"hmacMasterKey\": \"BJPIq5pvhN24iDtPJLMFPLaVJWdGog9k4n0P03j4ru+ivbWY9OaRGQ==\"," //
+ + " \"versionMac\": \"iUmRRHITuyJsJbVNqGNw+82YQ4A3Rma7j/y1v0DCVLA=\"" //
+ + "}";
+
+ @Rule
+ public final ExpectedException thrown = ExpectedException.none();
+ private final UpgradeStrategy upgradeStrategy = new UpgradeVersion3to4(L10N);
+ private FileSystem fs;
+ private Path fsRoot;
+ private Vault vault;
+ private Path dataDir;
+ private Path metadataDir;
+
+ @Before
+ public void setup() throws IOException {
+ fs = Jimfs.newFileSystem(Configuration.unix());
+ fsRoot = fs.getPath("/");
+ dataDir = fsRoot.resolve("d");
+ metadataDir = fsRoot.resolve("m");
+ vault = Mockito.mock(Vault.class);
+ Mockito.when(vault.getPath()).thenReturn(fsRoot);
+
+ Files.write(fsRoot.resolve("masterkey.cryptomator"), NULL_KEY_CONTENTS.getBytes(StandardCharsets.US_ASCII));
+ }
+
+ @After
+ public void teardown() throws IOException {
+ fs.close();
+ }
+
+ @Test
+ public void upgradeFailsWithWrongPassword() throws UpgradeFailedException {
+ thrown.expect(UpgradeFailedException.class);
+ thrown.expectMessage("unlock.errorMessage.wrongPassword");
+ upgradeStrategy.upgrade(vault, "asdd");
+ }
+
+ @Test
+ public void upgradeCreatesBackup() throws UpgradeFailedException {
+ upgradeStrategy.upgrade(vault, "asd");
+ Assert.assertTrue(Files.exists(fsRoot.resolve("masterkey.cryptomator.bkup")));
+ }
+
+ @Test
+ public void upgradeRenamesSimpleDirFile() throws IOException, UpgradeFailedException {
+ Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
+ Files.createDirectories(lvl2Dir);
+ Path oldFile = lvl2Dir.resolve("ABCDEFGH_");
+ Files.createFile(oldFile);
+
+ upgradeStrategy.upgrade(vault, "asd");
+ Path newFile = lvl2Dir.resolve("0ABCDEFGH");
+ Assert.assertTrue(Files.exists(newFile));
+ Assert.assertTrue(Files.notExists(oldFile));
+ }
+
+ @Test
+ public void upgradeRenamesConflictingDirFile() throws IOException, UpgradeFailedException {
+ Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
+ Files.createDirectories(lvl2Dir);
+ Path oldFile = lvl2Dir.resolve("ABCDEFGH_ (1)");
+ Files.createFile(oldFile);
+
+ upgradeStrategy.upgrade(vault, "asd");
+ Path newFile = lvl2Dir.resolve("0ABCDEFGH (1)");
+ Assert.assertTrue(Files.exists(newFile));
+ Assert.assertTrue(Files.notExists(oldFile));
+ }
+
+ @Test
+ public void upgradeDontRenameNonDirFile() throws IOException, UpgradeFailedException {
+ Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
+ Files.createDirectories(lvl2Dir);
+ Path oldFile = lvl2Dir.resolve("ABCDEFGH");
+ Files.createFile(oldFile);
+
+ upgradeStrategy.upgrade(vault, "asd");
+ Assert.assertTrue(Files.exists(oldFile));
+ }
+
+ @Test
+ public void upgradeRenameSimpleLongDirFile() throws IOException, UpgradeFailedException {
+ Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
+ Files.createDirectories(lvl2Dir);
+ Path oldFile = lvl2Dir.resolve("ABCDEFGH.lng");
+ Files.createFile(oldFile);
+ Path oldMetadataFile = metadataDir.resolve("AB/CD/ABCDEFGH.lng");
+ Files.createDirectories(oldMetadataFile.getParent());
+ Files.write(oldMetadataFile, "OPQRSTUVWXYZ====_".getBytes(StandardCharsets.UTF_8));
+
+ upgradeStrategy.upgrade(vault, "asd");
+ // hex2base32(sha1("0OPQRSTUVWXYZ====")) = DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G
+ Path newMetadataFile = metadataDir.resolve("DD/LC/DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G.lng");
+ Path newFile = lvl2Dir.resolve("DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G.lng");
+ Assert.assertTrue(Files.exists(newFile));
+ Assert.assertTrue(Files.exists(newMetadataFile));
+ Assert.assertTrue(Files.notExists(oldFile));
+ }
+
+ @Test
+ public void upgradeRenameConflictingLongDirFile() throws IOException, UpgradeFailedException {
+ Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
+ Files.createDirectories(lvl2Dir);
+ Path oldFile = lvl2Dir.resolve("ABCDEFGH (1).lng");
+ Files.createFile(oldFile);
+ Path oldMetadataFile = metadataDir.resolve("AB/CD/ABCDEFGH.lng");
+ Files.createDirectories(oldMetadataFile.getParent());
+ Files.write(oldMetadataFile, "OPQRSTUVWXYZ====_".getBytes(StandardCharsets.UTF_8));
+
+ upgradeStrategy.upgrade(vault, "asd");
+ // hex2base32(sha1("0OPQRSTUVWXYZ====")) = DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G
+ Path newMetadataFile = metadataDir.resolve("DD/LC/DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G.lng");
+ Path newFile = lvl2Dir.resolve("DDLCFQ3ODTEAHEZJPHIJQRDHROB3K42G (1).lng");
+ Assert.assertTrue(Files.exists(newFile));
+ Assert.assertTrue(Files.exists(newMetadataFile));
+ Assert.assertTrue(Files.notExists(oldFile));
+ }
+
+ @Test
+ public void upgradeDontRenameLongNonDirFile() throws IOException, UpgradeFailedException {
+ Path lvl2Dir = dataDir.resolve("AB/CDEFGHIJKLMNOPQRSTUVWXYZ234567");
+ Files.createDirectories(lvl2Dir);
+ Path oldFile = lvl2Dir.resolve("ABCDEFGH.lng");
+ Files.createFile(oldFile);
+ Path oldMetadataFile = metadataDir.resolve("AB/CD/ABCDEFGH.lng");
+ Files.createDirectories(oldMetadataFile.getParent());
+ Files.write(oldMetadataFile, "OPQRSTUVWXYZ====".getBytes(StandardCharsets.UTF_8));
+
+ upgradeStrategy.upgrade(vault, "asd");
+ Assert.assertTrue(Files.exists(oldFile));
+ }
+
+}