diff --git a/NuGet.config b/NuGet.config
index 699d9e10b1..389b3f7ed6 100644
--- a/NuGet.config
+++ b/NuGet.config
@@ -4,19 +4,11 @@
-
-
-
-
-
-
-
-
diff --git a/eng/Baseline.Designer.props b/eng/Baseline.Designer.props
index 00294a106f..67c2badad5 100644
--- a/eng/Baseline.Designer.props
+++ b/eng/Baseline.Designer.props
@@ -253,6 +253,7 @@
+
diff --git a/eng/scripts/CodeCheck.ps1 b/eng/scripts/CodeCheck.ps1
index 072f55fe21..7ee3d02cce 100644
--- a/eng/scripts/CodeCheck.ps1
+++ b/eng/scripts/CodeCheck.ps1
@@ -138,7 +138,7 @@ try {
Get-ChildItem "$repoRoot/*.sln" -Recurse `
| ? {
# These .sln files are used by the templating engine.
- ($_.Name -ne "BlazorServerWeb_CSharp.sln")
+ (($_.Name -ne "BlazorServerWeb_CSharp.sln") -and ($_.Name -ne 'ComponentsWebAssembly-CSharp.sln'))
} `
| % {
Write-Host " Checking $(Split-Path -Leaf $_)"
diff --git a/src/Components/Components.sln b/src/Components/Components.sln
index 99c12e091d..156f3870d8 100644
--- a/src/Components/Components.sln
+++ b/src/Components/Components.sln
@@ -25,15 +25,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Compon
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{A7ABAC29-F73F-456D-AE54-46842CFC2E10}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Client", "Blazor\testassets\HostedInAspNet.Client\HostedInAspNet.Client.csproj", "{FD37F740-A654-4117-BFB6-9112CE4C1D3B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Client", "WebAssembly\testassets\HostedInAspNet.Client\HostedInAspNet.Client.csproj", "{FD37F740-A654-4117-BFB6-9112CE4C1D3B}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Server", "Blazor\testassets\HostedInAspNet.Server\HostedInAspNet.Server.csproj", "{C1E2C117-BE47-4E29-94B3-753262D97A5C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostedInAspNet.Server", "WebAssembly\testassets\HostedInAspNet.Server\HostedInAspNet.Server.csproj", "{C1E2C117-BE47-4E29-94B3-753262D97A5C}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoSanity", "Blazor\testassets\MonoSanity\MonoSanity.csproj", "{F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoSanity", "WebAssembly\testassets\MonoSanity\MonoSanity.csproj", "{F16C1A7C-A2BD-4EB1-8BC8-23B1375F3B9E}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoSanityClient", "Blazor\testassets\MonoSanityClient\MonoSanityClient.csproj", "{1C4BF2D3-44A8-4A71-B031-15B983663CB0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MonoSanityClient", "WebAssembly\testassets\MonoSanityClient\MonoSanityClient.csproj", "{1C4BF2D3-44A8-4A71-B031-15B983663CB0}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StandaloneApp", "Blazor\testassets\StandaloneApp\StandaloneApp.csproj", "{C0FFB29E-4696-4875-9039-E5FA1AC5A42A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StandaloneApp", "WebAssembly\testassets\StandaloneApp\StandaloneApp.csproj", "{C0FFB29E-4696-4875-9039-E5FA1AC5A42A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Web", "Web", "{A27FF193-195B-4474-8E6C-840B2E339373}"
EndProject
diff --git a/src/Components/ComponentsNoDeps.slnf b/src/Components/ComponentsNoDeps.slnf
index df42481d3c..2a45ec68c9 100644
--- a/src/Components/ComponentsNoDeps.slnf
+++ b/src/Components/ComponentsNoDeps.slnf
@@ -30,6 +30,11 @@
"WebAssembly\\WebAssemblyHttpHandler\\src\\Microsoft.AspNetCore.Components.WebAssembly.HttpHandler.csproj",
"WebAssembly\\WebAssembly\\src\\Microsoft.AspNetCore.Components.WebAssembly.csproj",
"WebAssembly\\WebAssembly\\test\\Microsoft.AspNetCore.Components.WebAssembly.Tests.csproj",
+ "WebAssembly\\testassets\\HostedInAspNet.Client\\HostedInAspNet.Client.csproj",
+ "WebAssembly\\testassets\\HostedInAspNet.Server\\HostedInAspNet.Server.csproj",
+ "WebAssembly\\testassets\\MonoSanityClient\\MonoSanityClient.csproj",
+ "WebAssembly\\testassets\\MonoSanity\\MonoSanity.csproj",
+ "WebAssembly\\testassets\\StandaloneApp\\StandaloneApp.csproj",
"Web\\src\\Microsoft.AspNetCore.Components.Web.csproj",
"Web\\test\\Microsoft.AspNetCore.Components.Web.Tests.csproj",
"benchmarkapps\\Wasm.Performance\\Driver\\Wasm.Performance.Driver.csproj",
diff --git a/src/Components/WebAssembly/Authentication.Msal/src/Microsoft.Authentication.WebAssembly.Msal.csproj b/src/Components/WebAssembly/Authentication.Msal/src/Microsoft.Authentication.WebAssembly.Msal.csproj
index d2d5b02b4f..e74311cb93 100644
--- a/src/Components/WebAssembly/Authentication.Msal/src/Microsoft.Authentication.WebAssembly.Msal.csproj
+++ b/src/Components/WebAssembly/Authentication.Msal/src/Microsoft.Authentication.WebAssembly.Msal.csproj
@@ -39,7 +39,7 @@
-
+
$(IntermediateOutputPath)interop.cache
@@ -57,7 +57,7 @@
-
+
diff --git a/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.csproj b/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.csproj
index 796ee553e3..42d0927184 100644
--- a/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.csproj
+++ b/src/Components/WebAssembly/Build/src/Microsoft.AspNetCore.Components.WebAssembly.Build.csproj
@@ -40,6 +40,11 @@
Private="false"
Condition="'$(BuildNodeJS)' != 'false' and '$(BuildingInsideVisualStudio)' != 'true'" />
+
+
@@ -82,7 +87,8 @@
Name="GetBrotliTools"
BeforeTargets="Build;GenerateNuspec"
Inputs="@(_BrotliToolPathInput)"
- Outputs="@(_BrotliToolPathOutput)">
+ Outputs="@(_BrotliToolPathOutput)"
+ Condition="'$(DotNetBuildFromSource)' != 'true'">
<_BrotliToolsPath Include="$(MSBuildThisFileDirectory)bin\$(Configuration)\tools\compression\" />
diff --git a/src/Components/WebAssembly/Build/src/ReferenceFromSource.props b/src/Components/WebAssembly/Build/src/ReferenceFromSource.props
index afa2a5ada1..decf4343ee 100644
--- a/src/Components/WebAssembly/Build/src/ReferenceFromSource.props
+++ b/src/Components/WebAssembly/Build/src/ReferenceFromSource.props
@@ -20,7 +20,7 @@
-
+
$(ComponentsWebAssemblyVersionPrefix)
+
+
+ true
\ No newline at end of file
diff --git a/src/Components/WebAssembly/WebAssembly.Authentication/src/Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj b/src/Components/WebAssembly/WebAssembly.Authentication/src/Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj
index d0be43efcd..8514f8792d 100644
--- a/src/Components/WebAssembly/WebAssembly.Authentication/src/Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj
+++ b/src/Components/WebAssembly/WebAssembly.Authentication/src/Microsoft.AspNetCore.Components.WebAssembly.Authentication.csproj
@@ -40,7 +40,7 @@
-
+
$(IntermediateOutputPath)interop.cache
@@ -58,7 +58,7 @@
-
+
diff --git a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj
index f0a480a8b7..683cb2ff71 100644
--- a/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj
+++ b/src/Components/WebAssembly/WebAssembly/src/Microsoft.AspNetCore.Components.WebAssembly.csproj
@@ -13,9 +13,7 @@
-
+
@@ -30,5 +28,4 @@
-
diff --git a/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs b/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs
index 0b8e8b0c16..e1b5f9f616 100644
--- a/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs
+++ b/src/Components/WebAssembly/WebAssembly/test/TestWebAssemblyJSRuntimeInvoker.cs
@@ -23,10 +23,10 @@ namespace Microsoft.AspNetCore.Components.WebAssembly.Hosting
return (TResult)(object)_environment;
case "Blazor._internal.getConfig":
return (TResult)(object)null;
- case "Blazor._internal.navigationManager.getBaseURI":
+ case "Blazor._internal.navigationManager.getUnmarshalledBaseURI":
var testUri = "https://www.example.com/awesome-part-that-will-be-truncated-in-tests";
return (TResult)(object)testUri;
- case "Blazor._internal.navigationManager.getLocationHref":
+ case "Blazor._internal.navigationManager.getUnmarshalledLocationHref":
var testHref = "https://www.example.com/awesome-part-that-will-be-truncated-in-tests/cool";
return (TResult)(object)testHref;
default:
diff --git a/src/Components/WebAssembly/testassets/Directory.Build.props b/src/Components/WebAssembly/testassets/Directory.Build.props
new file mode 100644
index 0000000000..4f91e12ae4
--- /dev/null
+++ b/src/Components/WebAssembly/testassets/Directory.Build.props
@@ -0,0 +1,6 @@
+
+
+
+ false
+
+
\ No newline at end of file
diff --git a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj
index 4c09995278..3d6b47ebe7 100644
--- a/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj
+++ b/src/Components/WebAssembly/testassets/Wasm.Authentication.Server/Wasm.Authentication.Server.csproj
@@ -1,4 +1,4 @@
-
+
$(DefaultNetCoreTargetFramework)
@@ -10,9 +10,6 @@
-
-
-
diff --git a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj
index bee0f2b499..3451584734 100644
--- a/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj
+++ b/src/Framework/src/Microsoft.AspNetCore.App.Runtime.csproj
@@ -175,6 +175,7 @@ This package is an internal implementation of the .NET Core SDK and is not meant
_BatchCopyToRedistLayout;
_CreateInternalSharedFxArchive;
_CreateRedistSharedFxArchive;
+ _InstallFrameworkIntoLocalDotNet;
ResolveReferences;
diff --git a/src/Mvc/Mvc.NewtonsoftJson/src/JsonArrayPool.cs b/src/Mvc/Mvc.NewtonsoftJson/src/JsonArrayPool.cs
index 6b50b5bf84..c358bc2ba7 100644
--- a/src/Mvc/Mvc.NewtonsoftJson/src/JsonArrayPool.cs
+++ b/src/Mvc/Mvc.NewtonsoftJson/src/JsonArrayPool.cs
@@ -37,4 +37,3 @@ namespace Microsoft.AspNetCore.Mvc.NewtonsoftJson
}
}
}
-
\ No newline at end of file
diff --git a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj b/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj
index 18d8c0fa23..0c899f5f13 100644
--- a/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj
+++ b/src/ProjectTemplates/ComponentsWebAssembly.ProjectTemplates/Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj
@@ -14,18 +14,6 @@
DefaultNetCoreTargetFramework=$(DefaultNetCoreTargetFramework);
- MicrosoftAspNetCoreComponentsWebAssemblyPackageVersion=$(MicrosoftAspNetCoreComponentsWebAssemblyPackageVersion);
- MicrosoftAspNetCoreComponentsWebAssemblyBuildPackageVersion=$(MicrosoftAspNetCoreComponentsWebAssemblyBuildPackageVersion);
- MicrosoftAspNetCoreComponentsWebAssemblyDevServerPackageVersion=$(MicrosoftAspNetCoreComponentsWebAssemblyDevServerPackageVersion);
- MicrosoftAspNetCoreBlazorHttpClientPackageVersion=$(MicrosoftAspNetCoreBlazorHttpClientPackageVersion);
- MicrosoftAspNetCoreComponentsWebAssemblyServerPackageVersion=$(MicrosoftAspNetCoreComponentsWebAssemblyServerPackageVersion);
- MicrosoftAspNetCoreComponentsAuthorizationPackageVersion=$(MicrosoftAspNetCoreComponentsAuthorizationPackageVersion);
- MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion=$(MicrosoftAspNetCoreDiagnosticsEntityFrameworkCorePackageVersion);
- MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion=$(MicrosoftAspNetCoreIdentityEntityFrameworkCorePackageVersion);
- MicrosoftAspNetCoreAuthenticationAzureADUIPackageVersion=$(MicrosoftAspNetCoreAuthenticationAzureADUIPackageVersion);
- MicrosoftAspNetCoreAuthenticationAzureADB2CUIPackageVersion=$(MicrosoftAspNetCoreAuthenticationAzureADB2CUIPackageVersion);
- MicrosoftAspNetCoreIdentityUIPackageVersion=$(MicrosoftAspNetCoreIdentityUIPackageVersion);
- MicrosoftAspNetCoreApiAuthorizationIdentityServerPackageVersion=$(MicrosoftAspNetCoreApiAuthorizationIdentityServerPackageVersion);
MicrosoftEntityFrameworkCoreSqlServerPackageVersion=$(MicrosoftEntityFrameworkCoreSqlServerPackageVersion);
MicrosoftEntityFrameworkCoreSqlitePackageVersion=$(MicrosoftEntityFrameworkCoreSqlitePackageVersion);
MicrosoftEntityFrameworkCoreToolsPackageVersion=$(MicrosoftEntityFrameworkCoreToolsPackageVersion);
@@ -36,12 +24,19 @@
+
+
+
+
+
+
+
diff --git a/src/ProjectTemplates/ProjectTemplates.sln b/src/ProjectTemplates/ProjectTemplates.sln
index 97f3257819..d459ebe7dd 100644
--- a/src/ProjectTemplates/ProjectTemplates.sln
+++ b/src/ProjectTemplates/ProjectTemplates.sln
@@ -3,6 +3,14 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28627.84
MinimumVisualStudioVersion = 15.0.26124.0
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Web.ProjectTemplates", "Web.ProjectTemplates\Microsoft.DotNet.Web.ProjectTemplates.csproj", "{3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Web.Spa.ProjectTemplates", "Web.Spa.ProjectTemplates\Microsoft.DotNet.Web.Spa.ProjectTemplates.csproj", "{96251C41-7953-46DC-B131-5A070640959A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Web.Client.ItemTemplates", "Web.Client.ItemTemplates\Microsoft.DotNet.Web.Client.ItemTemplates.csproj", "{92F0615B-4C8F-456C-86C0-39384BB7031E}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.DotNet.Web.ItemTemplates", "Web.ItemTemplates\Microsoft.DotNet.Web.ItemTemplates.csproj", "{BC03F087-9B6F-4A66-9571-B0C5C204A101}"
+EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectTemplates.Tests", "test\ProjectTemplates.Tests.csproj", "{AF371A60-8A85-4ADF-BE44-0F2B94234DB1}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DotNetToolsInstaller", "testassets\DotNetToolsInstaller\DotNetToolsInstaller.csproj", "{4B971DBF-6B07-4DC5-914D-4D5681F220CC}"
@@ -169,7 +177,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.ApiAut
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.SpaServices.Extensions", "..\Middleware\SpaServices.Extensions\src\Microsoft.AspNetCore.SpaServices.Extensions.csproj", "{06D0D7B2-EDA3-45A2-A060-AB791ED1DB80}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Templates", "ComponentsWebAssembly.ProjectTemplates\Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj", "{F2870943-14EA-4AD2-AC01-E4E66E0B63F4}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Components.WebAssembly.Templates", "ComponentsWebAssembly.ProjectTemplates\Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj", "{5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -181,6 +189,54 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Debug|x64.Build.0 = Debug|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Debug|x86.Build.0 = Debug|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Release|x64.ActiveCfg = Release|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Release|x64.Build.0 = Release|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Release|x86.ActiveCfg = Release|Any CPU
+ {3D3DE8B3-6B54-4CF4-82B0-718E0009A4E5}.Release|x86.Build.0 = Release|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Debug|x64.Build.0 = Debug|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Debug|x86.Build.0 = Debug|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Release|x64.ActiveCfg = Release|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Release|x64.Build.0 = Release|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Release|x86.ActiveCfg = Release|Any CPU
+ {96251C41-7953-46DC-B131-5A070640959A}.Release|x86.Build.0 = Release|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Debug|x64.Build.0 = Debug|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Debug|x86.Build.0 = Debug|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Release|x64.ActiveCfg = Release|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Release|x64.Build.0 = Release|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Release|x86.ActiveCfg = Release|Any CPU
+ {92F0615B-4C8F-456C-86C0-39384BB7031E}.Release|x86.Build.0 = Release|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Debug|x64.Build.0 = Debug|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Debug|x86.Build.0 = Debug|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Release|x64.ActiveCfg = Release|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Release|x64.Build.0 = Release|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Release|x86.ActiveCfg = Release|Any CPU
+ {BC03F087-9B6F-4A66-9571-B0C5C204A101}.Release|x86.Build.0 = Release|Any CPU
{AF371A60-8A85-4ADF-BE44-0F2B94234DB1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF371A60-8A85-4ADF-BE44-0F2B94234DB1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF371A60-8A85-4ADF-BE44-0F2B94234DB1}.Debug|x64.ActiveCfg = Debug|Any CPU
@@ -1165,18 +1221,18 @@ Global
{06D0D7B2-EDA3-45A2-A060-AB791ED1DB80}.Release|x64.Build.0 = Release|Any CPU
{06D0D7B2-EDA3-45A2-A060-AB791ED1DB80}.Release|x86.ActiveCfg = Release|Any CPU
{06D0D7B2-EDA3-45A2-A060-AB791ED1DB80}.Release|x86.Build.0 = Release|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Debug|x64.ActiveCfg = Debug|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Debug|x64.Build.0 = Debug|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Debug|x86.ActiveCfg = Debug|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Debug|x86.Build.0 = Debug|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Release|Any CPU.Build.0 = Release|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Release|x64.ActiveCfg = Release|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Release|x64.Build.0 = Release|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Release|x86.ActiveCfg = Release|Any CPU
- {F2870943-14EA-4AD2-AC01-E4E66E0B63F4}.Release|x86.Build.0 = Release|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Debug|x64.Build.0 = Debug|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Debug|x86.Build.0 = Debug|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Release|x64.ActiveCfg = Release|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Release|x64.Build.0 = Release|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Release|x86.ActiveCfg = Release|Any CPU
+ {5AE7B4C4-790D-4809-A5FE-D7303DFBC11B}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/ProjectTemplates/ProjectTemplatesNoDeps.slnf b/src/ProjectTemplates/ProjectTemplatesNoDeps.slnf
index 5ca202469b..6d45dcfe3f 100644
--- a/src/ProjectTemplates/ProjectTemplatesNoDeps.slnf
+++ b/src/ProjectTemplates/ProjectTemplatesNoDeps.slnf
@@ -2,6 +2,7 @@
"solution": {
"path": "ProjectTemplates.sln",
"projects": [
+ "ComponentsWebAssembly.ProjectTemplates\\Microsoft.AspNetCore.Components.WebAssembly.Templates.csproj",
"Web.Client.ItemTemplates\\Microsoft.DotNet.Web.Client.ItemTemplates.csproj",
"Web.ItemTemplates\\Microsoft.DotNet.Web.ItemTemplates.csproj",
"Web.ProjectTemplates\\Microsoft.DotNet.Web.ProjectTemplates.csproj",
diff --git a/src/ProjectTemplates/test/BaselineTest.cs b/src/ProjectTemplates/test/BaselineTest.cs
index 8382a22cbd..ae518adfd7 100644
--- a/src/ProjectTemplates/test/BaselineTest.cs
+++ b/src/ProjectTemplates/test/BaselineTest.cs
@@ -122,6 +122,16 @@ namespace Templates.Test
text += "supportpagesandviewstrue";
}
+ if (arguments.Contains("-ho"))
+ {
+ text += "hosted";
+ }
+
+ if (arguments.Contains("--pwa"))
+ {
+ text += "pwa";
+ }
+
return text;
}
@@ -140,4 +150,4 @@ namespace Templates.Test
}
}
}
-}
+}
\ No newline at end of file
diff --git a/src/ProjectTemplates/test/EmptyWebTemplateTest.cs b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
new file mode 100644
index 0000000000..56e2e8c105
--- /dev/null
+++ b/src/ProjectTemplates/test/EmptyWebTemplateTest.cs
@@ -0,0 +1,73 @@
+// 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.Threading.Tasks;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test
+{
+ public class EmptyWebTemplateTest
+ {
+ public EmptyWebTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output)
+ {
+ ProjectFactory = projectFactory;
+ Output = output;
+ }
+
+ public Project Project { get; set; }
+
+ public ProjectFactoryFixture ProjectFactory { get; }
+
+ public ITestOutputHelper Output { get; }
+
+ [Fact]
+ public async Task EmptyWebTemplateCSharp()
+ {
+ await EmtpyTemplateCore(languageOverride: null);
+ }
+
+ [Fact]
+ public async Task EmptyWebTemplateFSharp()
+ {
+ await EmtpyTemplateCore("F#");
+ }
+
+ private async Task EmtpyTemplateCore(string languageOverride)
+ {
+ Project = await ProjectFactory.GetOrCreateProject("empty" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
+
+ var createResult = await Project.RunDotNetNewAsync("web", language: languageOverride);
+ Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
+
+ 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));
+
+ using (var aspNetProcess = Project.StartBuiltProjectAsync())
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process));
+
+ await aspNetProcess.AssertOk("/");
+ }
+
+ using (var aspNetProcess = Project.StartPublishedProjectAsync())
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process));
+
+ await aspNetProcess.AssertOk("/");
+ }
+ }
+ }
+}
diff --git a/src/ProjectTemplates/test/GrpcTemplateTest.cs b/src/ProjectTemplates/test/GrpcTemplateTest.cs
new file mode 100644
index 0000000000..4713a7a9c4
--- /dev/null
+++ b/src/ProjectTemplates/test/GrpcTemplateTest.cs
@@ -0,0 +1,89 @@
+// 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;
+using System.Runtime.InteropServices;
+using System.Threading.Tasks;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test
+{
+ public class GrpcTemplateTest
+ {
+ public GrpcTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output)
+ {
+ ProjectFactory = projectFactory;
+ Output = output;
+ }
+
+ public Project Project { get; set; }
+
+ public ProjectFactoryFixture ProjectFactory { get; }
+ public ITestOutputHelper Output { get; }
+
+ [Fact]
+ public async Task GrpcTemplate()
+ {
+ Project = await ProjectFactory.GetOrCreateProject("grpc", Output);
+
+ var createResult = await Project.RunDotNetNewAsync("grpc");
+ Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
+
+ var publishResult = await Project.RunDotNetPublishAsync();
+ Assert.True(0 == publishResult.ExitCode, ErrorMessages.GetFailedProcessMessage("publish", Project, publishResult));
+
+ var buildResult = await Project.RunDotNetBuildAsync();
+ Assert.True(0 == buildResult.ExitCode, ErrorMessages.GetFailedProcessMessage("build", Project, buildResult));
+
+ using (var serverProcess = Project.StartBuiltProjectAsync())
+ {
+ // These templates are HTTPS + HTTP/2 only which is not supported on Mac due to missing ALPN support.
+ // https://github.com/aspnet/AspNetCore/issues/11061
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ Assert.True(serverProcess.Process.HasExited, "built");
+ Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on macOS due to missing ALPN support.",
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process));
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version < new Version(6, 2))
+ {
+ Assert.True(serverProcess.Process.HasExited, "built");
+ Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on Windows 7 due to missing ALPN support.",
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process));
+ }
+ else
+ {
+ Assert.False(
+ serverProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built service", Project, serverProcess.Process));
+ }
+ }
+
+ using (var aspNetProcess = Project.StartPublishedProjectAsync())
+ {
+ // These templates are HTTPS + HTTP/2 only which is not supported on Mac due to missing ALPN support.
+ // https://github.com/aspnet/AspNetCore/issues/11061
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ Assert.True(aspNetProcess.Process.HasExited, "published");
+ Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on macOS due to missing ALPN support.",
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process));
+ }
+ else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Environment.OSVersion.Version < new Version(6, 2))
+ {
+ Assert.True(aspNetProcess.Process.HasExited, "published");
+ Assert.Contains("System.NotSupportedException: HTTP/2 over TLS is not supported on Windows 7 due to missing ALPN support.",
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process));
+ }
+ else
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run published service", Project, aspNetProcess.Process));
+ }
+ }
+ }
+ }
+}
diff --git a/src/ProjectTemplates/test/Helpers/AspNetProcess.cs b/src/ProjectTemplates/test/Helpers/AspNetProcess.cs
index 97cec926b8..eb4348d830 100644
--- a/src/ProjectTemplates/test/Helpers/AspNetProcess.cs
+++ b/src/ProjectTemplates/test/Helpers/AspNetProcess.cs
@@ -36,7 +36,7 @@ namespace Templates.Test.Helpers
string workingDirectory,
string dllPath,
IDictionary environmentVariables,
- bool published = true,
+ bool published,
bool hasListeningUri = true)
{
_output = output;
@@ -55,7 +55,7 @@ namespace Templates.Test.Helpers
output.WriteLine("Running ASP.NET application...");
- var arguments = published ? $"exec {dllPath}" : "run";
+ var arguments = published ? $"exec {dllPath}" : "run --no-build";
Process = ProcessEx.Run(output, workingDirectory, DotNetMuxer.MuxerPathOrDefault(), arguments, envVars: environmentVariables);
if (hasListeningUri)
{
diff --git a/src/ProjectTemplates/test/Helpers/Project.cs b/src/ProjectTemplates/test/Helpers/Project.cs
index 10dd191bc2..89bfce17eb 100644
--- a/src/ProjectTemplates/test/Helpers/Project.cs
+++ b/src/ProjectTemplates/test/Helpers/Project.cs
@@ -164,39 +164,6 @@ namespace Templates.Test.Helpers
return new AspNetProcess(Output, TemplateServerDir, projectDll, environment, published: false);
}
- internal AspNetProcess StartBuiltClientAsync(AspNetProcess serverProcess)
- {
- var environment = new Dictionary
- {
- ["ASPNETCORE_ENVIRONMENT"] = "Development"
- };
-
- var projectDll = Path.Combine(TemplateClientDebugDir, $"{ProjectName}.Client.dll {serverProcess.ListeningUri.Port}");
- return new AspNetProcess(Output, TemplateOutputDir, projectDll, environment, hasListeningUri: false);
- }
-
- internal AspNetProcess StartPublishedServerAsync()
- {
- var environment = new Dictionary
- {
- ["ASPNETCORE_URLS"] = _urls,
- };
-
- var projectDll = $"{ProjectName}.Server.dll";
- return new AspNetProcess(Output, TemplateServerReleaseDir, projectDll, environment);
- }
-
- internal AspNetProcess StartPublishedClientAsync()
- {
- var environment = new Dictionary
- {
- ["ASPNETCORE_URLS"] = _urls,
- };
-
- var projectDll = $"{ProjectName}.Client.dll";
- return new AspNetProcess(Output, TemplateClientReleaseDir, projectDll, environment);
- }
-
internal AspNetProcess StartBuiltProjectAsync(bool hasListeningUri = true)
{
var environment = new Dictionary
@@ -209,6 +176,32 @@ namespace Templates.Test.Helpers
["ASPNETCORE_Logging__Console__IncludeScopes"] = "true",
};
+ var launchSettingsJson = Path.Combine(TemplateOutputDir, "Properties", "launchSettings.json");
+ if (File.Exists(launchSettingsJson))
+ {
+ // When executing "dotnet run", the launch urls specified in the app's launchSettings.json have higher precedence
+ // than ambient environment variables. When present, we have to edit this file to allow the application to pick random ports.
+
+ var original = File.ReadAllText(launchSettingsJson);
+ var updated = original.Replace(
+ "\"applicationUrl\": \"https://localhost:5001;http://localhost:5000\"",
+ $"\"applicationUrl\": \"{_urls}\"");
+
+ if (updated == original)
+ {
+ Output.WriteLine("applicationUrl is not specified in launchSettings.json");
+ }
+ else
+ {
+ Output.WriteLine("Updating applicationUrl in launchSettings.json");
+ File.WriteAllText(launchSettingsJson, updated);
+ }
+ }
+ else
+ {
+ Output.WriteLine("No launchSettings.json found to update.");
+ }
+
var projectDll = Path.Combine(TemplateBuildDir, $"{ProjectName}.dll");
return new AspNetProcess(Output, TemplateOutputDir, projectDll, environment, published: false, hasListeningUri: hasListeningUri);
}
@@ -225,7 +218,7 @@ namespace Templates.Test.Helpers
};
var projectDll = $"{ProjectName}.dll";
- return new AspNetProcess(Output, TemplatePublishDir, projectDll, environment, hasListeningUri: hasListeningUri);
+ return new AspNetProcess(Output, TemplatePublishDir, projectDll, environment, published: true, hasListeningUri: hasListeningUri);
}
internal async Task RestoreWithRetryAsync(ITestOutputHelper output, string workingDirectory)
diff --git a/src/ProjectTemplates/test/IdentityUIPackageTest.cs b/src/ProjectTemplates/test/IdentityUIPackageTest.cs
new file mode 100644
index 0000000000..deede64521
--- /dev/null
+++ b/src/ProjectTemplates/test/IdentityUIPackageTest.cs
@@ -0,0 +1,190 @@
+// 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.Net;
+using System.Threading.Tasks;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test
+{
+ public class IdentityUIPackageTest
+ {
+ public IdentityUIPackageTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output)
+ {
+ ProjectFactory = projectFactory;
+ Output = output;
+ }
+
+ public Project Project { get; set; }
+
+ public ProjectFactoryFixture ProjectFactory { get; set; }
+
+ public ITestOutputHelper Output { get; }
+
+ public static TheoryData, string, string[]> MSBuildIdentityUIPackageOptions
+ {
+ get
+ {
+ var data = new TheoryData, string, string[]>();
+
+ data.Add(new Dictionary
+ {
+ ["IdentityUIFrameworkVersion"] = "Bootstrap3"
+ },
+ "Bootstrap v3.4.1",
+ Bootstrap3ContentFiles);
+
+ data.Add(new Dictionary(), "Bootstrap v4.3.1", Bootstrap4ContentFiles);
+
+ return data;
+ }
+ }
+
+ public static string[] Bootstrap3ContentFiles { get; } = new string[]
+ {
+ "Identity/css/site.css",
+ "Identity/js/site.js",
+ "Identity/lib/bootstrap/dist/css/bootstrap-theme.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap-theme.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap-theme.min.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap-theme.min.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap.min.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap.min.css.map",
+ "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot",
+ "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.svg",
+ "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf",
+ "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff",
+ "Identity/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2",
+ "Identity/lib/bootstrap/dist/js/bootstrap.js",
+ "Identity/lib/bootstrap/dist/js/bootstrap.min.js",
+ "Identity/lib/bootstrap/dist/js/npm.js",
+ "Identity/lib/jquery/LICENSE.txt",
+ "Identity/lib/jquery/dist/jquery.js",
+ "Identity/lib/jquery/dist/jquery.min.js",
+ "Identity/lib/jquery/dist/jquery.min.map",
+ "Identity/lib/jquery-validation/LICENSE.md",
+ "Identity/lib/jquery-validation/dist/additional-methods.js",
+ "Identity/lib/jquery-validation/dist/additional-methods.min.js",
+ "Identity/lib/jquery-validation/dist/jquery.validate.js",
+ "Identity/lib/jquery-validation/dist/jquery.validate.min.js",
+ "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
+ "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js",
+ "Identity/lib/jquery-validation-unobtrusive/LICENSE.txt",
+ };
+
+ public static string[] Bootstrap4ContentFiles { get; } = new string[]
+ {
+ "Identity/favicon.ico",
+ "Identity/css/site.css",
+ "Identity/js/site.js",
+ "Identity/lib/bootstrap/dist/css/bootstrap-grid.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap-grid.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap-grid.min.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap-grid.min.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap-reboot.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap-reboot.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap-reboot.min.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap-reboot.min.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap.css.map",
+ "Identity/lib/bootstrap/dist/css/bootstrap.min.css",
+ "Identity/lib/bootstrap/dist/css/bootstrap.min.css.map",
+ "Identity/lib/bootstrap/dist/js/bootstrap.bundle.js",
+ "Identity/lib/bootstrap/dist/js/bootstrap.bundle.js.map",
+ "Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js",
+ "Identity/lib/bootstrap/dist/js/bootstrap.bundle.min.js.map",
+ "Identity/lib/bootstrap/dist/js/bootstrap.js",
+ "Identity/lib/bootstrap/dist/js/bootstrap.js.map",
+ "Identity/lib/bootstrap/dist/js/bootstrap.min.js",
+ "Identity/lib/bootstrap/dist/js/bootstrap.min.js.map",
+ "Identity/lib/jquery/LICENSE.txt",
+ "Identity/lib/jquery/dist/jquery.js",
+ "Identity/lib/jquery/dist/jquery.min.js",
+ "Identity/lib/jquery/dist/jquery.min.map",
+ "Identity/lib/jquery-validation/LICENSE.md",
+ "Identity/lib/jquery-validation/dist/additional-methods.js",
+ "Identity/lib/jquery-validation/dist/additional-methods.min.js",
+ "Identity/lib/jquery-validation/dist/jquery.validate.js",
+ "Identity/lib/jquery-validation/dist/jquery.validate.min.js",
+ "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js",
+ "Identity/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js",
+ "Identity/lib/jquery-validation-unobtrusive/LICENSE.txt",
+ };
+
+ [Theory]
+ [MemberData(nameof(MSBuildIdentityUIPackageOptions))]
+ public async Task IdentityUIPackage_WorksWithDifferentOptions(IDictionary packageOptions, string versionValidator, string[] expectedFiles)
+ {
+ Project = await ProjectFactory.GetOrCreateProject("identityuipackage" + string.Concat(packageOptions.Values), Output);
+ var useLocalDB = false;
+
+ var createResult = await Project.RunDotNetNewAsync("razor", auth: "Individual", useLocalDB: useLocalDB, environmentVariables: packageOptions);
+ Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
+
+ var projectFileContents = ReadFile(Project.TemplateOutputDir, $"{Project.ProjectName}.csproj");
+ Assert.Contains(".db", projectFileContents);
+
+ var publishResult = await Project.RunDotNetPublishAsync(packageOptions: packageOptions);
+ 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(packageOptions: packageOptions);
+ 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");
+
+ using (var aspNetProcess = Project.StartBuiltProjectAsync())
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process));
+
+ var response = await aspNetProcess.SendRequest("/Identity/lib/bootstrap/dist/css/bootstrap.css");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Contains(versionValidator, await response.Content.ReadAsStringAsync());
+ await ValidatePublishedFiles(aspNetProcess, expectedFiles);
+ }
+
+ using (var aspNetProcess = Project.StartPublishedProjectAsync())
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process));
+
+ var response = await aspNetProcess.SendRequest("/Identity/lib/bootstrap/dist/css/bootstrap.css");
+ Assert.Equal(HttpStatusCode.OK, response.StatusCode);
+ Assert.Contains(versionValidator, await response.Content.ReadAsStringAsync());
+ await ValidatePublishedFiles(aspNetProcess, expectedFiles);
+ }
+ }
+
+ private async Task ValidatePublishedFiles(AspNetProcess aspNetProcess, string[] expectedContentFiles)
+ {
+ foreach (var file in expectedContentFiles)
+ {
+ var response = await aspNetProcess.SendRequest(file);
+ Assert.True(response?.StatusCode == HttpStatusCode.OK, $"Couldn't find file '{file}'");
+ }
+ }
+
+ 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));
+ }
+ }
+}
diff --git a/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets b/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets
index 6beacfa4d8..948108395a 100644
--- a/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets
+++ b/src/ProjectTemplates/test/Infrastructure/GenerateTestProps.targets
@@ -16,9 +16,6 @@
%(_TargetingPackVersionInfo.PackageVersion)
$(TargetingPackVersionPrefix)
-
-
- $(AspNetCoreBaselineVersion)
@@ -37,7 +34,7 @@
MicrosoftNETCorePlatformsPackageVersion=$(MicrosoftNETCorePlatformsPackageVersion);
MicrosoftNETSdkRazorPackageVersion=$(MicrosoftNETSdkRazorPackageVersion);
MicrosoftAspNetCoreAppRefPackageVersion=$(MicrosoftAspNetCoreAppRefPackageVersion);
- MicrosoftAspNetCoreAppRuntimePackageVersion=$(MicrosoftAspNetCoreAppRuntimePackageVersion);
+ MicrosoftAspNetCoreAppRuntimePackageVersion=@(_RuntimePackageVersionInfo->'%(PackageVersion)');
SupportedRuntimeIdentifiers=$(SupportedRuntimeIdentifiers);
DefaultNetCoreTargetFramework=$(DefaultNetCoreTargetFramework);
diff --git a/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in b/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in
index 103ccbeafc..25fbc524a4 100644
--- a/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in
+++ b/src/ProjectTemplates/test/Infrastructure/TemplateTests.props.in
@@ -40,14 +40,6 @@
IsImplicitlyDefined="true" />
-
-
-
- <_AnalyzerToRemove Include="@(Analyzer)" Condition="'%(Analyzer.NuGetPackageId)' == 'Microsoft.AspNetCore.Components.Analyzers'" />
-
-
-
-
diff --git a/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs
new file mode 100644
index 0000000000..0d02a56f8f
--- /dev/null
+++ b/src/ProjectTemplates/test/RazorClassLibraryTemplateTest.cs
@@ -0,0 +1,62 @@
+// 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.Threading.Tasks;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test
+{
+ public class RazorClassLibraryTemplateTest
+ {
+ public RazorClassLibraryTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output)
+ {
+ ProjectFactory = projectFactory;
+ Output = output;
+ }
+
+ public Project Project { get; set; }
+
+ public ProjectFactoryFixture ProjectFactory { get; }
+ public ITestOutputHelper Output { get; }
+
+ [Fact]
+ public async Task RazorClassLibraryTemplate_WithViews_Async()
+ {
+ Project = await ProjectFactory.GetOrCreateProject("razorclasslibwithviews", Output);
+
+ var createResult = await Project.RunDotNetNewAsync("razorclasslib", args: new[] { "--support-pages-and-views", "true" });
+ Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
+
+ 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));
+ }
+
+ [Fact]
+ public async Task RazorClassLibraryTemplateAsync()
+ {
+ Project = await ProjectFactory.GetOrCreateProject("razorclasslib", Output);
+
+ var createResult = await Project.RunDotNetNewAsync("razorclasslib");
+ Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
+
+ 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));
+ }
+ }
+}
diff --git a/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs
new file mode 100644
index 0000000000..8ea82fff71
--- /dev/null
+++ b/src/ProjectTemplates/test/SpaTemplateTest/AngularTemplateTest.cs
@@ -0,0 +1,30 @@
+// 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.Threading.Tasks;
+using Microsoft.AspNetCore.E2ETesting;
+using Microsoft.AspNetCore.Testing;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test.SpaTemplateTest
+{
+ public class AngularTemplateTest : SpaTemplateTestBase
+ {
+ public AngularTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output)
+ : base(projectFactory, browserFixture, output) { }
+
+ [Fact(Skip = "Skipping SPA tests in 3.1")]
+ public Task AngularTemplate_Works()
+ => SpaTemplateImplAsync("angularnoauth", "angular", useLocalDb: false, usesAuth: false);
+
+ [Fact(Skip = "Skipping SPA tests in 3.1")]
+ public Task AngularTemplate_IndividualAuth_Works()
+ => SpaTemplateImplAsync("angularindividual", "angular", useLocalDb: false, usesAuth: true);
+
+ [Fact(Skip = "Skipping SPA tests in 3.1")]
+ public Task AngularTemplate_IndividualAuth_Works_LocalDb()
+ => SpaTemplateImplAsync("angularindividualuld", "angular", useLocalDb: true, usesAuth: true);
+ }
+}
diff --git a/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs
new file mode 100644
index 0000000000..3e37085ed8
--- /dev/null
+++ b/src/ProjectTemplates/test/SpaTemplateTest/ReactReduxTemplateTest.cs
@@ -0,0 +1,23 @@
+// 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.Threading.Tasks;
+using Microsoft.AspNetCore.E2ETesting;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test.SpaTemplateTest
+{
+ public class ReactReduxTemplateTest : SpaTemplateTestBase
+ {
+ public ReactReduxTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output)
+ : base(projectFactory, browserFixture, output)
+ {
+ }
+
+ [Fact(Skip = "Skipping SPA tests in 3.1")]
+ public Task ReactReduxTemplate_Works_NetCore()
+ => SpaTemplateImplAsync("reactredux", "reactredux", useLocalDb: false, usesAuth: false);
+ }
+}
diff --git a/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs b/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs
new file mode 100644
index 0000000000..3b9c36986a
--- /dev/null
+++ b/src/ProjectTemplates/test/SpaTemplateTest/ReactTemplateTest.cs
@@ -0,0 +1,32 @@
+// 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.Threading.Tasks;
+using Microsoft.AspNetCore.E2ETesting;
+using Microsoft.AspNetCore.Testing;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test.SpaTemplateTest
+{
+ public class ReactTemplateTest : SpaTemplateTestBase
+ {
+ public ReactTemplateTest(ProjectFactoryFixture projectFactory, BrowserFixture browserFixture, ITestOutputHelper output)
+ : base(projectFactory, browserFixture, output)
+ {
+ }
+
+ [Fact(Skip = "Skipping SPA tests in 3.1")]
+ public Task ReactTemplate_Works_NetCore()
+ => SpaTemplateImplAsync("reactnoauth", "react", useLocalDb: false, usesAuth: false);
+
+ [Fact(Skip = "Skipping SPA tests in 3.1")]
+ public Task ReactTemplate_IndividualAuth_NetCore()
+ => SpaTemplateImplAsync("reactindividual", "react", useLocalDb: false, usesAuth: true);
+
+ [Fact(Skip = "Skipping SPA tests in 3.1")]
+ public Task ReactTemplate_IndividualAuth_NetCore_LocalDb()
+ => SpaTemplateImplAsync("reactindividualuld", "react", useLocalDb: true, usesAuth: true);
+ }
+}
diff --git a/src/ProjectTemplates/test/WebApiTemplateTest.cs b/src/ProjectTemplates/test/WebApiTemplateTest.cs
new file mode 100644
index 0000000000..89d047a06e
--- /dev/null
+++ b/src/ProjectTemplates/test/WebApiTemplateTest.cs
@@ -0,0 +1,70 @@
+// 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.Threading.Tasks;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test
+{
+ public class WebApiTemplateTest
+ {
+ public WebApiTemplateTest(ProjectFactoryFixture factoryFixture, ITestOutputHelper output)
+ {
+ FactoryFixture = factoryFixture;
+ Output = output;
+ }
+
+ public ProjectFactoryFixture FactoryFixture { get; }
+
+ public ITestOutputHelper Output { get; }
+
+ public Project Project { get; set; }
+
+ [Fact]
+ public async Task WebApiTemplateFSharp() => await WebApiTemplateCore(languageOverride: "F#");
+
+ [Fact]
+ public async Task WebApiTemplateCSharp() => await WebApiTemplateCore(languageOverride: null);
+
+ private async Task WebApiTemplateCore(string languageOverride)
+ {
+ Project = await FactoryFixture.GetOrCreateProject("webapi" + (languageOverride == "F#" ? "fsharp" : "csharp"), Output);
+
+ var createResult = await Project.RunDotNetNewAsync("webapi", language: languageOverride);
+ Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
+
+ 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));
+
+ using (var aspNetProcess = Project.StartBuiltProjectAsync())
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process));
+
+ await aspNetProcess.AssertOk("weatherforecast");
+ await aspNetProcess.AssertNotFound("/");
+ }
+
+ using (var aspNetProcess = Project.StartPublishedProjectAsync())
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process));
+
+
+ await aspNetProcess.AssertOk("weatherforecast");
+ await aspNetProcess.AssertNotFound("/");
+ }
+ }
+ }
+}
diff --git a/src/ProjectTemplates/test/WorkerTemplateTest.cs b/src/ProjectTemplates/test/WorkerTemplateTest.cs
new file mode 100644
index 0000000000..738eafc61d
--- /dev/null
+++ b/src/ProjectTemplates/test/WorkerTemplateTest.cs
@@ -0,0 +1,56 @@
+// 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.Threading.Tasks;
+using Templates.Test.Helpers;
+using Xunit;
+using Xunit.Abstractions;
+
+namespace Templates.Test
+{
+ public class WorkerTemplateTest
+ {
+ public WorkerTemplateTest(ProjectFactoryFixture projectFactory, ITestOutputHelper output)
+ {
+ ProjectFactory = projectFactory;
+ Output = output;
+ }
+
+ public Project Project { get; set; }
+ public ProjectFactoryFixture ProjectFactory { get; }
+ public ITestOutputHelper Output { get; }
+
+ [Fact]
+ public async Task WorkerTemplateAsync()
+ {
+ Project = await ProjectFactory.GetOrCreateProject("worker", Output);
+
+ var createResult = await Project.RunDotNetNewAsync("worker");
+ Assert.True(0 == createResult.ExitCode, ErrorMessages.GetFailedProcessMessage("create/restore", Project, createResult));
+
+ 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));
+
+ using (var aspNetProcess = Project.StartBuiltProjectAsync(hasListeningUri: false))
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run built project", Project, aspNetProcess.Process));
+ }
+
+ using (var aspNetProcess = Project.StartPublishedProjectAsync(hasListeningUri: false))
+ {
+ Assert.False(
+ aspNetProcess.Process.HasExited,
+ ErrorMessages.GetFailedProcessMessageOrEmpty("Run published project", Project, aspNetProcess.Process));
+ }
+ }
+ }
+}