public async Task ProcessAsync_Throws_IfMultipleInvalid(string multiple) { // Arrange var contextAttributes = new Dictionary <string, object>(); var originalAttributes = new Dictionary <string, string>(); var content = "original content"; var expectedTagName = "select"; var expectedMessage = "Cannot parse 'multiple' value '" + multiple + "' for <select>. Acceptable values are 'false', 'true' and 'multiple'."; var tagHelperContext = new TagHelperContext(contextAttributes); var output = new TagHelperOutput(expectedTagName, originalAttributes, content); var metadataProvider = new EmptyModelMetadataProvider(); string model = null; var metadata = metadataProvider.GetMetadataForType(() => model, typeof(string)); var modelExpression = new ModelExpression("Property1", metadata); var tagHelper = new SelectTagHelper { For = modelExpression, Multiple = multiple, }; // Act & Assert var exception = await Assert.ThrowsAsync <InvalidOperationException>( () => tagHelper.ProcessAsync(tagHelperContext, output)); Assert.Equal(expectedMessage, exception.Message); }
public async Task ProcessAsync_GeneratesExpectedOutput( object model, Type containerType, Func <object> modelAccessor, NameAndId nameAndId, string ignored) { // Arrange var originalAttributes = new Dictionary <string, string> { { "class", "form-control" }, }; var originalContent = "original content"; var originalTagName = "not-select"; var expectedAttributes = new Dictionary <string, string>(originalAttributes) { { "id", nameAndId.Id }, { "name", nameAndId.Name }, { "valid", "from validation attributes" }, }; var expectedContent = originalContent; var expectedTagName = "select"; var metadataProvider = new DataAnnotationsModelMetadataProvider(); // Property name is either nameof(Model.Text) or nameof(NestedModel.Text). var metadata = metadataProvider.GetMetadataForProperty(modelAccessor, containerType, propertyName: "Text"); var modelExpression = new ModelExpression(nameAndId.Name, metadata); var tagHelperContext = new TagHelperContext(new Dictionary <string, object>()); var output = new TagHelperOutput(originalTagName, originalAttributes, expectedContent) { SelfClosing = true, }; 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.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedContent, output.Content); Assert.False(output.SelfClosing); Assert.Equal(expectedTagName, output.TagName); }
public async Task ProcessAsync_CallsGeneratorWithExpectedValues_ItemsAndMultiple( IEnumerable <SelectListItem> inputItems, string multiple, IEnumerable <SelectListItem> expectedItems, bool expectedAllowMultiple) { // Arrange var contextAttributes = new Dictionary <string, object> { // Attribute will be restored if value matches "multiple". { "multiple", multiple }, }; var originalAttributes = new Dictionary <string, string>(); var content = "original content"; var propertyName = "Property1"; var tagName = "not-select"; var tagHelperContext = new TagHelperContext(contextAttributes); var output = new TagHelperOutput(tagName, originalAttributes, content); // TODO: In real (model => model) scenario, ModelExpression should have name "" and // TemplateInfo.HtmlFieldPrefix should be "Property1" but empty ModelExpression name is not currently // supported, see #1408. var metadataProvider = new EmptyModelMetadataProvider(); string model = null; var metadata = metadataProvider.GetMetadataForType(() => model, typeof(string)); var modelExpression = new ModelExpression(propertyName, metadata); var htmlGenerator = new Mock <IHtmlGenerator>(MockBehavior.Strict); var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator.Object, metadataProvider); htmlGenerator .Setup(real => real.GenerateSelect( viewContext, metadata, null, // optionLabel propertyName, // name expectedItems, expectedAllowMultiple, null)) // htmlAttributes .Returns((TagBuilder)null) .Verifiable(); var tagHelper = new SelectTagHelper { For = modelExpression, Items = inputItems, Generator = htmlGenerator.Object, Multiple = multiple, ViewContext = viewContext, }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert htmlGenerator.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, string>(); var propertyName = "Property1"; var tagName = "select"; var tagHelperContext = new TagHelperContext( contextAttributes, uniqueId: "test", getChildContentAsync: () => Task.FromResult("Something")); var output = new TagHelperOutput(tagName, originalAttributes); var metadataProvider = new EmptyModelMetadataProvider(); var metadata = metadataProvider.GetMetadataForType(() => model, modelType); var modelExpression = new ModelExpression(propertyName, metadata); var htmlGenerator = new Mock <IHtmlGenerator>(MockBehavior.Strict); var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator.Object, metadataProvider); ICollection <string> selectedValues = new string[0]; htmlGenerator .Setup(real => real.GenerateSelect( viewContext, metadata, null, // optionLabel propertyName, // name It.IsAny <IEnumerable <SelectListItem> >(), allowMultiple, null, // htmlAttributes out selectedValues)) .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(selectedValues, keyValuePair.Value); }
public async Task ProcessAsync_RestoresMultiple_IfForNotBound(string attributeName) { // Arrange var contextAttributes = new Dictionary <string, object> { { attributeName, "I'm more than one" }, }; var originalAttributes = new Dictionary <string, string> { { "class", "form-control" }, { "size", "2" }, }; var expectedAttributes = new Dictionary <string, string>(originalAttributes); expectedAttributes[attributeName] = (string)contextAttributes[attributeName]; var expectedPreContent = "original pre-content"; var expectedContent = "original content"; var expectedPostContent = "original post-content"; var expectedTagName = "select"; var tagHelperContext = new TagHelperContext( contextAttributes, uniqueId: "test", getChildContentAsync: () => Task.FromResult("Something")); var output = new TagHelperOutput(expectedTagName, originalAttributes) { PreContent = expectedPreContent, Content = expectedContent, PostContent = expectedPostContent, SelfClosing = true, }; var tagHelper = new SelectTagHelper { Multiple = "I'm more than one", }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedPreContent, output.PreContent); Assert.Equal(expectedContent, output.Content); Assert.Equal(expectedPostContent, output.PostContent); Assert.True(output.SelfClosing); Assert.Equal(expectedTagName, output.TagName); }
public async Task TagHelper_CallsGeneratorWithExpectedValues_RealModelType( Type modelType, object model, bool allowMultiple) { // Arrange var contextAttributes = new Dictionary <string, object>(); var originalAttributes = new Dictionary <string, string>(); var content = "original content"; var propertyName = "Property1"; var tagName = "not-select"; var tagHelperContext = new TagHelperContext(contextAttributes); var output = new TagHelperOutput(tagName, originalAttributes, content); var metadataProvider = new EmptyModelMetadataProvider(); var metadata = metadataProvider.GetMetadataForType(() => model, modelType); var modelExpression = new ModelExpression(propertyName, metadata); var htmlGenerator = new Mock <IHtmlGenerator>(MockBehavior.Strict); var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator.Object, metadataProvider); htmlGenerator .Setup(real => real.GenerateSelect( viewContext, metadata, null, // optionLabel propertyName, // name It.IsAny <IEnumerable <SelectListItem> >(), 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(); }
public async Task ProcessAsync_Throws_IfForNotBoundButItemsIs() { // Arrange var contextAttributes = new Dictionary <string, object>(); var originalAttributes = new Dictionary <string, string>(); var content = "original content"; var expectedTagName = "select"; var expectedMessage = "Cannot determine body for <select>. 'asp-items' must be null if 'asp-for' is null."; var tagHelperContext = new TagHelperContext(contextAttributes); var output = new TagHelperOutput(expectedTagName, originalAttributes, content); var tagHelper = new SelectTagHelper { Items = Enumerable.Empty <SelectListItem>(), }; // Act & Assert var exception = await Assert.ThrowsAsync <InvalidOperationException>( () => tagHelper.ProcessAsync(tagHelperContext, output)); Assert.Equal(expectedMessage, exception.Message); }
public async Task ProcessAsync_RestoresMultiple_IfForNotBound(string attributeName) { // Arrange var contextAttributes = new Dictionary <string, object> { { attributeName, "I'm more than one" }, }; var originalAttributes = new Dictionary <string, string> { { "class", "form-control" }, { "size", "2" }, }; var expectedAttributes = new Dictionary <string, string>(originalAttributes); expectedAttributes[attributeName] = (string)contextAttributes[attributeName]; var expectedContent = "original content"; var expectedTagName = "not-select"; var tagHelperContext = new TagHelperContext(contextAttributes); var output = new TagHelperOutput(expectedTagName, originalAttributes, expectedContent) { SelfClosing = true, }; var tagHelper = new SelectTagHelper { Multiple = "I'm more than one", }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedContent, output.Content); Assert.True(output.SelfClosing); Assert.Equal(expectedTagName, output.TagName); }
public async Task ProcessAsync_CallsGeneratorWithExpectedValues_ItemsAndAttribute( IEnumerable <SelectListItem> inputItems, string attributeName, string attributeValue, IEnumerable <SelectListItem> expectedItems) { // Arrange var contextAttributes = new TagHelperAttributeList { // Provided for completeness. Select tag helper does not confirm AllAttributes set is consistent. { attributeName, attributeValue }, }; var originalAttributes = new TagHelperAttributeList { { attributeName, attributeValue }, }; var propertyName = "Property1"; var expectedTagName = "select"; var tagHelperContext = new TagHelperContext( contextAttributes, items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, originalAttributes, getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); 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(htmlGenerator.Object) { For = modelExpression, Items = inputItems, ViewContext = viewContext, }; // Act tagHelper.Init(tagHelperContext); await tagHelper.ProcessAsync(tagHelperContext, output); // Assert htmlGenerator.Verify(); var keyValuePair = Assert.Single( tagHelperContext.Items, entry => (Type)entry.Key == typeof(SelectTagHelper)); Assert.Same(currentValues, keyValuePair.Value); }
public async Task ProcessAsync_GeneratesExpectedOutput_WithItems( object model, Type containerType, Func <object> modelAccessor, NameAndId nameAndId, string expectedOptions) { // Arrange var originalAttributes = new Dictionary <string, string> { { "class", "form-control" }, }; var originalContent = "original content"; var expectedAttributes = new Dictionary <string, string>(originalAttributes) { { "id", nameAndId.Id }, { "name", nameAndId.Name }, { "valid", "from validation attributes" }, }; var expectedContent = originalContent + expectedOptions; var expectedTagName = "select"; var metadataProvider = new DataAnnotationsModelMetadataProvider(); // Property name is either nameof(Model.Text) or nameof(NestedModel.Text). var metadata = metadataProvider.GetMetadataForProperty(modelAccessor, containerType, propertyName: "Text"); var modelExpression = new ModelExpression(nameAndId.Name, metadata); var tagHelperContext = new TagHelperContext(new Dictionary <string, object>()); var output = new TagHelperOutput(expectedTagName, originalAttributes, originalContent) { SelfClosing = true, }; var items = new SelectList(new[] { "", "outer text", "inner text", "other text" }); 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, Items = items, ViewContext = viewContext, }; // Act await tagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(expectedAttributes, output.Attributes); Assert.Equal(expectedContent, output.Content); Assert.False(output.SelfClosing); Assert.Equal(expectedTagName, output.TagName); Assert.NotNull(viewContext.FormContext?.FormData); var keyValuePair = Assert.Single( viewContext.FormContext.FormData, entry => entry.Key == SelectTagHelper.SelectedValuesFormDataKey); Assert.NotNull(keyValuePair.Value); var selectedValues = Assert.IsAssignableFrom <ICollection <string> >(keyValuePair.Value); Assert.InRange(selectedValues.Count, 0, 1); }
public async Task ProcessAsync_GeneratesExpectedOutput( object model, Type containerType, Func<object> modelAccessor, NameAndId nameAndId, string ignored) { // 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; 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 ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, originalAttributes, getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }) { TagMode = TagMode.SelfClosing, }; 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(htmlGenerator) { For = modelExpression, ViewContext = viewContext, }; // Act tagHelper.Init(tagHelperContext); 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, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); Assert.Single( tagHelperContext.Items, entry => (Type)entry.Key == typeof(SelectTagHelper)); }
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 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 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"); var output = new TagHelperOutput( expectedTagName, originalAttributes, getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.AppendHtml("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }) { TagMode = TagMode.SelfClosing, }; output.PreContent.AppendHtml(expectedPreContent); output.Content.AppendHtml(expectedContent); output.PostContent.AppendHtml(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 tagHelper.Init(tagHelperContext); 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.Single( tagHelperContext.Items, entry => (Type)entry.Key == typeof(SelectTagHelper)); 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 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; 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 ReadOnlyTagHelperAttributeList <IReadOnlyTagHelperAttribute>( Enumerable.Empty <IReadOnlyTagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, originalAttributes, getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }) { TagMode = TagMode.SelfClosing, }; 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(htmlGenerator) { For = modelExpression, ViewContext = viewContext, }; // Act tagHelper.Init(tagHelperContext); 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, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); Assert.Single( tagHelperContext.Items, entry => (Type)entry.Key == typeof(SelectTagHelper)); }
public async Task ProcessAsync_CallsGeneratorWithExpectedValues_ItemsAndMultiple( IEnumerable <SelectListItem> inputItems, string multiple, IEnumerable <SelectListItem> expectedItems, bool expectedAllowMultiple) { // Arrange var contextAttributes = new Dictionary <string, object> { // Attribute will be restored if value matches "multiple". { "multiple", multiple }, }; var originalAttributes = new Dictionary <string, string>(); var propertyName = "Property1"; var expectedTagName = "select"; var tagHelperContext = new TagHelperContext( contextAttributes, uniqueId: "test", getChildContentAsync: () => Task.FromResult("Something")); var output = new TagHelperOutput(expectedTagName, originalAttributes); var metadataProvider = new EmptyModelMetadataProvider(); string model = null; var metadata = metadataProvider.GetMetadataForType(() => model, typeof(string)); 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, metadata); viewContext.ViewData.TemplateInfo.HtmlFieldPrefix = propertyName; ICollection <string> selectedValues = new string[0]; htmlGenerator .Setup(real => real.GenerateSelect( viewContext, metadata, null, // optionLabel string.Empty, // name expectedItems, expectedAllowMultiple, null, // htmlAttributes out selectedValues)) .Returns((TagBuilder)null) .Verifiable(); var tagHelper = new SelectTagHelper { For = modelExpression, Items = inputItems, Generator = htmlGenerator.Object, Multiple = multiple, 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(selectedValues, keyValuePair.Value); }
public async Task ProcessAsync_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(nameAndId.Name, modelExplorer); var tagHelperContext = new TagHelperContext( allAttributes: new ReadOnlyTagHelperAttributeList<IReadOnlyTagHelperAttribute>( Enumerable.Empty<IReadOnlyTagHelperAttribute>()), items: new Dictionary<object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, originalAttributes, getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.AppendHtml("Something"); return Task.FromResult<TagHelperContent>(tagHelperContent); }) { TagMode = TagMode.SelfClosing, }; output.PreContent.AppendHtml(expectedPreContent); output.Content.AppendHtml(expectedContent); output.PostContent.AppendHtml(originalPostContent); var htmlGenerator = new TestableHtmlGenerator(metadataProvider) { ValidationAttributes = { { "valid", "from validation attributes" }, } }; var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider); 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 tagHelper.Init(tagHelperContext); 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.Single( tagHelperContext.Items, entry => (Type)entry.Key == typeof(SelectTagHelper)); 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 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 TagHelper_CallsGeneratorWithExpectedValues_RealModelType( Type modelType, object model, bool allowMultiple) { // Arrange var contextAttributes = new ReadOnlyTagHelperAttributeList <IReadOnlyTagHelperAttribute>( Enumerable.Empty <IReadOnlyTagHelperAttribute>()); var originalAttributes = new TagHelperAttributeList(); var propertyName = "Property1"; var tagName = "select"; var tagHelperContext = new TagHelperContext( contextAttributes, items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( tagName, originalAttributes, getChildContentAsync: useCachedResult => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); 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(htmlGenerator.Object) { For = modelExpression, ViewContext = viewContext, }; // Act tagHelper.Init(tagHelperContext); await tagHelper.ProcessAsync(tagHelperContext, output); // Assert htmlGenerator.Verify(); var keyValuePair = Assert.Single( tagHelperContext.Items, entry => (Type)entry.Key == typeof(SelectTagHelper)); Assert.Same(currentValues, keyValuePair.Value); }
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 async Task ProcessAsync_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(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 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)); }