/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Middleware/OutputCaching/test/OutputCachePolicyProviderTests.cs
395 строк
15 KB
Sébastien Ros
Improve vary-by rules (#43257)
01 сен 2022, 00:43
Не верифицирован
01 сен 2022, 00:43
1546cf9
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging.Testing; using Microsoft.Net.Http.Headers; namespace Microsoft.AspNetCore.OutputCaching.Tests; public class OutputCachePolicyProviderTests { public static TheoryData<string> CacheableMethods { get { return new TheoryData<string> { HttpMethods.Get, HttpMethods.Head }; } } public static TheoryData<string> NonCacheableMethods { get { return new TheoryData<string> { HttpMethods.Post, HttpMethods.Put, HttpMethods.Delete, HttpMethods.Trace, HttpMethods.Connect, HttpMethods.Options, "", null }; } } [Theory] [MemberData(nameof(CacheableMethods))] public async Task AttemptOutputCaching_CacheableMethods_IsAllowed(string method) { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); var policies = new[] { new OutputCachePolicyBuilder().Build() }; context.HttpContext.Request.Method = method; foreach (var policy in policies) { await policy.CacheRequestAsync(context, default); } Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Theory] [MemberData(nameof(NonCacheableMethods))] public async Task AttemptOutputCaching_UncacheableMethods_NotAllowed(string method) { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); var policy = new OutputCachePolicyBuilder().Build(); context.HttpContext.Request.Method = method; await policy.CacheRequestAsync(context, default); Assert.False(context.AllowCacheLookup); Assert.False(context.AllowCacheStorage); } [Fact] public async Task AttemptResponseCaching_AuthorizationHeaders_NotAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Request.Method = HttpMethods.Get; context.HttpContext.Request.Headers.Authorization = "Placeholder"; var policy = new OutputCachePolicyBuilder().Build(); await policy.CacheRequestAsync(context, default); Assert.False(context.AllowCacheStorage); Assert.False(context.AllowCacheLookup); } [Fact] public async Task AllowCacheStorage_NoStore_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Request.Method = HttpMethods.Get; context.HttpContext.Request.Headers.CacheControl = new CacheControlHeaderValue() { NoStore = true }.ToString(); var policy = new OutputCachePolicyBuilder().Build(); await policy.CacheRequestAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.Empty(sink.Writes); } [Fact] public async Task AllowCacheLookup_LegacyDirectives_OverridenByCacheControl() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Request.Method = HttpMethods.Get; context.HttpContext.Request.Headers.Pragma = "no-cache"; context.HttpContext.Request.Headers.CacheControl = "max-age=10"; var policy = new OutputCachePolicyBuilder().Build(); await policy.CacheRequestAsync(context, default); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_NoPublic_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_Public_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue() { Public = true }.ToString(); var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_NoCache_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue() { NoCache = true }.ToString(); var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_ResponseNoStore_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue() { NoStore = true }.ToString(); var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_SetCookieHeader_NotAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.Headers.SetCookie = "cookieName=cookieValue"; var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.False(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); } [Fact] public async Task IsResponseCacheable_VaryHeaderByStar_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.Headers.Vary = "*"; var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_Private_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue() { Private = true }.ToString(); var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Theory] [InlineData(StatusCodes.Status200OK)] public async Task IsResponseCacheable_SuccessStatusCodes_IsAllowed(int statusCode) { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.StatusCode = statusCode; var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Theory] [InlineData(StatusCodes.Status100Continue)] [InlineData(StatusCodes.Status101SwitchingProtocols)] [InlineData(StatusCodes.Status102Processing)] [InlineData(StatusCodes.Status201Created)] [InlineData(StatusCodes.Status202Accepted)] [InlineData(StatusCodes.Status203NonAuthoritative)] [InlineData(StatusCodes.Status204NoContent)] [InlineData(StatusCodes.Status205ResetContent)] [InlineData(StatusCodes.Status206PartialContent)] [InlineData(StatusCodes.Status207MultiStatus)] [InlineData(StatusCodes.Status208AlreadyReported)] [InlineData(StatusCodes.Status226IMUsed)] [InlineData(StatusCodes.Status300MultipleChoices)] [InlineData(StatusCodes.Status301MovedPermanently)] [InlineData(StatusCodes.Status302Found)] [InlineData(StatusCodes.Status303SeeOther)] [InlineData(StatusCodes.Status304NotModified)] [InlineData(StatusCodes.Status305UseProxy)] [InlineData(StatusCodes.Status306SwitchProxy)] [InlineData(StatusCodes.Status307TemporaryRedirect)] [InlineData(StatusCodes.Status308PermanentRedirect)] [InlineData(StatusCodes.Status400BadRequest)] [InlineData(StatusCodes.Status401Unauthorized)] [InlineData(StatusCodes.Status402PaymentRequired)] [InlineData(StatusCodes.Status403Forbidden)] [InlineData(StatusCodes.Status404NotFound)] [InlineData(StatusCodes.Status405MethodNotAllowed)] [InlineData(StatusCodes.Status406NotAcceptable)] [InlineData(StatusCodes.Status407ProxyAuthenticationRequired)] [InlineData(StatusCodes.Status408RequestTimeout)] [InlineData(StatusCodes.Status409Conflict)] [InlineData(StatusCodes.Status410Gone)] [InlineData(StatusCodes.Status411LengthRequired)] [InlineData(StatusCodes.Status412PreconditionFailed)] [InlineData(StatusCodes.Status413RequestEntityTooLarge)] [InlineData(StatusCodes.Status414RequestUriTooLong)] [InlineData(StatusCodes.Status415UnsupportedMediaType)] [InlineData(StatusCodes.Status416RequestedRangeNotSatisfiable)] [InlineData(StatusCodes.Status417ExpectationFailed)] [InlineData(StatusCodes.Status418ImATeapot)] [InlineData(StatusCodes.Status419AuthenticationTimeout)] [InlineData(StatusCodes.Status421MisdirectedRequest)] [InlineData(StatusCodes.Status422UnprocessableEntity)] [InlineData(StatusCodes.Status423Locked)] [InlineData(StatusCodes.Status424FailedDependency)] [InlineData(StatusCodes.Status426UpgradeRequired)] [InlineData(StatusCodes.Status428PreconditionRequired)] [InlineData(StatusCodes.Status429TooManyRequests)] [InlineData(StatusCodes.Status431RequestHeaderFieldsTooLarge)] [InlineData(StatusCodes.Status451UnavailableForLegalReasons)] [InlineData(StatusCodes.Status500InternalServerError)] [InlineData(StatusCodes.Status501NotImplemented)] [InlineData(StatusCodes.Status502BadGateway)] [InlineData(StatusCodes.Status503ServiceUnavailable)] [InlineData(StatusCodes.Status504GatewayTimeout)] [InlineData(StatusCodes.Status505HttpVersionNotsupported)] [InlineData(StatusCodes.Status506VariantAlsoNegotiates)] [InlineData(StatusCodes.Status507InsufficientStorage)] [InlineData(StatusCodes.Status508LoopDetected)] [InlineData(StatusCodes.Status510NotExtended)] [InlineData(StatusCodes.Status511NetworkAuthenticationRequired)] public async Task IsResponseCacheable_NonSuccessStatusCodes_NotAllowed(int statusCode) { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.StatusCode = statusCode; var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheLookup); Assert.False(context.AllowCacheStorage); } [Fact] public async Task IsResponseCacheable_NoExpiryRequirements_IsAllowed() { var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.StatusCode = StatusCodes.Status200OK; var utcNow = DateTimeOffset.UtcNow; context.HttpContext.Response.Headers.Date = HeaderUtilities.FormatDate(utcNow); context.ResponseTime = DateTimeOffset.MaxValue; var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_MaxAgeOverridesExpiry_IsAllowed() { var utcNow = DateTimeOffset.UtcNow; var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.StatusCode = StatusCodes.Status200OK; context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue() { MaxAge = TimeSpan.FromSeconds(10) }.ToString(); context.HttpContext.Response.Headers.Expires = HeaderUtilities.FormatDate(utcNow); context.HttpContext.Response.Headers.Date = HeaderUtilities.FormatDate(utcNow); context.ResponseTime = utcNow + TimeSpan.FromSeconds(9); var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } [Fact] public async Task IsResponseCacheable_SharedMaxAgeOverridesMaxAge_IsAllowed() { var utcNow = DateTimeOffset.UtcNow; var sink = new TestSink(); var context = TestUtils.CreateTestContext(testSink: sink); context.HttpContext.Response.StatusCode = StatusCodes.Status200OK; context.HttpContext.Response.Headers.CacheControl = new CacheControlHeaderValue() { MaxAge = TimeSpan.FromSeconds(10), SharedMaxAge = TimeSpan.FromSeconds(15) }.ToString(); context.HttpContext.Response.Headers.Date = HeaderUtilities.FormatDate(utcNow); context.ResponseTime = utcNow + TimeSpan.FromSeconds(11); var policy = new OutputCachePolicyBuilder().Build(); await policy.ServeResponseAsync(context, default); Assert.True(context.AllowCacheStorage); Assert.True(context.AllowCacheLookup); Assert.Empty(sink.Writes); } }