public void BuildPolicy_CreatesDefaultPolicy() { var builder = new OutputCachePolicyBuilder(); var policy = builder.Build(); Assert.Equal(DefaultPolicy.Instance, policy); }
/// <summary> /// Builds and adds an <see cref="IOutputCachePolicy"/> instance to base policies. /// </summary> /// <param name="build">an action on <see cref="OutputCachePolicyBuilder"/>.</param> public void AddBasePolicy(Action <OutputCachePolicyBuilder> build) { var builder = new OutputCachePolicyBuilder(); build(builder); BasePolicies ??= new(); BasePolicies.Add(builder.Build()); }
/// <summary> /// Defines a <see cref="IOutputCachePolicy"/> which can be referenced by name. /// </summary> /// <param name="name">The name of the policy.</param> /// <param name="build">an action on <see cref="OutputCachePolicyBuilder"/>.</param> public void AddPolicy(string name, Action <OutputCachePolicyBuilder> build) { var builder = new OutputCachePolicyBuilder(); build(builder); NamedPolicies ??= new Dictionary <string, IOutputCachePolicy>(StringComparer.OrdinalIgnoreCase); NamedPolicies[name] = builder.Build(); }
public async Task BuildPolicy_CreatesNoStorePolicy() { var context = TestUtils.CreateUninitializedContext(); var builder = new OutputCachePolicyBuilder(); var policy = builder.NoCache().Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.False(context.EnableOutputCaching); }
public async Task BuildPolicy_DisablesLocking() { var context = TestUtils.CreateUninitializedContext(); var builder = new OutputCachePolicyBuilder(); var policy = builder.AllowLocking(false).Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.False(context.AllowLocking); }
public async Task BuildPolicy_CreatesVaryByValuePolicy() { var context = TestUtils.CreateUninitializedContext(); var builder = new OutputCachePolicyBuilder(); var policy = builder.VaryByValue(context => new KeyValuePair <string, string>("color", "blue")).Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Equal("blue", context.CacheVaryByRules.VaryByCustom["color"]); }
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); }
public async Task BuildPolicy_CreatesExpirePolicy() { var context = TestUtils.CreateUninitializedContext(); var duration = 42; var builder = new OutputCachePolicyBuilder(); var policy = builder.Expire(TimeSpan.FromSeconds(duration)).Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Equal(duration, context.ResponseExpirationTimeSpan?.TotalSeconds); }
public async Task BuildPolicy_CreatesTagPolicy() { var context = TestUtils.CreateUninitializedContext(); var builder = new OutputCachePolicyBuilder(); var policy = builder.Tag("tag1", "tag2").Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Contains("tag1", context.Tags); Assert.Contains("tag2", context.Tags); }
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); }
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); }
public async Task BuildPolicy_ClearsDefaultPolicy() { var context = TestUtils.CreateUninitializedContext(); var builder = new OutputCachePolicyBuilder(); var policy = builder.Clear().Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.False(context.AllowLocking); Assert.False(context.AllowCacheLookup); Assert.False(context.AllowCacheStorage); Assert.False(context.EnableOutputCaching); }
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); }
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); }
public async Task BuildPolicy_CreatesVaryByQueryPolicy() { var context = TestUtils.CreateUninitializedContext(); context.HttpContext.Request.QueryString = new QueryString("?QueryA=ValueA&QueryB=ValueB"); var builder = new OutputCachePolicyBuilder(); var policy = builder.VaryByQuery("QueryA", "QueryC").Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Contains("QueryA", (IEnumerable <string>)context.CacheVaryByRules.QueryKeys); Assert.Contains("QueryC", (IEnumerable <string>)context.CacheVaryByRules.QueryKeys); Assert.DoesNotContain("QueryB", (IEnumerable <string>)context.CacheVaryByRules.QueryKeys); }
/// <summary> /// Marks an endpoint to be cached using the specified policy builder. /// </summary> public static TBuilder CacheOutput <TBuilder>(this TBuilder builder, Action <OutputCachePolicyBuilder> policy) where TBuilder : IEndpointConventionBuilder { ArgumentNullException.ThrowIfNull(builder); var outputCachePolicyBuilder = new OutputCachePolicyBuilder(); policy?.Invoke(outputCachePolicyBuilder); builder.Add(endpointBuilder => { endpointBuilder.Metadata.Add(outputCachePolicyBuilder.Build()); }); return(builder); }
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); }
public async Task BuildPolicy_CreatesVaryByHeaderPolicy() { var context = TestUtils.CreateUninitializedContext(); context.HttpContext.Request.Headers["HeaderA"] = "ValueA"; context.HttpContext.Request.Headers["HeaderB"] = "ValueB"; var builder = new OutputCachePolicyBuilder(); var policy = builder.VaryByHeader("HeaderA", "HeaderC").Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Contains("HeaderA", (IEnumerable <string>)context.CacheVaryByRules.HeaderNames); Assert.Contains("HeaderC", (IEnumerable <string>)context.CacheVaryByRules.HeaderNames); Assert.DoesNotContain("HeaderB", (IEnumerable <string>)context.CacheVaryByRules.HeaderNames); }
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); }
public async Task BuildPolicy_AddsCustomPolicy() { var options = new OutputCacheOptions(); var name = "MyPolicy"; var duration = 42; options.AddPolicy(name, b => b.Expire(TimeSpan.FromSeconds(duration))); var context = TestUtils.CreateUninitializedContext(options: options); var builder = new OutputCachePolicyBuilder(); var policy = builder.AddPolicy(new NamedPolicy(name)).Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Equal(duration, context.ResponseExpirationTimeSpan?.TotalSeconds); }
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); }
public async Task BuildPolicy_CreatesVaryByRoutePolicy() { var context = TestUtils.CreateUninitializedContext(); context.HttpContext.Request.RouteValues = new Routing.RouteValueDictionary() { ["RouteA"] = "ValueA", ["RouteB"] = 123.456, }; var builder = new OutputCachePolicyBuilder(); var policy = builder.VaryByRouteValue("RouteA", "RouteC").Build(); await policy.CacheRequestAsync(context, cancellation : default); Assert.True(context.EnableOutputCaching); Assert.Contains("RouteA", (IEnumerable <string>)context.CacheVaryByRules.RouteValueNames); Assert.Contains("RouteC", (IEnumerable <string>)context.CacheVaryByRules.RouteValueNames); Assert.DoesNotContain("RouteB", (IEnumerable <string>)context.CacheVaryByRules.RouteValueNames); }
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); }
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); }