From c22c028becc559fc5a144280b60d1895e5cabd9e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 Aug 2025 17:23:04 +0000 Subject: [PATCH 1/7] Initial plan From eda88a2bb85789720461951506e6083e1ced3169 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 6 Aug 2025 17:42:50 +0000 Subject: [PATCH 2/7] Fix script tag importmap regression - preserve user content when no asp-importmap Co-authored-by: MackinnonBuck <10456961+MackinnonBuck@users.noreply.github.com> --- src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs | 25 ++++++--- .../test/ScriptTagHelperTest.cs | 53 +++++++++++++++++++ 2 files changed, 70 insertions(+), 8 deletions(-) diff --git a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs index 64cc1be2f694..8f39476da710 100644 --- a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs +++ b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs @@ -247,16 +247,25 @@ public override void Process(TagHelperContext context, TagHelperOutput output) var importMap = ImportMap ?? ViewContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata(); if (importMap == null) { - // No importmap found, nothing to do. - output.SuppressOutput(); + // No importmap found. Only suppress output if this was intended to be + // an automatically generated importmap (i.e., when asp-importmap was used). + // If the user provided explicit content without asp-importmap, let it render as-is. + if (ImportMap != null || context.AllAttributes.ContainsName(ImportMapAttributeName)) + { + output.SuppressOutput(); + return; + } + // Let the tag render as-is by continuing with normal processing + // Don't return here, let normal attribute copying happen + } + else + { + output.TagName = "script"; + output.TagMode = TagMode.StartTagAndEndTag; + output.Attributes.SetAttribute("type", "importmap"); + output.Content.SetHtmlContent(importMap.ToString()); return; } - - output.TagName = "script"; - output.TagMode = TagMode.StartTagAndEndTag; - output.Attributes.SetAttribute("type", "importmap"); - output.Content.SetHtmlContent(importMap.ToString()); - return; } // Pass through attribute that is also a well-known HTML attribute. diff --git a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs index 18ffbc3cd10f..add27a9da7f2 100644 --- a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs +++ b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs @@ -794,6 +794,59 @@ public void ScriptTagHelper_RendersImportMap_FromEndpoint() Assert.Equal(importMap.ToJson(), output.Content.GetContent()); } + [Fact] + public void ScriptTagHelper_PreservesExplicitImportMapContent_WhenNoImportMapDefinition() + { + // Arrange - this simulates the user's scenario where they provide explicit importmap content + // without using asp-importmap attribute + var context = MakeTagHelperContext( + attributes: new TagHelperAttributeList + { + new TagHelperAttribute("type", "importmap"), + }); + + var output = MakeTagHelperOutput("script", attributes: new TagHelperAttributeList()); + + var helper = GetHelper(); + helper.Type = "importmap"; + // No endpoint with ImportMapDefinition and no asp-importmap attribute + // This should NOT suppress the output, allowing user content to render + + // Act + helper.Process(context, output); + + // Assert + Assert.Equal("script", output.TagName); // Tag should not be suppressed + Assert.Equal("importmap", output.Attributes["type"].Value); + // The output should not be suppressed, allowing user's explicit content to render + Assert.False(output.IsContentModified); // Content should remain as user provided + } + + [Fact] + public void ScriptTagHelper_SuppressesOutput_WhenAspImportMapAttributeUsedButNoDefinition() + { + // Arrange - this simulates using asp-importmap attribute but having no ImportMapDefinition + var context = MakeTagHelperContext( + attributes: new TagHelperAttributeList + { + new TagHelperAttribute("type", "importmap"), + new TagHelperAttribute("asp-importmap", null), // asp-importmap used but no value + }); + + var output = MakeTagHelperOutput("script", attributes: new TagHelperAttributeList()); + + var helper = GetHelper(); + helper.Type = "importmap"; + // No endpoint with ImportMapDefinition but asp-importmap attribute is present + // This should suppress the output since it was intended to be auto-generated + + // Act + helper.Process(context, output); + + // Assert - output should be suppressed when asp-importmap is used but no definition found + Assert.Null(output.TagName); // Tag should be suppressed + } + private Endpoint CreateEndpoint(ImportMapDefinition importMap = null) { return new Endpoint( From 736a44bb9681d1eaf22bdaa11eaa262ea54dacf2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 11 Aug 2025 13:55:51 +0000 Subject: [PATCH 3/7] Fix ScriptTagHelper importmap regression by checking for existing content Co-authored-by: javiercn <6995051+javiercn@users.noreply.github.com> --- .../src/PublicAPI.Unshipped.txt | 1 + src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs | 42 ++++++++++--------- .../test/ScriptTagHelperTest.cs | 29 ++++++------- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt b/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt index 7dc5c58110bf..1bbff6be240e 100644 --- a/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt +++ b/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt @@ -1 +1,2 @@ #nullable enable +~override Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper.ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) -> System.Threading.Tasks.Task diff --git a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs index 8f39476da710..3706be8d03ff 100644 --- a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs +++ b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs @@ -236,36 +236,40 @@ private StringWriter StringWriter /// public override void Process(TagHelperContext context, TagHelperOutput output) + { + ProcessAsync(context, output).GetAwaiter().GetResult(); + } + + /// + public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(output); if (string.Equals(Type, "importmap", StringComparison.OrdinalIgnoreCase)) { - // This is an importmap script, we'll write out the import map and - // stop processing. - var importMap = ImportMap ?? ViewContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata(); - if (importMap == null) + // This is an importmap script, check if there's existing content first + var childContent = await output.GetChildContentAsync(); + if (!childContent.IsEmptyOrWhiteSpace) { - // No importmap found. Only suppress output if this was intended to be - // an automatically generated importmap (i.e., when asp-importmap was used). - // If the user provided explicit content without asp-importmap, let it render as-is. - if (ImportMap != null || context.AllAttributes.ContainsName(ImportMapAttributeName)) - { - output.SuppressOutput(); - return; - } - // Let the tag render as-is by continuing with normal processing - // Don't return here, let normal attribute copying happen + // User provided explicit content, preserve it + return; } - else + + // No existing content, so we can apply import map logic + var importMap = ImportMap ?? ViewContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata(); + if (importMap == null) { - output.TagName = "script"; - output.TagMode = TagMode.StartTagAndEndTag; - output.Attributes.SetAttribute("type", "importmap"); - output.Content.SetHtmlContent(importMap.ToString()); + // No importmap found, nothing to do. + output.SuppressOutput(); return; } + + output.TagName = "script"; + output.TagMode = TagMode.StartTagAndEndTag; + output.Attributes.SetAttribute("type", "importmap"); + output.Content.SetHtmlContent(importMap.ToString()); + return; } // Pass through attribute that is also a well-known HTML attribute. diff --git a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs index add27a9da7f2..11003dcd5e3c 100644 --- a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs +++ b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs @@ -795,10 +795,9 @@ public void ScriptTagHelper_RendersImportMap_FromEndpoint() } [Fact] - public void ScriptTagHelper_PreservesExplicitImportMapContent_WhenNoImportMapDefinition() + public async Task ScriptTagHelper_PreservesExplicitImportMapContent_WhenUserProvidesContent() { // Arrange - this simulates the user's scenario where they provide explicit importmap content - // without using asp-importmap attribute var context = MakeTagHelperContext( attributes: new TagHelperAttributeList { @@ -806,44 +805,46 @@ public void ScriptTagHelper_PreservesExplicitImportMapContent_WhenNoImportMapDef }); var output = MakeTagHelperOutput("script", attributes: new TagHelperAttributeList()); + // Simulate user providing explicit content + output.Content.SetHtmlContent(@"{""imports"":{""jquery"":""https://code.jquery.com/jquery.js""}}"); var helper = GetHelper(); helper.Type = "importmap"; - // No endpoint with ImportMapDefinition and no asp-importmap attribute - // This should NOT suppress the output, allowing user content to render + // No endpoint with ImportMapDefinition - this should NOT suppress the output + // since user provided explicit content // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); // Tag should not be suppressed Assert.Equal("importmap", output.Attributes["type"].Value); - // The output should not be suppressed, allowing user's explicit content to render - Assert.False(output.IsContentModified); // Content should remain as user provided + // The user's explicit content should be preserved + Assert.Equal(@"{""imports"":{""jquery"":""https://code.jquery.com/jquery.js""}}", output.Content.GetContent()); } [Fact] - public void ScriptTagHelper_SuppressesOutput_WhenAspImportMapAttributeUsedButNoDefinition() + public async Task ScriptTagHelper_SuppressesOutput_WhenNoContentAndNoImportMapDefinition() { - // Arrange - this simulates using asp-importmap attribute but having no ImportMapDefinition + // Arrange - this simulates an empty importmap script with no definition var context = MakeTagHelperContext( attributes: new TagHelperAttributeList { new TagHelperAttribute("type", "importmap"), - new TagHelperAttribute("asp-importmap", null), // asp-importmap used but no value }); var output = MakeTagHelperOutput("script", attributes: new TagHelperAttributeList()); + // No content provided var helper = GetHelper(); helper.Type = "importmap"; - // No endpoint with ImportMapDefinition but asp-importmap attribute is present - // This should suppress the output since it was intended to be auto-generated + // No endpoint with ImportMapDefinition and no explicit content + // This should suppress the output since there's nothing to render // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); - // Assert - output should be suppressed when asp-importmap is used but no definition found + // Assert - output should be suppressed when no content and no definition Assert.Null(output.TagName); // Tag should be suppressed } From cd843e38b1815e800e711c098eee972108ba2afb Mon Sep 17 00:00:00 2001 From: Mackinnon Buck Date: Fri, 5 Sep 2025 11:52:06 -0700 Subject: [PATCH 4/7] Manual fixes --- src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs | 31 +++++++++---------- .../test/ScriptTagHelperTest.cs | 23 +++++++------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs index 3706be8d03ff..1cb795a8d9cb 100644 --- a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs +++ b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs @@ -234,12 +234,6 @@ private StringWriter StringWriter } } - /// - public override void Process(TagHelperContext context, TagHelperOutput output) - { - ProcessAsync(context, output).GetAwaiter().GetResult(); - } - /// public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { @@ -248,27 +242,30 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu if (string.Equals(Type, "importmap", StringComparison.OrdinalIgnoreCase)) { - // This is an importmap script, check if there's existing content first + // This is an importmap script, check if there's existing content first. var childContent = await output.GetChildContentAsync(); if (!childContent.IsEmptyOrWhiteSpace) { - // User provided explicit content, preserve it - return; + // User provided existing content; preserve it. + output.Content.SetHtmlContent(childContent); } - - // No existing content, so we can apply import map logic - var importMap = ImportMap ?? ViewContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata(); - if (importMap == null) + else { - // No importmap found, nothing to do. - output.SuppressOutput(); - return; + // No existing content, so we can apply import map logic. + var importMap = ImportMap ?? ViewContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata(); + if (importMap == null) + { + // No importmap found, nothing to do. + output.SuppressOutput(); + return; + } + + output.Content.SetHtmlContent(importMap.ToString()); } output.TagName = "script"; output.TagMode = TagMode.StartTagAndEndTag; output.Attributes.SetAttribute("type", "importmap"); - output.Content.SetHtmlContent(importMap.ToString()); return; } diff --git a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs index 11003dcd5e3c..651e8c81616d 100644 --- a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs +++ b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs @@ -798,18 +798,17 @@ public void ScriptTagHelper_RendersImportMap_FromEndpoint() public async Task ScriptTagHelper_PreservesExplicitImportMapContent_WhenUserProvidesContent() { // Arrange - this simulates the user's scenario where they provide explicit importmap content - var context = MakeTagHelperContext( - attributes: new TagHelperAttributeList - { - new TagHelperAttribute("type", "importmap"), - }); - - var output = MakeTagHelperOutput("script", attributes: new TagHelperAttributeList()); + var context = MakeTagHelperContext(attributes: [new TagHelperAttribute("type", "importmap")]); + // Simulate user providing explicit content - output.Content.SetHtmlContent(@"{""imports"":{""jquery"":""https://code.jquery.com/jquery.js""}}"); + var childContent = new DefaultTagHelperContent(); + childContent.SetHtmlContent(@"{""imports"":{""jquery"":""https://code.jquery.com/jquery.js""}}"); + + var output = MakeTagHelperOutput("script", attributes: [], childContent: childContent); var helper = GetHelper(); helper.Type = "importmap"; + // No endpoint with ImportMapDefinition - this should NOT suppress the output // since user provided explicit content @@ -1175,15 +1174,15 @@ private static ViewContext MakeViewContext(string requestPathBase = null) return viewContext; } - private TagHelperOutput MakeTagHelperOutput(string tagName, TagHelperAttributeList attributes = null) + private TagHelperOutput MakeTagHelperOutput(string tagName, TagHelperAttributeList attributes = null, TagHelperContent childContent = null) { - attributes = attributes ?? new TagHelperAttributeList(); + attributes ??= []; + childContent ??= new DefaultTagHelperContent(); return new TagHelperOutput( tagName, attributes, - getChildContentAsync: (useCachedResult, encoder) => Task.FromResult( - new DefaultTagHelperContent())); + getChildContentAsync: (useCachedResult, encoder) => Task.FromResult(childContent)); } private static IWebHostEnvironment MakeHostingEnvironment() From 1c33e546da8df0b5512ff20340383c24a9180506 Mon Sep 17 00:00:00 2001 From: Mackinnon Buck Date: Fri, 5 Sep 2025 12:06:56 -0700 Subject: [PATCH 5/7] Handle other tag helper setting content --- src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs | 26 +++++++++++-------- .../test/ScriptTagHelperTest.cs | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs index 1cb795a8d9cb..85952ce0865a 100644 --- a/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs +++ b/src/Mvc/Mvc.TagHelpers/src/ScriptTagHelper.cs @@ -242,27 +242,31 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu if (string.Equals(Type, "importmap", StringComparison.OrdinalIgnoreCase)) { + // Do not update the content if another tag helper targeting this element has already done so. + if (output.IsContentModified) + { + return; + } + // This is an importmap script, check if there's existing content first. var childContent = await output.GetChildContentAsync(); if (!childContent.IsEmptyOrWhiteSpace) { // User provided existing content; preserve it. output.Content.SetHtmlContent(childContent); + return; } - else - { - // No existing content, so we can apply import map logic. - var importMap = ImportMap ?? ViewContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata(); - if (importMap == null) - { - // No importmap found, nothing to do. - output.SuppressOutput(); - return; - } - output.Content.SetHtmlContent(importMap.ToString()); + // No existing content, so we can apply import map logic. + var importMap = ImportMap ?? ViewContext.HttpContext.GetEndpoint()?.Metadata.GetMetadata(); + if (importMap == null) + { + // No importmap found, nothing to do. + output.SuppressOutput(); + return; } + output.Content.SetHtmlContent(importMap.ToString()); output.TagName = "script"; output.TagMode = TagMode.StartTagAndEndTag; output.Attributes.SetAttribute("type", "importmap"); diff --git a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs index 651e8c81616d..123513a1014e 100644 --- a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs +++ b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs @@ -804,7 +804,7 @@ public async Task ScriptTagHelper_PreservesExplicitImportMapContent_WhenUserProv var childContent = new DefaultTagHelperContent(); childContent.SetHtmlContent(@"{""imports"":{""jquery"":""https://code.jquery.com/jquery.js""}}"); - var output = MakeTagHelperOutput("script", attributes: [], childContent: childContent); + var output = MakeTagHelperOutput("script", attributes: [new TagHelperAttribute("type", "importmap")], childContent: childContent); var helper = GetHelper(); helper.Type = "importmap"; From 9aba24990526e8f5125458d36afa6132229b66f4 Mon Sep 17 00:00:00 2001 From: Mackinnon Buck Date: Fri, 5 Sep 2025 12:50:25 -0700 Subject: [PATCH 6/7] Update PublicAPI.Unshipped.txt --- src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt b/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt index 1bbff6be240e..46ac17a8733c 100644 --- a/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt +++ b/src/Mvc/Mvc.TagHelpers/src/PublicAPI.Unshipped.txt @@ -1,2 +1,3 @@ #nullable enable +*REMOVED*~override Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper.Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) -> void ~override Microsoft.AspNetCore.Mvc.TagHelpers.ScriptTagHelper.ProcessAsync(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext context, Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput output) -> System.Threading.Tasks.Task From 6b024bf9d1f70318c4914193830479100460ab85 Mon Sep 17 00:00:00 2001 From: Mackinnon Buck Date: Tue, 9 Sep 2025 15:24:10 -0700 Subject: [PATCH 7/7] Use `ProcessAsync()` in tests --- .../test/ScriptTagHelperTest.cs | 84 +++++++++---------- 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs index 123513a1014e..11fec3545440 100644 --- a/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs +++ b/src/Mvc/Mvc.TagHelpers/test/ScriptTagHelperTest.cs @@ -30,7 +30,7 @@ public class ScriptTagHelperTest [InlineData("abcd.js", "test.js", "test.js")] [InlineData(null, "~/test.js", "virtualRoot/test.js")] [InlineData("abcd.js", "~/test.js", "virtualRoot/test.js")] - public void Process_SrcDefaultsToTagHelperOutputSrcAttributeAddedByOtherTagHelper( + public async Task ProcessAsync_SrcDefaultsToTagHelperOutputSrcAttributeAddedByOtherTagHelper( string src, string srcOutput, string expectedSrcPrefix) @@ -66,7 +66,7 @@ public void Process_SrcDefaultsToTagHelperOutputSrcAttributeAddedByOtherTagHelpe helper.Src = src; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal( @@ -77,7 +77,7 @@ public void Process_SrcDefaultsToTagHelperOutputSrcAttributeAddedByOtherTagHelpe [Theory] [MemberData(nameof(LinkTagHelperTest.MultiAttributeSameNameData), MemberType = typeof(LinkTagHelperTest))] - public void HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList outputAttributes) + public async Task HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList outputAttributes) { // Arrange var allAttributes = new TagHelperAttributeList( @@ -107,7 +107,7 @@ public void HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList ou expectedAttributes.Add(new TagHelperAttribute("src", "/blank.js")); // Act - helper.Process(tagHelperContext, output); + await helper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(expectedAttributes, output.Attributes); @@ -268,7 +268,7 @@ public static TheoryData> RunsWh [Theory] [MemberData(nameof(RunsWhenRequiredAttributesArePresent_Data))] - public void RunsWhenRequiredAttributesArePresent( + public async Task RunsWhenRequiredAttributesArePresent( TagHelperAttributeList attributes, Action setProperties) { @@ -287,7 +287,7 @@ public void RunsWhenRequiredAttributesArePresent( setProperties(helper); // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.NotNull(output.TagName); @@ -355,7 +355,7 @@ public static TheoryData> RunsWh [Theory] [MemberData(nameof(RunsWhenRequiredAttributesArePresent_NoSrc_Data))] - public void RunsWhenRequiredAttributesArePresent_NoSrc( + public async Task RunsWhenRequiredAttributesArePresent_NoSrc( TagHelperAttributeList attributes, Action setProperties) { @@ -374,7 +374,7 @@ public void RunsWhenRequiredAttributesArePresent_NoSrc( setProperties(helper); // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Null(output.TagName); @@ -449,7 +449,7 @@ public static TheoryData> DoesNo [Theory] [MemberData(nameof(DoesNotRunWhenARequiredAttributeIsMissing_Data))] - public void DoesNotRunWhenARequiredAttributeIsMissing( + public async Task DoesNotRunWhenARequiredAttributeIsMissing( TagHelperAttributeList attributes, Action setProperties) { @@ -462,7 +462,7 @@ public void DoesNotRunWhenARequiredAttributeIsMissing( setProperties(helper); // Act - helper.Process(tagHelperContext, output); + await helper.ProcessAsync(tagHelperContext, output); // Assert Assert.NotNull(output.TagName); @@ -472,7 +472,7 @@ public void DoesNotRunWhenARequiredAttributeIsMissing( } [Fact] - public void DoesNotRunWhenAllRequiredAttributesAreMissing() + public async Task DoesNotRunWhenAllRequiredAttributesAreMissing() { // Arrange var tagHelperContext = MakeTagHelperContext(); @@ -482,7 +482,7 @@ public void DoesNotRunWhenAllRequiredAttributesAreMissing() var helper = GetHelper(); // Act - helper.Process(tagHelperContext, output); + await helper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal("script", output.TagName); @@ -492,7 +492,7 @@ public void DoesNotRunWhenAllRequiredAttributesAreMissing() } [Fact] - public void PreservesOrderOfNonSrcAttributes() + public async Task PreservesOrderOfNonSrcAttributes() { // Arrange var tagHelperContext = MakeTagHelperContext( @@ -518,7 +518,7 @@ public void PreservesOrderOfNonSrcAttributes() helper.Src = "/blank.js"; // Act - helper.Process(tagHelperContext, output); + await helper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal("data-extra", output.Attributes[0].Name); @@ -527,7 +527,7 @@ public void PreservesOrderOfNonSrcAttributes() } [Fact] - public void RendersScriptTagsForGlobbedSrcResults() + public async Task RendersScriptTagsForGlobbedSrcResults() { // Arrange var expectedContent = "" + @@ -552,7 +552,7 @@ public void RendersScriptTagsForGlobbedSrcResults() helper.SrcInclude = "**/*.js"; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -562,7 +562,7 @@ public void RendersScriptTagsForGlobbedSrcResults() } [Fact] - public void RendersScriptTagsForGlobbedSrcResults_EncodesAsExpected() + public async Task RendersScriptTagsForGlobbedSrcResults_EncodesAsExpected() { // Arrange var expectedContent = @@ -605,7 +605,7 @@ public void RendersScriptTagsForGlobbedSrcResults_EncodesAsExpected() helper.SrcInclude = "**/*.js"; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -615,7 +615,7 @@ public void RendersScriptTagsForGlobbedSrcResults_EncodesAsExpected() } [Fact] - public void RenderScriptTags_WithFileVersion() + public async Task RenderScriptTags_WithFileVersion() { // Arrange var context = MakeTagHelperContext( @@ -631,7 +631,7 @@ public void RenderScriptTags_WithFileVersion() helper.AppendVersion = true; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -642,7 +642,7 @@ public void RenderScriptTags_WithFileVersion() [InlineData("~/js/site.js", "/js/site.fingerprint.js")] [InlineData("/js/site.js", "/js/site.fingerprint.js")] [InlineData("js/site.js", "js/site.fingerprint.js")] - public void RenderScriptTags_WithFileVersion_UsingResourceCollection(string src, string expected) + public async Task RenderScriptTags_WithFileVersion_UsingResourceCollection(string src, string expected) { // Arrange var context = MakeTagHelperContext( @@ -661,7 +661,7 @@ public void RenderScriptTags_WithFileVersion_UsingResourceCollection(string src, helper.AppendVersion = true; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -671,7 +671,7 @@ public void RenderScriptTags_WithFileVersion_UsingResourceCollection(string src, [Theory] [InlineData("~/js/site.js")] [InlineData("/approot/js/site.js")] - public void RenderScriptTags_PathBase_WithFileVersion_UsingResourceCollection(string path) + public async Task RenderScriptTags_PathBase_WithFileVersion_UsingResourceCollection(string path) { // Arrange var context = MakeTagHelperContext( @@ -699,7 +699,7 @@ public void RenderScriptTags_PathBase_WithFileVersion_UsingResourceCollection(st helper.AppendVersion = true; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -707,7 +707,7 @@ public void RenderScriptTags_PathBase_WithFileVersion_UsingResourceCollection(st } [Fact] - public void ScriptTagHelper_RendersProvided_ImportMap() + public async Task ScriptTagHelper_RendersProvided_ImportMap() { // Arrange var importMap = new ImportMapDefinition( @@ -744,7 +744,7 @@ public void ScriptTagHelper_RendersProvided_ImportMap() helper.ImportMap = importMap; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -752,7 +752,7 @@ public void ScriptTagHelper_RendersProvided_ImportMap() } [Fact] - public void ScriptTagHelper_RendersImportMap_FromEndpoint() + public async Task ScriptTagHelper_RendersImportMap_FromEndpoint() { // Arrange var importMap = new ImportMapDefinition( @@ -787,7 +787,7 @@ public void ScriptTagHelper_RendersImportMap_FromEndpoint() helper.Type = "importmap"; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -862,7 +862,7 @@ [new ResourceAssetCollection([ } [Fact] - public void RenderScriptTags_WithFileVersion_AndRequestPathBase() + public async Task RenderScriptTags_WithFileVersion_AndRequestPathBase() { // Arrange var context = MakeTagHelperContext( @@ -879,7 +879,7 @@ public void RenderScriptTags_WithFileVersion_AndRequestPathBase() helper.AppendVersion = true; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -887,7 +887,7 @@ public void RenderScriptTags_WithFileVersion_AndRequestPathBase() } [Fact] - public void RenderScriptTags_FallbackSrc_WithFileVersion() + public async Task RenderScriptTags_FallbackSrc_WithFileVersion() { // Arrange var context = MakeTagHelperContext( @@ -907,7 +907,7 @@ public void RenderScriptTags_FallbackSrc_WithFileVersion() helper.Src = "/js/site.js"; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -918,7 +918,7 @@ public void RenderScriptTags_FallbackSrc_WithFileVersion() } [Fact] - public void RenderScriptTags_FallbackSrc_AppendVersion_WithStaticAssets() + public async Task RenderScriptTags_FallbackSrc_AppendVersion_WithStaticAssets() { // Arrange var context = MakeTagHelperContext( @@ -939,7 +939,7 @@ public void RenderScriptTags_FallbackSrc_AppendVersion_WithStaticAssets() helper.Src = "/js/site.js"; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -950,7 +950,7 @@ public void RenderScriptTags_FallbackSrc_AppendVersion_WithStaticAssets() } [Fact] - public void RenderScriptTags_FallbackSrc_WithFileVersion_EncodesAsExpected() + public async Task RenderScriptTags_FallbackSrc_WithFileVersion_EncodesAsExpected() { // Arrange var expectedContent = @@ -992,7 +992,7 @@ public void RenderScriptTags_FallbackSrc_WithFileVersion_EncodesAsExpected() helper.Src = "/js/site.js"; // Act - helper.Process(context, output); + await helper.ProcessAsync(context, output); // Assert Assert.Equal("script", output.TagName); @@ -1002,7 +1002,7 @@ public void RenderScriptTags_FallbackSrc_WithFileVersion_EncodesAsExpected() } [Fact] - public void RenderScriptTags_GlobbedSrc_WithFileVersion() + public async Task RenderScriptTags_GlobbedSrc_WithFileVersion() { // Arrange var expectedContent = "