public async Task SetOutputContentAsync_SetsOutputsContent()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            var content = "Hello from child content";
            var executionContext = new TagHelperExecutionContext(
                "p",
                tagMode: TagMode.StartTagAndEndTag,
                items: new Dictionary<object, object>(),
                uniqueId: string.Empty,
                executeChildContentAsync: () =>
                {
                    tagHelperContent.SetContent(content);

                    return Task.FromResult(result: true);
                },
                startTagHelperWritingScope: _ => { },
                endTagHelperWritingScope: () => tagHelperContent);

            // Act
            await executionContext.SetOutputContentAsync();

            // Assert
            Assert.Equal(content, executionContext.Output.Content.GetContent());
        }
Exemple #2
0
        public async Task GetChildContentAsync_CallsGetChildContentAsync()
        {
            // Arrange
            bool? passedUseCacheResult = null;
            HtmlEncoder passedEncoder = null;
            var content = new DefaultTagHelperContent();
            var output = new TagHelperOutput(
                tagName: "tag",
                attributes: new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
                {
                    passedUseCacheResult = useCachedResult;
                    passedEncoder = encoder;
                    return Task.FromResult<TagHelperContent>(content);
                });

            // Act
            var result = await output.GetChildContentAsync();

            // Assert
            Assert.True(passedUseCacheResult.HasValue);
            Assert.True(passedUseCacheResult.Value);
            Assert.Null(passedEncoder);
            Assert.Same(content, result);
        }
		public static IHtmlContent GenerateGroupsAndOptions(string optionLabel, IEnumerable<SelectListItem> selectList)
		{
			var listItemBuilder = new DefaultTagHelperContent();

			// Make optionLabel the first item that gets rendered.
			if (optionLabel != null)
			{
				listItemBuilder.AppendLine(GenerateOption(new SelectListItem
				{
					Text = optionLabel,
					Value = string.Empty,
					Selected = false
				}));
			}

			// Group items in the SelectList if requested.
			// Treat each item with Group == null as a member of a unique group
			// so they are added according to the original order.
			var groupedSelectList = selectList.GroupBy(item => item.Group?.GetHashCode() ?? item.GetHashCode());

			foreach (var group in groupedSelectList)
			{
				var optGroup = group.First().Group;
				if (optGroup != null)
				{
					var groupBuilder = new TagBuilder("optgroup");
					if (optGroup.Name != null)
					{
						groupBuilder.MergeAttribute("label", optGroup.Name);
					}

					if (optGroup.Disabled)
					{
						groupBuilder.MergeAttribute("disabled", "disabled");
					}

					groupBuilder.InnerHtml.AppendLine();
					foreach (var item in group)
					{
						groupBuilder.InnerHtml.AppendLine(GenerateOption(item));
					}

					listItemBuilder.AppendLine(groupBuilder);
				}
				else
				{
					foreach (var item in group)
					{
						listItemBuilder.AppendLine(GenerateOption(item));
					}
				}
			}

			return listItemBuilder;
		}
        public void SetHtmlContent_TextIsNotFurtherEncoded()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();

            // Act
            tagHelperContent.SetHtmlContent("Hi");

            // Assert
            Assert.Equal("Hi", tagHelperContent.GetContent(new HtmlTestEncoder()));
        }
        public async Task ProcessAsync_GeneratesExpectedOutput()
        {
            // Arrange
            var expectedTagName = "not-div";
            var metadataProvider = new TestModelMetadataProvider();
            var htmlGenerator = new TestableHtmlGenerator(metadataProvider);

            var validationSummaryTagHelper = new ValidationSummaryTagHelper(htmlGenerator)
            {
                ValidationSummary = ValidationSummary.All,
            };

            var expectedPreContent = "original pre-content";
            var expectedContent = "original content";
            var tagHelperContext = new TagHelperContext(
                allAttributes: new TagHelperAttributeList(
                    Enumerable.Empty<TagHelperAttribute>()),
                items: new Dictionary<object, object>(),
                uniqueId: "test");
            var output = new TagHelperOutput(
                expectedTagName,
                attributes: new TagHelperAttributeList
                {
                    { "class", "form-control" }
                },
                getChildContentAsync: (useCachedResult, encoder) =>
                {
                    var tagHelperContent = new DefaultTagHelperContent();
                    tagHelperContent.SetContent("Something");
                    return Task.FromResult<TagHelperContent>(tagHelperContent);
                });
            output.PreContent.SetContent(expectedPreContent);
            output.Content.SetContent(expectedContent);
            output.PostContent.SetContent("Custom Content");

            Model model = null;
            var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider);
            validationSummaryTagHelper.ViewContext = viewContext;

            // Act
            await validationSummaryTagHelper.ProcessAsync(tagHelperContext, output);

            // Assert
            Assert.Equal(2, output.Attributes.Count);
            var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("class"));
            Assert.Equal("form-control validation-summary-valid", attribute.Value);
            attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-summary"));
            Assert.Equal("true", attribute.Value);
            Assert.Equal(expectedPreContent, output.PreContent.GetContent());
            Assert.Equal(expectedContent, output.Content.GetContent());
            Assert.Equal("Custom Content<ul><li style=\"display:none\"></li>" + Environment.NewLine + "</ul>",
                         output.PostContent.GetContent());
            Assert.Equal(expectedTagName, output.TagName);
        }
        public void CanSetContent()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            var expected = "HtmlEncode[[Hello World!]]";

            // Act
            tagHelperContent.SetContent("Hello World!");

            // Assert
            Assert.Equal(expected, tagHelperContent.GetContent(new HtmlTestEncoder()));
        }
        public void SetHtmlContent_ClearsExistingContent()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            tagHelperContent.AppendHtml("Contoso");

            // Act
            tagHelperContent.SetHtmlContent("Hello World!");

            // Assert
            Assert.Equal("Hello World!", tagHelperContent.GetContent(new HtmlTestEncoder()));
        }
        public void Reset_ClearsTheExpectedFields()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            tagHelperContent.SetContent("hello world");

            // Act
            tagHelperContent.Reinitialize();

            Assert.False(tagHelperContent.IsModified);
            Assert.Equal(string.Empty, tagHelperContent.GetContent());
        }
