public async Task GetChildContentAsync_CachesValue()
        {
            // Arrange
            var defaultTagHelperContent = new DefaultTagHelperContent();
            var content = string.Empty;
            var expectedContent = string.Empty;
            var executionContext = new TagHelperExecutionContext(
                "p",
                tagMode: TagMode.StartTagAndEndTag,
                items: new Dictionary<object, object>(),
                uniqueId: string.Empty,
                executeChildContentAsync: () =>
                {
                    if (string.IsNullOrEmpty(expectedContent))
                    {
                        content = "Hello from child content: " + Guid.NewGuid().ToString();
                        expectedContent = $"HtmlEncode[[{content}]]";
                    }

                    defaultTagHelperContent.SetContent(content);

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

            // Act
            var content1 = await executionContext.GetChildContentAsync(useCachedResult: true);
            var content2 = await executionContext.GetChildContentAsync(useCachedResult: true);

            // Assert
            Assert.Equal(expectedContent, content1.GetContent(new HtmlTestEncoder()));
            Assert.Equal(expectedContent, content2.GetContent(new HtmlTestEncoder()));
        }
        public async Task GetChildContentAsync_ReturnsNewObjectEveryTimeItIsCalled(bool useCachedResult)
        {
            // Arrange
            var defaultTagHelperContent = new DefaultTagHelperContent();
            var executionContext = new TagHelperExecutionContext(
                "p",
                tagMode: TagMode.StartTagAndEndTag,
                items: new Dictionary<object, object>(),
                uniqueId: string.Empty,
                executeChildContentAsync: () => { return Task.FromResult(result: true); },
                startTagHelperWritingScope: () => { },
                endTagHelperWritingScope: () => defaultTagHelperContent);

            // Act
            var content1 = await executionContext.GetChildContentAsync(useCachedResult);
            content1.Append("Hello");
            var content2 = await executionContext.GetChildContentAsync(useCachedResult);
            content2.Append("World!");

            // Assert
            Assert.NotSame(content1, content2);

            var content3 = await executionContext.GetChildContentAsync(useCachedResult);
            Assert.Empty(content3.GetContent(new HtmlTestEncoder()));
        }
Ejemplo n.º 3
0
        public async Task ProcessAsync_WithItems_GeneratesExpectedOutput_DoesNotChangeSelectList(
            object model,
            Type containerType,
            Func <object> modelAccessor,
            NameAndId nameAndId,
            string expectedOptions)
        {
            // Arrange
            var originalAttributes = new TagHelperAttributeList
            {
                { "class", "form-control" },
            };
            var originalPostContent = "original content";

            var expectedAttributes = new TagHelperAttributeList(originalAttributes)
            {
                { "id", nameAndId.Id },
                { "name", nameAndId.Name },
                { "valid", "from validation attributes" },
            };
            var expectedPreContent  = "original pre-content";
            var expectedContent     = "original content";
            var expectedPostContent = originalPostContent + expectedOptions;
            var expectedTagName     = "select";

            var metadataProvider = new TestModelMetadataProvider();

            var containerMetadata = metadataProvider.GetMetadataForType(containerType);
            var containerExplorer = metadataProvider.GetModelExplorerForType(containerType, model);

            var propertyMetadata = metadataProvider.GetMetadataForProperty(containerType, "Text");
            var modelExplorer    = containerExplorer.GetExplorerForExpression(propertyMetadata, modelAccessor());

            var modelExpression = new ModelExpression(nameAndId.Name, modelExplorer);

            var tagHelperContext = new TagHelperContext(
                tagName: "select",
                allAttributes: new TagHelperAttributeList(
                    Enumerable.Empty <TagHelperAttribute>()),
                items: new Dictionary <object, object>(),
                uniqueId: "test");
            var output = new TagHelperOutput(
                expectedTagName,
                originalAttributes,
                getChildContentAsync: (useCachedResult, encoder) =>
            {
                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.AppendHtml("Something");
                return(Task.FromResult <TagHelperContent>(tagHelperContent));
            })
            {
                TagMode = TagMode.SelfClosing,
            };

            output.PreContent.AppendHtml(expectedPreContent);
            output.Content.AppendHtml(expectedContent);
            output.PostContent.AppendHtml(originalPostContent);

            var htmlGenerator = new TestableHtmlGenerator(metadataProvider)
            {
                ValidationAttributes =
                {
                    { "valid", "from validation attributes" },
                }
            };
            var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider);

            var items         = new SelectList(new[] { "", "outer text", "inner text", "other text" });
            var savedDisabled = items.Select(item => item.Disabled).ToList();
            var savedGroup    = items.Select(item => item.Group).ToList();
            var savedSelected = items.Select(item => item.Selected).ToList();
            var savedText     = items.Select(item => item.Text).ToList();
            var savedValue    = items.Select(item => item.Value).ToList();

            var tagHelper = new SelectTagHelper(htmlGenerator)
            {
                For         = modelExpression,
                Items       = items,
                ViewContext = viewContext,
            };

            // Act
            tagHelper.Init(tagHelperContext);
            await tagHelper.ProcessAsync(tagHelperContext, output);

            // Assert
            Assert.Equal(TagMode.SelfClosing, output.TagMode);
            Assert.Equal(expectedAttributes, output.Attributes);
            Assert.Equal(expectedPreContent, output.PreContent.GetContent());
            Assert.Equal(expectedContent, output.Content.GetContent());
            Assert.Equal(expectedPostContent, HtmlContentUtilities.HtmlContentToString(output.PostContent));
            Assert.Equal(expectedTagName, output.TagName);

            Assert.Single(
                tagHelperContext.Items,
                entry => (Type)entry.Key == typeof(SelectTagHelper));

            Assert.Equal(savedDisabled, items.Select(item => item.Disabled));
            Assert.Equal(savedGroup, items.Select(item => item.Group));
            Assert.Equal(savedSelected, items.Select(item => item.Selected));
            Assert.Equal(savedText, items.Select(item => item.Text));
            Assert.Equal(savedValue, items.Select(item => item.Value));
        }
Ejemplo n.º 4
0
        public async Task ProcessAsync_WithItems_AndNoModelExpression_GeneratesExpectedOutput()
        {
            // Arrange
            var originalAttributes = new TagHelperAttributeList
            {
                { "class", "form-control" },
            };
            var originalPostContent = "original content";

            var expectedAttributes = new TagHelperAttributeList(originalAttributes);
            var selectItems        = new SelectList(Enumerable.Range(0, 5));
            var expectedOptions    = "<option>HtmlEncode[[0]]</option>" + Environment.NewLine
                                     + "<option>HtmlEncode[[1]]</option>" + Environment.NewLine
                                     + "<option>HtmlEncode[[2]]</option>" + Environment.NewLine
                                     + "<option>HtmlEncode[[3]]</option>" + Environment.NewLine
                                     + "<option>HtmlEncode[[4]]</option>" + Environment.NewLine;

            var expectedPreContent  = "original pre-content";
            var expectedContent     = "original content";
            var expectedPostContent = originalPostContent + expectedOptions;
            var expectedTagName     = "select";

            var tagHelperContext = new TagHelperContext(
                tagName: "select",
                allAttributes: new TagHelperAttributeList(
                    Enumerable.Empty <TagHelperAttribute>()),
                items: new Dictionary <object, object>(),
                uniqueId: "test");
            var output = new TagHelperOutput(
                expectedTagName,
                originalAttributes,
                getChildContentAsync: (useCachedResult, encoder) =>
            {
                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.AppendHtml("Something");
                return(Task.FromResult <TagHelperContent>(tagHelperContent));
            })
            {
                TagMode = TagMode.SelfClosing,
            };

            output.PreContent.AppendHtml(expectedPreContent);
            output.Content.AppendHtml(expectedContent);
            output.PostContent.AppendHtml(originalPostContent);

            var metadataProvider = new TestModelMetadataProvider();
            var htmlGenerator    = new TestableHtmlGenerator(metadataProvider);
            var viewContext      = TestableHtmlGenerator.GetViewContext(
                model: null,
                htmlGenerator: htmlGenerator,
                metadataProvider: metadataProvider);

            var tagHelper = new SelectTagHelper(htmlGenerator)
            {
                Items       = selectItems,
                ViewContext = viewContext,
            };

            // Act
            tagHelper.Init(tagHelperContext);
            await tagHelper.ProcessAsync(tagHelperContext, output);

            // Assert
            Assert.Equal(TagMode.SelfClosing, output.TagMode);
            Assert.Equal(expectedAttributes, output.Attributes);
            Assert.Equal(expectedPreContent, output.PreContent.GetContent());
            Assert.Equal(expectedContent, output.Content.GetContent());
            Assert.Equal(expectedPostContent, HtmlContentUtilities.HtmlContentToString(output.PostContent));
            Assert.Equal(expectedTagName, output.TagName);

            var kvp = Assert.Single(tagHelperContext.Items);

            Assert.Equal(typeof(SelectTagHelper), kvp.Key);
            Assert.Null(kvp.Value);
        }
Ejemplo n.º 5
0
        public async Task ProcessAsync_GeneratesExpectedOutput(
            object model,
            Type containerType,
            Func <object> modelAccessor,
            NameAndId nameAndId,
            string ignored)
        {
            // Arrange
            var originalAttributes = new TagHelperAttributeList
            {
                { "class", "form-control" },
            };
            var originalPostContent = "original content";

            var expectedAttributes = new TagHelperAttributeList(originalAttributes)
            {
                { "id", nameAndId.Id },
                { "name", nameAndId.Name },
                { "valid", "from validation attributes" },
            };
            var expectedPreContent  = "original pre-content";
            var expectedContent     = "original content";
            var expectedPostContent = originalPostContent;
            var expectedTagName     = "not-select";

            var metadataProvider  = new TestModelMetadataProvider();
            var containerMetadata = metadataProvider.GetMetadataForType(containerType);
            var containerExplorer = metadataProvider.GetModelExplorerForType(containerType, model);

            var propertyMetadata = metadataProvider.GetMetadataForProperty(containerType, "Text");
            var modelExplorer    = containerExplorer.GetExplorerForExpression(propertyMetadata, modelAccessor());

            var modelExpression = new ModelExpression(nameAndId.Name, modelExplorer);

            var tagHelperContext = new TagHelperContext(
                tagName: "select",
                allAttributes: new TagHelperAttributeList(
                    Enumerable.Empty <TagHelperAttribute>()),
                items: new Dictionary <object, object>(),
                uniqueId: "test");
            var output = new TagHelperOutput(
                expectedTagName,
                originalAttributes,
                getChildContentAsync: (useCachedResult, encoder) =>
            {
                var tagHelperContent = new DefaultTagHelperContent();
                tagHelperContent.SetContent("Something");
                return(Task.FromResult <TagHelperContent>(tagHelperContent));
            })
            {
                TagMode = TagMode.SelfClosing,
            };

            output.PreContent.SetContent(expectedPreContent);
            output.Content.SetContent(expectedContent);
            output.PostContent.SetContent(originalPostContent);

            var htmlGenerator = new TestableHtmlGenerator(metadataProvider)
            {
                ValidationAttributes =
                {
                    { "valid", "from validation attributes" },
                }
            };
            var viewContext = TestableHtmlGenerator.GetViewContext(model, htmlGenerator, metadataProvider);
            var tagHelper   = new SelectTagHelper(htmlGenerator)
            {
                For         = modelExpression,
                ViewContext = viewContext,
            };

            // Act
            tagHelper.Init(tagHelperContext);
            await tagHelper.ProcessAsync(tagHelperContext, output);

            // Assert
            Assert.Equal(TagMode.SelfClosing, output.TagMode);
            Assert.Equal(expectedAttributes, output.Attributes);
            Assert.Equal(expectedPreContent, output.PreContent.GetContent());
            Assert.Equal(expectedContent, output.Content.GetContent());
            Assert.Equal(expectedPostContent, output.PostContent.GetContent());
            Assert.Equal(expectedTagName, output.TagName);

            Assert.Single(
                tagHelperContext.Items,
                entry => (Type)entry.Key == typeof(SelectTagHelper));
        }
Ejemplo n.º 6
0
        public IActionResult Refresh(string data)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(data))
                {
                    return(BadRequest("The data is null or empty."));
                }

                var decryptedModel = _captchaProtectionProvider.Decrypt(data);
                if (decryptedModel == null)
                {
                    return(BadRequest("Couldn't decrypt the data."));
                }

                var model = _serializationProvider.Deserialize <DNTCaptchaTagHelperHtmlAttributes>(decryptedModel);
                if (model == null)
                {
                    return(BadRequest("Couldn't deserialize the model."));
                }

                invalidateToken(model);

                var tagHelper = HttpContext.RequestServices.GetRequiredService <DNTCaptchaTagHelper>();
                tagHelper.BackColor              = model.BackColor;
                tagHelper.FontName               = model.FontName;
                tagHelper.FontSize               = model.FontSize;
                tagHelper.ForeColor              = model.ForeColor;
                tagHelper.Language               = model.Language;
                tagHelper.Max                    = model.Max;
                tagHelper.Min                    = model.Min;
                tagHelper.Placeholder            = model.Placeholder;
                tagHelper.TextBoxClass           = model.TextBoxClass;
                tagHelper.TextBoxTemplate        = model.TextBoxTemplate;
                tagHelper.ValidationErrorMessage = model.ValidationErrorMessage;
                tagHelper.ValidationMessageClass = model.ValidationMessageClass;
                tagHelper.RefreshButtonClass     = model.RefreshButtonClass;
                tagHelper.DisplayMode            = model.DisplayMode;
                tagHelper.UseRelativeUrls        = model.UseRelativeUrls;
                tagHelper.UseNoise               = model.UseNoise;

                var tagHelperContext = new TagHelperContext(
                    allAttributes: new TagHelperAttributeList(),
                    items: new Dictionary <object, object> {
                    { typeof(IUrlHelper), this.Url }
                },
                    uniqueId: Guid.NewGuid().ToString("N"));

                var tagHelperOutput = new TagHelperOutput(
                    tagName: "div",
                    attributes: new TagHelperAttributeList(),
                    getChildContentAsync: (useCachedResult, encoder) =>
                {
                    var tagHelperContent = new DefaultTagHelperContent();
                    tagHelperContent.SetContent(string.Empty);
                    return(Task.FromResult <TagHelperContent>(tagHelperContent));
                });
                tagHelper.ViewContext = ViewContext ?? new ViewContext(
                    new ActionContext(this.HttpContext, HttpContext.GetRouteData(), ControllerContext.ActionDescriptor),
                    new FakeView(),
                    new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary())
                {
                    Model = null
                },
                    new TempDataDictionary(this.HttpContext, _tempDataProvider),
                    TextWriter.Null,
                    new HtmlHelperOptions());

                tagHelper.Process(tagHelperContext, tagHelperOutput);

                var attrs = new StringBuilder();
                foreach (var attr in tagHelperOutput.Attributes)
                {
                    attrs.Append(' ').Append(attr.Name).Append("='").Append(attr.Value).Append('\'');
                }

                var content = $"<div {attrs}>{tagHelperOutput.Content.GetContent()}</div>";
                return(Content(content));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Failed to refresh the captcha image.");
                return(BadRequest(ex.ToString()));
            }
        }
