public void StringEncode_EncodesAsExpected(string input, string expectedOutput) { // Arrange var encoder = new HtmlTestEncoder(); // Act var output = encoder.Encode(input); // Assert Assert.Equal(expectedOutput, output); }
public static string HtmlContentToString(IHtmlContent content, HtmlEncoder encoder = null) { if (encoder == null) { encoder = new HtmlTestEncoder(); } using (var writer = new StringWriter()) { content.WriteTo(writer, encoder); return writer.ToString(); } }
public TestableRazorPage() { HtmlEncoder = new HtmlTestEncoder(); }
public void TagHelperOutput_WritesFormattedTagHelper(TagHelperOutput output, string expected) { // Arrange var writer = new StringWriter(); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: output.TagName, tagMode: output.TagMode, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => Task.FromResult(result: true), startTagHelperWritingScope: () => { }, endTagHelperWritingScope: () => new DefaultTagHelperContent()); tagHelperExecutionContext.Output = output; var testEncoder = new HtmlTestEncoder(); // Act output.WriteTo(writer, testEncoder); // Assert Assert.Equal(expected, writer.ToString(), StringComparer.Ordinal); }
public async Task RenderAsync_ExecutesNestedLayoutPages() { // Arrange var htmlEncoder = new HtmlTestEncoder(); var expected = "HtmlEncode[[layout-2" + Environment.NewLine + "]]bar-content" + Environment.NewLine + "HtmlEncode[[layout-1" + Environment.NewLine + "]]foo-content" + Environment.NewLine + "body-content"; var page = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.DefineSection("foo", async writer => { await writer.WriteLineAsync("foo-content"); }); v.Layout = "~/Shared/Layout1.cshtml"; v.WriteLiteral("body-content"); }); var layout1 = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Write("layout-1" + Environment.NewLine); v.Write(v.RenderSection("foo")); v.DefineSection("bar", writer => writer.WriteLineAsync("bar-content")); v.RenderBodyPublic(); v.Layout = "~/Shared/Layout2.cshtml"; }); layout1.Path = "~/Shared/Layout1.cshtml"; var layout2 = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Write("layout-2" + Environment.NewLine); v.Write(v.RenderSection("bar")); v.RenderBodyPublic(); }); layout2.Path = "~/Shared/Layout2.cshtml"; var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict); viewEngine .Setup(p => p.GetPage(/*executingFilePath*/ null, "~/Shared/Layout1.cshtml")) .Returns(new RazorPageResult("~/Shared/Layout1.cshtml", layout1)); viewEngine .Setup(p => p.GetPage("~/Shared/Layout1.cshtml", "~/Shared/Layout2.cshtml")) .Returns(new RazorPageResult("~/Shared/Layout2.cshtml", layout2)); var view = new RazorView( viewEngine.Object, Mock.Of<IRazorPageActivator>(), new IRazorPage[0], page, new HtmlTestEncoder()); var viewContext = CreateViewContext(view); // Act await view.RenderAsync(viewContext); // Assert Assert.Equal(expected, viewContext.Writer.ToString()); }
public async Task RenderAsync_WithNestedSectionsOfTheSameName_ThrowsIfSectionsWereDefinedButNotRendered() { // Arrange var htmlEncoder = new HtmlTestEncoder(); var page = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = "~/Shared/Layout1.cshtml"; v.WriteLiteral("BodyContent"); v.DefineSection("foo", async writer => { await writer.WriteLineAsync("foo-content"); }); }) { Path = "Page" }; var nestedLayout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = "~/Shared/Layout2.cshtml"; v.Write("NestedLayout" + Environment.NewLine); v.RenderBodyPublic(); v.DefineSection("foo", async writer => { await writer.WriteLineAsync("dont-render-inner-foo"); }); }) { Path = "/Shared/Layout1.cshtml" }; var baseLayout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Write("BaseLayout" + Environment.NewLine); v.RenderBodyPublic(); v.RenderSection("foo"); }) { Path = "/Shared/Layout2.cshtml" }; var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict); viewEngine .Setup(p => p.GetPage("Page", "~/Shared/Layout1.cshtml")) .Returns(new RazorPageResult("~/Shared/Layout1.cshtml", nestedLayout)); viewEngine .Setup(p => p.GetPage("/Shared/Layout1.cshtml", "~/Shared/Layout2.cshtml")) .Returns(new RazorPageResult("~/Shared/Layout2.cshtml", baseLayout)); var view = new RazorView( viewEngine.Object, Mock.Of<IRazorPageActivator>(), new IRazorPage[0], page, new HtmlTestEncoder()); var viewContext = CreateViewContext(view); // Act and Assert var ex = await Assert.ThrowsAsync<InvalidOperationException>(() => view.RenderAsync(viewContext)); Assert.Equal("The following sections have been defined but have not been rendered by the page at " + "'/Shared/Layout1.cshtml': 'foo'.", ex.Message); }
public async Task RenderAsync_SucceedsIfRenderBodyIsNotInvoked_ButAllSectionsAreRendered() { // Arrange var expected = string.Join( Environment.NewLine, "layout-section-content", "page-section-content"); var htmlEncoder = new HtmlTestEncoder(); var page = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = "NestedLayout"; v.WriteLiteral("Page body content that will not be written"); v.DefineSection("sectionA", async writer => { await writer.WriteAsync("page-section-content"); }); }); var nestedLayout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = "Layout"; v.WriteLiteral("Nested layout content that will not be written"); v.DefineSection("sectionB", async writer => { await writer.WriteLineAsync("layout-section-content"); await v.RenderSectionAsync("sectionA"); }); }); nestedLayout.Path = "NestedLayout"; var baseLayout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.RenderSection("sectionB"); }); baseLayout.Path = "Layout"; var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict); viewEngine .Setup(v => v.GetPage(/*executingFilePath*/ null, "NestedLayout")) .Returns(new RazorPageResult("NestedLayout", Enumerable.Empty<string>())); viewEngine .Setup(p => p.FindPage(It.IsAny<ActionContext>(), "NestedLayout")) .Returns(new RazorPageResult("NestedLayout", nestedLayout)); viewEngine .Setup(v => v.GetPage("NestedLayout", "Layout")) .Returns(new RazorPageResult("Layout", Enumerable.Empty<string>())); viewEngine .Setup(p => p.FindPage(It.IsAny<ActionContext>(), "Layout")) .Returns(new RazorPageResult("Layout", baseLayout)); var view = new RazorView( viewEngine.Object, Mock.Of<IRazorPageActivator>(), new IRazorPage[0], page, new HtmlTestEncoder()); var viewContext = CreateViewContext(view); // Act await view.RenderAsync(viewContext); // Assert Assert.Equal(expected, viewContext.Writer.ToString()); }
public async Task RenderAsync_SucceedsIfNestedSectionsAreRendered() { // Arrange var expected = string.Join( Environment.NewLine, "layout-section-content", "page-section-content"); var htmlEncoder = new HtmlTestEncoder(); var page = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = "~/Shared/Layout1.cshtml"; v.DefineSection("foo", async writer => { await writer.WriteAsync("page-section-content"); }); }); var nestedLayout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = "~/Shared/Layout2.cshtml"; v.RenderBodyPublic(); v.DefineSection("foo", async writer => { await writer.WriteLineAsync("layout-section-content"); await v.RenderSectionAsync("foo"); }); }) { Path = "/Shared/Layout1.cshtml" }; var baseLayout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.RenderBodyPublic(); v.RenderSection("foo"); }) { Path = "/Shared/Layout2.cshtml" }; var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict); viewEngine .Setup(v => v.GetPage(/*executingFilePath*/ null, "~/Shared/Layout1.cshtml")) .Returns(new RazorPageResult("~/Shared/Layout1.cshtml", nestedLayout)); viewEngine .Setup(v => v.GetPage("/Shared/Layout1.cshtml", "~/Shared/Layout2.cshtml")) .Returns(new RazorPageResult("~/Shared/Layout2.cshtml", baseLayout)); var view = new RazorView( viewEngine.Object, Mock.Of<IRazorPageActivator>(), new IRazorPage[0], page, new HtmlTestEncoder()); var viewContext = CreateViewContext(view); // Act await view.RenderAsync(viewContext); // Assert Assert.Equal(expected, viewContext.Writer.ToString()); }
public async Task RenderAsync_ExecutesLayoutPages() { // Arrange var htmlEncoder = new HtmlTestEncoder(); var htmlEncodedNewLine = htmlEncoder.Encode(Environment.NewLine); var expected = "HtmlEncode[[layout-content" + Environment.NewLine + "]]head-content" + htmlEncodedNewLine + "body-content" + htmlEncodedNewLine + "foot-content"; var page = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.WriteLiteral("body-content"); v.Layout = LayoutPath; v.DefineSection("head", async writer => { await writer.WriteAsync("head-content"); }); v.DefineSection("foot", async writer => { await writer.WriteAsync("foot-content"); }); }); var layout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Write("layout-content" + Environment.NewLine); v.Write(v.RenderSection("head")); v.Write(Environment.NewLine); v.RenderBodyPublic(); v.Write(Environment.NewLine); v.Write(v.RenderSection("foot")); }); var activator = new Mock<IRazorPageActivator>(); activator .Setup(a => a.Activate(page, It.IsAny<ViewContext>())) .Verifiable(); activator .Setup(a => a.Activate(layout, It.IsAny<ViewContext>())) .Verifiable(); var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict); viewEngine .Setup(v => v.GetPage(/*executingFilePath*/ null, LayoutPath)) .Returns(new RazorPageResult(LayoutPath, layout)) .Verifiable(); var view = new RazorView( viewEngine.Object, activator.Object, new IRazorPage[0], page, new HtmlTestEncoder()); var viewContext = CreateViewContext(view); // Act await view.RenderAsync(viewContext); // Assert // Verify the activator was invoked for the primary page and layout page. activator.Verify(); Assert.Equal(expected, viewContext.Writer.ToString()); viewEngine.Verify(); }
public async Task RenderAsync_AsPartial_ExecutesLayout_ButNotViewStartPages() { // Arrange var htmlEncoder = new HtmlTestEncoder(); var expected = string.Join( Environment.NewLine, "HtmlEncode[[layout-content", "]]HtmlEncode[[page-content]]"); var page = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = LayoutPath; v.Write("page-content"); }); var layout = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Write("layout-content" + Environment.NewLine); v.RenderBodyPublic(); }); var pageFactory = new Mock<IRazorPageFactoryProvider>(); pageFactory .Setup(p => p.CreateFactory(LayoutPath)) .Returns(new RazorPageFactoryResult(() => layout, new IChangeToken[0])); var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict); viewEngine .Setup(v => v.GetPage(/*executingFilePath*/ null, LayoutPath)) .Returns(new RazorPageResult(LayoutPath, layout)); var view = new RazorView( viewEngine.Object, Mock.Of<IRazorPageActivator>(), new IRazorPage[0], page, new HtmlTestEncoder()); var viewContext = CreateViewContext(view); // Act await view.RenderAsync(viewContext); // Assert Assert.Equal(expected, viewContext.Writer.ToString()); }
public TestableRazorPage(Action<TestableRazorPage> executeAction) { _executeAction = executeAction; HtmlEncoder = new HtmlTestEncoder(); }
public async Task FlushAsync_DoesNotThrowWhenInvokedInsideOfASection() { // Arrange var htmlEncoder = new HtmlTestEncoder(); var expected = "HtmlEncode[[layout-1" + Environment.NewLine + "]]section-content-1" + Environment.NewLine + "section-content-2"; var page = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Layout = "layout-1"; v.DefineSection("foo", async _ => { v.WriteLiteral("section-content-1" + Environment.NewLine); await v.FlushAsync(); v.WriteLiteral("section-content-2"); }); }); var layout1 = new TestableRazorPage(v => { v.HtmlEncoder = htmlEncoder; v.Write("layout-1" + Environment.NewLine); v.RenderBodyPublic(); v.Write(v.RenderSection("foo")); }); var viewEngine = new Mock<IRazorViewEngine>(MockBehavior.Strict); viewEngine .Setup(p => p.GetPage(/*executingFilePath*/ null, "layout-1")) .Returns(new RazorPageResult("layout-1", Enumerable.Empty<string>())); viewEngine .Setup(p => p.FindPage(It.IsAny<ActionContext>(), "layout-1")) .Returns(new RazorPageResult("layout-1", layout1)); var view = new RazorView( viewEngine.Object, Mock.Of<IRazorPageActivator>(), new IRazorPage[0], page, new HtmlTestEncoder()); var viewContext = CreateViewContext(view); // Act await view.RenderAsync(viewContext); // Assert Assert.Equal(expected, viewContext.Writer.ToString()); }
public async Task GetChildContentAsync_CachesValuePerEncoderInstance(HtmlEncoder encoder) { // Arrange var executionCount = 0; var executionContext = new TagHelperExecutionContext( "p", tagMode: TagMode.StartTagAndEndTag, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => { executionCount++; return Task.FromResult(result: true); }, startTagHelperWritingScope: _ => { }, endTagHelperWritingScope: () => new DefaultTagHelperContent()); // HtmlEncoderData includes another HtmlTestEncoder instance but method compares HtmlEncoder instances. var firstEncoder = new HtmlTestEncoder(); // Act var content1 = await executionContext.GetChildContentAsync(useCachedResult: true, encoder: firstEncoder); var content2 = await executionContext.GetChildContentAsync(useCachedResult: true, encoder: encoder); // Assert Assert.Equal(2, executionCount); }
public void MoveTo_MovesToBuilder(TagHelperOutput output, string expected) { // Arrange var writer = new StringWriter(); var testEncoder = new HtmlTestEncoder(); var buffer = new HtmlContentBuilder(); var tagHelperExecutionContext = new TagHelperExecutionContext( tagName: output.TagName, tagMode: output.TagMode, items: new Dictionary<object, object>(), uniqueId: string.Empty, executeChildContentAsync: () => Task.FromResult(result: true), startTagHelperWritingScope: _ => { }, endTagHelperWritingScope: () => new DefaultTagHelperContent()); tagHelperExecutionContext.Output = output; // Act ((IHtmlContentContainer)output).MoveTo(buffer); // Assert buffer.WriteTo(writer, testEncoder); Assert.Equal(string.Empty, output.PreElement.GetContent()); Assert.Equal(string.Empty, output.PreContent.GetContent()); Assert.Equal(string.Empty, output.Content.GetContent()); Assert.Equal(string.Empty, output.PostContent.GetContent()); Assert.Equal(string.Empty, output.PostElement.GetContent()); Assert.Empty(output.Attributes); Assert.Equal(expected, writer.ToString(), StringComparer.Ordinal); }