|
42 | 42 | import java.nio.file.NoSuchFileException; |
43 | 43 | import java.nio.file.Path; |
44 | 44 | import java.nio.file.PathMatcher; |
| 45 | +import java.nio.file.ProviderMismatchException; |
45 | 46 | import java.nio.file.StandardCopyOption; |
46 | 47 | import java.nio.file.StandardOpenOption; |
47 | 48 | import java.nio.file.attribute.BasicFileAttributeView; |
@@ -119,11 +120,11 @@ public void setup() { |
119 | 120 |
|
120 | 121 | when(fileSystemProperties.maxCleartextNameLength()).thenReturn(32768); |
121 | 122 |
|
122 | | - inTest = new CryptoFileSystemImpl(provider, cryptoFileSystems, pathToVault, cryptor, |
123 | | - fileStore, stats, cryptoPathMapper, cryptoPathFactory, |
124 | | - pathMatcherFactory, directoryStreamFactory, dirIdProvider, dirIdBackup, |
125 | | - fileAttributeProvider, fileAttributeByNameProvider, fileAttributeViewProvider, |
126 | | - openCryptoFiles, symlinks, finallyUtil, ciphertextDirDeleter, readonlyFlag, |
| 123 | + inTest = new CryptoFileSystemImpl(provider, cryptoFileSystems, pathToVault, cryptor, // |
| 124 | + fileStore, stats, cryptoPathMapper, cryptoPathFactory, // |
| 125 | + pathMatcherFactory, directoryStreamFactory, dirIdProvider, dirIdBackup, // |
| 126 | + fileAttributeProvider, fileAttributeByNameProvider, fileAttributeViewProvider, // |
| 127 | + openCryptoFiles, symlinks, finallyUtil, ciphertextDirDeleter, readonlyFlag, // |
127 | 128 | fileSystemProperties); |
128 | 129 | } |
129 | 130 |
|
@@ -188,6 +189,89 @@ public void testGetFileStoresReturnsFileStore() { |
188 | 189 | Assertions.assertSame(fileStore, inTest.getFileStore()); |
189 | 190 | } |
190 | 191 |
|
| 192 | + @Nested |
| 193 | + public class PathToDataCiphertext { |
| 194 | + |
| 195 | + @Test |
| 196 | + @DisplayName("Getting data ciphertext path of directory returns ciphertext content dir") |
| 197 | + public void testCleartextDirectory() throws IOException { |
| 198 | + Path ciphertext = Mockito.mock(Path.class, "/d/AB/CD...XYZ/"); |
| 199 | + Path cleartext = inTest.getPath("/"); |
| 200 | + try (var cryptoPathMock = Mockito.mockStatic(CryptoPath.class)) { |
| 201 | + cryptoPathMock.when(() -> CryptoPath.castAndAssertAbsolute(any())).thenReturn(cleartext); |
| 202 | + when(cryptoPathMapper.getCiphertextFileType(any())).thenReturn(CiphertextFileType.DIRECTORY); |
| 203 | + when(cryptoPathMapper.getCiphertextDir(any())).thenReturn(new CiphertextDirectory("foo", ciphertext)); |
| 204 | + |
| 205 | + Path result = inTest.getCiphertextPath(cleartext); |
| 206 | + Assertions.assertEquals(ciphertext, result); |
| 207 | + } |
| 208 | + } |
| 209 | + |
| 210 | + @Test |
| 211 | + @DisplayName("Getting data ciphertext path of file returns ciphertext file") |
| 212 | + public void testCleartextFile() throws IOException { |
| 213 | + Path ciphertext = Mockito.mock(Path.class, "/d/AB/CD..XYZ/foo.c9r"); |
| 214 | + Path cleartext = inTest.getPath("/foo.bar"); |
| 215 | + try (var cryptoPathMock = Mockito.mockStatic(CryptoPath.class)) { |
| 216 | + CiphertextFilePath p = Mockito.mock(CiphertextFilePath.class); |
| 217 | + cryptoPathMock.when(() -> CryptoPath.castAndAssertAbsolute(any())).thenReturn(cleartext); |
| 218 | + when(cryptoPathMapper.getCiphertextFileType(any())).thenReturn(CiphertextFileType.FILE); |
| 219 | + when(cryptoPathMapper.getCiphertextFilePath(any())).thenReturn(p); |
| 220 | + when(p.getFilePath()).thenReturn(ciphertext); |
| 221 | + |
| 222 | + Path result = inTest.getCiphertextPath(cleartext); |
| 223 | + Assertions.assertEquals(ciphertext, result); |
| 224 | + } |
| 225 | + } |
| 226 | + |
| 227 | + @Test |
| 228 | + @DisplayName("Getting data ciphertext path of symlink returns ciphertext symlink.c9r") |
| 229 | + public void testCleartextSymlink() throws IOException { |
| 230 | + Path ciphertext = Mockito.mock(Path.class, "/d/AB/CD..XYZ/foo.c9s/symlink.c9r"); |
| 231 | + Path cleartext = inTest.getPath("/foo.bar"); |
| 232 | + try (var cryptoPathMock = Mockito.mockStatic(CryptoPath.class)) { |
| 233 | + CiphertextFilePath p = Mockito.mock(CiphertextFilePath.class); |
| 234 | + cryptoPathMock.when(() -> CryptoPath.castAndAssertAbsolute(any())).thenReturn(cleartext); |
| 235 | + when(cryptoPathMapper.getCiphertextFileType(any())).thenReturn(CiphertextFileType.SYMLINK); |
| 236 | + when(cryptoPathMapper.getCiphertextFilePath(any())).thenReturn(p); |
| 237 | + when(p.getSymlinkFilePath()).thenReturn(ciphertext); |
| 238 | + |
| 239 | + Path result = inTest.getCiphertextPath(cleartext); |
| 240 | + Assertions.assertEquals(ciphertext, result); |
| 241 | + } |
| 242 | + } |
| 243 | + |
| 244 | + @Test |
| 245 | + @DisplayName("Path not pointing into the vault throws exception") |
| 246 | + public void testForeignPathThrows() throws IOException { |
| 247 | + Path cleartext = Mockito.mock(Path.class, "/some.file"); |
| 248 | + Assertions.assertThrows(ProviderMismatchException.class, () -> inTest.getCiphertextPath(cleartext)); |
| 249 | + } |
| 250 | + |
| 251 | + @Test |
| 252 | + @DisplayName("Not existing resource throws NoSuchFileException") |
| 253 | + public void testNoSuchFile() throws IOException { |
| 254 | + Path cleartext = inTest.getPath("/i-do-not-exist"); |
| 255 | + try (var cryptoPathMock = Mockito.mockStatic(CryptoPath.class)) { |
| 256 | + cryptoPathMock.when(() -> CryptoPath.castAndAssertAbsolute(any())).thenReturn(cleartext); |
| 257 | + when(cryptoPathMapper.getCiphertextFileType(any())).thenThrow(new NoSuchFileException("no such file")); |
| 258 | + |
| 259 | + Assertions.assertThrows(NoSuchFileException.class, () -> inTest.getCiphertextPath(cleartext)); |
| 260 | + } |
| 261 | + } |
| 262 | + |
| 263 | + @Test |
| 264 | + @DisplayName("Relative cleartext path throws exception") |
| 265 | + public void testRelativePathException() throws IOException { |
| 266 | + Path cleartext = inTest.getPath("relative/path"); |
| 267 | + try (var cryptoPathMock = Mockito.mockStatic(CryptoPath.class)) { |
| 268 | + cryptoPathMock.when(() -> CryptoPath.castAndAssertAbsolute(any())).thenThrow(new IllegalArgumentException()); |
| 269 | + |
| 270 | + Assertions.assertThrows(IllegalArgumentException.class, () -> inTest.getCiphertextPath(cleartext)); |
| 271 | + } |
| 272 | + } |
| 273 | + } |
| 274 | + |
191 | 275 | @Nested |
192 | 276 | public class CloseAndIsOpen { |
193 | 277 |
|
|
0 commit comments