Exemple #9
0
        protected TagHelperOutput GetSimpleTagHelperOutput()
        {
            var output = new TagHelperOutput("a", new TagHelperAttributeList(), (useCachedResult, encoder) =>
            {
                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.SetContent("Something");
                return Task.FromResult<TagHelperContent>(tagHelperContent);
            });

            output.Content.SetContent(string.Empty);

            return output;
        }
Exemple #10
0
        public async Task Reinitialize_AllowsOutputToBeReused()
        {
            // Arrange
            var initialOutputChildContent = new DefaultTagHelperContent();
            initialOutputChildContent.SetContent("Initial output content.");
            var expectedGetChildContentContent = "Initial get child content content";
            var initialGetChildContent = new DefaultTagHelperContent();
            initialGetChildContent.SetContent(expectedGetChildContentContent);
            Func<bool, HtmlEncoder, Task<TagHelperContent>> initialGetChildContentAsync =
                (useCachedResult, encoder) => Task.FromResult<TagHelperContent>(initialGetChildContent);
            var initialTagMode = TagMode.StartTagOnly;
            var initialAttributes = new TagHelperAttributeList
            {
                { "name", "value" }
            };
            var initialTagName = "initialTagName";
            var output = new TagHelperOutput(initialTagName, initialAttributes, initialGetChildContentAsync)
            {
                TagMode = initialTagMode,
                Content = initialOutputChildContent,
            };
            output.PreContent.SetContent("something");
            output.PostContent.SetContent("something");
            output.PreElement.SetContent("something");
            output.PostElement.SetContent("something");
            var expectedTagName = "newTagName";
            var expectedTagMode = TagMode.SelfClosing;

            // Act
            output.Reinitialize(expectedTagName, expectedTagMode);

            // Assert
            Assert.Equal(expectedTagName, output.TagName);
            Assert.Equal(expectedTagMode, output.TagMode);
            Assert.Empty(output.Attributes);

            var getChildContent = await output.GetChildContentAsync();
            var content = getChildContent.GetContent();

            // We're expecting the initial child content here because normally the TagHelper infrastructure would
            // swap out the inner workings of GetChildContentAsync to work with its reinitialized state.
            Assert.Equal(expectedGetChildContentContent, content);
            Assert.False(output.PreContent.IsModified);
            Assert.False(output.PostContent.IsModified);
            Assert.False(output.PreElement.IsModified);
            Assert.False(output.PostElement.IsModified);
        }
 public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
 {
     if (ShowDismiss)
     {
         output.PreContent.AppendFormat(@"<button type='button' class='btn btn-default' data-dismiss='modal'>{0}</button>", DismissText);
     }
     var childContent = await output.GetChildContentAsync();
     var footerContent = new DefaultTagHelperContent();
     if (ShowDismiss)
     {
         footerContent.AppendFormat(@"<button type='button' class='btn btn-default' data-dismiss='modal'>{0}</button>", DismissText);
     }
     footerContent.AppendHtml(childContent);
     var modalContext = (ModalContext)context.Items[typeof(ModalTagHelper)];
     modalContext.Footer = footerContent;
     output.SuppressOutput();
 }
