| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the MIT license.
- using System;
- using System.Collections.Generic;
- using System.Globalization;
- using System.Linq;
- using System.Net;
- using System.Net.Http;
- using System.Net.Http.Headers;
- using System.Reflection;
- using System.Text;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Hosting;
- using Microsoft.AspNetCore.Mvc.Testing;
- using Microsoft.AspNetCore.Testing;
- using Xunit;
- namespace Microsoft.AspNetCore.Mvc.FunctionalTests
- {
- public class HtmlGenerationTest :
- IClassFixture<MvcTestFixture<HtmlGenerationWebSite.Startup>>,
- IClassFixture<MvcEncodedTestFixture<HtmlGenerationWebSite.Startup>>
- {
- private static readonly Assembly _resourcesAssembly = typeof(HtmlGenerationTest).GetTypeInfo().Assembly;
- public HtmlGenerationTest(
- MvcTestFixture<HtmlGenerationWebSite.Startup> fixture,
- MvcEncodedTestFixture<HtmlGenerationWebSite.Startup> encodedFixture)
- {
- Factory = fixture.Factories.FirstOrDefault() ?? fixture.WithWebHostBuilder(ConfigureWebHostBuilder);
- Client = fixture.CreateDefaultClient();
- EncodedClient = encodedFixture.CreateDefaultClient();
- }
- private static void ConfigureWebHostBuilder(IWebHostBuilder builder) =>
- builder.UseStartup<HtmlGenerationWebSite.Startup>();
- public HttpClient Client { get; }
- public HttpClient EncodedClient { get; }
- public WebApplicationFactory<HtmlGenerationWebSite.Startup> Factory { get; }
- public static TheoryData<string, string> WebPagesData
- {
- get
- {
- var data = new TheoryData<string, string>
- {
- { "Customer", "/Customer/HtmlGeneration_Customer" },
- { "Index", null },
- { "Product", null },
- { "Link", null },
- { "Script", null },
- // Testing attribute values with boolean and null values
- { "AttributesWithBooleanValues", null },
- // Testing SelectTagHelper with Html.BeginForm
- { "CreateWarehouse", "/HtmlGeneration_Home/CreateWarehouse" },
- // Testing the HTML helpers with FormTagHelper
- { "EditWarehouse", null },
- { "Form", "/HtmlGeneration_Home/Form" },
- // Testing MVC tag helpers invoked in the editor templates from HTML helpers
- { "EmployeeList", "/HtmlGeneration_Home/EmployeeList" },
- // Testing the EnvironmentTagHelper
- { "Environment", null },
- // Testing InputTagHelper with File
- { "Input", null },
- // Test ability to generate nearly identical HTML with MVC tag and HTML helpers.
- // Only attribute order should differ.
- { "Order", "/HtmlGeneration_Order/Submit" },
- { "OrderUsingHtmlHelpers", "/HtmlGeneration_Order/Submit" },
- // Testing PartialTagHelper
- { "PartialTagHelperWithoutModel", null },
- { "Warehouse", null },
- // Testing InputTagHelpers invoked in the partial views
- { "ProductList", "/HtmlGeneration_Product" },
- { "ProductListUsingTagHelpers", "/HtmlGeneration_Product" },
- { "ProductListUsingTagHelpersWithNullModel", "/HtmlGeneration_Product" },
- };
- return data;
- }
- }
- [Fact]
- public async Task EnumValues_SerializeCorrectly()
- {
- // Arrange & Act
- var response = await Client.GetStringAsync("http://localhost/HtmlGeneration_Home/Enum");
- // Assert
- Assert.Equal($"Vrijdag{Environment.NewLine}Month: FirstOne", response, ignoreLineEndingDifferences: true);
- }
- [Theory(Skip = "https://github.com/dotnet/aspnetcore/issues/34599")]
- [MemberData(nameof(WebPagesData))]
- public async Task HtmlGenerationWebSite_GeneratesExpectedResults(string action, string antiforgeryPath)
- {
- // Arrange
- var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
- var outputFile = "compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home." + action + ".html";
- var expectedContent =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
- // Act
- // The host is not important as everything runs in memory and tests are isolated from each other.
- var response = await Client.GetAsync("http://localhost/HtmlGeneration_Home/" + action);
- var responseContent = await response.Content.ReadAsStringAsync();
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
- responseContent = responseContent.Trim();
- if (antiforgeryPath == null)
- {
- ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
- Assert.Equal(expectedContent.Trim(), responseContent, ignoreLineEndingDifferences: true);
- }
- else
- {
- var forgeryToken = AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseContent, antiforgeryPath);
- if (ResourceFile.GenerateBaselines)
- {
- // Reverse usual substitution and insert a format item into the new file content.
- responseContent = responseContent.Replace(forgeryToken, "{0}");
- ResourceFile.UpdateFile(_resourcesAssembly, outputFile, expectedContent, responseContent);
- }
- else
- {
- expectedContent = string.Format(CultureInfo.InvariantCulture, expectedContent, forgeryToken);
- Assert.Equal(expectedContent.Trim(), responseContent, ignoreLineEndingDifferences: true);
- }
- }
- }
- [Fact(Skip = "https://github.com/dotnet/aspnetcore/issues/34599")]
- public async Task HtmlGenerationWebSite_GeneratesExpectedResults_WithImageData()
- {
- await HtmlGenerationWebSite_GeneratesExpectedResults("Image", antiforgeryPath: null);
- }
- [Fact]
- public async Task HtmlGenerationWebSite_LinkGeneration_With21CompatibilityBehavior()
- {
- // Arrange
- var client = Factory
- .WithWebHostBuilder(builder => builder.UseStartup<HtmlGenerationWebSite.StartupWithoutEndpointRouting>())
- .CreateDefaultClient();
- var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
- var outputFile = "compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home.Index21Compat.html";
- var expectedContent =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
- // Act
- // The host is not important as everything runs in memory and tests are isolated from each other.
- var response = await client.GetAsync("http://localhost/HtmlGeneration_Home/");
- var responseContent = await response.Content.ReadAsStringAsync();
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
- responseContent = responseContent.Trim();
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile, expectedContent, responseContent);
- }
- public static TheoryData<string, string> EncodedPagesData
- {
- get
- {
- return new TheoryData<string, string>
- {
- { "AttributesWithBooleanValues", null },
- { "EditWarehouse", null },
- { "Index", null },
- { "Order", "/HtmlGeneration_Order/Submit" },
- { "OrderUsingHtmlHelpers", "/HtmlGeneration_Order/Submit" },
- { "Product", null },
- };
- }
- }
- [Theory]
- [MemberData(nameof(EncodedPagesData))]
- public async Task HtmlGenerationWebSite_GenerateEncodedResults(string action, string antiforgeryPath)
- {
- // Arrange
- var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
- var outputFile = "compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Home." + action + ".Encoded.html";
- var expectedContent =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
- // Act
- // The host is not important as everything runs in memory and tests are isolated from each other.
- var response = await EncodedClient.GetAsync("http://localhost/HtmlGeneration_Home/" + action);
- var responseContent = await response.Content.ReadAsStringAsync();
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
- responseContent = responseContent.Trim();
- if (antiforgeryPath == null)
- {
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile, expectedContent, responseContent);
- }
- else
- {
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile, expectedContent, responseContent, token: AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseContent, antiforgeryPath));
- }
- }
- [ConditionalTheory]
- [InlineData("Link", null)]
- [InlineData("Script", null)]
- [SkipOnHelix("https://github.com/dotnet/aspnetcore/issues/10423")]
- public Task HtmlGenerationWebSite_GenerateEncodedResultsNotReadyForHelix(string action, string antiforgeryPath)
- => HtmlGenerationWebSite_GenerateEncodedResults(action, antiforgeryPath);
- // Testing how ModelMetadata is handled as ViewDataDictionary instances are created.
- [Theory]
- [InlineData("AtViewModel")]
- [InlineData("NullViewModel")]
- [InlineData("ViewModel")]
- public async Task CheckViewData_GeneratesExpectedResults(string action)
- {
- // Arrange
- var expectedMediaType = MediaTypeHeaderValue.Parse("text/html; charset=utf-8");
- var outputFile = "compiler/resources/HtmlGenerationWebSite.CheckViewData." + action + ".html";
- var expectedContent =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
- // Act
- var response = await Client.GetAsync("http://localhost/CheckViewData/" + action);
- var responseContent = await response.Content.ReadAsStringAsync();
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- Assert.Equal(expectedMediaType, response.Content.Headers.ContentType);
- responseContent = responseContent.Trim();
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile, expectedContent, responseContent);
- }
- [Fact]
- public async Task ValidationTagHelpers_GeneratesExpectedSpansAndDivs()
- {
- // Arrange
- var outputFile = "compiler/resources/HtmlGenerationWebSite.HtmlGeneration_Customer.Index.html";
- var expectedContent =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile, sourceFile: false);
- var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Customer/HtmlGeneration_Customer");
- var nameValueCollection = new List<KeyValuePair<string, string>>
- {
- new KeyValuePair<string,string>("Number", string.Empty),
- new KeyValuePair<string,string>("Name", string.Empty),
- new KeyValuePair<string,string>("Email", string.Empty),
- new KeyValuePair<string,string>("PhoneNumber", string.Empty),
- new KeyValuePair<string,string>("Password", string.Empty)
- };
- request.Content = new FormUrlEncodedContent(nameValueCollection);
- // Act
- var response = await Client.SendAsync(request);
- var responseContent = await response.Content.ReadAsStringAsync();
- // Assert
- Assert.Equal(HttpStatusCode.OK, response.StatusCode);
- responseContent = responseContent.Trim();
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile, expectedContent, responseContent, token: AntiforgeryTestHelper.RetrieveAntiforgeryToken(responseContent, "Customer/HtmlGeneration_Customer"));
- }
- [Fact]
- public async Task ClientValidators_AreGeneratedDuringInitialRender()
- {
- // Arrange
- var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer/HtmlGeneration_Customer/CustomerWithRecords");
- // Act
- var response = await Client.SendAsync(request);
- // Assert
- var document = await response.GetHtmlDocumentAsync();
- var numberInput = document.RequiredQuerySelector("input[id=Number]");
- Assert.Equal("true", numberInput.GetAttribute("data-val"));
- Assert.Equal("The field Number must be between 1 and 100.", numberInput.GetAttribute("data-val-range"));
- Assert.Equal("The Number field is required.", numberInput.GetAttribute("data-val-required"));
- var passwordInput = document.RequiredQuerySelector("input[id=Password]");
- Assert.Equal("true", passwordInput.GetAttribute("data-val"));
- Assert.Equal("The Password field is required.", passwordInput.GetAttribute("data-val-required"));
- var addressInput = document.RequiredQuerySelector("input[id=Address]");
- Assert.Equal("true", addressInput.GetAttribute("data-val"));
- Assert.Equal("The Address field is required.", addressInput.GetAttribute("data-val-required"));
- }
- [Fact]
- public async Task ValidationTagHelpers_UsingRecords()
- {
- // Arrange
- var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost/Customer/HtmlGeneration_Customer/CustomerWithRecords");
- var nameValueCollection = new List<KeyValuePair<string, string>>
- {
- new KeyValuePair<string,string>("Number", string.Empty),
- new KeyValuePair<string,string>("Name", string.Empty),
- new KeyValuePair<string,string>("Email", string.Empty),
- new KeyValuePair<string,string>("PhoneNumber", string.Empty),
- new KeyValuePair<string,string>("Password", string.Empty),
- new KeyValuePair<string,string>("Address", string.Empty),
- };
- request.Content = new FormUrlEncodedContent(nameValueCollection);
- // Act
- var response = await Client.SendAsync(request);
- // Assert
- var document = await response.GetHtmlDocumentAsync();
- var validation = document.RequiredQuerySelector("span[data-valmsg-for=Number]");
- Assert.Equal("The value '' is invalid.", validation.TextContent);
- validation = document.QuerySelector("span[data-valmsg-for=Name]");
- Assert.Null(validation);
- validation = document.QuerySelector("span[data-valmsg-for=Email]");
- Assert.Equal("field-validation-valid", validation.ClassName);
- validation = document.QuerySelector("span[data-valmsg-for=Password]");
- Assert.Equal("The Password field is required.", validation.TextContent);
- validation = document.QuerySelector("span[data-valmsg-for=Address]");
- Assert.Equal("The Address field is required.", validation.TextContent);
- }
- [Fact]
- public async Task CacheTagHelper_CanCachePortionsOfViewsPartialViewsAndViewComponents()
- {
- // Arrange
- var assertFile =
- "compiler/resources/CacheTagHelper_CanCachePortionsOfViewsPartialViewsAndViewComponents.Assert";
- var outputFile1 = assertFile + "1.txt";
- var expected1 =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile1, sourceFile: false);
- var outputFile2 = assertFile + "2.txt";
- var expected2 =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile2, sourceFile: false);
- var outputFile3 = assertFile + "3.txt";
- var expected3 =
- await ResourceFile.ReadResourceAsync(_resourcesAssembly, outputFile3, sourceFile: false);
- // Act - 1
- // Verify that content gets cached based on vary-by-params
- var targetUrl = "/catalog?categoryId=1&correlationid=1";
- var request = RequestWithLocale(targetUrl, "North");
- var response1 = await (await Client.SendAsync(request)).Content.ReadAsStringAsync();
- request = RequestWithLocale(targetUrl, "North");
- var response2 = await (await Client.SendAsync(request)).Content.ReadAsStringAsync();
- // Assert - 1
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile1, expected1, response1.Trim());
- if (!ResourceFile.GenerateBaselines)
- {
- Assert.Equal(expected1, response2.Trim(), ignoreLineEndingDifferences: true);
- }
- // Act - 2
- // Verify content gets changed in partials when one of the vary by parameters is changed
- targetUrl = "/catalog?categoryId=3&correlationid=2";
- request = RequestWithLocale(targetUrl, "North");
- var response3 = await (await Client.SendAsync(request)).Content.ReadAsStringAsync();
- request = RequestWithLocale(targetUrl, "North");
- var response4 = await (await Client.SendAsync(request)).Content.ReadAsStringAsync();
- // Assert - 2
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile2, expected2, response3.Trim());
- if (!ResourceFile.GenerateBaselines)
- {
- Assert.Equal(expected2, response4.Trim(), ignoreLineEndingDifferences: true);
- }
- // Act - 3
- // Verify content gets changed in a View Component when the Vary-by-header parameters is changed
- targetUrl = "/catalog?categoryId=3&correlationid=3";
- request = RequestWithLocale(targetUrl, "East");
- var response5 = await (await Client.SendAsync(request)).Content.ReadAsStringAsync();
- request = RequestWithLocale(targetUrl, "East");
- var response6 = await (await Client.SendAsync(request)).Content.ReadAsStringAsync();
- // Assert - 3
- ResourceFile.UpdateOrVerify(_resourcesAssembly, outputFile3, expected3, response5.Trim());
- if (!ResourceFile.GenerateBaselines)
- {
- Assert.Equal(expected3, response6.Trim(), ignoreLineEndingDifferences: true);
- }
- }
- [Fact]
- public async Task CacheTagHelper_ExpiresContent_BasedOnExpiresParameter()
- {
- // Arrange & Act - 1
- var response1 = await Client.GetStringAsync("/catalog/2");
- // Assert - 1
- var expected1 = "Cached content for 2";
- Assert.Equal(expected1, response1.Trim());
- // Act - 2
- await Task.Delay(TimeSpan.FromSeconds(2));
- var response2 = await Client.GetStringAsync("/catalog/3");
- // Assert - 2
- var expected2 = "Cached content for 3";
- Assert.Equal(expected2, response2.Trim());
- }
- [Fact]
- public async Task CacheTagHelper_UsesVaryByCookie_ToVaryContent()
- {
- // Arrange & Act - 1
- var response1 = await Client.GetStringAsync("/catalog/cart?correlationid=1");
- // Assert - 1
- var expected1 = "Cart content for 1";
- Assert.Equal(expected1, response1.Trim());
- // Act - 2
- var request = new HttpRequestMessage(HttpMethod.Get, "/catalog/cart?correlationid=2");
- request.Headers.Add("Cookie", "CartId=10");
- var response2 = await (await Client.SendAsync(request)).Content.ReadAsStringAsync();
- // Assert - 2
- var expected2 = "Cart content for 2";
- Assert.Equal(expected2, response2.Trim());
- // Act - 3
- // Resend the cookieless request and cached result from the first response.
- var response3 = await Client.GetStringAsync("/catalog/cart?correlationid=3");
- // Assert - 3
- Assert.Equal(expected1, response3.Trim());
- }
- [Fact]
- public async Task CacheTagHelper_VariesByRoute()
- {
- // Arrange & Act - 1
- var response1 = await Client.GetStringAsync(
- "/catalog/north-west/confirm-payment?confirmationId=1");
- // Assert - 1
- var expected1 = "Welcome Guest. Your confirmation id is 1. (Region north-west)";
- Assert.Equal(expected1, response1.Trim());
- // Act - 2
- var response2 = await Client.GetStringAsync(
- "/catalog/south-central/confirm-payment?confirmationId=2");
- // Assert - 2
- var expected2 = "Welcome Guest. Your confirmation id is 2. (Region south-central)";
- Assert.Equal(expected2, response2.Trim());
- // Act 3
- var response3 = await Client.GetStringAsync(
- "/catalog/north-west/Silver/confirm-payment?confirmationId=4");
- var expected3 = "Welcome Silver member. Your confirmation id is 4. (Region north-west)";
- Assert.Equal(expected3, response3.Trim());
- // Act 4
- var response4 = await Client.GetStringAsync(
- "/catalog/north-west/Gold/confirm-payment?confirmationId=5");
- var expected4 = "Welcome Gold member. Your confirmation id is 5. (Region north-west)";
- Assert.Equal(expected4, response4.Trim());
- // Act - 4
- // Resend the responses and expect cached results.
- response1 = await Client.GetStringAsync(
- "/catalog/north-west/confirm-payment?confirmationId=301");
- response2 = await Client.GetStringAsync(
- "/catalog/south-central/confirm-payment?confirmationId=402");
- response3 = await Client.GetStringAsync(
- "/catalog/north-west/Silver/confirm-payment?confirmationId=503");
- response4 = await Client.GetStringAsync(
- "/catalog/north-west/Gold/confirm-payment?confirmationId=608");
- // Assert - 4
- Assert.Equal(expected1, response1.Trim());
- Assert.Equal(expected2, response2.Trim());
- Assert.Equal(expected3, response3.Trim());
- Assert.Equal(expected4, response4.Trim());
- }
- [Fact]
- public async Task CacheTagHelper_VariesByUserId()
- {
- // Arrange & Act - 1
- var response1 = await Client.GetStringAsync("/catalog/past-purchases/test1?correlationid=1");
- var response2 = await Client.GetStringAsync("/catalog/past-purchases/test1?correlationid=2");
- // Assert - 1
- var expected1 = "Past purchases for user test1 (1)";
- Assert.Equal(expected1, response1.Trim());
- Assert.Equal(expected1, response2.Trim());
- // Act - 2
- var response3 = await Client.GetStringAsync("/catalog/past-purchases/test2?correlationid=3");
- var response4 = await Client.GetStringAsync("/catalog/past-purchases/test2?correlationid=4");
- // Assert - 2
- var expected2 = "Past purchases for user test2 (3)";
- Assert.Equal(expected2, response3.Trim());
- Assert.Equal(expected2, response4.Trim());
- }
- [Fact]
- [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/36765")]
- public async Task CacheTagHelper_BubblesExpirationOfNestedTagHelpers()
- {
- // Arrange & Act - 1
- var response1 = await Client.GetStringAsync("/categories/Books?correlationId=1");
- // Assert - 1
- var expected1 =
- @"Category: Books
- Products: Book1, Book2 (1)";
- Assert.Equal(expected1, response1.Trim(), ignoreLineEndingDifferences: true);
- // Act - 2
- var response2 = await Client.GetStringAsync("/categories/Electronics?correlationId=2");
- // Assert - 2
- var expected2 =
- @"Category: Electronics
- Products: Book1, Book2 (1)";
- Assert.Equal(expected2, response2.Trim(), ignoreLineEndingDifferences: true);
- // Act - 3
- // Trigger an expiration of the nested content.
- var content = @"[{ ""productName"": ""Music Systems"" },{ ""productName"": ""Televisions"" }]";
- var requestMessage = new HttpRequestMessage(HttpMethod.Post, "/categories/Electronics");
- requestMessage.Content = new StringContent(content, Encoding.UTF8, "application/json");
- (await Client.SendAsync(requestMessage)).EnsureSuccessStatusCode();
- var response3 = await Client.GetStringAsync("/categories/Electronics?correlationId=3");
- // Assert - 3
- var expected3 =
- @"Category: Electronics
- Products: Music Systems, Televisions (3)";
- Assert.Equal(expected3, response3.Trim(), ignoreLineEndingDifferences: true);
- }
- [Fact]
- public async Task CacheTagHelper_DoesNotCacheIfDisabled()
- {
- // Arrange & Act
- var response1 = await Client.GetStringAsync("/catalog/GetDealPercentage/20?isEnabled=true");
- var response2 = await Client.GetStringAsync("/catalog/GetDealPercentage/40?isEnabled=true");
- var response3 = await Client.GetStringAsync("/catalog/GetDealPercentage/30?isEnabled=false");
- // Assert
- Assert.Equal("Deal percentage is 20", response1.Trim());
- Assert.Equal("Deal percentage is 20", response2.Trim());
- Assert.Equal("Deal percentage is 30", response3.Trim());
- }
- [Fact]
- public async Task EditorTemplateWithNoModel_RendersWithCorrectMetadata()
- {
- // Arrange
- var expected =
- "<label class=\"control-label col-md-2\" for=\"Name\">ItemName</label>" + Environment.NewLine +
- "<input id=\"Name\" name=\"Name\" type=\"text\" value=\"\" />" + Environment.NewLine + Environment.NewLine +
- "<label class=\"control-label col-md-2\" for=\"Id\">ItemNo</label>" + Environment.NewLine +
- "<input data-val=\"true\" data-val-required=\"The ItemNo field is required.\" id=\"Id\" name=\"Id\" type=\"text\" value=\"\" />" +
- Environment.NewLine + Environment.NewLine;
- // Act
- var response = await Client.GetStringAsync("http://localhost/HtmlGeneration_Home/ItemUsingSharedEditorTemplate");
- // Assert
- Assert.Equal(expected, response, ignoreLineEndingDifferences: true);
- }
- [Fact]
- public async Task EditorTemplateWithSpecificModel_RendersWithCorrectMetadata()
- {
- // Arrange
- var expected = "<label for=\"Description\">ItemDesc</label>" + Environment.NewLine +
- "<input id=\"Description\" name=\"Description\" type=\"text\" value=\"\" />" + Environment.NewLine + Environment.NewLine;
- // Act
- var response = await Client.GetStringAsync("http://localhost/HtmlGeneration_Home/ItemUsingModelSpecificEditorTemplate");
- // Assert
- Assert.Equal(expected, response, ignoreLineEndingDifferences: true);
- }
- // We want to make sure that for 'weird' model expressions involving:
- // - fields
- // - statics
- // - private
- //
- // These tests verify that we don't throw, and can evaluate the expression to get the model
- // value. One quirk of behavior for these cases is that we can't return a correct model metadata
- // instance (this is true for anything other than a public instance property). We're not overly
- // concerned with that, and so the accuracy of the model metadata is not verified by the test.
- [Theory]
- [InlineData("GetWeirdWithHtmlHelpers")]
- [InlineData("GetWeirdWithTagHelpers")]
- public async Task WeirdModelExpressions_CanAccessModelValues(string action)
- {
- // Arrange
- var url = "http://localhost/HtmlGeneration_WeirdExpressions/" + action;
- // Act
- var response = await Client.GetStringAsync(url);
- // Assert
- Assert.Contains("Hello, Field World!", response);
- Assert.Contains("Hello, Static World!", response);
- Assert.Contains("Hello, Private World!", response);
- }
- [Fact]
- public async Task PartialTagHelper_AllowsPassingModelValue()
- {
- // Arrange
- var url = "/HtmlGeneration_Home/StatusMessage";
- // Act
- var document = await Client.GetHtmlDocumentAsync(url);
- // Assert
- var banner = document.RequiredQuerySelector(".banner");
- Assert.Equal("Some status message", banner.TextContent);
- }
- [Fact]
- public async Task PartialTagHelper_AllowsPassingNullModelValue()
- {
- // Regression test for https://github.com/aspnet/Mvc/issues/7667.
- // Arrange
- var url = "/HtmlGeneration_Home/NullStatusMessage";
- // Act
- var document = await Client.GetHtmlDocumentAsync(url);
- // Assert
- var banner = document.RequiredQuerySelector(".banner");
- Assert.Empty(banner.TextContent);
- }
- [Fact]
- public async Task PartialTagHelper_AllowsUsingFallback()
- {
- // Arrange
- var url = "/Customer/PartialWithFallback";
- // Act
- var document = await Client.GetHtmlDocumentAsync(url);
- // Assert
- var content = document.RequiredQuerySelector("#content");
- Assert.Equal("Hello from fallback", content.TextContent);
- }
- [Fact]
- public async Task PartialTagHelper_AllowsUsingOptional()
- {
- // Arrange
- var url = "/Customer/PartialWithOptional";
- // Act
- var document = await Client.GetHtmlDocumentAsync(url);
- // Assert
- var content = document.RequiredQuerySelector("#content");
- Assert.Empty(content.TextContent);
- }
- [Fact]
- public async Task ValidationProviderAttribute_ValidationTagHelpers_GeneratesExpectedDataAttributes()
- {
- // Act
- var document = await Client.GetHtmlDocumentAsync("HtmlGeneration_Home/ValidationProviderAttribute");
- // Assert
- var firstName = document.RequiredQuerySelector("#FirstName");
- Assert.Equal("true", firstName.GetAttribute("data-val"));
- Assert.Equal("The FirstName field is required.", firstName.GetAttribute("data-val-required"));
- Assert.Equal("The field FirstName must be a string with a maximum length of 5.", firstName.GetAttribute("data-val-length"));
- Assert.Equal("5", firstName.GetAttribute("data-val-length-max"));
- Assert.Equal("The field FirstName must match the regular expression '[A-Za-z]*'.", firstName.GetAttribute("data-val-regex"));
- Assert.Equal("[A-Za-z]*", firstName.GetAttribute("data-val-regex-pattern"));
- var lastName = document.RequiredQuerySelector("#LastName");
- Assert.Equal("true", lastName.GetAttribute("data-val"));
- Assert.Equal("The LastName field is required.", lastName.GetAttribute("data-val-required"));
- Assert.Equal("The field LastName must be a string with a maximum length of 6.", lastName.GetAttribute("data-val-length"));
- Assert.Equal("6", lastName.GetAttribute("data-val-length-max"));
- Assert.False(lastName.HasAttribute("data-val-regex"));
- }
- [Fact]
- public async Task ValidationProviderAttribute_ValidationTagHelpers_GeneratesExpectedSpansAndDivsOnValidationError()
- {
- // Arrange
- var request = new HttpRequestMessage(HttpMethod.Post, "HtmlGeneration_Home/ValidationProviderAttribute");
- request.Content = new FormUrlEncodedContent(new Dictionary<string, string>
- {
- { "FirstName", "TestFirstName" },
- });
- // Act
- var response = await Client.SendAsync(request);
- // Assert
- await response.AssertStatusCodeAsync(HttpStatusCode.OK);
- var document = await response.GetHtmlDocumentAsync();
- Assert.Collection(
- document.QuerySelectorAll("div.validation-summary-errors ul li"),
- item => Assert.Equal("The field FirstName must be a string with a maximum length of 5.", item.TextContent),
- item => Assert.Equal("The LastName field is required.", item.TextContent));
- }
- private static HttpRequestMessage RequestWithLocale(string url, string locale)
- {
- var request = new HttpRequestMessage(HttpMethod.Get, url);
- request.Headers.Add("Locale", locale);
- return request;
- }
- }
- }
|