public async Task ProcessAsync_ThrowsIfActionAndPageProvided() { // Arrange var formTagHelper = new FormTagHelper(new TestableHtmlGenerator(new EmptyModelMetadataProvider())) { Action = "Default", Page = "Page", }; var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => Task.FromResult <TagHelperContent>(null)); var expectedErrorMessage = string.Join( Environment.NewLine, "Cannot determine the 'action' attribute for <form>. The following attributes are mutually exclusive:", "asp-route", "asp-controller, asp-action", "asp-page"); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); // Act & Assert var ex = await Assert.ThrowsAsync <InvalidOperationException>( () => formTagHelper.ProcessAsync(context, output)); Assert.Equal(expectedErrorMessage, ex.Message); }
public async Task ProcessAsync_WithPageAndArea_InvokesGeneratePageForm() { // Arrange var viewContext = CreateViewContext(); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); var generator = new Mock <IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GeneratePageForm( viewContext, "/Home/Admin/Post", "page-handler", It.IsAny <object>(), "hello-world", null, null)) .Callback((ViewContext _, string pageName, string pageHandler, object routeValues, string fragment, string method, object htmlAttributes) => { var rvd = Assert.IsType <RouteValueDictionary>(routeValues); Assert.Collection( rvd.OrderBy(item => item.Key), item => { Assert.Equal("area", item.Key); Assert.Equal("test-area", item.Value); }); }) .Returns(new TagBuilder("form")) .Verifiable(); var formTagHelper = new FormTagHelper(generator.Object) { Antiforgery = false, ViewContext = viewContext, Page = "/Home/Admin/Post", PageHandler = "page-handler", Fragment = "hello-world", Area = "test-area", }; // Act & Assert await formTagHelper.ProcessAsync(context, output); generator.Verify(); }
public async Task ProcessAsync_EmptyStringOnAspAreaIsPassedThroughToRouteValues() { // Arrange var viewContext = CreateViewContext(); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); var expectedRouteValues = new Dictionary <string, object> { { "area", string.Empty } }; var generator = new Mock <IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GenerateForm( viewContext, "Index", "Home", expectedRouteValues, null, null)) .Returns(new TagBuilder("form")) .Verifiable(); var formTagHelper = new FormTagHelper(generator.Object) { Action = "Index", Antiforgery = false, Controller = "Home", Area = string.Empty, ViewContext = viewContext, }; // Act await formTagHelper.ProcessAsync(context, output); // Assert generator.Verify(); Assert.Equal("form", output.TagName); Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode); Assert.Empty(output.Attributes); Assert.Empty(output.PreElement.GetContent()); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.GetContent().Length == 0); Assert.Empty(output.PostContent.GetContent()); }
public async Task ProcessAsync_EmptyStringActionGeneratesAntiforgery() { // Arrange var expectedTagName = "form"; var metadataProvider = new TestModelMetadataProvider(); var tagHelperContext = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList() { { "method", new HtmlString("post") } }, items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, attributes: new TagHelperAttributeList() { { "action", string.Empty }, }, getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); 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 = HtmlContentUtilities.HtmlContentToString( htmlGenerator.GenerateAntiforgery(viewContext), HtmlEncoder.Default); var formTagHelper = new FormTagHelper(htmlGenerator) { ViewContext = viewContext, Method = "post", }; // Act await formTagHelper.ProcessAsync(tagHelperContext, output); // Assert var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("action")); Assert.Equal(string.Empty, attribute.Value); Assert.Empty(output.PreElement.GetContent()); Assert.Empty(output.PreContent.GetContent()); Assert.Empty(output.Content.GetContent()); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Empty(output.PostElement.GetContent()); Assert.Equal(expectedTagName, output.TagName); }
public async Task ProcessAsync_GeneratesAntiforgeryCorrectly( bool?antiforgery, FormMethod method, string expectedPostContent) { // Arrange var viewContext = CreateViewContext(); var expectedAttribute = new TagHelperAttribute("method", method.ToString().ToLowerInvariant()); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList(new[] { expectedAttribute }), items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); 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")); generator.Setup(mock => mock.GenerateAntiforgery(viewContext)) .Returns(new HtmlString("<input />")); var formTagHelper = new FormTagHelper(generator.Object) { Action = "Index", Antiforgery = antiforgery, ViewContext = viewContext, Method = method.ToString().ToLowerInvariant() }; // Act await formTagHelper.ProcessAsync(context, output); // Assert Assert.Equal("form", output.TagName); Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode); var attribute = Assert.Single(output.Attributes); Assert.Equal(expectedAttribute, attribute); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.GetContent().Length == 0); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); }
public async Task ProcessAsync_CallsIntoGenerateRouteFormWithExpectedParameters() { // Arrange var viewContext = CreateViewContext(); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); var generator = new Mock <IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GenerateRouteForm( viewContext, "Default", It.Is <RouteValueDictionary>(m => string.Equals(m["name"], "value")), null, null)) .Returns(new TagBuilder("form")) .Verifiable(); var formTagHelper = new FormTagHelper(generator.Object) { Antiforgery = false, Route = "Default", ViewContext = viewContext, RouteValues = { { "name", "value" }, }, }; // Act & Assert await formTagHelper.ProcessAsync(context, output); generator.Verify(); Assert.Equal("form", output.TagName); Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode); Assert.Empty(output.Attributes); Assert.Empty(output.PreElement.GetContent()); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.GetContent().Length == 0); Assert.Empty(output.PostContent.GetContent()); Assert.Empty(output.PostElement.GetContent()); }
public async Task ProcessAsync_AspAntiforgeryAloneGeneratesProperFormTag() { // Arrange var expectedTagName = "form"; var metadataProvider = new TestModelMetadataProvider(); var tagHelperContext = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList() { { "asp-antiforgery", true } }, items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); var urlHelper = new Mock <IUrlHelper>(); var htmlGenerator = new TestableHtmlGenerator(metadataProvider, urlHelper.Object); var viewContext = TestableHtmlGenerator.GetViewContext( model: null, htmlGenerator: htmlGenerator, metadataProvider: metadataProvider); viewContext.HttpContext.Request.Path = "/home/index"; var expectedPostContent = HtmlContentUtilities.HtmlContentToString( htmlGenerator.GenerateAntiforgery(viewContext), HtmlEncoder.Default); var formTagHelper = new FormTagHelper(htmlGenerator) { ViewContext = viewContext, Antiforgery = true, }; // Act await formTagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(2, output.Attributes.Count); var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("method")); Assert.Equal("post", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("action")); Assert.Equal("/home/index", attribute.Value); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.GetContent().Length == 0); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); }
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 HtmlString("<input />")); var formTagHelper = new FormTagHelper(generator.Object) { Antiforgery = antiforgery, ViewContext = viewContext, }; var output = new TagHelperOutput( tagName: "form", attributes: new TagHelperAttributeList { { "aCTiON", "my-action" }, }, getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); // Act await formTagHelper.ProcessAsync(context, output); // Assert Assert.Equal("form", output.TagName); Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode); var attribute = Assert.Single(output.Attributes); Assert.Equal(new TagHelperAttribute("aCTiON", "my-action"), attribute); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.GetContent().Length == 0); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); }
public async Task ProcessAsync_InvokesGeneratePageForm_WithOnlyPageHandler() { // Arrange var viewContext = CreateViewContext(); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList() { { "asp-handler", "page-handler" }, { "method", "get" } }, items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); var generator = new Mock <IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GeneratePageForm( viewContext, null, "page-handler", null, null, null, null)) .Returns(new TagBuilder("form")) .Verifiable(); var formTagHelper = new FormTagHelper(generator.Object) { ViewContext = viewContext, PageHandler = "page-handler", Method = "get" }; // Act & Assert await formTagHelper.ProcessAsync(context, output); generator.Verify(); }
public async Task ProcessAsync_InvokesGeneratePageForm() { // Arrange var viewContext = CreateViewContext(); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); var generator = new Mock <IHtmlGenerator>(MockBehavior.Strict); generator .Setup(mock => mock.GeneratePageForm( viewContext, "/Home/Admin/Post", "page-handler", null, "hello-world", null, null)) .Returns(new TagBuilder("form")) .Verifiable(); var formTagHelper = new FormTagHelper(generator.Object) { Antiforgery = false, ViewContext = viewContext, Page = "/Home/Admin/Post", PageHandler = "page-handler", Fragment = "hello-world", }; // Act & Assert await formTagHelper.ProcessAsync(context, output); generator.Verify(); }
public async Task ProcessAsync_ThrowsIfActionConflictsWithBoundAttributes(string propertyName) { // Arrange var formTagHelper = new FormTagHelper(new TestableHtmlGenerator(new EmptyModelMetadataProvider())); var tagHelperOutput = new TagHelperOutput( "form", attributes: new TagHelperAttributeList { { "action", "my-action" }, }, getChildContentAsync: (useCachedResult, encoder) => Task.FromResult <TagHelperContent>(null)); if (propertyName == "asp-route-") { formTagHelper.RouteValues.Add("name", "value"); } else { typeof(FormTagHelper).GetProperty(propertyName).SetValue(formTagHelper, "Home"); } var expectedErrorMessage = "Cannot override the 'action' attribute for <form>. A <form> with a specified " + "'action' must not have attributes starting with 'asp-route-' or an " + "'asp-action', 'asp-controller', 'asp-fragment', 'asp-area', 'asp-route', 'asp-page' or 'asp-page-handler' attribute."; var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); // Act & Assert var ex = await Assert.ThrowsAsync <InvalidOperationException>( () => formTagHelper.ProcessAsync(context, tagHelperOutput)); Assert.Equal(expectedErrorMessage, ex.Message); }
public async Task ProcessAsync_AspFragmentAddsFragmentToAction() { // Arrange var expectedTagName = "form"; var metadataProvider = new TestModelMetadataProvider(); var tagHelperContext = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList { { "id", "myform" }, { "asp-route-name", "value" }, { "asp-action", "index" }, { "asp-controller", "home" }, { "asp-fragment", "test" }, { "method", "post" }, { "asp-antiforgery", true } }, items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, attributes: new TagHelperAttributeList { { "id", "myform" }, }, getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); 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 formTagHelper = new FormTagHelper(htmlGenerator) { Action = "index", Antiforgery = true, Controller = "home", Fragment = "test", ViewContext = viewContext, RouteValues = { { "name", "value" }, }, }; // Act await formTagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal("form", output.TagName); Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode); var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("action")); Assert.Equal("home/index#test", attribute.Value); }
public async Task ProcessAsync_BindsRouteValues() { // Arrange var testViewContext = CreateViewContext(); var context = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList( Enumerable.Empty <TagHelperAttribute>()), items: new Dictionary <object, object>(), uniqueId: "test"); var expectedAttribute = new TagHelperAttribute("asp-ROUTEE-NotRoute", "something"); var output = new TagHelperOutput( "form", attributes: new TagHelperAttributeList(), getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); 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 = Assert.IsType <RouteValueDictionary>(routeValues); Assert.Equal(2, routeValueDictionary.Count); var routeValue = Assert.Single(routeValueDictionary, attr => attr.Key.Equals("val")); Assert.Equal("hello", routeValue.Value); routeValue = Assert.Single(routeValueDictionary, attr => attr.Key.Equals("-Name")); Assert.Equal("Value", routeValue.Value); }) .Returns(new TagBuilder("form")) .Verifiable(); var formTagHelper = new FormTagHelper(generator.Object) { Action = "Index", Antiforgery = false, ViewContext = testViewContext, RouteValues = { { "val", "hello" }, { "-Name", "Value" }, }, }; // Act & Assert await formTagHelper.ProcessAsync(context, output); Assert.Equal("form", output.TagName); Assert.Equal(TagMode.StartTagAndEndTag, output.TagMode); var attribute = Assert.Single(output.Attributes); Assert.Equal(expectedAttribute, attribute); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.GetContent().Length == 0); Assert.Empty(output.PostContent.GetContent()); generator.Verify(); }
public async Task ProcessAsync_GeneratesExpectedOutput() { // Arrange var expectedTagName = "not-form"; var metadataProvider = new TestModelMetadataProvider(); var tagHelperContext = new TagHelperContext( tagName: "form", allAttributes: new TagHelperAttributeList { { "id", "myform" }, { "asp-route-name", "value" }, { "asp-action", "index" }, { "asp-controller", "home" }, { "method", "post" }, { "asp-antiforgery", true } }, items: new Dictionary <object, object>(), uniqueId: "test"); var output = new TagHelperOutput( expectedTagName, attributes: new TagHelperAttributeList { { "id", "myform" }, }, getChildContentAsync: (useCachedResult, encoder) => { var tagHelperContent = new DefaultTagHelperContent(); tagHelperContent.SetContent("Something Else"); return(Task.FromResult <TagHelperContent>(tagHelperContent)); }); 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" + HtmlContentUtilities.HtmlContentToString( htmlGenerator.GenerateAntiforgery(viewContext), HtmlEncoder.Default); var formTagHelper = new FormTagHelper(htmlGenerator) { Action = "index", Antiforgery = true, Controller = "home", ViewContext = viewContext, RouteValues = { { "name", "value" }, }, }; // Act await formTagHelper.ProcessAsync(tagHelperContext, output); // Assert Assert.Equal(3, output.Attributes.Count); var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("id")); Assert.Equal("myform", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("method")); Assert.Equal("post", attribute.Value); attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("action")); Assert.Equal("home/index", attribute.Value); Assert.Empty(output.PreContent.GetContent()); Assert.True(output.Content.GetContent().Length == 0); Assert.Equal(expectedPostContent, output.PostContent.GetContent()); Assert.Equal(expectedTagName, output.TagName); }