// 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.Collections.Generic; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Testing; using Templates.Test.Helpers; using Xunit; using Xunit.Abstractions; namespace Templates.Test { public class RazorPagesTemplateTest { public RazorPagesTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output) { ProjectFactory = projectFactory; Output = output; } public Project Project { get; set; } public ProjectFactoryFixture ProjectFactory { get; set; } public ITestOutputHelper Output { get; } [ConditionalFact] [SkipOnHelix("Cert failures", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")] public async Task RazorPagesTemplate_NoAuth() { Project = await ProjectFactory.GetOrCreateProject("razorpagesnoauth", Output); var createResult = await Project.RunDotNetNewAsync("razor"); Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("razor", Project, createResult)); var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); Assert.DoesNotContain(".db", projectFileContents); Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools", projectFileContents); Assert.DoesNotContain("Microsoft.VisualStudio.Web.CodeGeneration.Design", projectFileContents); Assert.DoesNotContain("Microsoft.EntityFrameworkCore.Tools.DotNet", projectFileContents); Assert.DoesNotContain("Microsoft.Extensions.SecretManager.Tools", projectFileContents); var publishResult = await Project.RunDotNetPublishAsync(); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, createResult)); // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build // later, while the opposite is not true. var buildResult = await Project.RunDotNetBuildAsync(); Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, createResult)); var pages = new List { new Page { Url = PageUrls.HomeUrl, Links = new string[] { PageUrls.HomeUrl, PageUrls.HomeUrl, PageUrls.PrivacyUrl, PageUrls.DocsUrl, PageUrls.PrivacyUrl } }, new Page { Url = PageUrls.PrivacyUrl, Links = new string[] { PageUrls.HomeUrl, PageUrls.HomeUrl, PageUrls.PrivacyUrl, PageUrls.PrivacyUrl } } }; using (var aspNetProcess = Project.StartBuiltProjectAsync()) { Assert.False( aspNetProcess.Process.HasExited, ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); await aspNetProcess.AssertPagesOk(pages); } using (var aspNetProcess = Project.StartPublishedProjectAsync()) { Assert.False( aspNetProcess.Process.HasExited, ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process)); await aspNetProcess.AssertPagesOk(pages); } } [ConditionalTheory] [InlineData(false)] [InlineData(true)] [SkipOnHelix("cert failure", Queues = "OSX.1014.Amd64;OSX.1014.Amd64.Open")] [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task RazorPagesTemplate_IndividualAuth(bool useLocalDB) { Project = await ProjectFactory.GetOrCreateProject("razorpagesindividual" + (useLocalDB ? "uld" : ""), Output); var createResult = await Project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB); Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj"); if (!useLocalDB) { Assert.Contains(".db", projectFileContents); } var publishResult = await Project.RunDotNetPublishAsync(); Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult)); // Run dotnet build after publish. The reason is that one uses Config = Debug and the other uses Config = Release // The output from publish will go into bin/Release/netcoreappX.Y/publish and won't be affected by calling build // later, while the opposite is not true. var buildResult = await Project.RunDotNetBuildAsync(); Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); var migrationsResult = await Project.RunDotNetEfCreateMigrationAsync("razorpages"); Assert.True(0 == migrationsResult.ExitCode, ErrorMessages.GetFailedProcessMessage("run EF migrations", Project, migrationsResult)); Project.AssertEmptyMigration("razorpages"); var pages = new List { new Page { Url = PageUrls.ForgotPassword, Links = new string [] { PageUrls.HomeUrl, PageUrls.RegisterUrl, PageUrls.LoginUrl, PageUrls.HomeUrl, PageUrls.PrivacyUrl, PageUrls.PrivacyUrl } }, new Page { Url = PageUrls.HomeUrl, Links = new string[] { PageUrls.HomeUrl, PageUrls.RegisterUrl, PageUrls.LoginUrl, PageUrls.HomeUrl, PageUrls.PrivacyUrl, PageUrls.DocsUrl, PageUrls.PrivacyUrl } }, new Page { Url = PageUrls.PrivacyUrl, Links = new string[] { PageUrls.HomeUrl, PageUrls.RegisterUrl, PageUrls.LoginUrl, PageUrls.HomeUrl, PageUrls.PrivacyUrl, PageUrls.PrivacyUrl } }, new Page { Url = PageUrls.LoginUrl, Links = new string[] { PageUrls.HomeUrl, PageUrls.RegisterUrl, PageUrls.LoginUrl, PageUrls.HomeUrl, PageUrls.PrivacyUrl, PageUrls.ForgotPassword, PageUrls.RegisterUrl, PageUrls.ResendEmailConfirmation, PageUrls.ExternalArticle, PageUrls.PrivacyUrl } }, new Page { Url = PageUrls.RegisterUrl, Links = new string [] { PageUrls.HomeUrl, PageUrls.RegisterUrl, PageUrls.LoginUrl, PageUrls.HomeUrl, PageUrls.PrivacyUrl, PageUrls.ExternalArticle, PageUrls.PrivacyUrl } } }; using (var aspNetProcess = Project.StartBuiltProjectAsync()) { Assert.False( aspNetProcess.Process.HasExited, ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); await aspNetProcess.AssertPagesOk(pages); } using (var aspNetProcess = Project.StartPublishedProjectAsync()) { Assert.False( aspNetProcess.Process.HasExited, ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process)); await aspNetProcess.AssertPagesOk(pages); } } [Fact] [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/19716")] public async Task RazorPagesTemplate_RazorRuntimeCompilation_BuildsAndPublishes() { Project = await ProjectFactory.GetOrCreateProject("razorpages_rc", Output); var createResult = await Project.RunDotNetNewAsync("razor", args: new[] { "--razor-runtime-compilation" }); Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult)); // Verify building in debug works var buildResult = await Project.RunDotNetBuildAsync(); Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult)); // Publish builds in "release" configuration. Running publish should ensure we can compile in release and that we can publish without issues. buildResult = await Project.RunDotNetPublishAsync(); Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, buildResult)); Assert.False(Directory.Exists(Path.Combine(Project.TemplatePublishDir, "refs")), "The refs directory should not be published."); // Verify ref assemblies isn't published var refsDirectory = Path.Combine(Project.TemplatePublishDir, "refs"); Assert.False(Directory.Exists(refsDirectory), $"{refsDirectory} should not be in the publish output."); } private string ReadFile(string basePath, string path) { var fullPath = Path.Combine(basePath, path); var doesExist = File.Exists(fullPath); Assert.True(doesExist, $"Expected file to exist, but it doesn't: {path}"); return File.ReadAllText(Path.Combine(basePath, path)); } } }