Ejemplo n.º 7
0
        private void BuildFallbackBlock(IDictionary <string, object> attributes, DefaultTagHelperContent builder)
        {
            EnsureGlobbingUrlBuilder();
            EnsureFileVersionProvider();

            var fallbackSrcs = GlobbingUrlBuilder.BuildUrlList(FallbackSrc, FallbackSrcInclude, FallbackSrcExclude);

            if (fallbackSrcs.Any())
            {
                // Build the <script> tag that checks the test method and if it fails, renders the extra script.
                builder.Append(Environment.NewLine)
                .Append("<script>(")
                .Append(FallbackTestExpression)
                .Append("||document.write(\"");

                // May have no "src" attribute in the dictionary e.g. if Src and SrcInclude were not bound.
                if (!attributes.ContainsKey(SrcAttributeName))
                {
                    // Need this entry to place each fallback source.
                    attributes.Add(SrcAttributeName, null);
                }

                foreach (var src in fallbackSrcs)
                {
                    // Fallback "src" values come from bound attributes and globbing. Must always be non-null.
                    Debug.Assert(src != null);

                    builder.Append("<script");

                    foreach (var attribute in attributes)
                    {
                        if (!attribute.Key.Equals(SrcAttributeName, StringComparison.OrdinalIgnoreCase))
                        {
                            var encodedKey     = JavaScriptEncoder.JavaScriptStringEncode(attribute.Key);
                            var attributeValue = attribute.Value.ToString();
                            var encodedValue   = JavaScriptEncoder.JavaScriptStringEncode(attributeValue);

                            AppendAttribute(builder, encodedKey, encodedValue, escapeQuotes: true);
                        }
                        else
                        {
                            // Ignore attribute.Value; use src instead.
                            var attributeValue = src;
                            if (FileVersion == true)
                            {
                                attributeValue = _fileVersionProvider.AddFileVersionToPath(attributeValue);
                            }

                            // attribute.Key ("src") does not need to be JavaScript-encoded.
                            var encodedValue = JavaScriptEncoder.JavaScriptStringEncode(attributeValue);

                            AppendAttribute(builder, attribute.Key, encodedValue, escapeQuotes: true);
                        }
                    }

                    builder.Append("><\\/script>");
                }

                builder.Append("\"));</script>");
            }
        }
