From 71d3aa3e0936964a24dcad94575da007f8e0f865 Mon Sep 17 00:00:00 2001 From: Doug Bunting Date: Thu, 10 Mar 2016 22:07:48 -0800 Subject: [PATCH] Correct HTML and JavaScript encoding of `` and ` + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -120,7 +120,7 @@ - + diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Link.html b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Link.html index 585cf17fc6..0384f385c8 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Link.html +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Link.html @@ -39,7 +39,7 @@ - + diff --git a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html index 433539425e..f696105479 100644 --- a/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html +++ b/test/Microsoft.AspNetCore.Mvc.FunctionalTests/compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Script.Encoded.html @@ -1,4 +1,4 @@ - + @@ -13,27 +13,27 @@

Script tag helper test

- + - + - + - + - + - + - + - + - + - + - + "; + var context = MakeTagHelperContext( + attributes: new TagHelperAttributeList + { + { "asp-append-version", "true" }, + { "asp-fallback-href-include", "**/fallback.css" }, + { "asp-fallback-test-class", "hidden" }, + { "asp-fallback-test-property", "visibility" }, + { "asp-fallback-test-value", "hidden" }, + { "href", "/css/site.css" }, + }); + var output = MakeTagHelperOutput("link", attributes: new TagHelperAttributeList()); + var hostingEnvironment = MakeHostingEnvironment(); + var viewContext = MakeViewContext(); + var globbingUrlBuilder = new Mock( + new TestFileProvider(), + Mock.Of(), + PathString.Empty); + globbingUrlBuilder.Setup(g => g.BuildUrlList(null, "**/fallback.css", null)) + .Returns(new[] { "/fallback.css" }); + + var helper = new LinkTagHelper( + MakeHostingEnvironment(), + MakeCache(), + new HtmlTestEncoder(), + new JavaScriptTestEncoder(), + MakeUrlHelperFactory()) + { + AppendVersion = true, + Href = "/css/site.css", + FallbackHrefInclude = "**/fallback.css", + FallbackTestClass = "hidden", + FallbackTestProperty = "visibility", + FallbackTestValue = "hidden", + GlobbingUrlBuilder = globbingUrlBuilder.Object, + ViewContext = viewContext, + }; + + // Act + helper.Process(context, output); + + // Assert + Assert.Equal("link", output.TagName); + Assert.Equal("/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", output.Attributes["href"].Value); + Assert.Equal(expectedPostElement, output.PostElement.GetContent()); + } + + [Fact] + public void RenderLinkTags_FallbackHref_WithFileVersion_EncodesAsExpected() + { + // Arrange + var expectedContent = "" + + Environment.NewLine + + "" + + ""; + var mixed = new DefaultTagHelperContent(); + mixed.Append("HTML encoded"); + mixed.AppendHtml(" and contains \"quotes\""); + var context = MakeTagHelperContext( + attributes: new TagHelperAttributeList + { + { "asp-append-version", "true" }, + { "asp-fallback-href-include", "**/fallback.css" }, + { "asp-fallback-test-class", "hidden" }, + { "asp-fallback-test-property", "visibility" }, + { "asp-fallback-test-value", "hidden" }, + { "encoded", new HtmlString("contains \"quotes\"") }, + { "href", "/css/site.css" }, + { "literal", "all HTML encoded" }, + { "mixed", mixed }, + }); + var output = MakeTagHelperOutput( + "link", + attributes: new TagHelperAttributeList + { + { "encoded", new HtmlString("contains \"quotes\"") }, + { "literal", "all HTML encoded" }, + { "mixed", mixed }, + }); + var hostingEnvironment = MakeHostingEnvironment(); + var viewContext = MakeViewContext(); + var globbingUrlBuilder = new Mock( + new TestFileProvider(), + Mock.Of(), + PathString.Empty); + globbingUrlBuilder.Setup(g => g.BuildUrlList(null, "**/fallback.css", null)) + .Returns(new[] { "/fallback.css" }); + + var helper = new LinkTagHelper( + MakeHostingEnvironment(), + MakeCache(), + new HtmlTestEncoder(), + new JavaScriptTestEncoder(), + MakeUrlHelperFactory()) + { + AppendVersion = true, + FallbackHrefInclude = "**/fallback.css", + FallbackTestClass = "hidden", + FallbackTestProperty = "visibility", + FallbackTestValue = "hidden", + GlobbingUrlBuilder = globbingUrlBuilder.Object, + Href = "/css/site.css", + ViewContext = viewContext, + }; + + // Act + helper.Process(context, output); + + // Assert + Assert.Equal("link", output.TagName); + Assert.Equal("/css/site.css?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", output.Attributes["href"].Value); + var content = HtmlContentUtilities.HtmlContentToString(output, new HtmlTestEncoder()); + Assert.Equal(expectedContent, content); + } + + [Fact] + public void RendersLinkTags_GlobbedHref_WithFileVersion() { // Arrange var context = MakeTagHelperContext( @@ -848,7 +1005,10 @@ private static TagHelperOutput MakeTagHelperOutput(string tagName, TagHelperAttr tagName, attributes, getChildContentAsync: (useCachedResult, encoder) => Task.FromResult( - new DefaultTagHelperContent())); + new DefaultTagHelperContent())) + { + TagMode = TagMode.SelfClosing, + }; } private static IHostingEnvironment MakeHostingEnvironment() diff --git a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs index 95286d9a76..05c280f14a 100644 --- a/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs +++ b/test/Microsoft.AspNetCore.Mvc.TagHelpers.Test/ScriptTagHelperTest.cs @@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Mvc.TagHelpers.Internal; +using Microsoft.AspNetCore.Mvc.TestCommon; using Microsoft.AspNetCore.Mvc.ViewEngines; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Razor.TagHelpers; @@ -95,7 +96,7 @@ public void Process_SrcDefaultsToTagHelperOutputSrcAttributeAddedByOtherTagHelpe [Theory] [MemberData(nameof(LinkTagHelperTest.MultiAttributeSameNameData), MemberType = typeof(LinkTagHelperTest))] - public async Task HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList outputAttributes) + public void HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeList outputAttributes) { // Arrange var allAttributes = new TagHelperAttributeList( @@ -134,7 +135,7 @@ public async Task HandlesMultipleAttributesSameNameCorrectly(TagHelperAttributeL expectedAttributes.Add(new TagHelperAttribute("src", "/blank.js")); // Act - await helper.ProcessAsync(tagHelperContext, output); + helper.Process(tagHelperContext, output); // Assert Assert.Equal(expectedAttributes, output.Attributes); @@ -265,7 +266,7 @@ public static TheoryData RunsWhenRequiredAttributesArePresent_Data [Theory] [MemberData(nameof(RunsWhenRequiredAttributesArePresent_Data))] - public async Task RunsWhenRequiredAttributesArePresent( + public void RunsWhenRequiredAttributesArePresent( TagHelperAttributeList attributes, Action setProperties) { @@ -294,7 +295,7 @@ public async Task RunsWhenRequiredAttributesArePresent( setProperties(helper); // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); // Assert Assert.NotNull(output.TagName); @@ -362,7 +363,7 @@ public static TheoryData RunsWhenRequiredAttributesArePresent_NoSrc_Data [Theory] [MemberData(nameof(RunsWhenRequiredAttributesArePresent_NoSrc_Data))] - public async Task RunsWhenRequiredAttributesArePresent_NoSrc( + public void RunsWhenRequiredAttributesArePresent_NoSrc( TagHelperAttributeList attributes, Action setProperties) { @@ -391,11 +392,12 @@ public async Task RunsWhenRequiredAttributesArePresent_NoSrc( setProperties(helper); // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); // Assert Assert.Null(output.TagName); Assert.True(output.IsContentModified); + Assert.True(output.Content.IsEmpty); Assert.True(output.PostElement.IsModified); } @@ -498,7 +500,7 @@ public void DoesNotRunWhenARequiredAttributeIsMissing( } [Fact] - public async Task DoesNotRunWhenAllRequiredAttributesAreMissing() + public void DoesNotRunWhenAllRequiredAttributesAreMissing() { // Arrange var tagHelperContext = MakeTagHelperContext(); @@ -516,7 +518,7 @@ public async Task DoesNotRunWhenAllRequiredAttributesAreMissing() }; // Act - await helper.ProcessAsync(tagHelperContext, output); + helper.Process(tagHelperContext, output); // Assert Assert.Equal("script", output.TagName); @@ -526,7 +528,7 @@ public async Task DoesNotRunWhenAllRequiredAttributesAreMissing() } [Fact] - public async Task PreservesOrderOfNonSrcAttributes() + public void PreservesOrderOfNonSrcAttributes() { // Arrange var tagHelperContext = MakeTagHelperContext( @@ -564,7 +566,7 @@ public async Task PreservesOrderOfNonSrcAttributes() }; // Act - await helper.ProcessAsync(tagHelperContext, output); + helper.Process(tagHelperContext, output); // Assert Assert.Equal("data-extra", output.Attributes[0].Name); @@ -573,9 +575,11 @@ public async Task PreservesOrderOfNonSrcAttributes() } [Fact] - public async Task RendersScriptTagsForGlobbedSrcResults() + public void RendersScriptTagsForGlobbedSrcResults() { // Arrange + var expectedContent = "" + + ""; var context = MakeTagHelperContext( attributes: new TagHelperAttributeList { @@ -606,25 +610,46 @@ public async Task RendersScriptTagsForGlobbedSrcResults() }; // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); // Assert Assert.Equal("script", output.TagName); Assert.Equal("/js/site.js", output.Attributes["src"].Value); - Assert.Equal("", output.PostElement.GetContent()); + var content = HtmlContentUtilities.HtmlContentToString(output, new HtmlTestEncoder()); + Assert.Equal(expectedContent, content); } [Fact] - public async Task RendersScriptTagsForGlobbedSrcResults_UsesProvidedEncoder() + public void RendersScriptTagsForGlobbedSrcResults_EncodesAsExpected() { // Arrange + var expectedContent = + "" + + ""; + var mixed = new DefaultTagHelperContent(); + mixed.Append("HTML encoded"); + mixed.AppendHtml(" and contains \"quotes\""); var context = MakeTagHelperContext( attributes: new TagHelperAttributeList { - new TagHelperAttribute("src", "/js/site.js"), - new TagHelperAttribute("asp-src-include", "**/*.js") + { "asp-src-include", "**/*.js" }, + { "encoded", new HtmlString("contains \"quotes\"") }, + { "literal", "all HTML encoded" }, + { "mixed", mixed }, + { "src", "/js/site.js" }, + }); + var output = MakeTagHelperOutput( + "script", + attributes: new TagHelperAttributeList + { + { "encoded", new HtmlString("contains \"quotes\"") }, + { "literal", "all HTML encoded"}, + { "mixed", mixed}, }); - var output = MakeTagHelperOutput("script", attributes: new TagHelperAttributeList()); var hostingEnvironment = MakeHostingEnvironment(); var viewContext = MakeViewContext(); var globbingUrlBuilder = new Mock( @@ -642,22 +667,23 @@ public async Task RendersScriptTagsForGlobbedSrcResults_UsesProvidedEncoder() MakeUrlHelperFactory()) { GlobbingUrlBuilder = globbingUrlBuilder.Object, - ViewContext = viewContext, Src = "/js/site.js", SrcInclude = "**/*.js", + ViewContext = viewContext, }; // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); // Assert Assert.Equal("script", output.TagName); Assert.Equal("/js/site.js", output.Attributes["src"].Value); - Assert.Equal("", output.PostElement.GetContent()); + var content = HtmlContentUtilities.HtmlContentToString(output, new HtmlTestEncoder()); + Assert.Equal(expectedContent, content); } [Fact] - public async Task RenderScriptTags_WithFileVersion() + public void RenderScriptTags_WithFileVersion() { // Arrange var context = MakeTagHelperContext( @@ -684,7 +710,7 @@ public async Task RenderScriptTags_WithFileVersion() }; // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); // Assert Assert.Equal("script", output.TagName); @@ -692,7 +718,7 @@ public async Task RenderScriptTags_WithFileVersion() } [Fact] - public async Task RenderScriptTags_WithFileVersion_AndRequestPathBase() + public void RenderScriptTags_WithFileVersion_AndRequestPathBase() { // Arrange var context = MakeTagHelperContext( @@ -718,7 +744,7 @@ public async Task RenderScriptTags_WithFileVersion_AndRequestPathBase() }; // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); // Assert Assert.Equal("script", output.TagName); @@ -726,7 +752,7 @@ public async Task RenderScriptTags_WithFileVersion_AndRequestPathBase() } [Fact] - public async Task RenderScriptTags_FallbackSrc_WithFileVersion() + public void RenderScriptTags_FallbackSrc_WithFileVersion() { // Arrange var context = MakeTagHelperContext( @@ -756,20 +782,87 @@ public async Task RenderScriptTags_FallbackSrc_WithFileVersion() }; // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); + + // Assert + Assert.Equal("script", output.TagName); + Assert.Equal("/js/site.js?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", output.Attributes["src"].Value); + Assert.Equal(Environment.NewLine + "", output.PostElement.GetContent()); + } + + [Fact] + public void RenderScriptTags_FallbackSrc_WithFileVersion_EncodesAsExpected() + { + // Arrange + var expectedContent = + "" + + Environment.NewLine + + ""; + var mixed = new DefaultTagHelperContent(); + mixed.Append("HTML encoded"); + mixed.AppendHtml(" and contains \"quotes\""); + var context = MakeTagHelperContext( + attributes: new TagHelperAttributeList + { + { "asp-append-version", "true" }, + { "asp-fallback-src-include", "fallback.js" }, + { "asp-fallback-test", "isavailable()" }, + { "encoded", new HtmlString("contains \"quotes\"") }, + { "literal", "all HTML encoded" }, + { "mixed", mixed }, + { "src", "/js/site.js" }, + }); + var output = MakeTagHelperOutput( + "script", + attributes: new TagHelperAttributeList + { + { "encoded", new HtmlString("contains \"quotes\"") }, + { "literal", "all HTML encoded" }, + { "mixed", mixed }, + }); + var hostingEnvironment = MakeHostingEnvironment(); + var viewContext = MakeViewContext(); + + var helper = new ScriptTagHelper( + MakeHostingEnvironment(), + MakeCache(), + new HtmlTestEncoder(), + new JavaScriptTestEncoder(), + MakeUrlHelperFactory()) + { + AppendVersion = true, + FallbackSrc = "fallback.js", + FallbackTestExpression = "isavailable()", + Src = "/js/site.js", + ViewContext = viewContext, + }; + + // Act + helper.Process(context, output); // Assert Assert.Equal("script", output.TagName); Assert.Equal("/js/site.js?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", output.Attributes["src"].Value); - Assert.Equal(Environment.NewLine + "", output.PostElement.GetContent()); + var content = HtmlContentUtilities.HtmlContentToString(output, new HtmlTestEncoder()); + Assert.Equal(expectedContent, content); } [Fact] - public async Task RenderScriptTags_GlobbedSrc_WithFileVersion() + public void RenderScriptTags_GlobbedSrc_WithFileVersion() { // Arrange + var expectedContent = "" + + ""; var context = MakeTagHelperContext( attributes: new TagHelperAttributeList { @@ -802,13 +895,13 @@ public async Task RenderScriptTags_GlobbedSrc_WithFileVersion() }; // Act - await helper.ProcessAsync(context, output); + helper.Process(context, output); // Assert Assert.Equal("script", output.TagName); Assert.Equal("/js/site.js?v=f4OxZX_x_FO5LcGBSKHWXfwtSx-j1ncoSt3SABJtkGk", output.Attributes["src"].Value); - Assert.Equal("", output.PostElement.GetContent()); + var content = HtmlContentUtilities.HtmlContentToString(output, new HtmlTestEncoder()); + Assert.Equal(expectedContent, content); } private TagHelperContext MakeTagHelperContext(