Skip to content

Commit d8fef25

Browse files
authored
Merge pull request #261 from russcam/fix/directory-access-control
Add support for Directory AccessControl
2 parents 86a06ed + 92747f5 commit d8fef25

5 files changed

Lines changed: 171 additions & 12 deletions

File tree

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Security.AccessControl;
7+
8+
namespace System.IO.Abstractions.TestingHelpers.Tests
9+
{
10+
using XFS = MockUnixSupport;
11+
12+
[TestFixture]
13+
public class MockDirectoryGetAccessControlTests
14+
{
15+
[TestCase(" ")]
16+
[TestCase(" ")]
17+
public void MockDirectory_GetAccessControl_ShouldThrowArgumentExceptionIfPathContainsOnlyWhitespaces(string path)
18+
{
19+
// Arrange
20+
var fileSystem = new MockFileSystem();
21+
22+
// Act
23+
TestDelegate action = () => fileSystem.Directory.GetAccessControl(path);
24+
25+
// Assert
26+
var exception = Assert.Throws<ArgumentException>(action);
27+
Assert.That(exception.ParamName, Is.EqualTo("path"));
28+
}
29+
30+
[Test]
31+
public void MockDirectory_GetAccessControl_ShouldThrowDirectoryNotFoundExceptionIfDirectoryDoesNotExistInMockData()
32+
{
33+
// Arrange
34+
var fileSystem = new MockFileSystem();
35+
var expectedDirectoryName = XFS.Path(@"c:\a");
36+
37+
// Act
38+
TestDelegate action = () => fileSystem.Directory.GetAccessControl(expectedDirectoryName);
39+
40+
// Assert
41+
Assert.Throws<DirectoryNotFoundException>(action);
42+
}
43+
44+
[Test]
45+
public void MockDirectory_GetAccessControl_ShouldReturnAccessControlOfDirectoryData()
46+
{
47+
// Arrange
48+
var expectedDirectorySecurity = new DirectorySecurity();
49+
expectedDirectorySecurity.SetAccessRuleProtection(false, false);
50+
51+
var filePath = XFS.Path(@"c:\a\");
52+
var fileData = new MockDirectoryData()
53+
{
54+
AccessControl = expectedDirectorySecurity,
55+
};
56+
57+
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>()
58+
{
59+
{ filePath, fileData }
60+
});
61+
62+
// Act
63+
var directorySecurity = fileSystem.Directory.GetAccessControl(filePath);
64+
65+
// Assert
66+
Assert.That(directorySecurity, Is.EqualTo(expectedDirectorySecurity));
67+
}
68+
}
69+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using NUnit.Framework;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
using System.Text;
6+
7+
namespace System.IO.Abstractions.TestingHelpers.Tests
8+
{
9+
using Security.AccessControl;
10+
using XFS = MockUnixSupport;
11+
12+
[TestFixture]
13+
public class MockDirectorySetAccessControlTests
14+
{
15+
[TestCase(" ")]
16+
[TestCase(" ")]
17+
public void MockDirectory_SetAccessControl_ShouldThrowArgumentExceptionIfPathContainsOnlyWhitespaces(string path)
18+
{
19+
// Arrange
20+
var fileSystem = new MockFileSystem();
21+
var directorySecurity = new DirectorySecurity();
22+
23+
// Act
24+
TestDelegate action = () => fileSystem.Directory.SetAccessControl(path, directorySecurity);
25+
26+
// Assert
27+
var exception = Assert.Throws<ArgumentException>(action);
28+
Assert.That(exception.ParamName, Is.EqualTo("path"));
29+
}
30+
31+
[Test]
32+
public void MockDirectory_SetAccessControl_ShouldThrowDirectoryNotFoundExceptionIfDirectoryDoesNotExistInMockData()
33+
{
34+
// Arrange
35+
var fileSystem = new MockFileSystem();
36+
var expectedFileName = XFS.Path(@"c:\a\");
37+
var directorySecurity = new DirectorySecurity();
38+
39+
// Act
40+
TestDelegate action = () => fileSystem.Directory.SetAccessControl(expectedFileName, directorySecurity);
41+
42+
// Assert
43+
Assert.Throws<DirectoryNotFoundException>(action);
44+
}
45+
46+
[Test]
47+
public void MockDirectory_SetAccessControl_ShouldReturnAccessControlOfDirectoryData()
48+
{
49+
// Arrange
50+
var filePath = XFS.Path(@"c:\a\");
51+
var fileData = new MockDirectoryData();
52+
53+
var fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>()
54+
{
55+
{ filePath, fileData }
56+
});
57+
58+
// Act
59+
var expectedAccessControl = new DirectorySecurity();
60+
expectedAccessControl.SetAccessRuleProtection(false, false);
61+
fileSystem.Directory.SetAccessControl(filePath, expectedAccessControl);
62+
63+
// Assert
64+
var accessControl = fileSystem.Directory.GetAccessControl(filePath);
65+
Assert.That(accessControl, Is.EqualTo(expectedAccessControl));
66+
}
67+
}
68+
}

TestHelpers.Tests/MockDirectoryTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,10 +1391,10 @@ public void MockDirectory_GetAccessControl_ShouldReturnNewDirectorySecurity()
13911391
{
13921392
// Arrange
13931393
var fileSystem = new MockFileSystem();
1394-
fileSystem.Directory.CreateDirectory(XFS.Path(@"c:\foo"));
1394+
fileSystem.Directory.CreateDirectory(XFS.Path(@"c:\foo\"));
13951395

13961396
// Act
1397-
DirectorySecurity result = fileSystem.Directory.GetAccessControl(XFS.Path(@"c:\foo"));
1397+
DirectorySecurity result = fileSystem.Directory.GetAccessControl(XFS.Path(@"c:\foo\"));
13981398

13991399
// Assert
14001400
Assert.That(result, Is.Not.Null);

TestingHelpers/MockDirectory.cs

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public MockDirectory(IMockFileDataAccessor mockFileDataAccessor, FileBase fileBa
3232

3333
public override DirectoryInfoBase CreateDirectory(string path)
3434
{
35-
return CreateDirectoryInternal(path, null);
35+
return CreateDirectoryInternal(path, new DirectorySecurity());
3636
}
3737

3838
#if NET40
@@ -61,6 +61,7 @@ private DirectoryInfoBase CreateDirectoryInternal(string path, DirectorySecurity
6161
}
6262

6363
var created = new MockDirectoryInfo(mockFileDataAccessor, path);
64+
created.SetAccessControl(directorySecurity);
6465
return created;
6566
}
6667

@@ -93,7 +94,6 @@ public override bool Exists(string path)
9394
try
9495
{
9596
path = EnsurePathEndsWithDirectorySeparator(path);
96-
9797
path = mockFileDataAccessor.Path.GetFullPath(path);
9898
return mockFileDataAccessor.AllDirectories.Any(p => p.Equals(path, StringComparison.OrdinalIgnoreCase));
9999
}
@@ -104,19 +104,21 @@ public override bool Exists(string path)
104104
}
105105

106106
public override DirectorySecurity GetAccessControl(string path)
107-
{
108-
// First crude implementation to avoid NotImplementedException
109-
if (Exists(path))
107+
{
108+
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
109+
path = EnsurePathEndsWithDirectorySeparator(path);
110+
111+
if (!mockFileDataAccessor.Directory.Exists(path))
110112
{
111-
return new DirectorySecurity();
113+
throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), path));
112114
}
113115

114-
throw new DirectoryNotFoundException(path);
116+
var directoryData = (MockDirectoryData) mockFileDataAccessor.GetFile(path);
117+
return directoryData.AccessControl;
115118
}
116119

117120
public override DirectorySecurity GetAccessControl(string path, AccessControlSections includeSections)
118121
{
119-
// First crude implementation to avoid NotImplementedException
120122
return GetAccessControl(path);
121123
}
122124

@@ -376,7 +378,16 @@ public override void Move(string sourceDirName, string destDirName)
376378

377379
public override void SetAccessControl(string path, DirectorySecurity directorySecurity)
378380
{
379-
throw new NotImplementedException(StringResources.Manager.GetString("NOT_IMPLEMENTED_EXCEPTION"));
381+
mockFileDataAccessor.PathVerifier.IsLegalAbsoluteOrRelative(path, "path");
382+
path = EnsurePathEndsWithDirectorySeparator(path);
383+
384+
if (!mockFileDataAccessor.Directory.Exists(path))
385+
{
386+
throw new DirectoryNotFoundException(string.Format(CultureInfo.InvariantCulture, StringResources.Manager.GetString("COULD_NOT_FIND_PART_OF_PATH_EXCEPTION"), path));
387+
}
388+
389+
var directoryData = (MockDirectoryData)mockFileDataAccessor.GetFile(path);
390+
directoryData.AccessControl = directorySecurity;
380391
}
381392

382393
public override void SetCreationTime(string path, DateTime creationTime)
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,24 @@
1-
namespace System.IO.Abstractions.TestingHelpers
1+
using System.Security.AccessControl;
2+
3+
namespace System.IO.Abstractions.TestingHelpers
24
{
35
[Serializable]
46
public class MockDirectoryData : MockFileData
57
{
8+
[NonSerialized]
9+
private DirectorySecurity accessControl = new DirectorySecurity();
10+
611
public override bool IsDirectory { get { return true; } }
712

813
public MockDirectoryData() : base(string.Empty)
914
{
1015
Attributes = FileAttributes.Directory;
1116
}
17+
18+
public new DirectorySecurity AccessControl
19+
{
20+
get { return accessControl; }
21+
set { accessControl = value; }
22+
}
1223
}
1324
}

0 commit comments

Comments
 (0)