Ejemplo n.º 1
0
    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);
    }
Ejemplo n.º 2
0
    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();
    }
Ejemplo n.º 3
0
    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());
    }
Ejemplo n.º 4
0
    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);
    }
Ejemplo n.º 5
0
    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());
    }
Ejemplo n.º 6
0
    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());
    }
Ejemplo n.º 7
0
    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);
    }
Ejemplo n.º 8
0
    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());
    }
Ejemplo n.º 9
0
    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();
    }
Ejemplo n.º 10
0
    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();
    }
Ejemplo n.º 11
0
    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);
    }
Ejemplo n.º 12
0
    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);
    }
Ejemplo n.º 13
0
    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();
    }
Ejemplo n.º 14
0
    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);
    }