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 void CopyHtmlAttribute_DoesNotOverrideAttributes() { // Arrange var attributeName = "hello"; var tagHelperOutput = new TagHelperOutput( "p", attributes: new Dictionary<string, object>() { { attributeName, "world2" } }); var expectedAttribute = new KeyValuePair<string, object>(attributeName, "world2"); var tagHelperContext = new TagHelperContext( allAttributes: new Dictionary<string, object>(StringComparer.Ordinal) { { attributeName, "world" } }, items: new Dictionary<object, object>(), uniqueId: "test", getChildContentAsync: () => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.Append("Something Else"); return Task.FromResult<TagHelperContent>(tagHelperContent); }); // Act tagHelperOutput.CopyHtmlAttribute(attributeName, tagHelperContext); // Assert var attribute = Assert.Single(tagHelperOutput.Attributes); Assert.Equal(expectedAttribute, attribute); }
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 CommonTestEncoder())); Assert.Equal(expectedContent, content2.GetContent(new CommonTestEncoder())); }
/// <summary> /// Instantiates a new instance of <see cref="TagHelperOutput"/>. /// </summary> /// <param name="tagName">The HTML element's tag name.</param> /// <param name="attributes">The HTML attributes.</param> public TagHelperOutput( string tagName, [NotNull] IDictionary<string, object> attributes) { TagName = tagName; Attributes = new Dictionary<string, object>(attributes, StringComparer.OrdinalIgnoreCase); _preContent = new DefaultTagHelperContent(); _content = new DefaultTagHelperContent(); _postContent = new DefaultTagHelperContent(); }
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 CanAppendContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; // Act tagHelperContent.Append(expected); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
public void CanAppendContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "HtmlEncode[[Hello World!]]"; // Act tagHelperContent.Append("Hello World!"); // Assert Assert.Equal(expected, tagHelperContent.GetContent(new CommonTestEncoder())); }
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 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 SetContentClearsExistingContent() { // Arrange var tagHelperContent = new DefaultTagHelperContent(); var expected = "Hello World!"; tagHelperContent.SetContent("Contoso"); // Act tagHelperContent.SetContent(expected); // Assert Assert.Equal(expected, tagHelperContent.GetContent()); }
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 override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) { if (ShowDismiss) { output.PreContent.AppendFormat(@"<button type='button' class='btn btn-default' data-dismiss='modal'>{0}</button>", DismissText); } var childContent = await context.GetChildContentAsync(); var footerContent = new DefaultTagHelperContent(); if (ShowDismiss) { footerContent.AppendFormat(@"<button type='button' class='btn btn-default' data-dismiss='modal'>{0}</button>", DismissText); } footerContent.Append(childContent); var modalContext = (ModalContext)context.Items[typeof(ModalTagHelper)]; modalContext.Footer = footerContent; output.SuppressOutput(); }
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_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_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_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_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 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 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_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 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_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 GetChildContentAsync_ReturnsNewObjectEveryTimeItIsCalled() { // Arrange var defaultTagHelperContent = new DefaultTagHelperContent(); var executionContext = new TagHelperExecutionContext( "p", selfClosing: false, items: null, uniqueId: string.Empty, executeChildContentAsync: () => { return Task.FromResult(result: true); }, startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => defaultTagHelperContent); // Act var content1 = await executionContext.GetChildContentAsync(); content1.Append("Hello"); var content2 = await executionContext.GetChildContentAsync(); content2.Append("World!"); // Assert Assert.NotSame(content1, content2); Assert.Empty((await executionContext.GetChildContentAsync()).GetContent()); }
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); }
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_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_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 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()); }