public async Task WriteTagHelperAsync_WritesContentAppropriately( bool childContentRetrieved, string input, string expected) { // Arrange var defaultTagHelperContent = new DefaultTagHelperContent(); var writer = new StringCollectionTextWriter(Encoding.UTF8); var context = CreateViewContext(writer); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: "p", tagMode: TagMode.StartTagAndEndTag, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => { defaultTagHelperContent.AppendEncoded(input); return Task.FromResult(result: true); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => defaultTagHelperContent); tagHelperExecutionContext.Output = new TagHelperOutput("p", new TagHelperAttributeList()); if (childContentRetrieved) { await tagHelperExecutionContext.GetChildContentAsync(useCachedResult: true); } // Act var page = CreatePage(p => { p.HtmlEncoder = new CommonTestEncoder(); p.WriteTagHelperAsync(tagHelperExecutionContext).Wait(); }, context); await page.ExecuteAsync(); // Assert Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(writer.Content)); }
public async Task ProcessAsyncInTemplate_WithItems_GeneratesExpectedOutput_DoesNotChangeSelectList( object model, Type containerType, Func<object> modelAccessor, NameAndId nameAndId, string expectedOptions) { // Arrange var originalAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; var originalPostContent = "original content"; var expectedAttributes = new TagHelperAttributeList(originalAttributes) { { "id", nameAndId.Id }, { "name", nameAndId.Name }, { "valid", "from validation attributes" }, }; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = originalPostContent + expectedOptions; var expectedTagName = "select"; var metadataProvider = new TestModelMetadataProvider(); var containerMetadata = metadataProvider.GetMetadataForType(containerType); var containerExplorer = metadataProvider.GetModelExplorerForType(containerType, model); var propertyMetadata = metadataProvider.GetMetadataForProperty(containerType, "Text"); var modelExplorer = containerExplorer.GetExplorerForExpression(propertyMetadata, modelAccessor()); var modelExpression = new ModelExpression(name: string.Empty, modelExplorer: modelExplorer); var tagHelperContext = new TagHelperContext( allAttributes: new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.AppendEncoded("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput(expectedTagName, originalAttributes) { TagMode = TagMode.SelfClosing, }; output.PreContent.AppendEncoded(expectedPreContent); output.Content.AppendEncoded(expectedContent); output.PostContent.AppendEncoded(originalPostContent); var htmlGenerator = new TestableHtmlGenerator(metadataProvider) { ValidationAttributes = { { "valid", "from validation attributes" }, } }; var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); viewContext.ViewData.TemplateInfo.HtmlFieldPrefix = nameAndId.Name; var items = new SelectList(new[] { "", "outer text", "inner text", "other text" }); var savedDisabled = items.Select(item => item.Disabled).ToList(); var savedGroup = items.Select(item => item.Group).ToList(); var savedSelected = items.Select(item => item.Selected).ToList(); var savedText = items.Select(item => item.Text).ToList(); var savedValue = items.Select(item => item.Value).ToList(); var tagHelper = new SelectTagHelper(htmlGenerator) { For = modelExpression, Items = items, ViewContext = viewContext, }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(TagMode.SelfClosing, output.TagMode); Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, HtmlContentUtilities.HtmlContentToString(output.PostContent)); Assert.Equal(expectedTagName, output.TagName); Assert.NotNull(viewContext.FormContext?.FormData); Assert.Single( viewContext.FormContext.FormData, entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey); Assert.Equal(savedDisabled, items.Select(item => item.Disabled)); Assert.Equal(savedGroup, items.Select(item => item.Group)); Assert.Equal(savedSelected, items.Select(item => item.Selected)); Assert.Equal(savedText, items.Select(item => item.Text)); Assert.Equal(savedValue, items.Select(item => item.Value)); }
private void BuildFallbackBlock(TagHelperAttributeList attributes, DefaultTagHelperContent builder) { EnsureGlobbingUrlBuilder(); var fallbackSrcs = GlobbingUrlBuilder.BuildUrlList(FallbackSrc, FallbackSrcInclude, FallbackSrcExclude); if (fallbackSrcs.Any()) { // Build the <script> tag that checks the test method and if it fails, renders the extra script. builder.AppendEncoded(Environment.NewLine) .AppendEncoded("<script>(") .AppendEncoded(FallbackTestExpression) .AppendEncoded("||document.write(\""); // May have no "src" attribute in the dictionary e.g. if Src and SrcInclude were not bound. if (!attributes.ContainsName(SrcAttributeName)) { // Need this entry to place each fallback source. attributes.Add(new TagHelperAttribute(SrcAttributeName, value: null)); } foreach (var src in fallbackSrcs) { // Fallback "src" values come from bound attributes and globbing. Must always be non-null. Debug.Assert(src != null); builder.AppendEncoded("<script"); foreach (var attribute in attributes) { if (!attribute.Name.Equals(SrcAttributeName, StringComparison.OrdinalIgnoreCase)) { var encodedKey = JavaScriptEncoder.JavaScriptStringEncode(attribute.Name); var attributeValue = attribute.Value.ToString(); var encodedValue = JavaScriptEncoder.JavaScriptStringEncode(attributeValue); AppendAttribute(builder, encodedKey, encodedValue, escapeQuotes: true); } else { // Ignore attribute.Value; use src instead. var attributeValue = src; if (AppendVersion == true) { attributeValue = _fileVersionProvider.AddFileVersionToPath(attributeValue); } // attribute.Key ("src") does not need to be JavaScript-encoded. var encodedValue = JavaScriptEncoder.JavaScriptStringEncode(attributeValue); AppendAttribute(builder, attribute.Name, encodedValue, escapeQuotes: true); } } builder.AppendEncoded("><\\/script>"); } builder.AppendEncoded("\"));</script>"); } }
public void AppendEncoded_DoesNotGetEncoded() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.AppendEncoded("Hi"); var writer = new StringWriter(); // Act tagHelperContent.WriteTo(writer, new CommonTestEncoder()); // Assert Assert.Equal("Hi", writer.ToString()); }
public async Task ProcessAsync_GeneratesExpectedOutput( object model, Type containerType, Func<object> modelAccessor, string propertyPath, TagHelperOutputContent tagHelperOutputContent) { // Arrange var expectedTagName = "not-label"; var expectedAttributes = new TagHelperAttributeList { { "class", "form-control" }, { "for", tagHelperOutputContent.ExpectedId } }; var metadataProvider = new TestModelMetadataProvider(); var containerMetadata = metadataProvider.GetMetadataForType(containerType); var containerExplorer = metadataProvider.GetModelExplorerForType(containerType, model); var propertyMetadata = metadataProvider.GetMetadataForProperty(containerType, "Text"); var modelExplorer = containerExplorer.GetExplorerForExpression(propertyMetadata, modelAccessor()); var htmlGenerator = new TestableHtmlGenerator(metadataProvider); var modelExpression = new ModelExpression(propertyPath, modelExplorer); var tagHelper = new LabelTagHelper(htmlGenerator) { For = modelExpression, }; var expectedPreContent = "original pre-content"; var expectedPostContent = "original post-content"; var tagHelperContext = new TagHelperContext( allAttributes: new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.AppendEncoded(tagHelperOutputContent.OriginalChildContent); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var htmlAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; var output = new TagHelperOutput(expectedTagName, htmlAttributes); output.PreContent.AppendEncoded(expectedPreContent); output.PostContent.AppendEncoded(expectedPostContent); // LabelTagHelper checks IsContentModified so we don't want to forcibly set it if // tagHelperOutputContent.OriginalContent is going to be null or empty. if (!string.IsNullOrEmpty(tagHelperOutputContent.OriginalContent)) { output.Content.AppendEncoded(tagHelperOutputContent.OriginalContent); } var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); tagHelper.ViewContext = viewContext; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal( tagHelperOutputContent.ExpectedContent, HtmlContentUtilities.HtmlContentToString(output.Content)); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode); Assert.Equal(expectedTagName, output.TagName); }