mirror of
https://github.com/cryptomator/cryptomator.git
synced 2026-09-18 22:14:26 +00:00
Single maven module (#1676)
combined all sources into single maven module
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@DisplayName("Environment Variables Test")
|
||||
class EnvironmentTest {
|
||||
|
||||
private Environment env;
|
||||
|
||||
@BeforeEach
|
||||
void init() {
|
||||
env = Mockito.spy(new Environment());
|
||||
Mockito.when(env.getHomeDir()).thenReturn(Path.of("/home/testuser"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("cryptomator.settingsPath=~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json")
|
||||
public void testSettingsPath() {
|
||||
System.setProperty("cryptomator.settingsPath", "~/.config/Cryptomator/settings.json:~/.Cryptomator/settings.json");
|
||||
|
||||
List<Path> result = env.getSettingsPath().toList();
|
||||
MatcherAssert.assertThat(result, Matchers.hasSize(2));
|
||||
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/settings.json"), //
|
||||
Paths.get("/home/testuser/.Cryptomator/settings.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("cryptomator.ipcPortPath=~/.config/Cryptomator/ipcPort.bin:~/.Cryptomator/ipcPort.bin")
|
||||
public void testIpcPortPath() {
|
||||
System.setProperty("cryptomator.ipcPortPath", "~/.config/Cryptomator/ipcPort.bin:~/.Cryptomator/ipcPort.bin");
|
||||
|
||||
List<Path> result = env.getIpcPortPath().toList();
|
||||
MatcherAssert.assertThat(result, Matchers.hasSize(2));
|
||||
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/.config/Cryptomator/ipcPort.bin"), //
|
||||
Paths.get("/home/testuser/.Cryptomator/ipcPort.bin")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("cryptomator.keychainPath=~/AppData/Roaming/Cryptomator/keychain.json")
|
||||
public void testKeychainPath() {
|
||||
System.setProperty("cryptomator.keychainPath", "~/AppData/Roaming/Cryptomator/keychain.json");
|
||||
|
||||
List<Path> result = env.getKeychainPath().toList();
|
||||
MatcherAssert.assertThat(result, Matchers.hasSize(1));
|
||||
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/AppData/Roaming/Cryptomator/keychain.json")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("cryptomator.logDir=/foo/bar")
|
||||
public void testAbsoluteLogDir() {
|
||||
System.setProperty("cryptomator.logDir", "/foo/bar");
|
||||
|
||||
Optional<Path> logDir = env.getLogDir();
|
||||
|
||||
Assertions.assertTrue(logDir.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("cryptomator.logDir=~/foo/bar")
|
||||
public void testRelativeLogDir() {
|
||||
System.setProperty("cryptomator.logDir", "~/foo/bar");
|
||||
|
||||
Optional<Path> logDir = env.getLogDir();
|
||||
|
||||
Assertions.assertTrue(logDir.isPresent());
|
||||
Assertions.assertEquals(Paths.get("/home/testuser/foo/bar"), logDir.get());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Path Lists")
|
||||
class SettingsPath {
|
||||
|
||||
@Test
|
||||
@DisplayName("test.path.property=")
|
||||
public void testEmptyList() {
|
||||
System.setProperty("test.path.property", "");
|
||||
List<Path> result = env.getPaths("test.path.property").toList();
|
||||
|
||||
MatcherAssert.assertThat(result, Matchers.hasSize(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test.path.property=/foo/bar/test")
|
||||
public void testSingleAbsolutePath() {
|
||||
System.setProperty("test.path.property", "/foo/bar/test");
|
||||
List<Path> result = env.getPaths("test.path.property").toList();
|
||||
|
||||
MatcherAssert.assertThat(result, Matchers.hasSize(1));
|
||||
MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/foo/bar/test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test.path.property=~/test")
|
||||
public void testSingleHomeRelativePath() {
|
||||
System.setProperty("test.path.property", "~/test");
|
||||
List<Path> result = env.getPaths("test.path.property").toList();
|
||||
|
||||
MatcherAssert.assertThat(result, Matchers.hasSize(1));
|
||||
MatcherAssert.assertThat(result, Matchers.hasItem(Paths.get("/home/testuser/test")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test.path.property=~/test:~/test2:/foo/bar/test")
|
||||
public void testMultiplePaths() {
|
||||
System.setProperty("test.path.property", "~/test:~/test2:/foo/bar/test");
|
||||
List<Path> result = env.getPaths("test.path.property").toList();
|
||||
|
||||
MatcherAssert.assertThat(result, Matchers.hasSize(3));
|
||||
MatcherAssert.assertThat(result, Matchers.contains(Paths.get("/home/testuser/test"), //
|
||||
Paths.get("/home/testuser/test2"), //
|
||||
Paths.get("/foo/bar/test")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package org.cryptomator.common;
|
||||
|
||||
import com.auth0.jwt.interfaces.DecodedJWT;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
class LicenseCheckerTest {
|
||||
|
||||
private static final String PUBLIC_KEY = """
|
||||
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBgc4HZz+/fBbC7lmEww0AO3NK9wVZ\
|
||||
PDZ0VEnsaUFLEYpTzb90nITtJUcPUbvOsdZIZ1Q8fnbquAYgxXL5UgHMoywAib47\
|
||||
6MkyyYgPk0BXZq3mq4zImTRNuaU9slj9TVJ3ScT3L1bXwVuPJDzpr5GOFpaj+WwM\
|
||||
Al8G7CqwoJOsW7Kddns=\
|
||||
""";
|
||||
|
||||
private LicenseChecker licenseChecker;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
licenseChecker = new LicenseChecker(PUBLIC_KEY);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckValidLicense() {
|
||||
String license = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.eyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.AQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
Assertions.assertTrue(decoded.isPresent());
|
||||
Assertions.assertEquals("cryptobot@example.com", decoded.get().getSubject());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckInvalidLicenseHeader() {
|
||||
String license = "EyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.eyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.AQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
Assertions.assertFalse(decoded.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckInvalidLicensePayload() {
|
||||
String license = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.EyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.AQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
Assertions.assertFalse(decoded.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCheckInvalidLicenseSignature() {
|
||||
String license = "eyJhbGciOiJFUzUxMiIsInR5cCI6IkpXVCIsImtpZCI6InhaRGZacHJ5NFA5dlpQWnlHMmZOQlJqLTdMejVvbVZkbTd0SG9DZ1NOZlkifQ.eyJzdWIiOiJjcnlwdG9ib3RAZXhhbXBsZS5jb20iLCJpYXQiOjE1MTYyMzkwMjJ9.aQaBIKQdNCxmRJi2wLOcbagTgi39WhdWwgdpKTYSPicg-aPr_tst_RjmnqMemx3cBe0Blr4nEbj_lAtSKHz_i61fAUyI1xCIAZYbK9Q3ICHIHQl3AiuCpBwFl-k81OB4QDYiKpEc9gLN5dhW_VymJMsgOvyiC0UjC91f2AM7s46byDNj";
|
||||
|
||||
Optional<DecodedJWT> decoded = licenseChecker.check(license);
|
||||
|
||||
Assertions.assertFalse(decoded.isPresent());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
public class SemVerComparatorTest {
|
||||
|
||||
private final Comparator<String> semVerComparator = new SemVerComparator();
|
||||
|
||||
// equal versions
|
||||
|
||||
@Test
|
||||
public void compareEqualVersions() {
|
||||
Assertions.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4", "1.23.4")));
|
||||
Assertions.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4-alpha", "1.23.4-alpha")));
|
||||
Assertions.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4+20170101", "1.23.4+20171231")));
|
||||
Assertions.assertEquals(0, Integer.signum(semVerComparator.compare("1.23.4-alpha+20170101", "1.23.4-alpha+20171231")));
|
||||
}
|
||||
|
||||
// newer versions in first argument
|
||||
|
||||
@Test
|
||||
public void compareHigherToLowerVersions() {
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.5", "1.23.4")));
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.24.4", "1.23.4")));
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4", "1.23")));
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4", "1.23.4-SNAPSHOT")));
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4", "1.23.4-56.78")));
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4-beta", "1.23.4-alpha")));
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4-alpha.1", "1.23.4-alpha")));
|
||||
Assertions.assertEquals(1, Integer.signum(semVerComparator.compare("1.23.4-56.79", "1.23.4-56.78")));
|
||||
}
|
||||
|
||||
// newer versions in second argument
|
||||
|
||||
@Test
|
||||
public void compareLowerToHigherVersions() {
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4", "1.23.5")));
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4", "1.24.4")));
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23", "1.23.4")));
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-SNAPSHOT", "1.23.4")));
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-56.78", "1.23.4")));
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-alpha", "1.23.4-beta")));
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-alpha", "1.23.4-alpha.1")));
|
||||
Assertions.assertEquals(-1, Integer.signum(semVerComparator.compare("1.23.4-56.78", "1.23.4-56.79")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package org.cryptomator.common.keychain;
|
||||
|
||||
|
||||
import org.cryptomator.integrations.keychain.KeychainAccessException;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ReadOnlyBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
|
||||
public class KeychainManagerTest {
|
||||
|
||||
@Test
|
||||
public void testStoreAndLoad() throws KeychainAccessException {
|
||||
KeychainManager keychainManager = new KeychainManager(new SimpleObjectProperty<>(new MapKeychainAccess()));
|
||||
keychainManager.storePassphrase("test", "asd");
|
||||
Assertions.assertArrayEquals("asd".toCharArray(), keychainManager.loadPassphrase("test"));
|
||||
}
|
||||
|
||||
@Nested
|
||||
public static class WhenObservingProperties {
|
||||
|
||||
@BeforeAll
|
||||
public static void startup() throws InterruptedException {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
Platform.startup(latch::countDown);
|
||||
latch.await(5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyChangesWhenStoringPassword() throws KeychainAccessException, InterruptedException {
|
||||
KeychainManager keychainManager = new KeychainManager(new SimpleObjectProperty<>(new MapKeychainAccess()));
|
||||
ReadOnlyBooleanProperty property = keychainManager.getPassphraseStoredProperty("test");
|
||||
Assertions.assertEquals(false, property.get());
|
||||
|
||||
keychainManager.storePassphrase("test", "bar");
|
||||
|
||||
AtomicBoolean result = new AtomicBoolean(false);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
Platform.runLater(() -> {
|
||||
result.set(property.get());
|
||||
latch.countDown();
|
||||
});
|
||||
latch.await(1, TimeUnit.SECONDS);
|
||||
Assertions.assertEquals(true, result.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.keychain;
|
||||
|
||||
import org.cryptomator.integrations.keychain.KeychainAccessProvider;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
class MapKeychainAccess implements KeychainAccessProvider {
|
||||
|
||||
private final Map<String, char[]> map = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void storePassphrase(String key, CharSequence passphrase) {
|
||||
char[] pw = new char[passphrase.length()];
|
||||
for (int i = 0; i < passphrase.length(); i++) {
|
||||
pw[i] = passphrase.charAt(i);
|
||||
}
|
||||
map.put(key, pw);
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[] loadPassphrase(String key) {
|
||||
return map.get(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deletePassphrase(String key) {
|
||||
map.remove(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changePassphrase(String key, CharSequence passphrase) {
|
||||
map.get(key);
|
||||
storePassphrase(key, passphrase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocked() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SettingsJsonAdapterTest {
|
||||
|
||||
private final Environment env = Mockito.mock(Environment.class);
|
||||
private final SettingsJsonAdapter adapter = new SettingsJsonAdapter(env);
|
||||
|
||||
@Test
|
||||
public void testDeserialize() throws IOException {
|
||||
String json = """
|
||||
{
|
||||
"directories": [
|
||||
{"id": "1", "path": "/vault1", "mountName": "vault1", "winDriveLetter": "X"},
|
||||
{"id": "2", "path": "/vault2", "mountName": "vault2", "winDriveLetter": "Y"}
|
||||
],
|
||||
"checkForUpdatesEnabled": true,
|
||||
"port": 8080,
|
||||
"numTrayNotifications": 42,
|
||||
"preferredVolumeImpl": "FUSE"
|
||||
}
|
||||
""";
|
||||
|
||||
Settings settings = adapter.fromJson(json);
|
||||
|
||||
Assertions.assertTrue(settings.checkForUpdates().get());
|
||||
Assertions.assertEquals(2, settings.getDirectories().size());
|
||||
Assertions.assertEquals(8080, settings.port().get());
|
||||
Assertions.assertEquals(42, settings.numTrayNotifications().get());
|
||||
Assertions.assertEquals(WebDavUrlScheme.DAV, settings.preferredGvfsScheme().get());
|
||||
Assertions.assertEquals(VolumeImpl.FUSE, settings.preferredVolumeImpl().get());
|
||||
}
|
||||
|
||||
@ParameterizedTest(name = "fromJson() should throw IOException for input: {0}")
|
||||
@ValueSource(strings = { //
|
||||
"", //
|
||||
"<html>", //
|
||||
"{invalidjson}" //
|
||||
})
|
||||
public void testDeserializeMalformed(String input) {
|
||||
Assertions.assertThrows(IOException.class, () -> {
|
||||
adapter.fromJson(input);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class SettingsTest {
|
||||
|
||||
@Test
|
||||
public void testAutoSave() {
|
||||
Environment env = Mockito.mock(Environment.class);
|
||||
@SuppressWarnings("unchecked") Consumer<Settings> changeListener = Mockito.mock(Consumer.class);
|
||||
|
||||
Settings settings = new Settings(env);
|
||||
settings.setSaveCmd(changeListener);
|
||||
VaultSettings vaultSettings = VaultSettings.withRandomId();
|
||||
Mockito.verify(changeListener, Mockito.times(0)).accept(settings);
|
||||
|
||||
// first change (to property):
|
||||
settings.preferredGvfsScheme().set(WebDavUrlScheme.WEBDAV);
|
||||
Mockito.verify(changeListener, Mockito.times(1)).accept(settings);
|
||||
|
||||
// second change (to list):
|
||||
settings.getDirectories().add(vaultSettings);
|
||||
Mockito.verify(changeListener, Mockito.times(2)).accept(settings);
|
||||
|
||||
// third change (to property of list item):
|
||||
vaultSettings.displayName().set("asd");
|
||||
Mockito.verify(changeListener, Mockito.times(3)).accept(settings);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertAll;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class VaultSettingsJsonAdapterTest {
|
||||
|
||||
private final VaultSettingsJsonAdapter adapter = new VaultSettingsJsonAdapter();
|
||||
|
||||
@Test
|
||||
public void testDeserialize() throws IOException {
|
||||
String json = "{\"id\": \"foo\", \"path\": \"/foo/bar\", \"displayName\": \"test\", \"winDriveLetter\": \"X\", \"shouldBeIgnored\": true, \"individualMountPath\": \"/home/test/crypto\", \"mountFlags\":\"--foo --bar\"}";
|
||||
JsonReader jsonReader = new JsonReader(new StringReader(json));
|
||||
|
||||
VaultSettings vaultSettings = adapter.read(jsonReader);
|
||||
|
||||
assertAll(
|
||||
() -> assertEquals("foo", vaultSettings.getId()),
|
||||
() -> assertEquals(Paths.get("/foo/bar"), vaultSettings.path().get()),
|
||||
() -> assertEquals("test", vaultSettings.displayName().get()),
|
||||
() -> assertEquals("X", vaultSettings.winDriveLetter().get()),
|
||||
() -> assertEquals("/home/test/crypto", vaultSettings.customMountPath().get()),
|
||||
() -> assertEquals("--foo --bar", vaultSettings.mountFlags().get())
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSerialize() throws IOException {
|
||||
VaultSettings vaultSettings = new VaultSettings("test");
|
||||
vaultSettings.path().set(Paths.get("/foo/bar"));
|
||||
vaultSettings.displayName().set("mountyMcMountFace");
|
||||
vaultSettings.mountFlags().set("--foo --bar");
|
||||
|
||||
StringWriter buf = new StringWriter();
|
||||
JsonWriter jsonWriter = new JsonWriter(buf);
|
||||
adapter.write(jsonWriter, vaultSettings);
|
||||
String result = buf.toString();
|
||||
|
||||
assertAll(
|
||||
() -> assertThat(result, containsString("\"id\":\"test\"")),
|
||||
() -> {
|
||||
if (System.getProperty("os.name").contains("Windows")) {
|
||||
assertThat(result, containsString("\"path\":\"\\\\foo\\\\bar\""));
|
||||
} else {
|
||||
assertThat(result, containsString("\"path\":\"/foo/bar\""));
|
||||
}
|
||||
},
|
||||
() -> assertThat(result, containsString("\"displayName\":\"mountyMcMountFace\"")),
|
||||
() -> assertThat(result, containsString("\"mountFlags\":\"--foo --bar\""))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2016, 2017 Sebastian Stenzel and others.
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials are made available under the terms of the accompanying LICENSE file.
|
||||
*
|
||||
* Contributors:
|
||||
* Sebastian Stenzel - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.common.settings;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class VaultSettingsTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({"a\u000Fa,a_a", ": \\,_ _", "汉语,汉语", "..,_", "a\ta,a\u0020a", "\t\n\r,_"})
|
||||
public void testNormalize(String test, String expected) {
|
||||
VaultSettings settings = new VaultSettings("id");
|
||||
settings.displayName().setValue(test);
|
||||
assertEquals(expected, settings.normalizeDisplayName());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.cryptomator.common.vaults;
|
||||
|
||||
import org.cryptomator.common.settings.Settings;
|
||||
import org.cryptomator.common.settings.VaultSettings;
|
||||
import org.cryptomator.common.settings.VolumeImpl;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledOnOs;
|
||||
import org.junit.jupiter.api.condition.OS;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.beans.binding.StringBinding;
|
||||
import javafx.beans.property.SimpleBooleanProperty;
|
||||
import javafx.beans.property.SimpleObjectProperty;
|
||||
import javafx.beans.property.SimpleStringProperty;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public class VaultModuleTest {
|
||||
|
||||
private final Settings settings = Mockito.mock(Settings.class);
|
||||
private final VaultSettings vaultSettings = Mockito.mock(VaultSettings.class);
|
||||
|
||||
private final VaultModule module = new VaultModule();
|
||||
|
||||
@BeforeEach
|
||||
public void setup(@TempDir Path tmpDir) {
|
||||
Mockito.when(vaultSettings.mountName()).thenReturn(Bindings.createStringBinding(() -> "TEST"));
|
||||
Mockito.when(vaultSettings.usesReadOnlyMode()).thenReturn(new SimpleBooleanProperty(true));
|
||||
Mockito.when(vaultSettings.displayName()).thenReturn(new SimpleStringProperty("Vault"));
|
||||
System.setProperty("user.home", tmpDir.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("provideDefaultMountFlags on Mac/FUSE")
|
||||
@EnabledOnOs(OS.MAC)
|
||||
public void testMacFuseDefaultMountFlags() {
|
||||
Mockito.when(settings.preferredVolumeImpl()).thenReturn(new SimpleObjectProperty<>(VolumeImpl.FUSE));
|
||||
|
||||
StringBinding result = module.provideDefaultMountFlags(settings, vaultSettings);
|
||||
|
||||
MatcherAssert.assertThat(result.get(), CoreMatchers.containsString("-ovolname=\"TEST\""));
|
||||
MatcherAssert.assertThat(result.get(), CoreMatchers.containsString("-ordonly"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("provideDefaultMountFlags on Linux/FUSE")
|
||||
@EnabledOnOs(OS.LINUX)
|
||||
public void testLinuxFuseDefaultMountFlags() {
|
||||
Mockito.when(settings.preferredVolumeImpl()).thenReturn(new SimpleObjectProperty<>(VolumeImpl.FUSE));
|
||||
|
||||
StringBinding result = module.provideDefaultMountFlags(settings, vaultSettings);
|
||||
|
||||
MatcherAssert.assertThat(result.get(), CoreMatchers.containsString("-oro"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("provideDefaultMountFlags on Windows/Dokany")
|
||||
@EnabledOnOs(OS.WINDOWS)
|
||||
public void testWinDokanyDefaultMountFlags() {
|
||||
Mockito.when(settings.preferredVolumeImpl()).thenReturn(new SimpleObjectProperty<>(VolumeImpl.DOKANY));
|
||||
|
||||
StringBinding result = module.provideDefaultMountFlags(settings, vaultSettings);
|
||||
|
||||
MatcherAssert.assertThat(result.get(), CoreMatchers.containsString("--options CURRENT_SESSION,WRITE_PROTECTION"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.launcher;
|
||||
|
||||
import org.cryptomator.ui.launcher.AppLaunchEvent;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.InvalidPathException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
public class FileOpenRequestHandlerTest {
|
||||
|
||||
private FileOpenRequestHandler inTest;
|
||||
private BlockingQueue<AppLaunchEvent> queue;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
queue = new ArrayBlockingQueue<>(1);
|
||||
inTest = new FileOpenRequestHandler(queue);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("./cryptomator.exe foo bar")
|
||||
public void testOpenArgsWithCorrectPaths() {
|
||||
inTest.handleLaunchArgs(new String[]{"foo", "bar"});
|
||||
|
||||
AppLaunchEvent evt = queue.poll();
|
||||
Assertions.assertNotNull(evt);
|
||||
Collection<Path> paths = evt.getPathsToOpen();
|
||||
MatcherAssert.assertThat(paths, CoreMatchers.hasItems(Paths.get("foo"), Paths.get("bar")));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("./cryptomator.exe foo (with 'foo' being an invalid path)")
|
||||
public void testOpenArgsWithIncorrectPaths() {
|
||||
FileSystem fs = Mockito.mock(FileSystem.class);
|
||||
Mockito.when(fs.getPath("foo")).thenThrow(new InvalidPathException("foo", "foo is not a path"));
|
||||
inTest.handleLaunchArgs(fs, new String[]{"foo"});
|
||||
|
||||
AppLaunchEvent evt = queue.poll();
|
||||
Assertions.assertNull(evt);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("./cryptomator.exe foo (with full event queue)")
|
||||
public void testOpenArgsWithFullQueue() {
|
||||
queue.add(new AppLaunchEvent(AppLaunchEvent.EventType.OPEN_FILE, Collections.emptyList()));
|
||||
Assumptions.assumeTrue(queue.remainingCapacity() == 0);
|
||||
|
||||
inTest.handleLaunchArgs(new String[]{"foo"});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.launcher;
|
||||
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.cryptomator.launcher.IpcFactory.IpcEndpoint;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class IpcFactoryTest {
|
||||
|
||||
private Environment environment = Mockito.mock(Environment.class);
|
||||
private IpcProtocolImpl protocolHandler = Mockito.mock(IpcProtocolImpl.class);
|
||||
|
||||
@Test
|
||||
@DisplayName("Wihout IPC port files")
|
||||
public void testNoIpcWithoutPortFile() throws IOException {
|
||||
IpcFactory inTest = new IpcFactory(environment, protocolHandler);
|
||||
|
||||
Mockito.when(environment.getIpcPortPath()).thenReturn(Stream.empty());
|
||||
try (IpcEndpoint endpoint1 = inTest.create()) {
|
||||
Assertions.assertEquals(IpcFactory.SelfEndpoint.class, endpoint1.getClass());
|
||||
Assertions.assertFalse(endpoint1.isConnectedToRemote());
|
||||
Assertions.assertSame(protocolHandler, endpoint1.getRemote());
|
||||
try (IpcEndpoint endpoint2 = inTest.create()) {
|
||||
Assertions.assertEquals(IpcFactory.SelfEndpoint.class, endpoint2.getClass());
|
||||
Assertions.assertNotSame(endpoint1, endpoint2);
|
||||
Assertions.assertFalse(endpoint2.isConnectedToRemote());
|
||||
Assertions.assertSame(protocolHandler, endpoint2.getRemote());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Start server and client with port shared via file")
|
||||
public void testInterProcessCommunication(@TempDir Path tmpDir) throws IOException {
|
||||
Path portFile = tmpDir.resolve("testPortFile");
|
||||
Mockito.when(environment.getIpcPortPath()).thenReturn(Stream.of(portFile));
|
||||
IpcFactory inTest = new IpcFactory(environment, protocolHandler);
|
||||
|
||||
Assertions.assertFalse(Files.exists(portFile));
|
||||
try (IpcEndpoint endpoint1 = inTest.create()) {
|
||||
Assertions.assertEquals(IpcFactory.ServerEndpoint.class, endpoint1.getClass());
|
||||
Assertions.assertFalse(endpoint1.isConnectedToRemote());
|
||||
Assertions.assertTrue(Files.exists(portFile));
|
||||
Assertions.assertSame(protocolHandler, endpoint1.getRemote());
|
||||
Mockito.verifyZeroInteractions(protocolHandler);
|
||||
try (IpcEndpoint endpoint2 = inTest.create()) {
|
||||
Assertions.assertEquals(IpcFactory.ClientEndpoint.class, endpoint2.getClass());
|
||||
Assertions.assertNotSame(endpoint1, endpoint2);
|
||||
Assertions.assertTrue(endpoint2.isConnectedToRemote());
|
||||
Assertions.assertNotSame(protocolHandler, endpoint2.getRemote());
|
||||
Mockito.verifyZeroInteractions(protocolHandler);
|
||||
endpoint2.getRemote().handleLaunchArgs(new String[]{"foo"});
|
||||
Mockito.verify(protocolHandler).handleLaunchArgs(new String[]{"foo"});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*******************************************************************************
|
||||
* Copyright (c) 2017 Skymatic UG (haftungsbeschränkt).
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the accompanying LICENSE file.
|
||||
*******************************************************************************/
|
||||
package org.cryptomator.logging;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class LaunchBasedTriggeringPolicyTest {
|
||||
|
||||
@Test
|
||||
public void testTriggerOnceAndNeverAgain() {
|
||||
LaunchBasedTriggeringPolicy<Object> policy = new LaunchBasedTriggeringPolicy<>();
|
||||
File activeFile = Mockito.mock(File.class);
|
||||
Object event = Mockito.mock(Object.class);
|
||||
|
||||
// 1st invocation
|
||||
boolean triggered = policy.isTriggeringEvent(activeFile, event);
|
||||
Assertions.assertTrue(triggered);
|
||||
|
||||
// 2nd invocation
|
||||
triggered = policy.isTriggeringEvent(activeFile, event);
|
||||
Assertions.assertFalse(triggered);
|
||||
|
||||
// 3rd invocation
|
||||
triggered = policy.isTriggeringEvent(activeFile, event);
|
||||
Assertions.assertFalse(triggered);
|
||||
|
||||
Mockito.verifyZeroInteractions(activeFile);
|
||||
Mockito.verifyZeroInteractions(event);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package org.cryptomator.ui.addvaultwizard;
|
||||
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.CsvSource;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class ReadMeGeneratorTest {
|
||||
|
||||
@ParameterizedTest
|
||||
@CsvSource({ //
|
||||
"test,test", //
|
||||
"t\u00E4st,t\\u228st", //
|
||||
"t\uD83D\uDE09st,t\\u55357\\u56841st", //
|
||||
})
|
||||
public void testEscapeNonAsciiChars(String input, String expectedResult) {
|
||||
ReadmeGenerator readmeGenerator = new ReadmeGenerator(null);
|
||||
|
||||
String actualResult = readmeGenerator.escapeNonAsciiChars(input);
|
||||
|
||||
Assertions.assertEquals(expectedResult, actualResult);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateDocument() {
|
||||
ReadmeGenerator readmeGenerator = new ReadmeGenerator(null);
|
||||
Iterable<String> paragraphs = List.of( //
|
||||
"Dear User,", //
|
||||
"\\b please don't touch the \"d\" directory.", //
|
||||
"Thank you for your cooperation \uD83D\uDE09" //
|
||||
);
|
||||
|
||||
String result = readmeGenerator.createDocument(paragraphs);
|
||||
|
||||
MatcherAssert.assertThat(result, CoreMatchers.startsWith("{\\rtf1\\fbidis\\ansi\\uc0\\fs32"));
|
||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Dear User,}\\par"));
|
||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 \\b please don't touch the \"d\" directory.}\\par "));
|
||||
MatcherAssert.assertThat(result, CoreMatchers.containsString("{\\sa80 Thank you for your cooperation \\u55357\\u56841}\\par"));
|
||||
MatcherAssert.assertThat(result, CoreMatchers.endsWith("}"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package org.cryptomator.ui.common;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import org.cryptomator.common.Environment;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class PasswordStrengthUtilTest {
|
||||
|
||||
@Test
|
||||
public void testLongPasswords() {
|
||||
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(ResourceBundle.class), Mockito.mock(Environment.class));
|
||||
String longPw = Strings.repeat("x", 10_000);
|
||||
Assertions.assertTimeout(Duration.ofSeconds(5), () -> {
|
||||
util.computeRate(longPw);
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("waiting on upstream fix") // https://github.com/nulab/zxcvbn4j/issues/54
|
||||
public void testIssue979() {
|
||||
PasswordStrengthUtil util = new PasswordStrengthUtil(Mockito.mock(ResourceBundle.class), Mockito.mock(Environment.class));
|
||||
int result1 = util.computeRate("backed derrick buckling mountains glove client procedures desire destination sword hidden ram");
|
||||
int result2 = util.computeRate("backed derrick buckling mountains glove client procedures desire destination sword hidden ram escalation");
|
||||
Assertions.assertEquals(4, result1);
|
||||
Assertions.assertEquals(4, result2);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package org.cryptomator.ui.controls;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import javafx.application.Platform;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
class SecurePasswordFieldTest {
|
||||
|
||||
private SecurePasswordField pwField = new SecurePasswordField();
|
||||
|
||||
@BeforeAll
|
||||
static void initJavaFx() throws InterruptedException {
|
||||
Assumptions.assumeFalse(GraphicsEnvironment.isHeadless());
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Platform.startup(latch::countDown);
|
||||
|
||||
if (!latch.await(5L, TimeUnit.SECONDS)) {
|
||||
throw new ExceptionInInitializerError();
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("Content Update Events")
|
||||
class TextChange {
|
||||
|
||||
@Test
|
||||
@DisplayName("\"ant\".append(\"eater\")")
|
||||
public void append() {
|
||||
pwField.setPassword("ant");
|
||||
pwField.appendText("eater");
|
||||
|
||||
Assertions.assertEquals("anteater", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("\"eater\".insert(0, \"ant\")")
|
||||
public void insert1() {
|
||||
pwField.setPassword("eater");
|
||||
pwField.insertText(0, "ant");
|
||||
|
||||
Assertions.assertEquals("anteater", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("\"anteater\".insert(3, \"b\")")
|
||||
public void insert2() {
|
||||
pwField.setPassword("anteater");
|
||||
pwField.insertText(3, "b");
|
||||
|
||||
Assertions.assertEquals("antbeater", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("\"anteater\".delete(0, 3)")
|
||||
public void delete1() {
|
||||
pwField.setPassword("anteater");
|
||||
pwField.deleteText(0, 3);
|
||||
|
||||
Assertions.assertEquals("eater", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("\"anteater\".delete(3, 8)")
|
||||
public void delete2() {
|
||||
pwField.setPassword("anteater");
|
||||
pwField.deleteText(3, 8);
|
||||
|
||||
Assertions.assertEquals("ant", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("\"anteater\".replace(0, 3, \"hand\")")
|
||||
public void replace1() {
|
||||
pwField.setPassword("anteater");
|
||||
pwField.replaceText(0, 3, "hand");
|
||||
|
||||
Assertions.assertEquals("handeater", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("\"anteater\".replace(3, 6, \"keep\")")
|
||||
public void replace2() {
|
||||
pwField.setPassword("anteater");
|
||||
pwField.replaceText(3, 6, "keep");
|
||||
|
||||
Assertions.assertEquals("antkeeper", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("\"anteater\".replace(0, 3, \"bee\")")
|
||||
public void replace3() {
|
||||
pwField.setPassword("anteater");
|
||||
pwField.replaceText(0, 3, "bee");
|
||||
|
||||
Assertions.assertEquals("beeeater", pwField.getCharacters().toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("entering NFC string leads to NFC char[]")
|
||||
public void enterNfcString() {
|
||||
pwField.appendText("str\u00F6m"); // ström
|
||||
pwField.insertText(0, "\u212Bng"); // Ång
|
||||
pwField.appendText("\uD83D\uDCA9"); // 💩
|
||||
|
||||
CharSequence result = pwField.getCharacters();
|
||||
Assertions.assertEquals('\u00C5', result.charAt(0));
|
||||
Assertions.assertEquals('n', result.charAt(1));
|
||||
Assertions.assertEquals('g', result.charAt(2));
|
||||
Assertions.assertEquals('s', result.charAt(3));
|
||||
Assertions.assertEquals('t', result.charAt(4));
|
||||
Assertions.assertEquals('r', result.charAt(5));
|
||||
Assertions.assertEquals('ö', result.charAt(6));
|
||||
Assertions.assertEquals('m', result.charAt(7));
|
||||
Assertions.assertEquals('\uD83D', result.charAt(8));
|
||||
Assertions.assertEquals('\uDCA9', result.charAt(9));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("entering NFD string leads to NFC char[]")
|
||||
public void enterNfdString() {
|
||||
pwField.appendText("str\u006F\u0308m"); // ström
|
||||
pwField.insertText(0, "\u0041\u030Ang"); // Ång
|
||||
pwField.appendText("\uD83D\uDCA9"); // 💩
|
||||
|
||||
CharSequence result = pwField.getCharacters();
|
||||
Assertions.assertEquals('\u00C5', result.charAt(0));
|
||||
Assertions.assertEquals('n', result.charAt(1));
|
||||
Assertions.assertEquals('g', result.charAt(2));
|
||||
Assertions.assertEquals('s', result.charAt(3));
|
||||
Assertions.assertEquals('t', result.charAt(4));
|
||||
Assertions.assertEquals('r', result.charAt(5));
|
||||
Assertions.assertEquals('ö', result.charAt(6));
|
||||
Assertions.assertEquals('m', result.charAt(7));
|
||||
Assertions.assertEquals('\uD83D', result.charAt(8));
|
||||
Assertions.assertEquals('\uDCA9', result.charAt(9));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test swipe char[]")
|
||||
public void testSwipe() {
|
||||
pwField.appendText("topSecret");
|
||||
|
||||
CharSequence result1 = pwField.getCharacters();
|
||||
Assertions.assertEquals("topSecret", result1.toString());
|
||||
pwField.wipe();
|
||||
CharSequence result2 = pwField.getCharacters();
|
||||
Assertions.assertEquals(" ", result1.toString());
|
||||
Assertions.assertEquals("", result2.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("test control characters")
|
||||
public void testControlCharacters() {
|
||||
pwField.appendText("normal");
|
||||
Assertions.assertFalse(pwField.containsNonPrintableCharacters());
|
||||
|
||||
pwField.appendText("\00\01\02");
|
||||
Assertions.assertTrue(pwField.containsNonPrintableCharacters());
|
||||
|
||||
CharSequence result1 = pwField.getCharacters();
|
||||
Assertions.assertEquals("normal\00\01\02", result1.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
class AutoCompleterTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("no match in []")
|
||||
public void testNoMatchInEmptyDict() {
|
||||
AutoCompleter autoCompleter = new AutoCompleter(Set.of());
|
||||
Optional<String> result = autoCompleter.autocomplete("tea");
|
||||
Assertions.assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("no match for \"\"")
|
||||
public void testNoMatchForEmptyString() {
|
||||
AutoCompleter autoCompleter = new AutoCompleter(Set.of("asd"));
|
||||
Optional<String> result = autoCompleter.autocomplete("");
|
||||
Assertions.assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
@Nested
|
||||
@DisplayName("search in dict: ['tame', 'teach', 'teacher']")
|
||||
class NarrowedDownDict {
|
||||
|
||||
AutoCompleter autoCompleter = new AutoCompleter(Set.of("tame", "teach", "teacher"));
|
||||
|
||||
@ParameterizedTest
|
||||
@DisplayName("find 'tame'")
|
||||
@ValueSource(strings = {"t", "ta", "tam", "tame"})
|
||||
public void testFindTame(String prefix) {
|
||||
Optional<String> result = autoCompleter.autocomplete(prefix);
|
||||
Assertions.assertTrue(result.isPresent());
|
||||
Assertions.assertEquals("tame", result.get());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@DisplayName("find 'teach'")
|
||||
@ValueSource(strings = {"te", "tea", "teac", "teach"})
|
||||
public void testFindTeach(String prefix) {
|
||||
Optional<String> result = autoCompleter.autocomplete(prefix);
|
||||
Assertions.assertTrue(result.isPresent());
|
||||
Assertions.assertEquals("teach", result.get());
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@DisplayName("find 'teacher'")
|
||||
@ValueSource(strings = {"teache", "teacher"})
|
||||
public void testFindTeacher(String prefix) {
|
||||
Optional<String> result = autoCompleter.autocomplete(prefix);
|
||||
Assertions.assertTrue(result.isPresent());
|
||||
Assertions.assertEquals("teacher", result.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("don't find 'teachers'")
|
||||
public void testDontFindTeachers() {
|
||||
Optional<String> result = autoCompleter.autocomplete("teachers");
|
||||
Assertions.assertFalse(result.isPresent());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
import org.cryptomator.cryptolib.api.CryptoException;
|
||||
import org.cryptomator.cryptolib.api.Masterkey;
|
||||
import org.cryptomator.cryptolib.common.MasterkeyFileAccess;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.SecureRandom;
|
||||
|
||||
class RecoveryKeyFactoryTest {
|
||||
|
||||
private WordEncoder wordEncoder = new WordEncoder();
|
||||
private MasterkeyFileAccess masterkeyFileAccess = Mockito.mock(MasterkeyFileAccess.class);
|
||||
private RecoveryKeyFactory inTest = new RecoveryKeyFactory(wordEncoder, masterkeyFileAccess);
|
||||
|
||||
@Test
|
||||
@DisplayName("createRecoveryKey() creates 44 words")
|
||||
public void testCreateRecoveryKey() throws IOException, CryptoException {
|
||||
Path pathToVault = Path.of("path/to/vault");
|
||||
Masterkey masterkey = Mockito.mock(Masterkey.class);
|
||||
Mockito.when(masterkeyFileAccess.load(pathToVault.resolve("masterkey.cryptomator"), "asd")).thenReturn(masterkey);
|
||||
|
||||
Mockito.when(masterkey.getEncoded()).thenReturn(new byte[64]);
|
||||
|
||||
String recoveryKey = inTest.createRecoveryKey(pathToVault, "asd");
|
||||
Assertions.assertNotNull(recoveryKey);
|
||||
Assertions.assertEquals(44, Splitter.on(' ').splitToList(recoveryKey).size()); // 66 bytes encoded as 44 words
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("validateRecoveryKey() with odd number of words")
|
||||
public void testValidateValidateRecoveryKeyWithOddNumberOfWords() {
|
||||
boolean result = inTest.validateRecoveryKey("pathway");
|
||||
Assertions.assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("validateRecoveryKey() with words not in dictionary")
|
||||
public void testValidateValidateRecoveryKeyWithGarbageInput() {
|
||||
boolean result = inTest.validateRecoveryKey("Backpfeifengesicht Schweinehund"); // according to le internet these are typical German words
|
||||
Assertions.assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("validateRecoveryKey() with too short input")
|
||||
public void testValidateValidateRecoveryKeyWithTooShortInput() {
|
||||
boolean result = inTest.validateRecoveryKey("pathway lift");
|
||||
Assertions.assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("validateRecoveryKey() with invalid checksum")
|
||||
public void testValidateValidateRecoveryKeyWithInvalidCrc() {
|
||||
boolean result = inTest.validateRecoveryKey("""
|
||||
pathway lift abuse plenty export texture gentleman landscape beyond ceiling around leaf cafe charity \
|
||||
border breakdown victory surely computer cat linger restrict infer crowd live computer true written amazed \
|
||||
investor boot depth left theory snow whereby terminal weekly reject happiness circuit partial cup wrong \
|
||||
""");
|
||||
Assertions.assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("validateRecoveryKey() with valid input")
|
||||
public void testValidateValidateRecoveryKeyWithValidKey() {
|
||||
boolean result = inTest.validateRecoveryKey("""
|
||||
pathway lift abuse plenty export texture gentleman landscape beyond ceiling around leaf cafe charity \
|
||||
border breakdown victory surely computer cat linger restrict infer crowd live computer true written amazed \
|
||||
investor boot depth left theory snow whereby terminal weekly reject happiness circuit partial cup ad \
|
||||
""");
|
||||
Assertions.assertTrue(result);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.cryptomator.ui.recoverykey;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class WordEncoderTest {
|
||||
|
||||
private static final Random PRNG = new Random(42l);
|
||||
private WordEncoder encoder;
|
||||
|
||||
@BeforeAll
|
||||
public void setup() {
|
||||
encoder = new WordEncoder();
|
||||
}
|
||||
|
||||
@DisplayName("decode(encode(input)) == input")
|
||||
@ParameterizedTest(name = "test {index}")
|
||||
@MethodSource("createRandomByteSequences")
|
||||
void encodeAndDecode(byte[] input) {
|
||||
String encoded = encoder.encodePadded(input);
|
||||
byte[] decoded = encoder.decode(encoded);
|
||||
Assertions.assertArrayEquals(input, decoded);
|
||||
}
|
||||
|
||||
static Stream<byte[]> createRandomByteSequences() {
|
||||
return IntStream.range(0, 30).mapToObj(i -> {
|
||||
byte[] randomBytes = new byte[i * 3];
|
||||
PRNG.nextBytes(randomBytes);
|
||||
return randomBytes;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
mock-maker-inline
|
||||
Reference in New Issue
Block a user