|
5 | 5 | import org.cryptomator.cryptofs.attr.AttributeProvider;
|
6 | 6 | import org.cryptomator.cryptofs.attr.AttributeViewProvider;
|
7 | 7 | import org.cryptomator.cryptofs.attr.AttributeViewType;
|
| 8 | +import org.cryptomator.cryptofs.fh.OpenCryptoFile; |
8 | 9 | import org.cryptomator.cryptofs.fh.OpenCryptoFiles;
|
9 | 10 | import org.cryptomator.cryptofs.fh.OpenCryptoFiles.TwoPhaseMove;
|
10 | 11 | import org.cryptomator.cryptofs.mocks.FileChannelMock;
|
|
17 | 18 | import org.junit.jupiter.api.Test;
|
18 | 19 | import org.mockito.Mockito;
|
19 | 20 |
|
| 21 | +import javax.inject.Named; |
20 | 22 | import java.io.IOException;
|
21 | 23 | import java.lang.reflect.Field;
|
22 | 24 | import java.nio.ByteBuffer;
|
|
52 | 54 | import java.util.Collections;
|
53 | 55 | import java.util.EnumSet;
|
54 | 56 | import java.util.Iterator;
|
| 57 | +import java.util.Optional; |
55 | 58 | import java.util.Set;
|
56 | 59 | import java.util.concurrent.TimeUnit;
|
57 | 60 |
|
@@ -333,6 +336,59 @@ public void testNewWatchServiceThrowsUnsupportedOperationException() throws IOEx
|
333 | 336 | inTest.newWatchService();
|
334 | 337 | });
|
335 | 338 | }
|
| 339 | + |
| 340 | + @Nested |
| 341 | + public class NewFileChannel { |
| 342 | + |
| 343 | + private final CryptoPath cleartextPath = mock(CryptoPath.class, "cleartext"); |
| 344 | + private final Path ciphertextPath = mock(Path.class, "ciphertext"); |
| 345 | + private final OpenCryptoFile openCryptoFile = mock(OpenCryptoFile.class); |
| 346 | + private final FileChannel fileChannel = mock(FileChannel.class); |
| 347 | + |
| 348 | + @BeforeEach |
| 349 | + public void setup() throws IOException { |
| 350 | + when(cryptoPathMapper.getCiphertextFileType(cleartextPath)).thenReturn(CiphertextFileType.FILE); |
| 351 | + when(cryptoPathMapper.getCiphertextFilePath(cleartextPath, CiphertextFileType.FILE)).thenReturn(ciphertextPath); |
| 352 | + when(openCryptoFiles.getOrCreate(ciphertextPath)).thenReturn(openCryptoFile); |
| 353 | + when(openCryptoFile.newFileChannel(any())).thenReturn(fileChannel); |
| 354 | + } |
| 355 | + |
| 356 | + @Test |
| 357 | + @Named("newFileChannel read-only") |
| 358 | + public void testNewFileChannelReadOnly() throws IOException { |
| 359 | + FileChannel ch = inTest.newFileChannel(cleartextPath, EnumSet.of(StandardOpenOption.READ)); |
| 360 | + |
| 361 | + Assertions.assertSame(fileChannel, ch); |
| 362 | + verify(readonlyFlag, Mockito.never()).assertWritable(); |
| 363 | + } |
| 364 | + |
| 365 | + @Test |
| 366 | + @Named("newFileChannel read-only with long filename") |
| 367 | + public void testNewFileChannelReadOnlyShortened() throws IOException { |
| 368 | + LongFileNameProvider.DeflatedFileName deflatedFileName = Mockito.mock(LongFileNameProvider.DeflatedFileName.class); |
| 369 | + when(longFileNameProvider.getCached(ciphertextPath)).thenReturn(Optional.of(deflatedFileName)); |
| 370 | + |
| 371 | + FileChannel ch = inTest.newFileChannel(cleartextPath, EnumSet.of(StandardOpenOption.READ)); |
| 372 | + |
| 373 | + Assertions.assertSame(fileChannel, ch); |
| 374 | + verify(readonlyFlag, Mockito.never()).assertWritable(); |
| 375 | + verify(deflatedFileName, Mockito.never()).persist(); |
| 376 | + } |
| 377 | + |
| 378 | + @Test |
| 379 | + @Named("newFileChannel read-write with long filename") |
| 380 | + public void testNewFileChannelReadWriteShortened() throws IOException { |
| 381 | + LongFileNameProvider.DeflatedFileName deflatedFileName = Mockito.mock(LongFileNameProvider.DeflatedFileName.class); |
| 382 | + when(longFileNameProvider.getCached(ciphertextPath)).thenReturn(Optional.of(deflatedFileName)); |
| 383 | + |
| 384 | + FileChannel ch = inTest.newFileChannel(cleartextPath, EnumSet.of(StandardOpenOption.WRITE)); |
| 385 | + |
| 386 | + Assertions.assertSame(fileChannel, ch); |
| 387 | + verify(readonlyFlag, Mockito.atLeastOnce()).assertWritable(); |
| 388 | + verify(deflatedFileName).persist(); |
| 389 | + } |
| 390 | + |
| 391 | + } |
336 | 392 |
|
337 | 393 | @Nested
|
338 | 394 | public class Delete {
|
|
0 commit comments