diff --git a/src/Ramstack.FileProviders/PrefixedFileProvider.cs b/src/Ramstack.FileProviders/PrefixedFileProvider.cs index a63280a..9609e46 100644 --- a/src/Ramstack.FileProviders/PrefixedFileProvider.cs +++ b/src/Ramstack.FileProviders/PrefixedFileProvider.cs @@ -98,6 +98,9 @@ public void Dispose() => { Debug.Assert(path == FilePath.Normalize(path)); + if (prefix == "/") + return path; + if (path == prefix) return "/"; diff --git a/tests/Ramstack.FileProviders.Tests/PrefixedFileProviderTests.cs b/tests/Ramstack.FileProviders.Tests/PrefixedFileProviderTests.cs index f18f2f8..a88668b 100644 --- a/tests/Ramstack.FileProviders.Tests/PrefixedFileProviderTests.cs +++ b/tests/Ramstack.FileProviders.Tests/PrefixedFileProviderTests.cs @@ -12,6 +12,11 @@ public sealed class PrefixedFileProviderTests : AbstractFileProviderTests .GetMethod("ResolveGlobFilter", BindingFlags.Static | BindingFlags.NonPublic)! .CreateDelegate>(); + private static readonly Func s_resolvePath = + typeof(PrefixedFileProvider) + .GetMethod("ResolvePath", BindingFlags.Static | BindingFlags.NonPublic)! + .CreateDelegate>(); + private readonly TempFileStorage _storage = new TempFileStorage(); protected override IFileProvider GetFileProvider() => @@ -37,4 +42,52 @@ protected override DirectoryInfo GetDirectoryInfo() => [TestCase("/modules/profile/assets", "/*.js", ExpectedResult = null)] public string? ResolveGlobFilter(string prefix, string filter) => s_resolveGlobFilter(prefix, filter); + + [TestCase("/", "/", ExpectedResult = "/")] + [TestCase("/", "/foo", ExpectedResult = "/foo")] + [TestCase("/", "/a/b/c", ExpectedResult = "/a/b/c")] + + [TestCase("/a/b", "/a/b", ExpectedResult = "/")] + + [TestCase("/a/b", "/a/b/c", ExpectedResult = "/c")] + [TestCase("/a/b", "/a/b/c/d", ExpectedResult = "/c/d")] + + [TestCase("/a/b", "/a/bc", ExpectedResult = null)] + + [TestCase("/a/b", "/a/c", ExpectedResult = null)] + [TestCase("/a/b", "/a", ExpectedResult = null)] + public string? ResolvePath(string prefix, string path) => + s_resolvePath(prefix, path); + + [Test] + public void GetFileInfo_RootPrefix_DelegatesToInnerProvider() + { + using var provider = new PrefixedFileProvider("/", + new PhysicalFileProvider(_storage.Root, ExclusionFilters.None)); + + var file = provider.GetFileInfo("/project/README.md"); + Assert.That(file.Exists, Is.True); + Assert.That(file.IsDirectory, Is.False); + } + + [Test] + public void GetDirectoryContents_RootPrefix_DelegatesToInnerProvider() + { + using var provider = new PrefixedFileProvider("/", + new PhysicalFileProvider(_storage.Root, ExclusionFilters.None)); + + var contents = provider.GetDirectoryContents("/project/docs"); + Assert.That(contents.Exists, Is.True); + Assert.That(contents.Any(), Is.True); + } + + [Test] + public void GetFileInfo_RootPrefix_MissingFile_ReturnsNotFound() + { + using var provider = new PrefixedFileProvider("/", + new PhysicalFileProvider(_storage.Root, ExclusionFilters.None)); + + var file = provider.GetFileInfo("/project/nonexistent.txt"); + Assert.That(file.Exists, Is.False); + } }