Couple of HttpUtil issues.
AddQueryParam
HttpUtils.AddQueryParam
doesn’t work with hash params. The hash fragment should be at the end of the url according to https://tools.ietf.org/html/rfc3986#page-16
If a hash param exists the query param should go before it.
Here are some tests:
Assert.That("http://example.com?f=1#hash".AddQueryParam("f", "2"), Is.EqualTo("http://example.com?f=1&f=2#hash"));
Assert.That("#hash".AddQueryParam("a", "b"), Is.EqualTo("?a=b#hash"));
Assert.That("/#hash".AddQueryParam("a", "b"), Is.EqualTo("/?a=b#hash"));
Assert.That("?#hash".AddQueryParam("a", "b"), Is.EqualTo("?a=b#hash"));
AddHashParam
The hash fragment, when used for anchor bookmarks can have a null/empty value without the =
, e.g. #bookmark
. https://tools.ietf.org/html/rfc3986#page-16
So not sure if you want a different named extension method instead of AddHashParam
or change AddHashParam
to work with null/empty param values (which means removing some existing nunit tests).
Here are some tests for the hash fragment:
// This tests that a null value enters the key without the "="
Assert.That("http://example.com?f=1".AddHashParam("#hash", null), Is.EqualTo("http://example.com?f=1&f=2#hash"));
// This tests to see if the HashParam is missing the `#` prefix and if so add it.
Assert.That("http://example.com?f=1".AddHashParam("hash", null), Is.EqualTo("http://example.com?f=1&f=2#hash"));
using NUnit.Framework;
namespace ServiceStack.Text.Tests
{
[TestFixture]
public class HttpUtilsTests
{
[Test]
public void Can_AddQueryParam()
{
Assert.That("http://example.com".AddQueryParam("f", "1"), Is.EqualTo("http://example.com?f=1"));
Assert.That("http://example.com?s=0".AddQueryParam("f", "1"), Is.EqualTo("http://example.com?s=0&f=1"));
Assert.That("http://example.com?f=1".AddQueryParam("f", "2"), Is.EqualTo("http://example.com?f=1&f=2"));
Assert.That("http://example.com?s=0&f=1&s=1".AddQueryParam("f", "2"), Is.EqualTo("http://example.com?s=0&f=1&s=1&f=2"));
Assert.That("http://example.com?s=rf&f=1".AddQueryParam("f", "2"), Is.EqualTo("http://example.com?s=rf&f=1&f=2"));
Assert.That("http://example.com?".AddQueryParam("f", "1"), Is.EqualTo("http://example.com?f=1"));
Assert.That("http://example.com?f=1&".AddQueryParam("f", "2"), Is.EqualTo("http://example.com?f=1&f=2"));
Assert.That("http://example.com?ab=0".AddQueryParam("a", "1"), Is.EqualTo("http://example.com?ab=0&a=1"));
{
Assert.That("http://example.com".SetQueryParam("f", "1"), Is.EqualTo("http://example.com?f=1"));
Assert.That("http://example.com?s=0".SetQueryParam("f", "1"), Is.EqualTo("http://example.com?s=0&f=1"));
Assert.That("http://example.com?f=1".SetQueryParam("f", "2"), Is.EqualTo("http://example.com?f=2"));
Assert.That("http://example.com?s=0&f=1&s=1".SetQueryParam("f", "2"), Is.EqualTo("http://example.com?s=0&f=2&s=1"));
Assert.That("http://example.com?s=rf&f=1".SetQueryParam("f", "2"), Is.EqualTo("http://example.com?s=rf&f=2"));
Assert.That("http://example.com?ab=0".SetQueryParam("a", "1"), Is.EqualTo("http://example.com?ab=0&a=1"));
}
[Test]
public void Can_AddHashParam()
{
Assert.That("http://example.com".AddHashParam("f", "1"), Is.EqualTo("http://example.com#f=1"));
Assert.That("http://example.com#s=0".AddHashParam("f", "1"), Is.EqualTo("http://example.com#s=0/f=1"));
Assert.That("http://example.com#f=1".AddHashParam("f", "2"), Is.EqualTo("http://example.com#f=1/f=2"));
Assert.That("http://example.com#s=0/f=1/s=1".AddHashParam("f", "2"), Is.EqualTo("http://example.com#s=0/f=1/s=1/f=2"));
Assert.That("http://example.com#s=rf/f=1".AddHashParam("f", "2"), Is.EqualTo("http://example.com#s=rf/f=1/f=2"));
Assert.That("http://example.com#ab=0".AddHashParam("a", "1"), Is.EqualTo("http://example.com#ab=0/a=1"));
Assert.That("".AddHashParam("a", ""), Is.EqualTo("#a="));
Assert.That("".AddHashParam("a", null), Is.EqualTo(""));
mythz
December 7, 2019, 7:10am
2
AddQueryParam
and AddHashParam
only appends to the URL, it doesn’t replace or insert contents, you can use SetHashParam
to replace existing params. For your valueless #hash
param, just append it to the URL yourself where it’s more readable as I don’t want to change existing behavior, esp. for that which has been defined by unit tests.