Ejemplo n.º 8
0
        public async Task WriteTagHelperAsync_WritesContentAppropriately(
            bool childContentRetrieved, string input, string expected)
        {
            // Arrange
            var defaultTagHelperContent = new DefaultTagHelperContent();
            var writer = new StringCollectionTextWriter(Encoding.UTF8);
            var context = CreateViewContext(writer);
            var tagHelperExecutionContext = new TagHelperExecutionContext(
                tagName: "p",
                tagMode: TagMode.StartTagAndEndTag,
                items: new Dictionary<object, object>(),
                uniqueId: string.Empty,
                executeChildContentAsync: () =>
                {
                    defaultTagHelperContent.AppendHtml(input);
                    return Task.FromResult(result: true);
                },
                startTagHelperWritingScope: () => { },
                endTagHelperWritingScope: () => defaultTagHelperContent);
            tagHelperExecutionContext.Output = new TagHelperOutput(
                tagName: "p",
                attributes: new TagHelperAttributeList(),
                getChildContentAsync: (_) => Task.FromResult<TagHelperContent>(new DefaultTagHelperContent()));
            if (childContentRetrieved)
            {
                await tagHelperExecutionContext.GetChildContentAsync(useCachedResult: true);
            }

            // Act
            var page = CreatePage(p =>
            {
                p.HtmlEncoder = new CommonTestEncoder();
                p.WriteTagHelperAsync(tagHelperExecutionContext).Wait();
            }, context);
            await page.ExecuteAsync();

            // Assert
            Assert.Equal(expected, HtmlContentUtilities.HtmlContentToString(writer.Content));
        }
