From b20e35e76abf78f3f99e52e336ff429083b9cb8c Mon Sep 17 00:00:00 2001 From: Ajay Bhargav Baaskaran Date: Tue, 9 Jan 2018 17:37:47 -0800 Subject: [PATCH] Set RelativePhysicalPath in FileProviderRazorProjectItem --- .../Internal/FileProviderRazorProject.cs | 28 +++- .../Internal/FileProviderRazorProjectItem.cs | 7 +- .../ErrorPageTests.cs | 2 +- .../RazorPagesTest.cs | 4 +- .../Internal/ChecksumValidatorTest.cs | 5 +- .../CompilerFailedExceptionFactoryTest.cs | 11 +- .../Internal/FileProviderRazorProjectTest.cs | 145 ++++++++++++++---- .../Internal/RazorViewCompilerProviderTest.cs | 2 +- .../Internal/RazorViewCompilerTest.cs | 5 +- .../RazorViewEngineTest.cs | 10 +- .../PageActionDescriptorProviderTest.cs | 13 -- .../CompiledPageRouteModelProviderTest.cs | 5 +- .../PageActionDescriptorChangeProviderTest.cs | 17 +- .../Internal/PageActionInvokerProviderTest.cs | 9 +- .../RazorProjectPageRouteModelProviderTest.cs | 22 +-- .../TestRazorProject.cs | 5 +- .../TestFileProvider.cs | 13 +- .../TestRazorCompilationService.cs | 7 +- 18 files changed, 225 insertions(+), 85 deletions(-) diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProject.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProject.cs index fd0509924f..f05429bb2a 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProject.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProject.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Razor.Language; using Microsoft.Extensions.FileProviders; @@ -13,22 +14,38 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal { private const string RazorFileExtension = ".cshtml"; private readonly IFileProvider _provider; + private readonly IHostingEnvironment _hostingEnvironment; - public FileProviderRazorProject(IRazorViewEngineFileProviderAccessor accessor) + public FileProviderRazorProject(IRazorViewEngineFileProviderAccessor accessor, IHostingEnvironment hostingEnviroment) { if (accessor == null) { throw new ArgumentNullException(nameof(accessor)); } + if (hostingEnviroment == null) + { + throw new ArgumentNullException(nameof(hostingEnviroment)); + } + _provider = accessor.FileProvider; + _hostingEnvironment = hostingEnviroment; } public override RazorProjectItem GetItem(string path) { path = NormalizeAndEnsureValidPath(path); var fileInfo = _provider.GetFileInfo(path); - return new FileProviderRazorProjectItem(fileInfo, basePath: string.Empty, path: path); + + string relativePhysicalPath = null; + if (fileInfo != null && fileInfo.Exists) + { + var absoluteBasePath = _hostingEnvironment.ContentRootPath; + relativePhysicalPath = fileInfo?.PhysicalPath?.Substring(absoluteBasePath.Length + 1); // Include leading separator + relativePhysicalPath = relativePhysicalPath ?? path; // Use the incoming path if the file is not directly accessible + } + + return new FileProviderRazorProjectItem(fileInfo, basePath: string.Empty, filePath: path, relativePhysicalPath: relativePhysicalPath); } public override IEnumerable EnumerateItems(string path) @@ -55,7 +72,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal } else if (string.Equals(RazorFileExtension, Path.GetExtension(file.Name), StringComparison.OrdinalIgnoreCase)) { - yield return new FileProviderRazorProjectItem(file, basePath, prefix + "/" + file.Name); + var filePath = prefix + "/" + file.Name; + var absoluteBasePath = _hostingEnvironment.ContentRootPath; + var relativePhysicalPath = file.PhysicalPath?.Substring(absoluteBasePath.Length + 1); // Include leading separator + relativePhysicalPath = relativePhysicalPath ?? filePath; // Use the incoming path if the file is not directly accessible + + yield return new FileProviderRazorProjectItem(file, basePath, filePath: filePath, relativePhysicalPath: relativePhysicalPath); } } } diff --git a/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProjectItem.cs b/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProjectItem.cs index 727ce68e42..e7238fb542 100644 --- a/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProjectItem.cs +++ b/src/Microsoft.AspNetCore.Mvc.Razor/Internal/FileProviderRazorProjectItem.cs @@ -9,11 +9,12 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal { public class FileProviderRazorProjectItem : RazorProjectItem { - public FileProviderRazorProjectItem(IFileInfo fileInfo, string basePath, string path) + public FileProviderRazorProjectItem(IFileInfo fileInfo, string basePath, string filePath, string relativePhysicalPath) { FileInfo = fileInfo; BasePath = basePath; - FilePath = path; + FilePath = filePath; + RelativePhysicalPath = relativePhysicalPath; } public IFileInfo FileInfo { get; } @@ -26,6 +27,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal public override string PhysicalPath => FileInfo.PhysicalPath; + public override string RelativePhysicalPath { get; } + public override Stream Read() { return FileInfo.CreateReadStream(); diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ErrorPageTests.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ErrorPageTests.cs index 8b90922e05..8ede2636f9 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ErrorPageTests.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/ErrorPageTests.cs @@ -74,7 +74,7 @@ namespace Microsoft.AspNetCore.Mvc.FunctionalTests // Arrange var expectedMessage = "The type or namespace name 'NamespaceDoesNotExist' could not be found (" + "are you missing a using directive or an assembly reference?)"; - var expectedCompilationContent = "public class _Views_ErrorFromViewImports_Index : " + var expectedCompilationContent = "public class Views_ErrorFromViewImports_Index : " + "global::Microsoft.AspNetCore.Mvc.Razor.RazorPage<dynamic>"; var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8"); diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorPagesTest.cs b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorPagesTest.cs index 287151d89e..856e88cb94 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorPagesTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/RazorPagesTest.cs @@ -797,8 +797,8 @@ Hello from /Pages/WithViewStart/Index.cshtml!"; // Arrange var expected = @"Microsoft.AspNetCore.Mvc.Routing.UrlHelper -Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper`1[AspNetCore._InjectedPageProperties] -Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary`1[AspNetCore._InjectedPageProperties]"; +Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper`1[AspNetCore.InjectedPageProperties] +Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary`1[AspNetCore.InjectedPageProperties]"; // Act var response = await Client.GetStringAsync("InjectedPageProperties"); diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/ChecksumValidatorTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/ChecksumValidatorTest.cs index b95d2122e3..1a27d231cd 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/ChecksumValidatorTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/ChecksumValidatorTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Razor.Hosting; using Microsoft.AspNetCore.Razor.Language; using Moq; @@ -14,7 +15,9 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal public ChecksumValidatorTest() { FileProvider = new TestFileProvider(); - Project = new FileProviderRazorProject(Mock.Of(a => a.FileProvider == FileProvider)); + Project = new FileProviderRazorProject( + Mock.Of(a => a.FileProvider == FileProvider), + Mock.Of(e => e.ContentRootPath == "BasePath")); } public RazorProject Project { get; } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/CompilerFailedExceptionFactoryTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/CompilerFailedExceptionFactoryTest.cs index fee54e3fdd..149103a8e4 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/CompilerFailedExceptionFactoryTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/CompilerFailedExceptionFactoryTest.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Razor.Extensions; using Microsoft.AspNetCore.Razor.Language; using Microsoft.CodeAnalysis; @@ -14,6 +15,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal { public class CompilerFailedExceptionFactoryTest { + private readonly IHostingEnvironment _hostingEnvironment = Mock.Of(e => e.ContentRootPath == "BasePath"); + [Fact] public void GetCompilationFailedResult_ReadsRazorErrorsFromPage() { @@ -25,7 +28,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal fileProvider.AddFile(viewPath, ""); var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, _hostingEnvironment); var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject); var codeDocument = templateEngine.CreateCodeDocument(viewPath); @@ -59,7 +62,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal var accessor = Mock.Of(a => a.FileProvider == fileProvider); var razorEngine = RazorEngine.Create(); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, _hostingEnvironment); var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject); var codeDocument = templateEngine.CreateCodeDocument(viewPath); @@ -91,7 +94,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal fileProvider.AddFile(viewPath, fileContent); var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, _hostingEnvironment); var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject); var codeDocument = templateEngine.CreateCodeDocument(viewPath); @@ -121,7 +124,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal var accessor = Mock.Of(a => a.FileProvider == fileProvider); var razorEngine = RazorEngine.Create(); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, _hostingEnvironment); var templateEngine = new MvcRazorTemplateEngine(razorEngine, razorProject) { Options = diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/FileProviderRazorProjectTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/FileProviderRazorProjectTest.cs index eaf215ec67..f192efebc1 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/FileProviderRazorProjectTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/FileProviderRazorProjectTest.cs @@ -1,7 +1,9 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.IO; using System.Linq; +using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.FileProviders; using Moq; using Xunit; @@ -14,14 +16,14 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal public void EnumerateFiles_ReturnsEmptySequenceIfNoCshtmlFilesArePresent() { // Arrange - var fileProvider = new TestFileProvider(); + var fileProvider = new TestFileProvider("BasePath"); var file1 = fileProvider.AddFile("File1.txt", "content"); var file2 = fileProvider.AddFile("File2.js", "content"); fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2 }); var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, Mock.Of(e => e.ContentRootPath == "BasePath")); // Act var razorFiles = razorProject.EnumerateItems("/"); @@ -34,7 +36,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal public void EnumerateFiles_ReturnsCshtmlFiles() { // Arrange - var fileProvider = new TestFileProvider(); + var fileProvider = new TestFileProvider("BasePath"); var file1 = fileProvider.AddFile("File1.cshtml", "content"); var file2 = fileProvider.AddFile("File2.js", "content"); var file3 = fileProvider.AddFile("File3.cshtml", "content"); @@ -42,22 +44,35 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, Mock.Of(e => e.ContentRootPath == "BasePath")); // Act var razorFiles = razorProject.EnumerateItems("/"); // Assert - Assert.Collection(razorFiles.OrderBy(f => f.FilePath), - file => Assert.Equal("/File1.cshtml", file.FilePath), - file => Assert.Equal("/File3.cshtml", file.FilePath)); + Assert.Collection( + razorFiles.OrderBy(f => f.FilePath), + file => + { + Assert.Equal("/File1.cshtml", file.FilePath); + Assert.Equal("/", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "File1.cshtml"), file.PhysicalPath); + Assert.Equal("File1.cshtml", file.RelativePhysicalPath); + }, + file => + { + Assert.Equal("/File3.cshtml", file.FilePath); + Assert.Equal("/", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "File3.cshtml"), file.PhysicalPath); + Assert.Equal("File3.cshtml", file.RelativePhysicalPath); + }); } [Fact] public void EnumerateFiles_IteratesOverAllCshtmlUnderRoot() { // Arrange - var fileProvider = new TestFileProvider(); + var fileProvider = new TestFileProvider("BasePath"); var directory1 = new TestDirectoryFileInfo { Name = "Level1-Dir1", @@ -69,72 +84,150 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal }; fileProvider.AddDirectoryContent("/", new IFileInfo[] { directory1, file1, directory2 }); - var file2 = fileProvider.AddFile("Level1-Dir1/File2.cshtml", "content"); - var file3 = fileProvider.AddFile("Level1-Dir1/File3.cshtml", "content"); - var file4 = fileProvider.AddFile("Level1-Dir1/File4.txt", "content"); + var file2 = fileProvider.AddFile(Path.Combine("Level1-Dir1", "File2.cshtml"), "content"); + var file3 = fileProvider.AddFile(Path.Combine("Level1-Dir1", "File3.cshtml"), "content"); + var file4 = fileProvider.AddFile(Path.Combine("Level1-Dir1", "File4.txt"), "content"); var directory3 = new TestDirectoryFileInfo { Name = "Level2-Dir1" }; fileProvider.AddDirectoryContent("/Level1-Dir1", new IFileInfo[] { file2, directory3, file3, file4 }); - var file5 = fileProvider.AddFile("Level1-Dir2/File5.cshtml", "content"); + var file5 = fileProvider.AddFile(Path.Combine("Level1-Dir2", "File5.cshtml"), "content"); fileProvider.AddDirectoryContent("/Level1-Dir2", new IFileInfo[] { file5 }); fileProvider.AddDirectoryContent("/Level1/Level2", new IFileInfo[0]); var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, Mock.Of(e => e.ContentRootPath == "BasePath")); // Act var razorFiles = razorProject.EnumerateItems("/"); // Assert Assert.Collection(razorFiles.OrderBy(f => f.FilePath), - file => Assert.Equal("/File1.cshtml", file.FilePath), - file => Assert.Equal("/Level1-Dir1/File2.cshtml", file.FilePath), - file => Assert.Equal("/Level1-Dir1/File3.cshtml", file.FilePath), - file => Assert.Equal("/Level1-Dir2/File5.cshtml", file.FilePath)); + file => + { + Assert.Equal("/File1.cshtml", file.FilePath); + Assert.Equal("/", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "File1.cshtml"), file.PhysicalPath); + Assert.Equal("File1.cshtml", file.RelativePhysicalPath); + }, + file => + { + Assert.Equal("/Level1-Dir1/File2.cshtml", file.FilePath); + Assert.Equal("/", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "Level1-Dir1", "File2.cshtml"), file.PhysicalPath); + Assert.Equal(Path.Combine("Level1-Dir1", "File2.cshtml"), file.RelativePhysicalPath); + }, + file => + { + Assert.Equal("/Level1-Dir1/File3.cshtml", file.FilePath); + Assert.Equal("/", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "Level1-Dir1", "File3.cshtml"), file.PhysicalPath); + Assert.Equal(Path.Combine("Level1-Dir1", "File3.cshtml"), file.RelativePhysicalPath); + }, + file => + { + Assert.Equal("/Level1-Dir2/File5.cshtml", file.FilePath); + Assert.Equal("/", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "Level1-Dir2", "File5.cshtml"), file.PhysicalPath); + Assert.Equal(Path.Combine("Level1-Dir2", "File5.cshtml"), file.RelativePhysicalPath); + }); } [Fact] public void EnumerateFiles_IteratesOverAllCshtmlUnderPath() { // Arrange - var fileProvider = new TestFileProvider(); + var fileProvider = new TestFileProvider("BasePath"); var directory1 = new TestDirectoryFileInfo { Name = "Level1-Dir1", }; - var file1 = fileProvider.AddFile("File1.cshtml", "content"); + var file1 = fileProvider.AddFile(Path.Combine("BasePath", "File1.cshtml"), "content"); var directory2 = new TestDirectoryFileInfo { Name = "Level1-Dir2", }; fileProvider.AddDirectoryContent("/", new IFileInfo[] { directory1, file1, directory2 }); - var file2 = fileProvider.AddFile("Level1-Dir1/File2.cshtml", "content"); - var file3 = fileProvider.AddFile("Level1-Dir1/File3.cshtml", "content"); - var file4 = fileProvider.AddFile("Level1-Dir1/File4.txt", "content"); + var file2 = fileProvider.AddFile(Path.Combine("Level1-Dir1", "File2.cshtml"), "content"); + var file3 = fileProvider.AddFile(Path.Combine("Level1-Dir1", "File3.cshtml"), "content"); + var file4 = fileProvider.AddFile(Path.Combine("Level1-Dir1", "File4.txt"), "content"); var directory3 = new TestDirectoryFileInfo { Name = "Level2-Dir1" }; fileProvider.AddDirectoryContent("/Level1-Dir1", new IFileInfo[] { file2, directory3, file3, file4 }); - var file5 = fileProvider.AddFile("Level1-Dir2/File5.cshtml", "content"); + var file5 = fileProvider.AddFile(Path.Combine("Level1-Dir2", "File5.cshtml"), "content"); fileProvider.AddDirectoryContent("/Level1-Dir2", new IFileInfo[] { file5 }); fileProvider.AddDirectoryContent("/Level1/Level2", new IFileInfo[0]); var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, Mock.Of(e => e.ContentRootPath == "BasePath")); // Act var razorFiles = razorProject.EnumerateItems("/Level1-Dir1"); // Assert Assert.Collection(razorFiles.OrderBy(f => f.FilePath), - file => Assert.Equal("/File2.cshtml", file.FilePath), - file => Assert.Equal("/File3.cshtml", file.FilePath)); + file => + { + Assert.Equal("/File2.cshtml", file.FilePath); + Assert.Equal("/Level1-Dir1", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "Level1-Dir1", "File2.cshtml"), file.PhysicalPath); + Assert.Equal(Path.Combine("Level1-Dir1", "File2.cshtml"), file.RelativePhysicalPath); + }, + file => + { + Assert.Equal("/File3.cshtml", file.FilePath); + Assert.Equal("/Level1-Dir1", file.BasePath); + Assert.Equal(Path.Combine("BasePath", "Level1-Dir1", "File3.cshtml"), file.PhysicalPath); + Assert.Equal(Path.Combine("Level1-Dir1", "File3.cshtml"), file.RelativePhysicalPath); + }); + } + + [Fact(Skip = "Need to follow-up https://github.com/aspnet/Mvc/pull/7228")] + public void GetItem_ReturnsFileFromDisk() + { + var fileProvider = new TestFileProvider("BasePath"); + var file1 = fileProvider.AddFile("File1.cshtml", "content"); + var file2 = fileProvider.AddFile("File2.js", "content"); + var file3 = fileProvider.AddFile("File3.cshtml", "content"); + fileProvider.AddDirectoryContent("/", new IFileInfo[] { file1, file2, file3 }); + + var accessor = Mock.Of(a => a.FileProvider == fileProvider); + + var razorProject = new FileProviderRazorProject(accessor, Mock.Of(e => e.ContentRootPath == "BasePath")); + + // Act + var item = razorProject.GetItem("/File3.cshtml"); + + // Assert + Assert.True(item.Exists); + Assert.Equal("/File3.cshtml", item.FilePath); + Assert.Equal(string.Empty, item.BasePath); + Assert.Equal(Path.Combine("BasePath", "File3.cshtml"), item.PhysicalPath); + Assert.Equal("File3.cshtml", item.RelativePhysicalPath); + } + + [Fact] + public void GetItem_ReturnsNotFoundResult() + { + // Arrange + var fileProvider = new TestFileProvider("BasePath"); + var file = fileProvider.AddFile("SomeFile.cshtml", "content"); + fileProvider.AddDirectoryContent("/", new IFileInfo[] { file }); + var accessor = Mock.Of(a => a.FileProvider == fileProvider); + + var razorProject = new FileProviderRazorProject(accessor, Mock.Of(e => e.ContentRootPath == "BasePath")); + + // Act + var item = razorProject.GetItem("/NotFound.cshtml"); + + // Assert + Assert.False(item.Exists); } } } diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerProviderTest.cs index 97a90b4cfe..fd6bc9798d 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerProviderTest.cs @@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor.Internal partManager, new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)), + new FileProviderRazorProject(accessor, Mock.Of())), accessor, new CSharpCompiler(referenceManager, Mock.Of()), options, diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerTest.cs index b30295c3c6..5ad82ca791 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/Internal/RazorViewCompilerTest.cs @@ -821,7 +821,8 @@ this should fail"; precompiledViews = precompiledViews ?? Array.Empty(); - var projectSystem = new FileProviderRazorProject(accessor); + var hostingEnvironment = Mock.Of(e => e.ContentRootPath == "BasePath"); + var projectSystem = new FileProviderRazorProject(accessor, hostingEnvironment); var templateEngine = new RazorTemplateEngine(RazorEngine.Create(), projectSystem) { Options = @@ -832,7 +833,7 @@ this should fail"; var viewCompiler = new TestRazorViewCompiler( fileProvider, templateEngine, - new CSharpCompiler(referenceManager, Mock.Of()), + new CSharpCompiler(referenceManager, hostingEnvironment), compilationCallback, precompiledViews); return viewCompiler; diff --git a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorViewEngineTest.cs b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorViewEngineTest.cs index e77430ee08..e49434ba3b 100644 --- a/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorViewEngineTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.Razor.Test/RazorViewEngineTest.cs @@ -935,7 +935,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor var fileProvider = new TestFileProvider(); var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var razorProject = new FileProviderRazorProject(accessor); + var razorProject = new FileProviderRazorProject(accessor, Mock.Of()); var viewEngine = CreateViewEngine(pageFactory.Object, razorProject: razorProject); var context = GetActionContext(_controllerTestContext); @@ -1386,7 +1386,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor new HtmlTestEncoder(), GetOptionsAccessor(expanders: null), new FileProviderRazorProject( - Mock.Of(a => a.FileProvider == new TestFileProvider())), + Mock.Of(a => a.FileProvider == new TestFileProvider()), + Mock.Of()), loggerFactory, new DiagnosticListener("Microsoft.AspNetCore.Mvc.Razor")); @@ -1974,7 +1975,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor if (razorProject == null) { var accessor = Mock.Of(a => a.FileProvider == new TestFileProvider()); - razorProject = new FileProviderRazorProject(accessor); + razorProject = new FileProviderRazorProject(accessor, Mock.Of()); } return new TestableRazorViewEngine(pageFactory, GetOptionsAccessor(expanders), razorProject); } @@ -2080,7 +2081,8 @@ namespace Microsoft.AspNetCore.Mvc.Razor pageFactory, optionsAccessor, new FileProviderRazorProject( - Mock.Of(a => a.FileProvider == new TestFileProvider()))) + Mock.Of(a => a.FileProvider == new TestFileProvider()), + Mock.Of())) { } diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs index 966289fe81..b12d32443b 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Infrastructure/PageActionDescriptorProviderTest.cs @@ -4,9 +4,6 @@ using System; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.ApplicationModels; -using Microsoft.AspNetCore.Mvc.Razor; -using Microsoft.AspNetCore.Mvc.Razor.Internal; -using Microsoft.AspNetCore.Razor.Language; using Microsoft.Extensions.Options; using Moq; using Xunit; @@ -207,16 +204,6 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure return Options.Create(new RazorPagesOptions()); } - private static RazorProjectItem GetProjectItem(string basePath, string path, string content) - { - var testFileInfo = new TestFileInfo - { - Content = content, - }; - - return new FileProviderRazorProjectItem(testFileInfo, basePath, path); - } - private class TestPageRouteModelProvider : IPageRouteModelProvider { private readonly PageRouteModel[] _models; diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageRouteModelProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageRouteModelProviderTest.cs index 888b699202..3aeebad54f 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageRouteModelProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/CompiledPageRouteModelProviderTest.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.ApplicationParts; using Microsoft.AspNetCore.Mvc.Razor; @@ -26,7 +27,9 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal public CompiledPageRouteModelProviderTest() { FileProvider = new TestFileProvider(); - Project = new FileProviderRazorProject(Mock.Of(a => a.FileProvider == FileProvider)); + Project = new FileProviderRazorProject( + Mock.Of(a => a.FileProvider == FileProvider), + Mock.Of(e => e.ContentRootPath == "BasePath")); TemplateEngine = new RazorTemplateEngine(RazorEngine.Create(), Project); PagesOptions = new RazorPagesOptions(); diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionDescriptorChangeProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionDescriptorChangeProviderTest.cs index 961b333e28..48322b8a06 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionDescriptorChangeProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionDescriptorChangeProviderTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Razor.Internal; using Microsoft.AspNetCore.Razor.Language; @@ -14,6 +15,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal { public class PageActionDescriptorChangeProviderTest { + private readonly IHostingEnvironment _hostingEnvironment = Mock.Of(e => e.ContentRootPath == "BasePath"); + [Fact] public void GetChangeToken_WatchesAllCshtmlFilesUnderFileSystemRoot() { @@ -25,7 +28,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var templateEngine = new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)); + new FileProviderRazorProject(accessor, _hostingEnvironment)); var options = Options.Create(new RazorPagesOptions()); var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options); @@ -49,7 +52,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var templateEngine = new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)); + new FileProviderRazorProject(accessor, _hostingEnvironment)); var options = Options.Create(new RazorPagesOptions()); options.Value.RootDirectory = rootDirectory; @@ -73,7 +76,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var templateEngine = new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)); + new FileProviderRazorProject(accessor, _hostingEnvironment)); var options = Options.Create(new RazorPagesOptions { AllowAreas = true }); var changeProvider = new PageActionDescriptorChangeProvider(templateEngine, accessor, options); @@ -97,7 +100,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var templateEngine = new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)); + new FileProviderRazorProject(accessor, _hostingEnvironment)); var options = Options.Create(new RazorPagesOptions { AllowAreas = true, @@ -121,7 +124,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var templateEngine = new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)); + new FileProviderRazorProject(accessor, _hostingEnvironment)); templateEngine.Options.ImportsFileName = "_ViewImports.cshtml"; var options = Options.Create(new RazorPagesOptions()); options.Value.RootDirectory = "/dir1/dir2"; @@ -145,7 +148,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var templateEngine = new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)); + new FileProviderRazorProject(accessor, _hostingEnvironment)); templateEngine.Options.ImportsFileName = "_ViewImports.cshtml"; var options = Options.Create(new RazorPagesOptions()); options.Value.RootDirectory = "/dir1/dir2"; @@ -173,7 +176,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var templateEngine = new RazorTemplateEngine( RazorEngine.Create(), - new FileProviderRazorProject(accessor)); + new FileProviderRazorProject(accessor, _hostingEnvironment)); templateEngine.Options.ImportsFileName = "_ViewImports.cshtml"; var options = Options.Create(new RazorPagesOptions { AllowAreas = false }); diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionInvokerProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionInvokerProviderTest.cs index 6ca00e12ab..34acdef27b 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionInvokerProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/PageActionInvokerProviderTest.cs @@ -5,6 +5,7 @@ using System; using System.Diagnostics; using System.Linq; using System.Reflection; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Filters; @@ -28,6 +29,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal { public class PageInvokerProviderTest { + private readonly IHostingEnvironment _hostingEnvironment = Mock.Of(e => e.ContentRootPath == "BasePath"); + [Fact] public void OnProvidersExecuting_WithEmptyModel_PopulatesCacheEntry() { @@ -190,7 +193,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal fileProvider.AddFile("/_ViewStart.cshtml", "content2"); var accessor = Mock.Of(a => a.FileProvider == fileProvider); - var defaultRazorProject = new FileProviderRazorProject(accessor); + var defaultRazorProject = new FileProviderRazorProject(accessor, _hostingEnvironment); var invokerProvider = CreateInvokerProvider( loader.Object, @@ -347,7 +350,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal fileProvider.AddFile("/Pages/Level1/Level2/_ViewStart.cshtml", "page content"); fileProvider.AddFile("/Pages/Level1/Level3/_ViewStart.cshtml", "page content"); - var razorProject = new TestRazorProject(fileProvider); + var razorProject = new TestRazorProject(fileProvider, _hostingEnvironment); var mock = new Mock(MockBehavior.Strict); mock @@ -413,7 +416,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal // No files var fileProvider = new TestFileProvider(); - var razorProject = new TestRazorProject(fileProvider); + var razorProject = new TestRazorProject(fileProvider, _hostingEnvironment); var invokerProvider = CreateInvokerProvider( loader.Object, diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/RazorProjectPageRouteModelProviderTest.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/RazorProjectPageRouteModelProviderTest.cs index eefef307f6..37fd8c6ac6 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/RazorProjectPageRouteModelProviderTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/Internal/RazorProjectPageRouteModelProviderTest.cs @@ -3,17 +3,21 @@ using System; using System.Linq; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; +using Moq; using Xunit; namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal { public class RazorProjectPageRouteModelProviderTest { + private readonly IHostingEnvironment _hostingEnvironment = Mock.Of(e => e.ContentRootPath == "BasePath"); + [Fact] public void OnProvidersExecuting_ReturnsPagesWithPageDirective() { @@ -25,7 +29,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var dir1 = fileProvider.AddDirectoryContent("/Pages", new IFileInfo[] { file1, file2 }); fileProvider.AddDirectoryContent("/", new[] { dir1 }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/"; @@ -67,7 +71,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var areasDir = fileProvider.AddDirectoryContent("/Areas", new[] { productsDir }); var rootDir = fileProvider.AddDirectoryContent("/", new[] { areasDir }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions { AllowAreas = true }); var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance); @@ -151,7 +155,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var pagesDir = fileProvider.AddDirectoryContent("/Pages", new[] { file4 }); var rootDir = fileProvider.AddDirectoryContent("/", new[] { areasDir, pagesDir }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions { AllowAreas = false }); var provider = new RazorProjectPageRouteModelProvider(project, optionsManager, NullLoggerFactory.Instance); @@ -185,7 +189,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var areasDir = fileProvider.AddDirectoryContent("/Areas", new IFileInfo[] { productsDir, nonConformingFileUnderAreasDirectory }); var rootDir = fileProvider.AddDirectoryContent("/", new IFileInfo[] { areasDir, rootFile }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions { @@ -247,7 +251,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var dir1 = fileProvider.AddDirectoryContent("/Pages", new IFileInfo[] { dir2, file1, file2 }); fileProvider.AddDirectoryContent("/", new[] { dir1 }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/"; @@ -285,7 +289,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var file = fileProvider.AddFile("/Index.cshtml", "@page \"/custom-route\""); fileProvider.AddDirectoryContent("/", new[] { file }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/"; @@ -311,7 +315,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal }); fileProvider.AddDirectoryContent("/", new[] { dir1 }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/"; @@ -349,7 +353,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var rootFile = fileProvider.AddFile("/Index.cshtml", "@page"); fileProvider.AddDirectoryContent("/", new IFileInfo[] { rootFile, dir1, dir2 }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/Pages"; @@ -378,7 +382,7 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages.Internal var dir1 = fileProvider.AddDirectoryContent("/Pages", new IFileInfo[] { file1, file2 }); fileProvider.AddDirectoryContent("/", new[] { dir1 }); - var project = new TestRazorProject(fileProvider); + var project = new TestRazorProject(fileProvider, _hostingEnvironment); var optionsManager = Options.Create(new RazorPagesOptions()); optionsManager.Value.RootDirectory = "/"; diff --git a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/TestRazorProject.cs b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/TestRazorProject.cs index be0a434c34..7a8d56bb70 100644 --- a/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/TestRazorProject.cs +++ b/test/Microsoft.AspNetCore.Mvc.RazorPages.Test/TestRazorProject.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Razor.Internal; using Microsoft.Extensions.FileProviders; using Moq; @@ -9,8 +10,8 @@ namespace Microsoft.AspNetCore.Mvc.RazorPages { public class TestRazorProject : FileProviderRazorProject { - public TestRazorProject(IFileProvider fileProvider) - :base(GetAccessor(fileProvider)) + public TestRazorProject(IFileProvider fileProvider, IHostingEnvironment hostingEnvironment) + :base(GetAccessor(fileProvider), hostingEnvironment) { } diff --git a/test/Microsoft.AspNetCore.Mvc.TestCommon/TestFileProvider.cs b/test/Microsoft.AspNetCore.Mvc.TestCommon/TestFileProvider.cs index e7d32519dc..a92d8c4e56 100644 --- a/test/Microsoft.AspNetCore.Mvc.TestCommon/TestFileProvider.cs +++ b/test/Microsoft.AspNetCore.Mvc.TestCommon/TestFileProvider.cs @@ -20,6 +20,17 @@ namespace Microsoft.AspNetCore.Mvc.Razor private readonly Dictionary _fileTriggers = new Dictionary(StringComparer.Ordinal); + public TestFileProvider() : this(string.Empty) + { + } + + public TestFileProvider(string root) + { + Root = root; + } + + public string Root { get; } + public virtual IDirectoryContents GetDirectoryContents(string subpath) { if (_directoryContentsLookup.TryGetValue(subpath, out var value)) @@ -35,7 +46,7 @@ namespace Microsoft.AspNetCore.Mvc.Razor var fileInfo = new TestFileInfo { Content = contents, - PhysicalPath = path, + PhysicalPath = Path.Combine(Root, path), Name = Path.GetFileName(path), LastModified = DateTime.UtcNow, }; diff --git a/test/WebSites/RazorPageExecutionInstrumentationWebSite/TestRazorCompilationService.cs b/test/WebSites/RazorPageExecutionInstrumentationWebSite/TestRazorCompilationService.cs index 44cd35fd9e..495ce53a3f 100644 --- a/test/WebSites/RazorPageExecutionInstrumentationWebSite/TestRazorCompilationService.cs +++ b/test/WebSites/RazorPageExecutionInstrumentationWebSite/TestRazorCompilationService.cs @@ -3,6 +3,7 @@ using System.IO; using System.Text; +using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Mvc.Razor.Internal; using Microsoft.AspNetCore.Razor.Language; @@ -10,8 +11,8 @@ namespace RazorPageExecutionInstrumentationWebSite { public class TestRazorProject : FileProviderRazorProject { - public TestRazorProject(IRazorViewEngineFileProviderAccessor fileProviderAccessor) - : base(fileProviderAccessor) + public TestRazorProject(IRazorViewEngineFileProviderAccessor fileProviderAccessor, IHostingEnvironment hostingEnvironment) + : base(fileProviderAccessor, hostingEnvironment) { } @@ -24,7 +25,7 @@ namespace RazorPageExecutionInstrumentationWebSite private class TestRazorProjectItem : FileProviderRazorProjectItem { public TestRazorProjectItem(FileProviderRazorProjectItem projectItem) - : base(projectItem.FileInfo, projectItem.BasePath, projectItem.FilePath) + : base(projectItem.FileInfo, projectItem.BasePath, projectItem.FilePath, projectItem.RelativePhysicalPath) { }