public async Task Attribute_CreatesNoStorePolicy()
    {
        var context = TestUtils.CreateUninitializedContext();

        var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.NoStore));
        await attribute.BuildPolicy().CacheRequestAsync(context, cancellation: default);

        Assert.False(context.EnableOutputCaching);
    }
    public void Attribute_CreatesDefaultPolicy()
    {
        var context = TestUtils.CreateUninitializedContext();

        var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.Default));
        var policy    = attribute.BuildPolicy();

        Assert.Equal(DefaultPolicy.Instance, policy);
    }
    public async Task Attribute_CreatesExpirePolicy()
    {
        var context = TestUtils.CreateUninitializedContext();

        var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.Duration));
        await attribute.BuildPolicy().CacheRequestAsync(context, cancellation: default);

        Assert.True(context.EnableOutputCaching);
        Assert.Equal(42, context.ResponseExpirationTimeSpan?.TotalSeconds);
    }
    public async Task Attribute_CreatesVaryByQueryPolicy()
    {
        var context = TestUtils.CreateUninitializedContext();

        context.HttpContext.Request.QueryString = new QueryString("?QueryA=ValueA&QueryB=ValueB");

        var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.VaryByQueryKeys));
        await attribute.BuildPolicy().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);
    }
    public async Task Attribute_CreatesNamedPolicy()
    {
        var options = new OutputCacheOptions();

        options.AddPolicy("MyPolicy", b => b.Expire(TimeSpan.FromSeconds(42)));

        var context = TestUtils.CreateTestContext(options: options);

        var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.PolicyName));
        await attribute.BuildPolicy().CacheRequestAsync(context, cancellation: default);

        Assert.True(context.EnableOutputCaching);
        Assert.Equal(42, context.ResponseExpirationTimeSpan?.TotalSeconds);
    }
    public async Task Attribute_CreatesVaryByHeaderPolicy()
    {
        var context = TestUtils.CreateUninitializedContext();

        context.HttpContext.Request.Headers["HeaderA"] = "ValueA";
        context.HttpContext.Request.Headers["HeaderB"] = "ValueB";

        var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.VaryByHeaderNames));
        await attribute.BuildPolicy().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 Attribute_CreatesVaryByRoutePolicy()
    {
        var context = TestUtils.CreateUninitializedContext();

        context.HttpContext.Request.RouteValues = new Routing.RouteValueDictionary()
        {
            ["RouteA"] = "ValueA",
            ["RouteB"] = 123.456,
        };

        var attribute = OutputCacheMethods.GetAttribute(nameof(OutputCacheMethods.VaryByRouteValueNames));
        await attribute.BuildPolicy().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);
    }