|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
using System;
using System.Collections.Generic;
using Xunit;
namespace Microsoft.AspNetCore.Internal;
public class QueryStringEnumerableTest
{
[Fact]
public void ParseQueryWithUniqueKeysWorks()
{
Assert.Collection(Parse("?key1=value1&key2=value2"),
kvp => AssertKeyValuePair("key1", "value1", kvp),
kvp => AssertKeyValuePair("key2", "value2", kvp));
}
[Fact]
public void ParseQueryWithoutQuestionmarkWorks()
{
Assert.Collection(Parse("key1=value1&key2=value2"),
kvp => AssertKeyValuePair("key1", "value1", kvp),
kvp => AssertKeyValuePair("key2", "value2", kvp));
}
[Fact]
public void ParseQueryWithDuplicateKeysGroups()
{
Assert.Collection(Parse("?key1=valueA&key2=valueB&key1=valueC"),
kvp => AssertKeyValuePair("key1", "valueA", kvp),
kvp => AssertKeyValuePair("key2", "valueB", kvp),
kvp => AssertKeyValuePair("key1", "valueC", kvp));
}
[Fact]
public void ParseQueryWithEmptyValuesWorks()
{
Assert.Collection(Parse("?key1=&key2="),
kvp => AssertKeyValuePair("key1", string.Empty, kvp),
kvp => AssertKeyValuePair("key2", string.Empty, kvp));
}
[Fact]
public void ParseQueryWithEmptyKeyWorks()
{
Assert.Collection(Parse("?=value1&="),
kvp => AssertKeyValuePair(string.Empty, "value1", kvp),
kvp => AssertKeyValuePair(string.Empty, string.Empty, kvp));
}
[Fact]
public void ParseQueryWithEncodedKeyWorks()
{
Assert.Collection(Parse("?fields+%5BtodoItems%5D"),
kvp => AssertKeyValuePair("fields+%5BtodoItems%5D", string.Empty, kvp));
}
[Fact]
public void ParseQueryWithEncodedValueWorks()
{
Assert.Collection(Parse("?=fields+%5BtodoItems%5D"),
kvp => AssertKeyValuePair(string.Empty, "fields+%5BtodoItems%5D", kvp));
}
[Theory]
[InlineData("?")]
[InlineData("")]
[InlineData(null)]
[InlineData("?&&")]
public void ParseEmptyOrNullQueryWorks(string? queryString)
{
Assert.Empty(Parse(queryString));
}
[Fact]
public void ParseIgnoresEmptySegments()
{
Assert.Collection(Parse("?&key1=value1&&key2=value2&"),
kvp => AssertKeyValuePair("key1", "value1", kvp),
kvp => AssertKeyValuePair("key2", "value2", kvp));
}
[Theory]
[InlineData("?a+b=c+d", "a b", "c d")]
[InlineData("? %5Bkey%5D = %26value%3D ", " [key] ", " &value= ")]
[InlineData("?+", " ", "")]
[InlineData("?=+", "", " ")]
public void DecodingWorks(string queryString, string expectedDecodedName, string expectedDecodedValue)
{
foreach (var kvp in new QueryStringEnumerable(queryString))
{
Assert.Equal(expectedDecodedName, kvp.DecodeName().ToString());
Assert.Equal(expectedDecodedValue, kvp.DecodeValue().ToString());
}
}
[Fact]
public void DecodingReusesMemoryIfDecodingNotNeeded()
{
foreach (var kvp in new QueryStringEnumerable("?key=value"))
{
Assert.True(kvp.EncodedName.Equals(kvp.DecodeName()));
Assert.True(kvp.EncodedValue.Equals(kvp.DecodeValue()));
}
}
private static void AssertKeyValuePair(string expectedKey, string expectedValue, (string key, string value) actual)
{
Assert.Equal(expectedKey, actual.key);
Assert.Equal(expectedValue, actual.value);
}
private static IReadOnlyList<(string key, string value)> Parse(string query)
{
var result = new List<(string key, string value)>();
var enumerable = new QueryStringEnumerable(query);
foreach (var pair in enumerable)
{
result.Add((pair.EncodedName.ToString(), pair.EncodedValue.ToString()));
}
return result;
}
}
|