Exemple #12
0
        public async Task ProcessAsync_CallsIntoGenerateRouteFormWithExpectedParameters()
        {
            // Arrange
            var viewContext = CreateViewContext();
            var context = new TagHelperContext(
                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<Dictionary<string, object>>(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());
        }
Exemple #13
0
        public async Task ProcessAsync_AspAreaOverridesAspRouteArea()
        {
            // Arrange
            var viewContext = CreateViewContext();
            var context = new TagHelperContext(
                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", "Admin" } };
            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 = "Admin",
                RouteValues = new Dictionary<string, string> { { "area", "Client" } },
                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());
        }
Exemple #14
0
        public async Task ProcessAsync_GeneratesExpectedOutput()
        {
            // Arrange
            var expectedTagName = "not-form";
            var metadataProvider = new TestModelMetadataProvider();
            var tagHelperContext = new TagHelperContext(
                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);
        }
Exemple #15
0
        public async Task ProcessAsync_BindsRouteValues()
        {
            // Arrange
            var testViewContext = CreateViewContext();
            var context = new TagHelperContext(
                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 = (Dictionary<string, object>)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();
        }
Exemple #16
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(
                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());
        }
Exemple #17
0
 private Func<bool, HtmlEncoder, Task<TagHelperContent>> GetEmptyChildContent()
 {
     TagHelperContent content = new DefaultTagHelperContent();
     return (b, encoder) => Task.FromResult(content);
 }
Exemple #18
0
        /// <inheritdoc />
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            if (context == null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            if (output == null)
            {
                throw new ArgumentNullException(nameof(output));
            }

            // Pass through attribute that is also a well-known HTML attribute.
            if (Href != null)
            {
                output.CopyHtmlAttribute(HrefAttributeName, context);
            }

            // If there's no "href" attribute in output.Attributes this will noop.
            ProcessUrlAttribute(HrefAttributeName, output);

            // Retrieve the TagHelperOutput variation of the "href" attribute in case other TagHelpers in the
            // pipeline have touched the value. If the value is already encoded this LinkTagHelper may
            // not function properly.
            Href = output.Attributes[HrefAttributeName]?.Value as string;

            Mode mode;
            if (!AttributeMatcher.TryDetermineMode(context, ModeDetails, Compare, out mode))
            {
                // No attributes matched so we have nothing to do
                return;
            }

            if (AppendVersion == true)
            {
                EnsureFileVersionProvider();

                if (Href != null)
                {
                    var index = output.Attributes.IndexOfName(HrefAttributeName);
                    output.Attributes[index] = new TagHelperAttribute(
                        HrefAttributeName,
                        _fileVersionProvider.AddFileVersionToPath(Href));
                }
            }

            var builder = new DefaultTagHelperContent();
            if (mode == Mode.GlobbedHref || mode == Mode.Fallback && !string.IsNullOrEmpty(HrefInclude))
            {
                BuildGlobbedLinkTags(output.Attributes, builder);
                if (string.IsNullOrEmpty(Href))
                {
                    // Only HrefInclude is specified. Don't render the original tag.
                    output.TagName = null;
                    output.Content.SetHtmlContent(HtmlString.Empty);
                }
            }

            if (mode == Mode.Fallback)
            {
                string resolvedUrl;
                if (TryResolveUrl(FallbackHref, resolvedUrl: out resolvedUrl))
                {
                    FallbackHref = resolvedUrl;
                }

                BuildFallbackBlock(builder);
            }

            output.PostElement.SetHtmlContent(builder);
        }
        public void SetHtmlContent_WithTagHelperContent_WorksAsExpected(string content, string expected)
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            var copiedTagHelperContent = new DefaultTagHelperContent();
            tagHelperContent.SetContent(content);

            // Act
            copiedTagHelperContent.SetHtmlContent(tagHelperContent);

            // Assert
            Assert.Equal(expected, copiedTagHelperContent.GetContent(new HtmlTestEncoder()));
        }
        public void IsEmptyOrWhiteSpace_FalseAfterAppend()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();

            // Act
            tagHelperContent.Append("Hello");

            // Assert
            Assert.False(tagHelperContent.IsEmptyOrWhiteSpace);
        }
