Files
git.stella-ops.org/src/__Libraries/__Tests/StellaOps.Microservice.Tests/HeaderCollectionTests.cs

409 lines
10 KiB
C#

namespace StellaOps.Microservice.Tests;
/// <summary>
/// Unit tests for <see cref="HeaderCollection"/>.
/// </summary>
public sealed class HeaderCollectionTests
{
#region Constructor Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Constructor_Default_CreatesEmptyCollection()
{
// Arrange & Act
var headers = new HeaderCollection();
// Assert
headers.Should().BeEmpty();
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Constructor_WithKeyValuePairs_AddsAllHeaders()
{
// Arrange
var pairs = new[]
{
new KeyValuePair<string, string>("Content-Type", "application/json"),
new KeyValuePair<string, string>("Accept", "application/json")
};
// Act
var headers = new HeaderCollection(pairs);
// Assert
headers["Content-Type"].Should().Be("application/json");
headers["Accept"].Should().Be("application/json");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Constructor_WithDuplicateKeys_AddsMultipleValues()
{
// Arrange
var pairs = new[]
{
new KeyValuePair<string, string>("Accept", "application/json"),
new KeyValuePair<string, string>("Accept", "text/plain")
};
// Act
var headers = new HeaderCollection(pairs);
// Assert
headers.GetValues("Accept").Should().BeEquivalentTo(["application/json", "text/plain"]);
}
#endregion
#region Empty Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Empty_IsSharedInstance()
{
// Arrange & Act
var empty1 = HeaderCollection.Empty;
var empty2 = HeaderCollection.Empty;
// Assert
empty1.Should().BeSameAs(empty2);
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Empty_HasNoHeaders()
{
// Arrange & Act
var empty = HeaderCollection.Empty;
// Assert
empty.Should().BeEmpty();
}
#endregion
#region Indexer Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Indexer_ExistingKey_ReturnsFirstValue()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
// Act
var value = headers["Content-Type"];
// Assert
value.Should().Be("application/json");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Indexer_MultipleValues_ReturnsFirstValue()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Accept", "application/json");
headers.Add("Accept", "text/plain");
// Act
var value = headers["Accept"];
// Assert
value.Should().Be("application/json");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Indexer_NonexistentKey_ReturnsNull()
{
// Arrange
var headers = new HeaderCollection();
// Act
var value = headers["X-Missing"];
// Assert
value.Should().BeNull();
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Indexer_IsCaseInsensitive()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
// Act & Assert
headers["content-type"].Should().Be("application/json");
headers["CONTENT-TYPE"].Should().Be("application/json");
headers["Content-TYPE"].Should().Be("application/json");
}
#endregion
#region Add Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Add_NewKey_AddsHeader()
{
// Arrange
var headers = new HeaderCollection();
// Act
headers.Add("Content-Type", "application/json");
// Assert
headers["Content-Type"].Should().Be("application/json");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Add_ExistingKey_AppendsValue()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Accept", "application/json");
// Act
headers.Add("Accept", "text/plain");
// Assert
headers.GetValues("Accept").Should().HaveCount(2);
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Add_CaseInsensitiveKey_AppendsToExisting()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
// Act
headers.Add("content-type", "text/plain");
// Assert
headers.GetValues("Content-Type").Should().HaveCount(2);
}
#endregion
#region Set Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Set_NewKey_AddsHeader()
{
// Arrange
var headers = new HeaderCollection();
// Act
headers.Set("Content-Type", "application/json");
// Assert
headers["Content-Type"].Should().Be("application/json");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void Set_ExistingKey_ReplacesValue()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "text/plain");
headers.Add("Content-Type", "text/html");
// Act
headers.Set("Content-Type", "application/json");
// Assert
headers.GetValues("Content-Type").Should().BeEquivalentTo(["application/json"]);
}
#endregion
#region GetValues Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetValues_ExistingKey_ReturnsAllValues()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Accept", "application/json");
headers.Add("Accept", "text/plain");
headers.Add("Accept", "text/html");
// Act
var values = headers.GetValues("Accept");
// Assert
values.Should().BeEquivalentTo(["application/json", "text/plain", "text/html"]);
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetValues_NonexistentKey_ReturnsEmptyEnumerable()
{
// Arrange
var headers = new HeaderCollection();
// Act
var values = headers.GetValues("X-Missing");
// Assert
values.Should().BeEmpty();
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetValues_IsCaseInsensitive()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Accept", "application/json");
// Act & Assert
headers.GetValues("accept").Should().Contain("application/json");
headers.GetValues("ACCEPT").Should().Contain("application/json");
}
#endregion
#region TryGetValue Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void TryGetValue_ExistingKey_ReturnsTrueAndValue()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
// Act
var result = headers.TryGetValue("Content-Type", out var value);
// Assert
result.Should().BeTrue();
value.Should().Be("application/json");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void TryGetValue_NonexistentKey_ReturnsFalse()
{
// Arrange
var headers = new HeaderCollection();
// Act
var result = headers.TryGetValue("X-Missing", out var value);
// Assert
result.Should().BeFalse();
value.Should().BeNull();
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void TryGetValue_IsCaseInsensitive()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
// Act
var result = headers.TryGetValue("content-type", out var value);
// Assert
result.Should().BeTrue();
value.Should().Be("application/json");
}
#endregion
#region ContainsKey Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ContainsKey_ExistingKey_ReturnsTrue()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
// Act & Assert
headers.ContainsKey("Content-Type").Should().BeTrue();
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ContainsKey_NonexistentKey_ReturnsFalse()
{
// Arrange
var headers = new HeaderCollection();
// Act & Assert
headers.ContainsKey("X-Missing").Should().BeFalse();
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void ContainsKey_IsCaseInsensitive()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
// Act & Assert
headers.ContainsKey("content-type").Should().BeTrue();
headers.ContainsKey("CONTENT-TYPE").Should().BeTrue();
}
#endregion
#region Enumeration Tests
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetEnumerator_EnumeratesAllHeaderValues()
{
// Arrange
var headers = new HeaderCollection();
headers.Add("Content-Type", "application/json");
headers.Add("Accept", "text/plain");
headers.Add("Accept", "text/html");
// Act
var list = headers.ToList();
// Assert
list.Should().HaveCount(3);
list.Should().Contain(kvp => kvp.Key == "Content-Type" && kvp.Value == "application/json");
list.Should().Contain(kvp => kvp.Key == "Accept" && kvp.Value == "text/plain");
list.Should().Contain(kvp => kvp.Key == "Accept" && kvp.Value == "text/html");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public void GetEnumerator_EmptyCollection_EnumeratesNothing()
{
// Arrange
var headers = new HeaderCollection();
// Act
var list = headers.ToList();
// Assert
list.Should().BeEmpty();
}
#endregion
}