public void SetContentClearsExistingContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "HtmlEncode[[Hello World!]]"; tagHelperContent.SetContent("Contoso"); // Act tagHelperContent.SetContent("Hello World!"); // Assert Assert.Equal(expected, tagHelperContent.GetContent(new CommonTestEncoder())); }
public void SetContentClearsExistingContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; tagHelperContent.SetContent("Contoso"); // Act tagHelperContent.SetContent(expected); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
public async Task GetChildContentAsync_CachesValue() { // Arrange var defaultTagHelperContent = new DefaultTagHelperContent(); var expectedContent = string.Empty; var executionContext = new TagHelperExecutionContext( "p", selfClosing: false, items: null, uniqueId: string.Empty, executeChildContentAsync: () => { if (string.IsNullOrEmpty(expectedContent)) { expectedContent = "Hello from child content: " + Guid.NewGuid().ToString(); } defaultTagHelperContent.SetContent(expectedContent); return Task.FromResult(result: true); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => defaultTagHelperContent); // Act var content1 = await executionContext.GetChildContentAsync(); var content2 = await executionContext.GetChildContentAsync(); // Assert Assert.Equal(expectedContent, content1.GetContent()); Assert.Equal(expectedContent, content2.GetContent()); }
public async Task GetChildContentAsync_CachesValue() { // Arrange var defaultTagHelperContent = new DefaultTagHelperContent(); var content = string.Empty; var expectedContent = string.Empty; var executionContext = new TagHelperExecutionContext( "p", tagMode: TagMode.StartTagAndEndTag, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => { if (string.IsNullOrEmpty(expectedContent)) { content = "Hello from child content: " + Guid.NewGuid().ToString(); expectedContent = $"HtmlEncode[[{content}]]"; } defaultTagHelperContent.SetContent(content); return Task.FromResult(result: true); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => defaultTagHelperContent); // Act var content1 = await executionContext.GetChildContentAsync(useCachedResult: true); var content2 = await executionContext.GetChildContentAsync(useCachedResult: true); // Assert Assert.Equal(expectedContent, content1.GetContent(new HtmlTestEncoder())); Assert.Equal(expectedContent, content2.GetContent(new HtmlTestEncoder())); }
public async Task ProcessAsync_GeneratesExpectedOutput() { // Arrange var expectedTagName = "not-div"; var metadataProvider = new TestModelMetadataProvider(); var htmlGenerator = new TestableHtmlGenerator(metadataProvider); var validationSummaryTagHelper = new ValidationSummaryTagHelper(htmlGenerator) { ValidationSummary = ValidationSummary.All, }; var expectedPreContent = "original pre-content"; var expectedContent = "original 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.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput( expectedTagName, attributes: new TagHelperAttributeList { { "class", "form-control" } }); output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent("Custom Content"); Model model = null; var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); validationSummaryTagHelper.ViewContext = viewContext; // Act await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(2, output.Attributes.Count); var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("class")); Assert.Equal("form-control validation-summary-valid", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-summary")); Assert.Equal("true", attribute.Value); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal("Custom Content<ul><li style=\"display:none\"></li>" + Environment.NewLine + "</ul>", output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); }
public void CanSetContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; // Act tagHelperContent.SetContent(expected); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
public void SetContent_WithTagHelperContent_WorksAsExpected(string expected) { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var copiedTagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent(expected); // Act copiedTagHelperContent.SetContent(tagHelperContent); // Assert Assert.Equal(expected, copiedTagHelperContent.GetContent()); }
public void CanGetContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; tagHelperContent.SetContent(expected); // Act var actual = tagHelperContent.GetContent(); // Assert Assert.Equal(expected, actual); }
public void Fluent_Clear_Set_Append_WritesExpectedContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; tagHelperContent.SetContent("Some Random Content"); // Act tagHelperContent.Clear().SetContent("Hello ").Append("World!"); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
public void ToString_ReturnsExpectedValue() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; tagHelperContent.SetContent(expected); // Act var actual = tagHelperContent.ToString(); // Assert Assert.Equal(expected, actual, StringComparer.Ordinal); }
public void SetContent_WithTagHelperContent_WorksAsExpected(string expected) { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var copiedTagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent(expected); // Act copiedTagHelperContent.SetContent(tagHelperContent); // Assert Assert.Equal(expected, copiedTagHelperContent.GetContent()); }
public void IsEmpty_FalseAfterAppendTagHelper() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var copiedTagHelperContent = new DefaultTagHelperContent(); copiedTagHelperContent.SetContent("Hello"); // Act tagHelperContent.Append(copiedTagHelperContent); // Assert Assert.False(tagHelperContent.IsEmpty); }
public void WriteTo_WritesToATextWriter() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var writer = new StringWriter(); tagHelperContent.SetContent("Hello "); tagHelperContent.Append("World"); // Act tagHelperContent.WriteTo(writer, new CommonTestEncoder()); // Assert Assert.Equal("Hello World", writer.ToString()); }
public void Fluent_SetContent_AppendFormat_Append_WritesExpectedContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "First Second Third Fourth"; // Act tagHelperContent .SetContent("First ") .AppendFormat("{0} Third ", "Second") .Append("Fourth"); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
public void CanAppendDefaultTagHelperContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var helloWorldContent = new DefaultTagHelperContent(); helloWorldContent.SetContent("HelloWorld"); var expected = "Content was HelloWorld"; // Act tagHelperContent.AppendFormat("Content was {0}", helloWorldContent); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
public void Fluent_SetContent_AppendFormat_WritesExpectedContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = new[] { "First ", "Second Third" }; var i = 0; // Act tagHelperContent.SetContent("First ").AppendFormat("{0} Third", "Second"); // Assert foreach (var value in tagHelperContent) { Assert.Equal(expected[i++], value); } }
public void GetEnumerator_EnumeratesThroughBuffer() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = new string[] { "Hello", "World" }; tagHelperContent.SetContent(expected[0]); tagHelperContent.Append(expected[1]); var i = 0; // Act & Assert foreach (var val in tagHelperContent) { Assert.Equal(expected[i++], val); } }
public async Task ProcessAsync_GeneratesAntiForgeryCorrectly( bool? antiForgery, string expectedPostContent) { // Arrange var viewContext = CreateViewContext(); var context = new TagHelperContext( allAttributes: new Dictionary<string, object>(), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput( "form", attributes: new Dictionary<string, object>()); var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GenerateForm( It.IsAny<ViewContext>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(), It.IsAny<object>())) .Returns(new TagBuilder("form", new HtmlEncoder())); generator.Setup(mock => mock.GenerateAntiForgery(viewContext)) .Returns(new TagBuilder("input", new HtmlEncoder())); var formTagHelper = new FormTagHelper { Action = "Index", AntiForgery = antiForgery, Generator = generator.Object, ViewContext = viewContext, }; // Act await formTagHelper.ProcessAsync(context, output); // Assert Assert.Equal("form", output.TagName); Assert.False(output.SelfClosing); Assert.Empty(output.Attributes); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.IsEmpty); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); }
public async Task ProcessAsync_SupportsAntiForgeryIfActionIsSpecified( bool? antiForgery, string expectedPostContent) { // Arrange var viewContext = CreateViewContext(); var generator = new Mock<IHtmlGenerator>(); generator.Setup(mock => mock.GenerateAntiForgery(It.IsAny<ViewContext>())) .Returns(new TagBuilder("input", new HtmlEncoder())); var formTagHelper = new FormTagHelper { AntiForgery = antiForgery, Generator = generator.Object, ViewContext = viewContext, }; var output = new TagHelperOutput("form", attributes: new Dictionary<string, object> { { "aCTiON", "my-action" }, }); var context = new TagHelperContext( allAttributes: new Dictionary<string, object>(), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); // Act await formTagHelper.ProcessAsync(context, output); // Assert Assert.Equal("form", output.TagName); Assert.False(output.SelfClosing); var attribute = Assert.Single(output.Attributes); Assert.Equal(new KeyValuePair<string, object>("aCTiON", "my-action"), attribute); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.IsEmpty); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); }
public async Task ProcessAsync_CallsIntoGenerateFormWithExpectedParameters() { // Arrange var viewContext = CreateViewContext(); var context = new TagHelperContext( allAttributes: new Dictionary<string, object>(), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput( "form", attributes: new Dictionary<string, object>()); var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GenerateForm(viewContext, "Index", "Home", null, null, null)) .Returns(new TagBuilder("form", new HtmlEncoder())) .Verifiable(); var formTagHelper = new FormTagHelper { Action = "Index", AntiForgery = false, Controller = "Home", Generator = generator.Object, ViewContext = viewContext, }; // Act & Assert await formTagHelper.ProcessAsync(context, output); generator.Verify(); Assert.Equal("form", output.TagName); Assert.False(output.SelfClosing); Assert.Empty(output.Attributes); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.IsEmpty); Assert.Empty(output.PostContent.GetContent()); }
public async Task ProcessAsync_GeneratesExpectedOutput() { // Arrange var expectedTagName = "not-form"; var metadataProvider = new TestModelMetadataProvider(); var tagHelperContext = new TagHelperContext( allAttributes: new Dictionary<string, object> { { "id", "myform" }, { "asp-route-foo", "bar" }, { "asp-action", "index" }, { "asp-controller", "home" }, { "method", "post" }, { "asp-anti-forgery", true } }, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something Else"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput( expectedTagName, attributes: new Dictionary<string, object> { { "id", "myform" }, { "asp-route-foo", "bar" }, }); output.PostContent.SetContent("Something"); var urlHelper = new Mock<IUrlHelper>(); urlHelper .Setup(mock => mock.Action(It.IsAny<UrlActionContext>())).Returns("home/index"); var htmlGenerator = new TestableHtmlGenerator(metadataProvider, urlHelper.Object); var viewContext = TestableHtmlGenerator.GetViewContext(model: null, htmlGenerator: htmlGenerator, metadataProvider: metadataProvider); var expectedPostContent = "Something" + htmlGenerator.GenerateAntiForgery(viewContext) .ToString(TagRenderMode.SelfClosing); var formTagHelper = new FormTagHelper { Action = "index", AntiForgery = true, Controller = "home", Generator = htmlGenerator, ViewContext = viewContext, }; // Act await formTagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(3, output.Attributes.Count); var attribute = Assert.Single(output.Attributes, kvp => kvp.Key.Equals("id")); Assert.Equal("myform", attribute.Value); attribute = Assert.Single(output.Attributes, kvp => kvp.Key.Equals("method")); Assert.Equal("post", attribute.Value); attribute = Assert.Single(output.Attributes, kvp => kvp.Key.Equals("action")); Assert.Equal("home/index", attribute.Value); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.IsEmpty); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); }
public async Task ProcessAsync_BindsRouteValuesFromTagHelperOutput() { // Arrange var testViewContext = CreateViewContext(); var context = new TagHelperContext( allAttributes: new Dictionary<string, object>(), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var expectedAttribute = new KeyValuePair<string, object>("asp-ROUTEE-NotRoute", "something"); var output = new TagHelperOutput( "form", attributes: new Dictionary<string, object>() { { "asp-route-val", "hello" }, { "asp-roUte--Foo", "bar" } }); output.Attributes.Add(expectedAttribute); var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GenerateForm( It.IsAny<ViewContext>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object>(), It.IsAny<string>(), It.IsAny<object>())) .Callback<ViewContext, string, string, object, string, object>( (viewContext, actionName, controllerName, routeValues, method, htmlAttributes) => { // Fixes Roslyn bug with lambdas generator.ToString(); var routeValueDictionary = (Dictionary<string, object>)routeValues; Assert.Equal(2, routeValueDictionary.Count); var routeValue = Assert.Single(routeValueDictionary, kvp => kvp.Key.Equals("val")); Assert.Equal("hello", routeValue.Value); routeValue = Assert.Single(routeValueDictionary, kvp => kvp.Key.Equals("-Foo")); Assert.Equal("bar", routeValue.Value); }) .Returns(new TagBuilder("form", new HtmlEncoder())) .Verifiable(); var formTagHelper = new FormTagHelper { Action = "Index", AntiForgery = false, Generator = generator.Object, ViewContext = testViewContext, }; // Act & Assert await formTagHelper.ProcessAsync(context, output); Assert.Equal("form", output.TagName); Assert.False(output.SelfClosing); var attribute = Assert.Single(output.Attributes); Assert.Equal(expectedAttribute, attribute); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.IsEmpty); Assert.Empty(output.PostContent.GetContent()); generator.Verify(); }
public async Task TagHelper_CallsGeneratorWithExpectedValues_RealModelType( Type modelType, object model, bool allowMultiple) { // Arrange var contextAttributes = new Dictionary<string, object>(); var originalAttributes = new Dictionary<string, object>(); var propertyName = "Property1"; var tagName = "select"; var tagHelperContext = new TagHelperContext( contextAttributes, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput(tagName, originalAttributes); var metadataProvider = new EmptyModelMetadataProvider(); var modelExplorer = metadataProvider.GetModelExplorerForType(modelType, model); var modelExpression = new ModelExpression(propertyName, modelExplorer); var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict); var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator.Object, metadataProvider); var currentValues = new string[0]; htmlGenerator .Setup(real => real.GetCurrentValues( viewContext, modelExplorer, propertyName, // expression allowMultiple)) .Returns(currentValues) .Verifiable(); htmlGenerator .Setup(real => real.GenerateSelect( viewContext, modelExplorer, null, // optionLabel propertyName, // expression It.IsAny<IEnumerable<SelectListItem>>(), currentValues, allowMultiple, null)) // htmlAttributes .Returns((TagBuilder)null) .Verifiable(); var tagHelper = new SelectTagHelper { For = modelExpression, Generator = htmlGenerator.Object, ViewContext = viewContext, }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert htmlGenerator.Verify(); Assert.NotNull(viewContext.FormContext?.FormData); var keyValuePair = Assert.Single( viewContext.FormContext.FormData, entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey); Assert.Same(currentValues, keyValuePair.Value); }
public void Fluent_Clear_Set_Append_WritesExpectedContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; tagHelperContent.SetContent("Some Random Content"); // Act tagHelperContent.Clear().SetContent("Hello ").Append("World!"); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
public async Task ProcessAsyncInTemplate_WithItems_GeneratesExpectedOutput_DoesNotChangeSelectList( object model, Type containerType, Func<object> modelAccessor, NameAndId nameAndId, string expectedOptions) { // Arrange var originalAttributes = new Dictionary<string, object> { { "class", "form-control" }, }; var originalPostContent = "original content"; var expectedAttributes = new Dictionary<string, object>(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 Dictionary<string, object>(), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput(expectedTagName, originalAttributes) { SelfClosing = true }; output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent(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 { For = modelExpression, Generator = htmlGenerator, Items = items, ViewContext = viewContext, }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.True(output.SelfClosing); Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); 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)); }
public async Task ProcessAsync_GeneratesExpectedOutput( object model, Type containerType, Func<object> modelAccessor, NameAndId nameAndId, string ignored) { // Arrange var originalAttributes = new Dictionary<string, object> { { "class", "form-control" }, }; var originalPostContent = "original content"; var expectedAttributes = new Dictionary<string, object>(originalAttributes) { { "id", nameAndId.Id }, { "name", nameAndId.Name }, { "valid", "from validation attributes" }, }; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = originalPostContent; var expectedTagName = "not-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(nameAndId.Name, modelExplorer); var tagHelperContext = new TagHelperContext( allAttributes: new Dictionary<string, object>(), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput(expectedTagName, originalAttributes) { SelfClosing = true, }; output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent(originalPostContent); var htmlGenerator = new TestableHtmlGenerator(metadataProvider) { ValidationAttributes = { { "valid", "from validation attributes" }, } }; var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); var tagHelper = new SelectTagHelper { For = modelExpression, Generator = htmlGenerator, ViewContext = viewContext, }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.True(output.SelfClosing); Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); Assert.NotNull(viewContext.FormContext?.FormData); Assert.Single( viewContext.FormContext.FormData, entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey); }
public async Task ProcessAsync_GeneratesExpectedOutput() { // Arrange var expectedTagName = "not-span"; var metadataProvider = new TestModelMetadataProvider(); var modelExpression = CreateModelExpression("Name"); var htmlGenerator = new TestableHtmlGenerator(metadataProvider); var validationMessageTagHelper = new ValidationMessageTagHelper(htmlGenerator) { For = modelExpression }; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = "original post-content"; var tagHelperContext = new TagHelperContext( allAttributes: new TagHelperAttributeList { { "id", "myvalidationmessage" }, { "for", modelExpression }, }, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput( expectedTagName, attributes: new TagHelperAttributeList { { "id", "myvalidationmessage" } }); output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent(expectedPostContent); var viewContext = TestableHtmlGenerator.GetViewContext(model: null, htmlGenerator: htmlGenerator, metadataProvider: metadataProvider); validationMessageTagHelper.ViewContext = viewContext; // Act await validationMessageTagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(4, output.Attributes.Count); var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("id")); Assert.Equal("myvalidationmessage", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("class")); Assert.Equal("field-validation-valid", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-for")); Assert.Equal("Name", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-replace")); Assert.Equal("true", attribute.Value); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); }
public async Task ProcessAsync_DoesNotUseGenerator_IfSelectedNullOrNoSelectedValues( string originalContent, string selected, string value, IEnumerable<string> selectedValues, TagHelperOutput ignored) { // Arrange var originalAttributes = new TagHelperAttributeList { { "label", "my-label" }, { "selected", selected }, }; var originalTagName = "not-option"; var contextAttributes = new TagHelperAttributeList { { "label", "my-label" }, { "selected", selected }, { "value", value }, }; var originalPreContent = "original pre-content"; var originalPostContent = "original post-content"; var tagHelperContext = new TagHelperContext( contextAttributes, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent(originalContent); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput(originalTagName, originalAttributes) { TagMode = TagMode.StartTagAndEndTag, }; output.PreContent.SetContent(originalPreContent); output.Content.SetContent(originalContent); output.PostContent.SetContent(originalPostContent); var metadataProvider = new EmptyModelMetadataProvider(); var htmlGenerator = new TestableHtmlGenerator(metadataProvider); var viewContext = TestableHtmlGenerator.GetViewContext( model: null, htmlGenerator: htmlGenerator, metadataProvider: metadataProvider); viewContext.FormContext.FormData[SelectTagHelper.SelectedValuesFormDataKey] = selectedValues; var tagHelper = new OptionTagHelper(htmlGenerator) { Value = value, ViewContext = viewContext, }; // Act & Assert (does not throw) // Tag helper would throw an NRE if it used Generator value. await tagHelper.ProcessAsync(tagHelperContext, output); }
private TagHelperContext MakeTagHelperContext( IDictionary<string, object> attributes = null, string content = null) { attributes = attributes ?? new Dictionary<string, object>(); return new TagHelperContext( attributes, items: new Dictionary<object, object>(), uniqueId: Guid.NewGuid().ToString("N"), getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent(content); return Task.FromResult<TagHelperContent>(tagHelperContent); }); }
public async Task ProcessAsync_CallsGeneratorWithExpectedValues_ItemsAndAttribute( IEnumerable<SelectListItem> inputItems, string attributeName, string attributeValue, IEnumerable<SelectListItem> expectedItems) { // Arrange var contextAttributes = new Dictionary<string, object> { // Provided for completeness. Select tag helper does not confirm AllAttributes set is consistent. { attributeName, attributeValue }, }; var originalAttributes = new Dictionary<string, object> { { attributeName, attributeValue }, }; var propertyName = "Property1"; var expectedTagName = "select"; var tagHelperContext = new TagHelperContext( contextAttributes, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput(expectedTagName, originalAttributes); var metadataProvider = new EmptyModelMetadataProvider(); string model = null; var modelExplorer = metadataProvider.GetModelExplorerForType(typeof(string), model); var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict); var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator.Object, metadataProvider); // Simulate a (model => model) scenario. E.g. the calling helper may appear in a low-level template. var modelExpression = new ModelExpression(string.Empty, modelExplorer); viewContext.ViewData.TemplateInfo.HtmlFieldPrefix = propertyName; var currentValues = new string[0]; htmlGenerator .Setup(real => real.GetCurrentValues( viewContext, modelExplorer, string.Empty, // expression false)) // allowMultiple .Returns(currentValues) .Verifiable(); htmlGenerator .Setup(real => real.GenerateSelect( viewContext, modelExplorer, null, // optionLabel string.Empty, // expression expectedItems, currentValues, false, // allowMultiple null)) // htmlAttributes .Returns((TagBuilder)null) .Verifiable(); var tagHelper = new SelectTagHelper { For = modelExpression, Items = inputItems, Generator = htmlGenerator.Object, ViewContext = viewContext, }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert htmlGenerator.Verify(); Assert.NotNull(viewContext.FormContext?.FormData); var keyValuePair = Assert.Single( viewContext.FormContext.FormData, entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey); Assert.Same(currentValues, keyValuePair.Value); }
public async Task ProcessAsync_GeneratesExpectedOutput( object container, Type containerType, object model, NameAndId nameAndId, string expectedValue) { // Arrange var expectedAttributes = new TagHelperAttributeList { { "class", "form-control" }, { "type", "text" }, { "id", nameAndId.Id }, { "name", nameAndId.Name }, { "valid", "from validation attributes" }, { "value", expectedValue }, }; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = "original post-content"; var expectedTagName = "not-input"; var context = new TagHelperContext( allAttributes: new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var originalAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; var output = new TagHelperOutput(expectedTagName, originalAttributes) { TagMode = TagMode.StartTagOnly, }; output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent(expectedPostContent); var htmlGenerator = new TestableHtmlGenerator(new EmptyModelMetadataProvider()) { ValidationAttributes = { { "valid", "from validation attributes" }, } }; // Property name is either nameof(Model.Text) or nameof(NestedModel.Text). var tagHelper = GetTagHelper( htmlGenerator, container, containerType, model, propertyName: nameof(Model.Text), expressionName: nameAndId.Name); // Act await tagHelper.ProcessAsync(context, output); // Assert Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(TagMode.StartTagOnly, output.TagMode); Assert.Equal(expectedTagName, output.TagName); }
public void Fluent_SetContent_AppendFormat_Append_WritesExpectedContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = new[] { "First ", "Second Third ", "Fourth" }; var i = 0; // Act tagHelperContent .SetContent("First ") .AppendFormat("{0} Third ", "Second") .Append("Fourth"); // Assert foreach (var value in tagHelperContent) { Assert.Equal(expected[i++], value); } }
public async Task ProcessAsync_MergesTagBuilderFromGenerateValidationMessage( string childContent, string expectedOutputContent) { // Arrange var tagBuilder = new TagBuilder("span2", new CommonTestEncoder()) { InnerHtml = "New HTML" }; tagBuilder.Attributes.Add("data-foo", "bar"); tagBuilder.Attributes.Add("data-hello", "world"); var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict); var setup = generator .Setup(mock => mock.GenerateValidationMessage( It.IsAny<ViewContext>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<object>())) .Returns(tagBuilder); var validationMessageTagHelper = new ValidationMessageTagHelper(generator.Object) { For = CreateModelExpression("Hello") }; var output = new TagHelperOutput( "span", attributes: new TagHelperAttributeList()); var context = new TagHelperContext( allAttributes: new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent(childContent); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var viewContext = CreateViewContext(); validationMessageTagHelper.ViewContext = viewContext; // Act await validationMessageTagHelper.ProcessAsync(context, output: output); // Assert Assert.Equal("span", output.TagName); Assert.Equal(2, output.Attributes.Count); var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-foo")); Assert.Equal("bar", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-hello")); Assert.Equal("world", attribute.Value); Assert.Equal(expectedOutputContent, output.Content.GetContent()); }
public async Task ProcessAsync_CallsGenerateCheckBox_WithExpectedParameters() { // Arrange var originalContent = "original content"; var originalTagName = "not-input"; var expectedPreContent = "original pre-content"; var expectedContent = originalContent + "<input class=\"HtmlEncode[[form-control]]\" /><hidden />"; var expectedPostContent = "original post-content"; var context = new TagHelperContext( allAttributes: new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var originalAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; var output = new TagHelperOutput(originalTagName, originalAttributes) { TagMode = TagMode.SelfClosing, }; output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(originalContent); output.PostContent.SetContent(expectedPostContent); var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict); var tagHelper = GetTagHelper(htmlGenerator.Object, model: false, propertyName: nameof(Model.IsACar)); var tagBuilder = new TagBuilder("input") { Attributes = { { "class", "form-control" }, }, TagRenderMode = TagRenderMode.SelfClosing }; htmlGenerator .Setup(mock => mock.GenerateCheckBox( tagHelper.ViewContext, tagHelper.For.ModelExplorer, tagHelper.For.Name, null, // isChecked It.IsAny<object>())) // htmlAttributes .Returns(tagBuilder) .Verifiable(); htmlGenerator .Setup(mock => mock.GenerateHiddenForCheckbox( tagHelper.ViewContext, tagHelper.For.ModelExplorer, tagHelper.For.Name)) .Returns(new TagBuilder("hidden") { TagRenderMode = TagRenderMode.SelfClosing }) .Verifiable(); // Act await tagHelper.ProcessAsync(context, output); // Assert htmlGenerator.Verify(); Assert.Empty(output.Attributes); // Moved to Content and cleared Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, HtmlContentUtilities.HtmlContentToString(output.Content)); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(TagMode.SelfClosing, output.TagMode); Assert.Null(output.TagName); // Cleared }
public async Task ProcessAsync_CallsIntoGenerateValidationMessageWithExpectedParameters() { // Arrange var expectedViewContext = CreateViewContext(); var generator = new Mock<IHtmlGenerator>(); generator .Setup(mock => mock.GenerateValidationMessage(expectedViewContext, "Hello", null, null, null)) .Returns(new TagBuilder("span", new CommonTestEncoder())) .Verifiable(); var validationMessageTagHelper = new ValidationMessageTagHelper(generator.Object) { For = CreateModelExpression("Hello") }; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = "original post-content"; var context = new TagHelperContext( allAttributes: new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput( "span", attributes: new TagHelperAttributeList()); output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent(expectedPostContent); validationMessageTagHelper.ViewContext = expectedViewContext; // Act & Assert await validationMessageTagHelper.ProcessAsync(context, output: output); generator.Verify(); Assert.Equal("span", output.TagName); Assert.Empty(output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); }
public async Task ProcessAsync_CallsGenerateRadioButton_WithExpectedParameters( string inputTypeName, string model) { // Arrange var value = "match"; // Real generator would use this for comparison with For.Metadata.Model. var contextAttributes = new TagHelperAttributeList { { "class", "form-control" }, { "value", value }, }; if (!string.IsNullOrEmpty(inputTypeName)) { contextAttributes["type"] = inputTypeName; // Support restoration of type attribute, if any. } var expectedAttributes = new TagHelperAttributeList { { "class", "form-control radio-control" }, { "type", inputTypeName ?? "radio" }, // Generator restores type attribute; adds "radio" if none. { "value", value }, }; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = "original post-content"; var expectedTagName = "not-input"; var context = new TagHelperContext( allAttributes: contextAttributes, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var originalAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; var output = new TagHelperOutput(expectedTagName, originalAttributes) { TagMode = TagMode.StartTagOnly, }; output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent(expectedPostContent); var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict); var tagHelper = GetTagHelper(htmlGenerator.Object, model, nameof(Model.Text)); tagHelper.InputTypeName = inputTypeName; tagHelper.Value = value; var tagBuilder = new TagBuilder("input") { Attributes = { { "class", "radio-control" }, }, }; htmlGenerator .Setup(mock => mock.GenerateRadioButton( tagHelper.ViewContext, tagHelper.For.ModelExplorer, tagHelper.For.Name, value, null, // isChecked null)) // htmlAttributes .Returns(tagBuilder) .Verifiable(); // Act await tagHelper.ProcessAsync(context, output); // Assert htmlGenerator.Verify(); Assert.Equal(TagMode.StartTagOnly, output.TagMode); Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); }
private static TagHelperContext MakeTagHelperContext( TagHelperAttributeList attributes) { return new TagHelperContext( attributes, items: new Dictionary<object, object>(), uniqueId: Guid.NewGuid().ToString("N"), getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent(default(string)); return Task.FromResult<TagHelperContent>(tagHelperContent); }); }
public async Task ProcessAsync_CallsGenerateTextBox_WithExpectedParameters( string dataTypeName, string inputTypeName, string model) { // Arrange var contextAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; if (!string.IsNullOrEmpty(inputTypeName)) { contextAttributes["type"] = inputTypeName; // Support restoration of type attribute, if any. } var expectedAttributes = new TagHelperAttributeList { { "class", "form-control text-control" }, { "type", inputTypeName ?? "text" }, // Generator restores type attribute; adds "text" if none. }; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = "original post-content"; var expectedTagName = "not-input"; var context = new TagHelperContext( allAttributes: contextAttributes, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var originalAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; var output = new TagHelperOutput(expectedTagName, originalAttributes) { TagMode = TagMode.StartTagOnly, }; output.PreContent.SetContent(expectedPreContent); output.Content.SetContent(expectedContent); output.PostContent.SetContent(expectedPostContent); var metadataProvider = new TestModelMetadataProvider(); metadataProvider.ForProperty<Model>("Text").DisplayDetails(dd => dd.DataTypeName = dataTypeName); var htmlGenerator = new Mock<IHtmlGenerator>(MockBehavior.Strict); var tagHelper = GetTagHelper( htmlGenerator.Object, model, nameof(Model.Text), metadataProvider: metadataProvider); tagHelper.InputTypeName = inputTypeName; var tagBuilder = new TagBuilder("input") { Attributes = { { "class", "text-control" }, }, }; htmlGenerator .Setup(mock => mock.GenerateTextBox( tagHelper.ViewContext, tagHelper.For.ModelExplorer, tagHelper.For.Name, model, // value null, // format It.Is<Dictionary<string, object>>(m => m.ContainsKey("type")))) // htmlAttributes .Returns(tagBuilder) .Verifiable(); // Act await tagHelper.ProcessAsync(context, output); // Assert htmlGenerator.Verify(); Assert.Equal(TagMode.StartTagOnly, output.TagMode); Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent.GetContent()); Assert.Equal(expectedContent, output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); }
public async Task ProcessAsync_DoesNotUseViewContext_IfSelectedNotNull( string originalContent, string selected, string value, IEnumerable<string> ignoredValues, TagHelperOutput ignoredOutput) { // Arrange var originalAttributes = new TagHelperAttributeList { { "label", "my-label" }, { "selected", selected }, }; var originalTagName = "not-option"; var contextAttributes = new TagHelperAttributeList { { "label", "my-label" }, { "selected", selected }, { "value", value }, }; var originalPreContent = "original pre-content"; var originalPostContent = "original post-content"; var tagHelperContext = new TagHelperContext( contextAttributes, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent(originalContent); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var output = new TagHelperOutput(originalTagName, originalAttributes) { SelfClosing = false, }; output.PreContent.SetContent(originalPreContent); output.Content.SetContent(originalContent); output.PostContent.SetContent(originalPostContent); var metadataProvider = new EmptyModelMetadataProvider(); var htmlGenerator = new TestableHtmlGenerator(metadataProvider); var tagHelper = new OptionTagHelper(htmlGenerator) { Value = value, }; // Act & Assert (does not throw) // Tag helper would throw an NRE if it used ViewContext or Generator values. await tagHelper.ProcessAsync(tagHelperContext, output); }
public async Task Process_GeneratesExpectedOutput( object container, Type containerType, object model, NameAndId nameAndId, string expectedContent) { // Arrange var expectedAttributes = new TagHelperAttributeList { { "class", "form-control" }, { "id", nameAndId.Id }, { "name", nameAndId.Name }, { "valid", "from validation attributes" }, }; var expectedTagName = "not-textarea"; var metadataProvider = new TestModelMetadataProvider(); var containerMetadata = metadataProvider.GetMetadataForType(containerType); var containerExplorer = metadataProvider.GetModelExplorerForType(containerType, container); var propertyMetadata = metadataProvider.GetMetadataForProperty(containerType, "Text"); var modelExplorer = containerExplorer.GetExplorerForExpression(propertyMetadata, model); var htmlGenerator = new TestableHtmlGenerator(metadataProvider) { ValidationAttributes = { { "valid", "from validation attributes" }, } }; // Property name is either nameof(Model.Text) or nameof(NestedModel.Text). var modelExpression = new ModelExpression(nameAndId.Name, modelExplorer); var tagHelper = new TextAreaTagHelper(htmlGenerator) { For = modelExpression, }; 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.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); var htmlAttributes = new TagHelperAttributeList { { "class", "form-control" }, }; var output = new TagHelperOutput(expectedTagName, htmlAttributes) { TagMode = TagMode.SelfClosing, }; output.Content.SetContent("original content"); var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); tagHelper.ViewContext = viewContext; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(TagMode.SelfClosing, output.TagMode); Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedContent, HtmlContentUtilities.HtmlContentToString(output.Content)); Assert.Equal(expectedTagName, output.TagName); }