600 lines
25 KiB
C#
600 lines
25 KiB
C#
// Copyright (c) .NET Foundation. All rights reserved.
|
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Xunit;
|
|
|
|
namespace Microsoft.Net.Http.Headers
|
|
{
|
|
public class CacheControlHeaderValueTest
|
|
{
|
|
[Fact]
|
|
public void Properties_SetAndGetAllProperties_SetValueReturnedInGetter()
|
|
{
|
|
var cacheControl = new CacheControlHeaderValue();
|
|
|
|
// Bool properties
|
|
cacheControl.NoCache = true;
|
|
Assert.True(cacheControl.NoCache, "NoCache");
|
|
cacheControl.NoStore = true;
|
|
Assert.True(cacheControl.NoStore, "NoStore");
|
|
cacheControl.MaxStale = true;
|
|
Assert.True(cacheControl.MaxStale, "MaxStale");
|
|
cacheControl.NoTransform = true;
|
|
Assert.True(cacheControl.NoTransform, "NoTransform");
|
|
cacheControl.OnlyIfCached = true;
|
|
Assert.True(cacheControl.OnlyIfCached, "OnlyIfCached");
|
|
cacheControl.Public = true;
|
|
Assert.True(cacheControl.Public, "Public");
|
|
cacheControl.Private = true;
|
|
Assert.True(cacheControl.Private, "Private");
|
|
cacheControl.MustRevalidate = true;
|
|
Assert.True(cacheControl.MustRevalidate, "MustRevalidate");
|
|
cacheControl.ProxyRevalidate = true;
|
|
Assert.True(cacheControl.ProxyRevalidate, "ProxyRevalidate");
|
|
|
|
// TimeSpan properties
|
|
TimeSpan timeSpan = new TimeSpan(1, 2, 3);
|
|
cacheControl.MaxAge = timeSpan;
|
|
Assert.Equal(timeSpan, cacheControl.MaxAge);
|
|
cacheControl.SharedMaxAge = timeSpan;
|
|
Assert.Equal(timeSpan, cacheControl.SharedMaxAge);
|
|
cacheControl.MaxStaleLimit = timeSpan;
|
|
Assert.Equal(timeSpan, cacheControl.MaxStaleLimit);
|
|
cacheControl.MinFresh = timeSpan;
|
|
Assert.Equal(timeSpan, cacheControl.MinFresh);
|
|
|
|
// String collection properties
|
|
Assert.NotNull(cacheControl.NoCacheHeaders);
|
|
Assert.Throws<ArgumentException>(() => cacheControl.NoCacheHeaders.Add(null));
|
|
Assert.Throws<FormatException>(() => cacheControl.NoCacheHeaders.Add("invalid token"));
|
|
cacheControl.NoCacheHeaders.Add("token");
|
|
Assert.Equal(1, cacheControl.NoCacheHeaders.Count);
|
|
Assert.Equal("token", cacheControl.NoCacheHeaders.First());
|
|
|
|
Assert.NotNull(cacheControl.PrivateHeaders);
|
|
Assert.Throws<ArgumentException>(() => cacheControl.PrivateHeaders.Add(null));
|
|
Assert.Throws<FormatException>(() => cacheControl.PrivateHeaders.Add("invalid token"));
|
|
cacheControl.PrivateHeaders.Add("token");
|
|
Assert.Equal(1, cacheControl.PrivateHeaders.Count);
|
|
Assert.Equal("token", cacheControl.PrivateHeaders.First());
|
|
|
|
// NameValueHeaderValue collection property
|
|
Assert.NotNull(cacheControl.Extensions);
|
|
Assert.Throws<ArgumentNullException>(() => cacheControl.Extensions.Add(null));
|
|
cacheControl.Extensions.Add(new NameValueHeaderValue("name", "value"));
|
|
Assert.Equal(1, cacheControl.Extensions.Count);
|
|
Assert.Equal(new NameValueHeaderValue("name", "value"), cacheControl.Extensions.First());
|
|
}
|
|
|
|
[Fact]
|
|
public void ToString_UseRequestDirectiveValues_AllSerializedCorrectly()
|
|
{
|
|
var cacheControl = new CacheControlHeaderValue();
|
|
Assert.Equal("", cacheControl.ToString());
|
|
|
|
// Note that we allow all combinations of all properties even though the RFC specifies rules what value
|
|
// can be used together.
|
|
// Also for property pairs (bool property + collection property) like 'NoCache' and 'NoCacheHeaders' the
|
|
// caller needs to set the bool property in order for the collection to be populated as string.
|
|
|
|
// Cache Request Directive sample
|
|
cacheControl.NoStore = true;
|
|
Assert.Equal("no-store", cacheControl.ToString());
|
|
cacheControl.NoCache = true;
|
|
Assert.Equal("no-store, no-cache", cacheControl.ToString());
|
|
cacheControl.MaxAge = new TimeSpan(0, 1, 10);
|
|
Assert.Equal("no-store, no-cache, max-age=70", cacheControl.ToString());
|
|
cacheControl.MaxStale = true;
|
|
Assert.Equal("no-store, no-cache, max-age=70, max-stale", cacheControl.ToString());
|
|
cacheControl.MaxStaleLimit = new TimeSpan(0, 2, 5);
|
|
Assert.Equal("no-store, no-cache, max-age=70, max-stale=125", cacheControl.ToString());
|
|
cacheControl.MinFresh = new TimeSpan(0, 3, 0);
|
|
Assert.Equal("no-store, no-cache, max-age=70, max-stale=125, min-fresh=180", cacheControl.ToString());
|
|
|
|
cacheControl = new CacheControlHeaderValue();
|
|
cacheControl.NoTransform = true;
|
|
Assert.Equal("no-transform", cacheControl.ToString());
|
|
cacheControl.OnlyIfCached = true;
|
|
Assert.Equal("no-transform, only-if-cached", cacheControl.ToString());
|
|
cacheControl.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
cacheControl.Extensions.Add(new NameValueHeaderValue("customName", "customValue"));
|
|
Assert.Equal("no-transform, only-if-cached, custom, customName=customValue", cacheControl.ToString());
|
|
|
|
cacheControl = new CacheControlHeaderValue();
|
|
cacheControl.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
Assert.Equal("custom", cacheControl.ToString());
|
|
}
|
|
|
|
[Fact]
|
|
public void ToString_UseResponseDirectiveValues_AllSerializedCorrectly()
|
|
{
|
|
var cacheControl = new CacheControlHeaderValue();
|
|
Assert.Equal("", cacheControl.ToString());
|
|
|
|
cacheControl.NoCache = true;
|
|
Assert.Equal("no-cache", cacheControl.ToString());
|
|
cacheControl.NoCacheHeaders.Add("token1");
|
|
Assert.Equal("no-cache=\"token1\"", cacheControl.ToString());
|
|
cacheControl.Public = true;
|
|
Assert.Equal("public, no-cache=\"token1\"", cacheControl.ToString());
|
|
|
|
cacheControl = new CacheControlHeaderValue();
|
|
cacheControl.Private = true;
|
|
Assert.Equal("private", cacheControl.ToString());
|
|
cacheControl.PrivateHeaders.Add("token2");
|
|
cacheControl.PrivateHeaders.Add("token3");
|
|
Assert.Equal("private=\"token2, token3\"", cacheControl.ToString());
|
|
cacheControl.MustRevalidate = true;
|
|
Assert.Equal("must-revalidate, private=\"token2, token3\"", cacheControl.ToString());
|
|
cacheControl.ProxyRevalidate = true;
|
|
Assert.Equal("must-revalidate, proxy-revalidate, private=\"token2, token3\"", cacheControl.ToString());
|
|
}
|
|
|
|
[Fact]
|
|
public void GetHashCode_CompareValuesWithBoolFieldsSet_MatchExpectation()
|
|
{
|
|
// Verify that different bool fields return different hash values.
|
|
var values = new CacheControlHeaderValue[9];
|
|
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
values[i] = new CacheControlHeaderValue();
|
|
}
|
|
|
|
values[0].ProxyRevalidate = true;
|
|
values[1].NoCache = true;
|
|
values[2].NoStore = true;
|
|
values[3].MaxStale = true;
|
|
values[4].NoTransform = true;
|
|
values[5].OnlyIfCached = true;
|
|
values[6].Public = true;
|
|
values[7].Private = true;
|
|
values[8].MustRevalidate = true;
|
|
|
|
// Only one bool field set. All hash codes should differ
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
for (int j = 0; j < values.Length; j++)
|
|
{
|
|
if (i != j)
|
|
{
|
|
CompareHashCodes(values[i], values[j], false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Validate that two instances with the same bool fields set are equal.
|
|
values[0].NoCache = true;
|
|
CompareHashCodes(values[0], values[1], false);
|
|
values[1].ProxyRevalidate = true;
|
|
CompareHashCodes(values[0], values[1], true);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetHashCode_CompareValuesWithTimeSpanFieldsSet_MatchExpectation()
|
|
{
|
|
// Verify that different timespan fields return different hash values.
|
|
var values = new CacheControlHeaderValue[4];
|
|
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
values[i] = new CacheControlHeaderValue();
|
|
}
|
|
|
|
values[0].MaxAge = new TimeSpan(0, 1, 1);
|
|
values[1].MaxStaleLimit = new TimeSpan(0, 1, 1);
|
|
values[2].MinFresh = new TimeSpan(0, 1, 1);
|
|
values[3].SharedMaxAge = new TimeSpan(0, 1, 1);
|
|
|
|
// Only one timespan field set. All hash codes should differ
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
for (int j = 0; j < values.Length; j++)
|
|
{
|
|
if (i != j)
|
|
{
|
|
CompareHashCodes(values[i], values[j], false);
|
|
}
|
|
}
|
|
}
|
|
|
|
values[0].MaxStaleLimit = new TimeSpan(0, 1, 2);
|
|
CompareHashCodes(values[0], values[1], false);
|
|
|
|
values[1].MaxAge = new TimeSpan(0, 1, 1);
|
|
values[1].MaxStaleLimit = new TimeSpan(0, 1, 2);
|
|
CompareHashCodes(values[0], values[1], true);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetHashCode_CompareCollectionFieldsSet_MatchExpectation()
|
|
{
|
|
var cacheControl1 = new CacheControlHeaderValue();
|
|
var cacheControl2 = new CacheControlHeaderValue();
|
|
var cacheControl3 = new CacheControlHeaderValue();
|
|
var cacheControl4 = new CacheControlHeaderValue();
|
|
var cacheControl5 = new CacheControlHeaderValue();
|
|
|
|
cacheControl1.NoCache = true;
|
|
cacheControl1.NoCacheHeaders.Add("token2");
|
|
|
|
cacheControl2.NoCache = true;
|
|
cacheControl2.NoCacheHeaders.Add("token1");
|
|
cacheControl2.NoCacheHeaders.Add("token2");
|
|
|
|
CompareHashCodes(cacheControl1, cacheControl2, false);
|
|
|
|
cacheControl1.NoCacheHeaders.Add("token1");
|
|
CompareHashCodes(cacheControl1, cacheControl2, true);
|
|
|
|
// Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders
|
|
// have the same values, the hash code will be different.
|
|
cacheControl3.Private = true;
|
|
cacheControl3.PrivateHeaders.Add("token2");
|
|
CompareHashCodes(cacheControl1, cacheControl3, false);
|
|
|
|
|
|
cacheControl4.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
CompareHashCodes(cacheControl1, cacheControl4, false);
|
|
|
|
cacheControl5.Extensions.Add(new NameValueHeaderValue("customN", "customV"));
|
|
cacheControl5.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
CompareHashCodes(cacheControl4, cacheControl5, false);
|
|
|
|
cacheControl4.Extensions.Add(new NameValueHeaderValue("customN", "customV"));
|
|
CompareHashCodes(cacheControl4, cacheControl5, true);
|
|
}
|
|
|
|
[Fact]
|
|
public void Equals_CompareValuesWithBoolFieldsSet_MatchExpectation()
|
|
{
|
|
// Verify that different bool fields return different hash values.
|
|
var values = new CacheControlHeaderValue[9];
|
|
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
values[i] = new CacheControlHeaderValue();
|
|
}
|
|
|
|
values[0].ProxyRevalidate = true;
|
|
values[1].NoCache = true;
|
|
values[2].NoStore = true;
|
|
values[3].MaxStale = true;
|
|
values[4].NoTransform = true;
|
|
values[5].OnlyIfCached = true;
|
|
values[6].Public = true;
|
|
values[7].Private = true;
|
|
values[8].MustRevalidate = true;
|
|
|
|
// Only one bool field set. All hash codes should differ
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
for (int j = 0; j < values.Length; j++)
|
|
{
|
|
if (i != j)
|
|
{
|
|
CompareValues(values[i], values[j], false);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Validate that two instances with the same bool fields set are equal.
|
|
values[0].NoCache = true;
|
|
CompareValues(values[0], values[1], false);
|
|
values[1].ProxyRevalidate = true;
|
|
CompareValues(values[0], values[1], true);
|
|
}
|
|
|
|
[Fact]
|
|
public void Equals_CompareValuesWithTimeSpanFieldsSet_MatchExpectation()
|
|
{
|
|
// Verify that different timespan fields return different hash values.
|
|
var values = new CacheControlHeaderValue[4];
|
|
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
values[i] = new CacheControlHeaderValue();
|
|
}
|
|
|
|
values[0].MaxAge = new TimeSpan(0, 1, 1);
|
|
values[1].MaxStaleLimit = new TimeSpan(0, 1, 1);
|
|
values[2].MinFresh = new TimeSpan(0, 1, 1);
|
|
values[3].SharedMaxAge = new TimeSpan(0, 1, 1);
|
|
|
|
// Only one timespan field set. All hash codes should differ
|
|
for (int i = 0; i < values.Length; i++)
|
|
{
|
|
for (int j = 0; j < values.Length; j++)
|
|
{
|
|
if (i != j)
|
|
{
|
|
CompareValues(values[i], values[j], false);
|
|
}
|
|
}
|
|
}
|
|
|
|
values[0].MaxStaleLimit = new TimeSpan(0, 1, 2);
|
|
CompareValues(values[0], values[1], false);
|
|
|
|
values[1].MaxAge = new TimeSpan(0, 1, 1);
|
|
values[1].MaxStaleLimit = new TimeSpan(0, 1, 2);
|
|
CompareValues(values[0], values[1], true);
|
|
|
|
var value1 = new CacheControlHeaderValue();
|
|
value1.MaxStale = true;
|
|
var value2 = new CacheControlHeaderValue();
|
|
value2.MaxStale = true;
|
|
CompareValues(value1, value2, true);
|
|
|
|
value2.MaxStaleLimit = new TimeSpan(1, 2, 3);
|
|
CompareValues(value1, value2, false);
|
|
}
|
|
|
|
[Fact]
|
|
public void Equals_CompareCollectionFieldsSet_MatchExpectation()
|
|
{
|
|
var cacheControl1 = new CacheControlHeaderValue();
|
|
var cacheControl2 = new CacheControlHeaderValue();
|
|
var cacheControl3 = new CacheControlHeaderValue();
|
|
var cacheControl4 = new CacheControlHeaderValue();
|
|
var cacheControl5 = new CacheControlHeaderValue();
|
|
var cacheControl6 = new CacheControlHeaderValue();
|
|
|
|
cacheControl1.NoCache = true;
|
|
cacheControl1.NoCacheHeaders.Add("token2");
|
|
|
|
Assert.False(cacheControl1.Equals(null), "Compare with 'null'");
|
|
|
|
cacheControl2.NoCache = true;
|
|
cacheControl2.NoCacheHeaders.Add("token1");
|
|
cacheControl2.NoCacheHeaders.Add("token2");
|
|
|
|
CompareValues(cacheControl1, cacheControl2, false);
|
|
|
|
cacheControl1.NoCacheHeaders.Add("token1");
|
|
CompareValues(cacheControl1, cacheControl2, true);
|
|
|
|
// Since NoCache and Private generate different hash codes, even if NoCacheHeaders and PrivateHeaders
|
|
// have the same values, the hash code will be different.
|
|
cacheControl3.Private = true;
|
|
cacheControl3.PrivateHeaders.Add("token2");
|
|
CompareValues(cacheControl1, cacheControl3, false);
|
|
|
|
cacheControl4.Private = true;
|
|
cacheControl4.PrivateHeaders.Add("token3");
|
|
CompareValues(cacheControl3, cacheControl4, false);
|
|
|
|
cacheControl5.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
CompareValues(cacheControl1, cacheControl5, false);
|
|
|
|
cacheControl6.Extensions.Add(new NameValueHeaderValue("customN", "customV"));
|
|
cacheControl6.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
CompareValues(cacheControl5, cacheControl6, false);
|
|
|
|
cacheControl5.Extensions.Add(new NameValueHeaderValue("customN", "customV"));
|
|
CompareValues(cacheControl5, cacheControl6, true);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryParse_DifferentValidScenarios_AllReturnTrue()
|
|
{
|
|
var expected = new CacheControlHeaderValue();
|
|
expected.NoCache = true;
|
|
CheckValidTryParse(" , no-cache ,,", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.NoCache = true;
|
|
expected.NoCacheHeaders.Add("token1");
|
|
expected.NoCacheHeaders.Add("token2");
|
|
CheckValidTryParse("no-cache=\"token1, token2\"", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.NoStore = true;
|
|
expected.MaxAge = new TimeSpan(0, 0, 125);
|
|
expected.MaxStale = true;
|
|
CheckValidTryParse(" no-store , max-age = 125, max-stale,", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.MinFresh = new TimeSpan(0, 0, 123);
|
|
expected.NoTransform = true;
|
|
expected.OnlyIfCached = true;
|
|
expected.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
CheckValidTryParse("min-fresh=123, no-transform, only-if-cached, custom", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.Public = true;
|
|
expected.Private = true;
|
|
expected.PrivateHeaders.Add("token1");
|
|
expected.MustRevalidate = true;
|
|
expected.ProxyRevalidate = true;
|
|
expected.Extensions.Add(new NameValueHeaderValue("c", "d"));
|
|
expected.Extensions.Add(new NameValueHeaderValue("a", "b"));
|
|
CheckValidTryParse(",public, , private=\"token1\", must-revalidate, c=d, proxy-revalidate, a=b", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.Private = true;
|
|
expected.SharedMaxAge = new TimeSpan(0, 0, 1234567890);
|
|
expected.MaxAge = new TimeSpan(0, 0, 987654321);
|
|
CheckValidTryParse("s-maxage=1234567890, private, max-age = 987654321,", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.Extensions.Add(new NameValueHeaderValue("custom", ""));
|
|
CheckValidTryParse("custom=", expected);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(null)]
|
|
[InlineData("")]
|
|
[InlineData(" ")]
|
|
// Token-only values
|
|
[InlineData("no-store=15")]
|
|
[InlineData("no-store=")]
|
|
[InlineData("no-transform=a")]
|
|
[InlineData("no-transform=")]
|
|
[InlineData("only-if-cached=\"x\"")]
|
|
[InlineData("only-if-cached=")]
|
|
[InlineData("public=\"x\"")]
|
|
[InlineData("public=")]
|
|
[InlineData("must-revalidate=\"1\"")]
|
|
[InlineData("must-revalidate=")]
|
|
[InlineData("proxy-revalidate=x")]
|
|
[InlineData("proxy-revalidate=")]
|
|
// Token with optional field-name list
|
|
[InlineData("no-cache=")]
|
|
[InlineData("no-cache=token")]
|
|
[InlineData("no-cache=\"token")]
|
|
[InlineData("no-cache=\"\"")] // at least one token expected as value
|
|
[InlineData("private=")]
|
|
[InlineData("private=token")]
|
|
[InlineData("private=\"token")]
|
|
[InlineData("private=\",\"")] // at least one token expected as value
|
|
[InlineData("private=\"=\"")]
|
|
// Token with delta-seconds value
|
|
[InlineData("max-age")]
|
|
[InlineData("max-age=")]
|
|
[InlineData("max-age=a")]
|
|
[InlineData("max-age=\"1\"")]
|
|
[InlineData("max-age=1.5")]
|
|
[InlineData("max-stale=")]
|
|
[InlineData("max-stale=a")]
|
|
[InlineData("max-stale=\"1\"")]
|
|
[InlineData("max-stale=1.5")]
|
|
[InlineData("min-fresh")]
|
|
[InlineData("min-fresh=")]
|
|
[InlineData("min-fresh=a")]
|
|
[InlineData("min-fresh=\"1\"")]
|
|
[InlineData("min-fresh=1.5")]
|
|
[InlineData("s-maxage")]
|
|
[InlineData("s-maxage=")]
|
|
[InlineData("s-maxage=a")]
|
|
[InlineData("s-maxage=\"1\"")]
|
|
[InlineData("s-maxage=1.5")]
|
|
// Invalid Extension values
|
|
[InlineData("custom value")]
|
|
public void TryParse_DifferentInvalidScenarios_ReturnsFalse(string input)
|
|
{
|
|
CheckInvalidTryParse(input);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_SetOfValidValueStrings_ParsedCorrectly()
|
|
{
|
|
// Just verify parser is implemented correctly. Don't try to test syntax parsed by CacheControlHeaderValue.
|
|
var expected = new CacheControlHeaderValue();
|
|
expected.NoStore = true;
|
|
expected.MinFresh = new TimeSpan(0, 2, 3);
|
|
CheckValidParse(" , no-store, min-fresh=123", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.MaxStale = true;
|
|
expected.NoCache = true;
|
|
expected.NoCacheHeaders.Add("t");
|
|
CheckValidParse("max-stale, no-cache=\"t\", ,,", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
CheckValidParse("custom =", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.Extensions.Add(new NameValueHeaderValue("custom", ""));
|
|
CheckValidParse("custom =", expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void Parse_SetOfInvalidValueStrings_Throws()
|
|
{
|
|
CheckInvalidParse(null);
|
|
CheckInvalidParse("");
|
|
CheckInvalidParse(" ");
|
|
CheckInvalidParse("no-cache,=");
|
|
CheckInvalidParse("max-age=123x");
|
|
CheckInvalidParse("=no-cache");
|
|
CheckInvalidParse("no-cache no-store");
|
|
CheckInvalidParse("会");
|
|
}
|
|
|
|
[Fact]
|
|
public void TryParse_SetOfValidValueStrings_ParsedCorrectly()
|
|
{
|
|
// Just verify parser is implemented correctly. Don't try to test syntax parsed by CacheControlHeaderValue.
|
|
var expected = new CacheControlHeaderValue();
|
|
expected.NoStore = true;
|
|
expected.MinFresh = new TimeSpan(0, 2, 3);
|
|
CheckValidTryParse(" , no-store, min-fresh=123", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.MaxStale = true;
|
|
expected.NoCache = true;
|
|
expected.NoCacheHeaders.Add("t");
|
|
CheckValidTryParse("max-stale, no-cache=\"t\", ,,", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.Extensions.Add(new NameValueHeaderValue("custom"));
|
|
CheckValidTryParse("custom = ", expected);
|
|
|
|
expected = new CacheControlHeaderValue();
|
|
expected.Extensions.Add(new NameValueHeaderValue("custom", ""));
|
|
CheckValidTryParse("custom =", expected);
|
|
}
|
|
|
|
[Fact]
|
|
public void TryParse_SetOfInvalidValueStrings_ReturnsFalse()
|
|
{
|
|
CheckInvalidTryParse("no-cache,=");
|
|
CheckInvalidTryParse("max-age=123x");
|
|
CheckInvalidTryParse("=no-cache");
|
|
CheckInvalidTryParse("no-cache no-store");
|
|
CheckInvalidTryParse("会");
|
|
}
|
|
|
|
#region Helper methods
|
|
|
|
private void CompareHashCodes(CacheControlHeaderValue x, CacheControlHeaderValue y, bool areEqual)
|
|
{
|
|
if (areEqual)
|
|
{
|
|
Assert.Equal(x.GetHashCode(), y.GetHashCode());
|
|
}
|
|
else
|
|
{
|
|
Assert.NotEqual(x.GetHashCode(), y.GetHashCode());
|
|
}
|
|
}
|
|
|
|
private void CompareValues(CacheControlHeaderValue x, CacheControlHeaderValue y, bool areEqual)
|
|
{
|
|
Assert.Equal(areEqual, x.Equals(y));
|
|
Assert.Equal(areEqual, y.Equals(x));
|
|
}
|
|
|
|
private void CheckValidParse(string input, CacheControlHeaderValue expectedResult)
|
|
{
|
|
var result = CacheControlHeaderValue.Parse(input);
|
|
Assert.Equal(expectedResult, result);
|
|
}
|
|
|
|
private void CheckInvalidParse(string input)
|
|
{
|
|
Assert.Throws<FormatException>(() => CacheControlHeaderValue.Parse(input));
|
|
}
|
|
|
|
private void CheckValidTryParse(string input, CacheControlHeaderValue expectedResult)
|
|
{
|
|
CacheControlHeaderValue result = null;
|
|
Assert.True(CacheControlHeaderValue.TryParse(input, out result));
|
|
Assert.Equal(expectedResult, result);
|
|
}
|
|
|
|
private void CheckInvalidTryParse(string input)
|
|
{
|
|
CacheControlHeaderValue result = null;
|
|
Assert.False(CacheControlHeaderValue.TryParse(input, out result));
|
|
Assert.Null(result);
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|