Skip to content

Commit b6e34e5

Browse files
authored
fix: move a read-only file (#1239)
Fixes the bug reported in #1207 (which was introduced in #870) that it is not possible to move a read-only file: The `AddFile` and `RemoveFile` now have an optional parameter `verifyAccess` which if set to `false` will omit the access check, thus not throwing the `UnauthorizedAccessException`.
1 parent d1f3aa5 commit b6e34e5

10 files changed

+50
-44
lines changed

src/TestableIO.System.IO.Abstractions.TestingHelpers/IMockFileDataAccessor.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,12 @@ public interface IMockFileDataAccessor : IFileSystem
3131
MockDriveData GetDrive(string name);
3232

3333
/// <summary>
34+
/// Adds the file.
3435
/// </summary>
35-
void AddFile(string path, MockFileData mockFile);
36+
/// <param name="path">The path of the file to add.</param>
37+
/// <param name="mockFile">The file data to add.</param>
38+
/// <param name="verifyAccess">Flag indicating if the access conditions should be verified.</param>
39+
void AddFile(string path, MockFileData mockFile, bool verifyAccess = true);
3640

3741
/// <summary>
3842
/// </summary>
@@ -58,10 +62,11 @@ public interface IMockFileDataAccessor : IFileSystem
5862
/// Removes the file.
5963
/// </summary>
6064
/// <param name="path">The file to remove.</param>
65+
/// <param name="verifyAccess">Flag indicating if the access conditions should be verified.</param>
6166
/// <remarks>
6267
/// The file must not exist.
6368
/// </remarks>
64-
void RemoveFile(string path);
69+
void RemoveFile(string path, bool verifyAccess = true);
6570

6671
/// <summary>
6772
/// Determines whether the file exists.

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFile.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -546,8 +546,8 @@ public override void Move(string sourceFileName, string destFileName)
546546
}
547547
VerifyDirectoryExists(destFileName);
548548

549-
mockFileDataAccessor.RemoveFile(sourceFileName);
550-
mockFileDataAccessor.AddFile(destFileName, mockFileDataAccessor.AdjustTimes(new MockFileData(sourceFile), TimeAdjustments.LastAccessTime));
549+
mockFileDataAccessor.RemoveFile(sourceFileName, false);
550+
mockFileDataAccessor.AddFile(destFileName, mockFileDataAccessor.AdjustTimes(new MockFileData(sourceFile), TimeAdjustments.LastAccessTime), false);
551551
}
552552

553553
#if FEATURE_FILE_MOVE_WITH_OVERWRITE

src/TestableIO.System.IO.Abstractions.TestingHelpers/MockFileSystem.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ private void SetEntry(string path, MockFileData mockFile)
225225
}
226226

