diff --git a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs index d2e4aa601..b51377d15 100644 --- a/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs +++ b/Source/Testably.Abstractions.Testing/Storage/InMemoryStorage.cs @@ -199,8 +199,14 @@ public IEnumerable EnumerateLocations( throw ExceptionFactory.DirectoryNotFound(location.FullPath); } - return EnumerateLocationsImpl(location, type, requestParentAccess, searchPattern, - enumerationOptions, parentContainer); + IDisposable parentAccess = new NoOpDisposable(); + if (requestParentAccess) + { + parentAccess = parentContainer.RequestAccess(FileAccess.Read, FileShare.ReadWrite); + } + + return EnumerateLocationsImpl(location, type, searchPattern, + enumerationOptions, parentAccess); } /// @@ -210,17 +216,10 @@ public IEnumerable EnumerateLocations( private IEnumerable EnumerateLocationsImpl( IStorageLocation location, FileSystemTypes type, - bool requestParentAccess, string searchPattern, EnumerationOptions? enumerationOptions, - IStorageContainer parentContainer) + IDisposable parentAccess) { - IDisposable parentAccess = new NoOpDisposable(); - if (requestParentAccess) - { - parentAccess = parentContainer.RequestAccess(FileAccess.Read, FileShare.ReadWrite); - } - using (parentAccess) { enumerationOptions ??= EnumerationOptionsHelper.Compatible; diff --git a/Tests/Testably.Abstractions.Testing.Tests/FileSystem/DirectoryMockTests.cs b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/DirectoryMockTests.cs new file mode 100644 index 000000000..9e8fcf62f --- /dev/null +++ b/Tests/Testably.Abstractions.Testing.Tests/FileSystem/DirectoryMockTests.cs @@ -0,0 +1,69 @@ +using Testably.Abstractions.Testing.FileSystem; + +namespace Testably.Abstractions.Testing.Tests.FileSystem; + +public class DirectoryMockTests +{ + [Fact] + public async Task + EnumerateDirectories_UnauthorizedParentAccess_ShouldThrowUnauthorizedAccessExceptionImmediately() + { + Skip.IfNot(Test.RunsOnWindows); + + string path = "foo"; + MockFileSystem fileSystem = new(); + IDirectoryInfo sut = fileSystem.Directory.CreateDirectory(path); + fileSystem.WithAccessControlStrategy( + new DefaultAccessControlStrategy((p, _) + => !p.EndsWith(path, StringComparison.Ordinal))); + + void Act() => + _ = fileSystem.Directory.EnumerateDirectories(path); + + await That(Act).Throws() + .WithMessageContaining($"'{sut.FullName}'").And + .WithHResult(-2147024891); + } + + [Fact] + public async Task + EnumerateFiles_UnauthorizedParentAccess_ShouldThrowUnauthorizedAccessExceptionImmediately() + { + Skip.IfNot(Test.RunsOnWindows); + + string path = "foo"; + MockFileSystem fileSystem = new(); + IDirectoryInfo sut = fileSystem.Directory.CreateDirectory(path); + fileSystem.WithAccessControlStrategy( + new DefaultAccessControlStrategy((p, _) + => !p.EndsWith(path, StringComparison.Ordinal))); + + void Act() => + _ = fileSystem.Directory.EnumerateFiles(path); + + await That(Act).Throws() + .WithMessageContaining($"'{sut.FullName}'").And + .WithHResult(-2147024891); + } + + [Fact] + public async Task + EnumerateFileSystemEntries_UnauthorizedParentAccess_ShouldThrowUnauthorizedAccessExceptionImmediately() + { + Skip.IfNot(Test.RunsOnWindows); + + string path = "foo"; + MockFileSystem fileSystem = new(); + IDirectoryInfo sut = fileSystem.Directory.CreateDirectory(path); + fileSystem.WithAccessControlStrategy( + new DefaultAccessControlStrategy((p, _) + => !p.EndsWith(path, StringComparison.Ordinal))); + + void Act() => + _ = fileSystem.Directory.EnumerateFileSystemEntries(path); + + await That(Act).Throws() + .WithMessageContaining($"'{sut.FullName}'").And + .WithHResult(-2147024891); + } +}