Exemple #21
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(
                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_GeneratesExpectedOutput()
        {
            // Arrange
            var expectedTagName = "not-span";
            var metadataProvider = new TestModelMetadataProvider();
            var modelExpression = CreateModelExpression("Name");
            var htmlGenerator = new TestableHtmlGenerator(metadataProvider);

            var validationMessageTagHelper = new ValidationMessageTagHelper(htmlGenerator)
            {
                For = modelExpression
            };

            var expectedPreContent = "original pre-content";
            var expectedContent = "original content";
            var expectedPostContent = "original post-content";

            var tagHelperContext = new TagHelperContext(
                allAttributes: new TagHelperAttributeList
                {
                    { "id", "myvalidationmessage" },
                    { "for", modelExpression },
                },
                items: new Dictionary<object, object>(),
                uniqueId: "test");
            var output = new TagHelperOutput(
                expectedTagName,
                attributes: new TagHelperAttributeList
                {
                    { "id", "myvalidationmessage" }
                },
                getChildContentAsync: (useCachedResult, encoder) =>
                {
                    var tagHelperContent = new DefaultTagHelperContent();
                    tagHelperContent.SetContent("Something");
                    return Task.FromResult<TagHelperContent>(tagHelperContent);
                });
            output.PreContent.SetContent(expectedPreContent);
            output.Content.SetContent(expectedContent);
            output.PostContent.SetContent(expectedPostContent);

            var viewContext = TestableHtmlGenerator.GetViewContext(
                model: null,
                htmlGenerator: htmlGenerator,
                metadataProvider: metadataProvider);
            validationMessageTagHelper.ViewContext = viewContext;

            // Act
            await validationMessageTagHelper.ProcessAsync(tagHelperContext, output);

            // Assert
            Assert.Equal(4, output.Attributes.Count);
            var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("id"));
            Assert.Equal("myvalidationmessage", attribute.Value);
            attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("class"));
            Assert.Equal("field-validation-valid", attribute.Value);
            attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-for"));
            Assert.Equal("Name", attribute.Value);
            attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-valmsg-replace"));
            Assert.Equal("true", attribute.Value);
            Assert.Equal(expectedPreContent, output.PreContent.GetContent());
            Assert.Equal(expectedContent, output.Content.GetContent());
            Assert.Equal(expectedPostContent, output.PostContent.GetContent());
            Assert.Equal(expectedTagName, output.TagName);
        }
        public void Fluent_Clear_Set_Append_WritesExpectedContent()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            var expected = "HtmlEncode[[Hello ]]HtmlEncode[[World!]]";
            tagHelperContent.SetContent("Some Random Content");

            // Act
            tagHelperContent.Clear().SetContent("Hello ").Append("World!");

            // Assert
            Assert.Equal(expected, tagHelperContent.GetContent(new HtmlTestEncoder()));
        }
        public void Fluent_SetContent_AppendFormat_Append_WritesExpectedContent()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            var expected = "HtmlEncode[[First ]]HtmlEncode[[Second]] Third HtmlEncode[[Fourth]]";

            // Act
            tagHelperContent
                .SetContent("First ")
                .AppendFormat("{0} Third ", "Second")
                .Append("Fourth");

            // Assert
            Assert.Equal(expected, tagHelperContent.GetContent(new HtmlTestEncoder()));
        }
        public void CanClearContent()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            tagHelperContent.SetContent("Hello World");

            // Act
            tagHelperContent.Clear();

            // Assert
            Assert.True(tagHelperContent.IsEmptyOrWhiteSpace);
        }
        public void IsEmptyOrWhiteSpace_FalseAfterAppendTagHelper()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            var copiedTagHelperContent = new DefaultTagHelperContent();
            copiedTagHelperContent.SetContent("Hello");

            // Act
            tagHelperContent.AppendHtml(copiedTagHelperContent);

            // Assert
            Assert.False(tagHelperContent.IsEmptyOrWhiteSpace);
        }
        public async Task ProcessAsync_MergesTagBuilderFromGenerateValidationMessage(
            string childContent, string expectedOutputContent)
        {
            // Arrange
            var tagBuilder = new TagBuilder("span2");
            tagBuilder.InnerHtml.SetHtmlContent("New HTML");
            tagBuilder.Attributes.Add("data-foo", "bar");
            tagBuilder.Attributes.Add("data-hello", "world");

            var generator = new Mock<IHtmlGenerator>(MockBehavior.Strict);
            var setup = generator
                .Setup(mock => mock.GenerateValidationMessage(
                    It.IsAny<ViewContext>(),
                    It.IsAny<ModelExplorer>(),
                    It.IsAny<string>(),
                    It.IsAny<string>(),
                    It.IsAny<string>(),
                    It.IsAny<object>()))
                .Returns(tagBuilder);

            var validationMessageTagHelper = new ValidationMessageTagHelper(generator.Object)
            {
                For = CreateModelExpression("Hello")
            };
            var output = new TagHelperOutput(
                "span",
                attributes: new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
                {
                    var tagHelperContent = new DefaultTagHelperContent();
                    tagHelperContent.SetContent(childContent);
                    return Task.FromResult<TagHelperContent>(tagHelperContent);
                });

            var context = new TagHelperContext(
                allAttributes: new TagHelperAttributeList(
                    Enumerable.Empty<TagHelperAttribute>()),
                items: new Dictionary<object, object>(),
                uniqueId: "test");

            var viewContext = CreateViewContext();
            validationMessageTagHelper.ViewContext = viewContext;

            // Act
            await validationMessageTagHelper.ProcessAsync(context, output);

            // Assert
            Assert.Equal("span", output.TagName);
            Assert.Equal(2, output.Attributes.Count);
            var attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-foo"));
            Assert.Equal("bar", attribute.Value);
            attribute = Assert.Single(output.Attributes, attr => attr.Name.Equals("data-hello"));
            Assert.Equal("world", attribute.Value);
            Assert.Equal(expectedOutputContent, output.Content.GetContent());
        }
        public void AppendHtml_DoesNotGetEncoded()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            tagHelperContent.AppendHtml("Hi");

            var writer = new StringWriter();

            // Act
            tagHelperContent.WriteTo(writer, new HtmlTestEncoder());

            // Assert
            Assert.Equal("Hi", writer.ToString());
        }
        public async Task ProcessAsync_CallsIntoGenerateValidationMessageWithExpectedParameters()
        {
            // Arrange
            var expectedViewContext = CreateViewContext();
            var modelExpression = CreateModelExpression("Hello");
            var generator = new Mock<IHtmlGenerator>();
            generator
                .Setup(mock => mock.GenerateValidationMessage(
                    expectedViewContext,
                    modelExpression.ModelExplorer,
                    modelExpression.Name,
                    null,
                    null,
                    null))
                .Returns(new TagBuilder("span"))
                .Verifiable();

            var validationMessageTagHelper = new ValidationMessageTagHelper(generator.Object)
            {
                For = modelExpression,
            };
            var expectedPreContent = "original pre-content";
            var expectedContent = "original content";
            var expectedPostContent = "original post-content";
            var context = new TagHelperContext(
                allAttributes: new TagHelperAttributeList(
                    Enumerable.Empty<TagHelperAttribute>()),
                items: new Dictionary<object, object>(),
                uniqueId: "test");
            var output = new TagHelperOutput(
                "span",
                attributes: new TagHelperAttributeList(),
                getChildContentAsync: (useCachedResult, encoder) =>
                {
                    var tagHelperContent = new DefaultTagHelperContent();
                    tagHelperContent.SetContent("Something");
                    return Task.FromResult<TagHelperContent>(tagHelperContent);
                });
            output.PreContent.SetContent(expectedPreContent);
            output.Content.SetContent(expectedContent);
            output.PostContent.SetContent(expectedPostContent);

            validationMessageTagHelper.ViewContext = expectedViewContext;

            // Act & Assert
            await validationMessageTagHelper.ProcessAsync(context, output);

            generator.Verify();
            Assert.Equal("span", output.TagName);
            Assert.Empty(output.Attributes);
            Assert.Equal(expectedPreContent, output.PreContent.GetContent());
            Assert.Equal(expectedContent, output.Content.GetContent());
            Assert.Equal(expectedPostContent, output.PostContent.GetContent());
        }
        public void WriteTo_WritesToATextWriter()
        {
            // Arrange
            var tagHelperContent = new DefaultTagHelperContent();
            var writer = new StringWriter();
            tagHelperContent.SetContent("Hello ");
            tagHelperContent.Append("World");

            // Act
            tagHelperContent.WriteTo(writer, new HtmlTestEncoder());

            // Assert
            Assert.Equal("HtmlEncode[[Hello ]]HtmlEncode[[World]]", writer.ToString());
        }