227227
/// <inheritdoc />
228-
public void AddFile(string path, MockFileData mockFile)
228+
public void AddFile(string path, MockFileData mockFile, bool verifyAccess = true)
229229
{
230230
var fixedPath = FixPath(path, true);
231231

@@ -237,7 +237,7 @@ public void AddFile(string path, MockFileData mockFile)
237237
var isReadOnly = (file.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly;
238238
var isHidden = (file.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden;
239239

240-
if (isReadOnly || isHidden)
240+
if (verifyAccess && (isReadOnly || isHidden))
241241
{
242242
throw CommonExceptions.AccessDenied(path);
243243
}
@@ -294,9 +294,10 @@ public void AddDirectory(IDirectoryInfo path)
294294
/// </summary>
295295
/// <param name="path">An <see cref="IFileInfo"/> representing the path of the new file to add.</param>
296296
/// <param name="data">The data to use for the contents of the new file.</param>
297-
public void AddFile(IFileInfo path, MockFileData data)
297+
/// <param name="verifyAccess">Flag indicating if the access conditions should be verified.</param>
298+
public void AddFile(IFileInfo path, MockFileData data, bool verifyAccess = true)
298299
{
299-
AddFile(path.FullName, data);
300+
AddFile(path.FullName, data, verifyAccess);
300301
path.Refresh();
301302
}
302303

@@ -444,13 +445,13 @@ bool PathStartsWith(string path, string[] minMatch)
444445
}
445446

446447
/// <inheritdoc />
447-
public void RemoveFile(string path)
448+
public void RemoveFile(string path, bool verifyAccess = true)
448449
{
449450
path = FixPath(path);
450451

451452
lock (files)
452453
{
453-
if (FileExists(path) && (FileIsReadOnly(path) || Directory.Exists(path) && AnyFileIsReadOnly(path)))
454+
if (FileExists(path) && verifyAccess && (FileIsReadOnly(path) || Directory.Exists(path) && AnyFileIsReadOnly(path)))
454455
{
455456
throw CommonExceptions.AccessDenied(path);
456457
}

tests/TestableIO.System.IO.Abstractions.Api.Tests/Expected/TestableIO.System.IO.Abstractions.TestingHelpers_net472.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ namespace System.IO.Abstractions.TestingHelpers
1313
System.IO.Abstractions.TestingHelpers.StringOperations StringOperations { get; }
1414
void AddDirectory(string path);
1515
void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive);
16-
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile);
16+
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true);
1717
void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1818
void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1919
System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments);
2020
bool FileExists(string path);
2121
System.IO.Abstractions.TestingHelpers.MockDriveData GetDrive(string name);
2222
System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path);
2323
void MoveDirectory(string sourcePath, string destPath);
24-
void RemoveFile(string path);
24+
void RemoveFile(string path, bool verifyAccess = true);
2525
}
2626
[System.Serializable]
2727
public class MockDirectory : System.IO.Abstractions.DirectoryBase
@@ -360,8 +360,8 @@ namespace System.IO.Abstractions.TestingHelpers
360360
public void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive) { }
361361
public void AddEmptyFile(System.IO.Abstractions.IFileInfo path) { }
362362
public void AddEmptyFile(string path) { }
363-
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data) { }
364-
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile) { }
363+
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data, bool verifyAccess = true) { }
364+
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true) { }
365365
public void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
366366
public void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
367367
public System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments) { }
@@ -371,7 +371,7 @@ namespace System.IO.Abstractions.TestingHelpers
371371
public System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path) { }
372372
public System.IO.Abstractions.TestingHelpers.MockFileSystem MockTime(System.Func<System.DateTime> dateTimeProvider) { }
373373
public void MoveDirectory(string sourcePath, string destPath) { }
374-
public void RemoveFile(string path) { }
374+
public void RemoveFile(string path, bool verifyAccess = true) { }
375375
}
376376
public class MockFileSystemOptions
377377
{

tests/TestableIO.System.IO.Abstractions.Api.Tests/Expected/TestableIO.System.IO.Abstractions.TestingHelpers_net6.0.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ namespace System.IO.Abstractions.TestingHelpers
1313
System.IO.Abstractions.TestingHelpers.StringOperations StringOperations { get; }
1414
void AddDirectory(string path);
1515
void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive);
16-
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile);
16+
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true);
1717
void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1818
void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1919
System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments);
2020
bool FileExists(string path);
2121
System.IO.Abstractions.TestingHelpers.MockDriveData GetDrive(string name);
2222
System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path);
2323
void MoveDirectory(string sourcePath, string destPath);
24-
void RemoveFile(string path);
24+
void RemoveFile(string path, bool verifyAccess = true);
2525
}
2626
[System.Serializable]
2727
public class MockDirectory : System.IO.Abstractions.DirectoryBase
@@ -415,8 +415,8 @@ namespace System.IO.Abstractions.TestingHelpers
415415
public void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive) { }
416416
public void AddEmptyFile(System.IO.Abstractions.IFileInfo path) { }
417417
public void AddEmptyFile(string path) { }
418-
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data) { }
419-
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile) { }
418+
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data, bool verifyAccess = true) { }
419+
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true) { }
420420
public void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
421421
public void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
422422
public System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments) { }
@@ -426,7 +426,7 @@ namespace System.IO.Abstractions.TestingHelpers
426426
public System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path) { }
427427
public System.IO.Abstractions.TestingHelpers.MockFileSystem MockTime(System.Func<System.DateTime> dateTimeProvider) { }
428428
public void MoveDirectory(string sourcePath, string destPath) { }
429-
public void RemoveFile(string path) { }
429+
public void RemoveFile(string path, bool verifyAccess = true) { }
430430
}
431431
public class MockFileSystemOptions
432432
{

tests/TestableIO.System.IO.Abstractions.Api.Tests/Expected/TestableIO.System.IO.Abstractions.TestingHelpers_net8.0.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ namespace System.IO.Abstractions.TestingHelpers
1313
System.IO.Abstractions.TestingHelpers.StringOperations StringOperations { get; }
1414
void AddDirectory(string path);
1515
void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive);
16-
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile);
16+
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true);
1717
void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1818
void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1919
System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments);
2020
bool FileExists(string path);
2121
System.IO.Abstractions.TestingHelpers.MockDriveData GetDrive(string name);
2222
System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path);
2323
void MoveDirectory(string sourcePath, string destPath);
24-
void RemoveFile(string path);
24+
void RemoveFile(string path, bool verifyAccess = true);
2525
}
2626
[System.Serializable]
2727
public class MockDirectory : System.IO.Abstractions.DirectoryBase
@@ -439,8 +439,8 @@ namespace System.IO.Abstractions.TestingHelpers
439439
public void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive) { }
440440
public void AddEmptyFile(System.IO.Abstractions.IFileInfo path) { }
441441
public void AddEmptyFile(string path) { }
442-
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data) { }
443-
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile) { }
442+
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data, bool verifyAccess = true) { }
443+
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true) { }
444444
public void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
445445
public void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
446446
public System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments) { }
@@ -450,7 +450,7 @@ namespace System.IO.Abstractions.TestingHelpers
450450
public System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path) { }
451451
public System.IO.Abstractions.TestingHelpers.MockFileSystem MockTime(System.Func<System.DateTime> dateTimeProvider) { }
452452
public void MoveDirectory(string sourcePath, string destPath) { }
453-
public void RemoveFile(string path) { }
453+
public void RemoveFile(string path, bool verifyAccess = true) { }
454454
}
455455
public class MockFileSystemOptions
456456
{

tests/TestableIO.System.IO.Abstractions.Api.Tests/Expected/TestableIO.System.IO.Abstractions.TestingHelpers_net9.0.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ namespace System.IO.Abstractions.TestingHelpers
1313
System.IO.Abstractions.TestingHelpers.StringOperations StringOperations { get; }
1414
void AddDirectory(string path);
1515
void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive);
16-
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile);
16+
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true);
1717
void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1818
void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1919
System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments);
2020
bool FileExists(string path);
2121
System.IO.Abstractions.TestingHelpers.MockDriveData GetDrive(string name);
2222
System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path);
2323
void MoveDirectory(string sourcePath, string destPath);
24-
void RemoveFile(string path);
24+
void RemoveFile(string path, bool verifyAccess = true);
2525
}
2626
[System.Serializable]
2727
public class MockDirectory : System.IO.Abstractions.DirectoryBase
@@ -453,8 +453,8 @@ namespace System.IO.Abstractions.TestingHelpers
453453
public void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive) { }
454454
public void AddEmptyFile(System.IO.Abstractions.IFileInfo path) { }
455455
public void AddEmptyFile(string path) { }
456-
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data) { }
457-
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile) { }
456+
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data, bool verifyAccess = true) { }
457+
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true) { }
458458
public void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
459459
public void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
460460
public System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments) { }
@@ -464,7 +464,7 @@ namespace System.IO.Abstractions.TestingHelpers
464464
public System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path) { }
465465
public System.IO.Abstractions.TestingHelpers.MockFileSystem MockTime(System.Func<System.DateTime> dateTimeProvider) { }
466466
public void MoveDirectory(string sourcePath, string destPath) { }
467-
public void RemoveFile(string path) { }
467+
public void RemoveFile(string path, bool verifyAccess = true) { }
468468
}
469469
public class MockFileSystemOptions
470470
{

tests/TestableIO.System.IO.Abstractions.Api.Tests/Expected/TestableIO.System.IO.Abstractions.TestingHelpers_netstandard2.0.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@ namespace System.IO.Abstractions.TestingHelpers
1313
System.IO.Abstractions.TestingHelpers.StringOperations StringOperations { get; }
1414
void AddDirectory(string path);
1515
void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive);
16-
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile);
16+
void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true);
1717
void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1818
void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath);
1919
System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments);
2020
bool FileExists(string path);
2121
System.IO.Abstractions.TestingHelpers.MockDriveData GetDrive(string name);
2222
System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path);
2323
void MoveDirectory(string sourcePath, string destPath);
24-
void RemoveFile(string path);
24+
void RemoveFile(string path, bool verifyAccess = true);
2525
}
2626
[System.Serializable]
2727
public class MockDirectory : System.IO.Abstractions.DirectoryBase
@@ -360,8 +360,8 @@ namespace System.IO.Abstractions.TestingHelpers
360360
public void AddDrive(string name, System.IO.Abstractions.TestingHelpers.MockDriveData mockDrive) { }
361361
public void AddEmptyFile(System.IO.Abstractions.IFileInfo path) { }
362362
public void AddEmptyFile(string path) { }
363-
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data) { }
364-
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile) { }
363+
public void AddFile(System.IO.Abstractions.IFileInfo path, System.IO.Abstractions.TestingHelpers.MockFileData data, bool verifyAccess = true) { }
364+
public void AddFile(string path, System.IO.Abstractions.TestingHelpers.MockFileData mockFile, bool verifyAccess = true) { }
365365
public void AddFileFromEmbeddedResource(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
366366
public void AddFilesFromEmbeddedNamespace(string path, System.Reflection.Assembly resourceAssembly, string embeddedResourcePath) { }
367367
public System.IO.Abstractions.TestingHelpers.MockFileData AdjustTimes(System.IO.Abstractions.TestingHelpers.MockFileData fileData, System.IO.Abstractions.TestingHelpers.TimeAdjustments timeAdjustments) { }
@@ -371,7 +371,7 @@ namespace System.IO.Abstractions.TestingHelpers
371371
public System.IO.Abstractions.TestingHelpers.MockFileData GetFile(string path) { }
372372
public System.IO.Abstractions.TestingHelpers.MockFileSystem MockTime(System.Func<System.DateTime> dateTimeProvider) { }
373373
public void MoveDirectory(string sourcePath, string destPath) { }
374-
public void RemoveFile(string path) { }
374+
public void RemoveFile(string path, bool verifyAccess = true) { }
375375
}
376376
public class MockFileSystemOptions
377377
{

0 commit comments

Comments
 (0)