Ejemplo n.º 9
0
        /// <inheritdoc />
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            string resolvedUrl;

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

                // Resolve any application relative URLs (~/) now so they can be used in comparisons later.
                if (TryResolveUrl(Href, encodeWebRoot: false, resolvedUrl: out resolvedUrl))
                {
                    Href = resolvedUrl;
                }

                ProcessUrlAttribute(HrefAttributeName, output);
            }

            var modeResult = AttributeMatcher.DetermineMode(context, ModeDetails);

            modeResult.LogDetails(Logger, this, context.UniqueId, ViewContext.View.Path);

            if (!modeResult.FullMatches.Any())
            {
                // No attributes matched so we have nothing to do
                return;
            }

            // NOTE: Values in TagHelperOutput.Attributes may already be HTML-encoded.
            var attributes = new TagHelperAttributeList(output.Attributes);

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

                var attributeStringValue = output.Attributes[HrefAttributeName]?.Value as string;
                if (attributeStringValue != null)
                {
                    output.Attributes[HrefAttributeName].Value =
                        _fileVersionProvider.AddFileVersionToPath(attributeStringValue);
                }
            }

            var builder = new DefaultTagHelperContent();

            // Get the highest matched mode
            var mode = modeResult.FullMatches.Select(match => match.Mode).Max();

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

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

                BuildFallbackBlock(builder);
            }

            output.PostElement.SetContent(builder);
        }