Skip to content

Commit

Permalink
Allow adding empty value for URL segments
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyzimarev committed Dec 17, 2024
1 parent ba2ebac commit 40b9416
Show file tree
Hide file tree
Showing 17 changed files with 330 additions and 322 deletions.
3 changes: 2 additions & 1 deletion src/RestSharp/Parameters/UrlSegmentParameter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
// limitations under the License.

using System.Text.RegularExpressions;
using RestSharp.Extensions;

namespace RestSharp;

Expand All @@ -30,7 +31,7 @@ public partial record UrlSegmentParameter : NamedParameter {
public UrlSegmentParameter(string name, string value, bool encode = true, bool replaceEncodedSlash = true)
: base(
name,
replaceEncodedSlash ? RegexPattern.Replace(Ensure.NotEmptyString(value, nameof(value)), "/") : value,
value.IsEmpty() ? value : replaceEncodedSlash ? RegexPattern.Replace(value, "/") : value,
ParameterType.UrlSegment,
encode
) { }
Expand Down
23 changes: 23 additions & 0 deletions test/RestSharp.Tests/Headers/DefaultHeaderTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
namespace RestSharp.Tests.Headers;

public class DefaultHeaderTests {
const string BaseUrl = "http://localhost:8888/";

[Fact]
public void AddDefaultHeadersUsingDictionary() {
var headers = new Dictionary<string, string> {
{ KnownHeaders.ContentType, ContentType.Json },
{ KnownHeaders.Accept, ContentType.Json },
{ KnownHeaders.ContentEncoding, "gzip, deflate" }
};

var expected = headers.Select(x => new HeaderParameter(x.Key, x.Value));

using var client = new RestClient(BaseUrl);
client.AddDefaultHeaders(headers);

var actual = client.DefaultParameters.Select(x => x as HeaderParameter);
expected.Should().BeSubsetOf(actual);
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public class AddRangeTests {
public class HeaderRangeTests {
[Fact]
public async Task ShouldParseOutLongRangeSpecifier() {
using var restClient = new RestClient("http://localhost");
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public partial class ObjectParameterTests {
sealed record ArrayData<TEnumerable>([property: RequestProperty(ArrayQueryType = RequestArrayQueryType.ArrayParameters)] TEnumerable Array) where TEnumerable : notnull;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public partial class ObjectParameterTests {
sealed record CsvData<TEnumerable>([property: RequestProperty(ArrayQueryType = RequestArrayQueryType.CommaSeparated)] TEnumerable Csv) where TEnumerable : notnull;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public partial class ObjectParameterTests {
sealed record FormattedData<TDateTime>([property: RequestProperty(Format = "hh:mm tt")] TDateTime FormattedParameter) where TDateTime : notnull;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public partial class ObjectParameterTests {
sealed record NamedData([property: RequestProperty(Name = "CustomName")] object NamedParameter);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections;
using System.Globalization;

namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public partial class ObjectParameterTests {
public ObjectParameterTests() => Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public class ParameterValidationTests {
[Fact]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,8 @@
namespace RestSharp.Tests;
namespace RestSharp.Tests.Parameters;

public class ParametersTests {
public class UrlSegmentTests {
const string BaseUrl = "http://localhost:8888/";

[Fact]
public void AddDefaultHeadersUsingDictionary() {
var headers = new Dictionary<string, string> {
{ KnownHeaders.ContentType, ContentType.Json },
{ KnownHeaders.Accept, ContentType.Json },
{ KnownHeaders.ContentEncoding, "gzip, deflate" }
};

var expected = headers.Select(x => new HeaderParameter(x.Key, x.Value));

using var client = new RestClient(BaseUrl);
client.AddDefaultHeaders(headers);

var actual = client.DefaultParameters.Select(x => x as HeaderParameter);
expected.Should().BeSubsetOf(actual);
}

[Fact]
public void AddUrlSegmentWithInt() {
const string name = "foo";
Expand Down
32 changes: 0 additions & 32 deletions test/RestSharp.Tests/RestClientTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,38 +32,6 @@ public async Task ConfigureHttp_will_set_proxy_to_null_with_no_exceptions_When_n
await client.ExecuteAsync(req);
}

[Fact]
public void BuildUri_should_build_with_passing_link_as_Uri() {
// arrange
var relative = new Uri("/foo/bar/baz", UriKind.Relative);
var absoluteUri = new Uri(new Uri(BaseUrl), relative);
var req = new RestRequest(absoluteUri);

// act
using var client = new RestClient();

var builtUri = client.BuildUri(req);

// assert
absoluteUri.Should().Be(builtUri);
}

[Fact]
public void BuildUri_should_build_with_passing_link_as_Uri_with_set_BaseUrl() {
// arrange
var baseUrl = new Uri(BaseUrl);
var relative = new Uri("/foo/bar/baz", UriKind.Relative);
var req = new RestRequest(relative);

// act
using var client = new RestClient(baseUrl);

var builtUri = client.BuildUri(req);

// assert
new Uri(baseUrl, relative).Should().Be(builtUri);
}

[Fact]
public void UseJson_leaves_only_json_serializer() {
// arrange
Expand Down
14 changes: 4 additions & 10 deletions test/RestSharp.Tests/RestSharp.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,11 @@
<None Update="SampleData\underscore_prefix.json" CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>
<ItemGroup>
<Compile Update="ObjectParameterTests.ArrayData.cs">
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
<Compile Update="UrlBuilderTests.Get.cs">
<DependentUpon>UrlBuilderTests.cs</DependentUpon>
</Compile>
<Compile Update="ObjectParameterTests.CsvData.cs">
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
</Compile>
<Compile Update="ObjectParameterTests.FormattedData.cs">
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
</Compile>
<Compile Update="ObjectParameterTests.NamedData.cs">
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
<Compile Update="UrlBuilderTests.Post.cs">
<DependentUpon>UrlBuilderTests.cs</DependentUpon>
</Compile>
</ItemGroup>
</Project>
197 changes: 197 additions & 0 deletions test/RestSharp.Tests/UrlBuilderTests.Get.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
namespace RestSharp.Tests;

public partial class UrlBuilderTests {
[Fact]
public void GET_with_empty_base_and_query_parameters_without_encoding() {
var request = new RestRequest($"{Base}/{Resource}?param1=value1")
.AddQueryParameter("foo", "bar,baz", false);
var expected = new Uri($"{Base}/{Resource}?param1=value1&foo=bar,baz");

using var client = new RestClient();

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_empty_base_and_resource_containing_tokens() {
var request = new RestRequest($"{Base}/{Resource}/{{foo}}");
request.AddUrlSegment("foo", "bar");

using var client = new RestClient();

var expected = new Uri($"{Base}/{Resource}/bar");
var output = client.BuildUri(request);

Assert.Equal(expected, output);
}

[Fact]
public void GET_with_empty_request() {
var request = new RestRequest();
var expected = new Uri(Base);

using var client = new RestClient(new Uri(Base));

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_empty_request_and_bare_hostname() {
var request = new RestRequest();
var expected = new Uri(Base);

using var client = new RestClient(new Uri(Base));

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_empty_request_and_query_parameters_without_encoding() {
var request = new RestRequest();
request.AddQueryParameter("foo", "bar,baz", false);
var expected = new Uri($"{Base}/{Resource}?param1=value1&foo=bar,baz");

using var client = new RestClient($"{Base}/{Resource}?param1=value1");

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_Invalid_Url_string_throws_exception()
=> Assert.Throws<UriFormatException>(
() => { _ = new RestClient("invalid url"); }
);

[Fact]
public void GET_with_leading_slash() {
var request = new RestRequest($"/{Resource}");
var expected = new Uri($"{Base}/{Resource}");

using var client = new RestClient(new Uri(Base));

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_leading_slash_and_baseurl_trailing_slash() {
var request = new RestRequest($"/{Resource}");
request.AddParameter("foo", "bar");
var expected = new Uri($"{Base}/{Resource}?foo=bar");

using var client = new RestClient(new Uri(Base));

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_multiple_instances_of_same_key() {
var request = new RestRequest("v1/people/~/network/updates");
request.AddParameter("type", "STAT");
request.AddParameter("type", "PICT");
request.AddParameter("count", "50");
request.AddParameter("start", "50");
var expected = new Uri("https://api.linkedin.com/v1/people/~/network/updates?type=STAT&type=PICT&count=50&start=50");

using var client = new RestClient("https://api.linkedin.com");

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_resource_containing_null_token() {
var request = new RestRequest($"/{Resource}/{{foo}}");
Assert.Throws<ArgumentNullException>(() => request.AddUrlSegment("foo", null!));
}

[Fact]
public void GET_with_resource_containing_slashes() {
var request = new RestRequest($"{Resource}/foo");
var expected = new Uri($"{Base}/{Resource}/foo");

using var client = new RestClient(new Uri(Base));

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_resource_containing_tokens() {
var request = new RestRequest($"{Resource}/{{foo}}");
request.AddUrlSegment("foo", "bar");
var expected = new Uri($"{Base}/{Resource}/bar");

using var client = new RestClient(new Uri(Base));

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_Uri_and_resource_containing_tokens() {
var request = new RestRequest($"/{{foo}}/{Resource}/{{baz}}");
request.AddUrlSegment("foo", "bar");
request.AddUrlSegment("baz", "bat");
var expected = new Uri($"{Base}/bar/{Resource}/bat");

using var client = new RestClient(Base);

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_Uri_containing_tokens() {
var request = new RestRequest();
request.AddUrlSegment("foo", "bar");
var expected = new Uri(Base);

using var client = new RestClient(Base);

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_Url_string_and_resource_containing_tokens() {
var request = new RestRequest($"{Resource}/{{baz}}");
request.AddUrlSegment("foo", "bar");
request.AddUrlSegment("baz", "bat");
var expected = new Uri($"{Base}/bar/{Resource}/bat");

using var client = new RestClient($"{Base}/{{foo}}");

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_with_Url_string_containing_tokens() {
var request = new RestRequest();
request.AddUrlSegment("foo", "bar");
var expected = new Uri($"{Base}/bar");

using var client = new RestClient($"{Base}/{{foo}}");

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}

[Fact]
public void GET_wth_trailing_slash_and_query_parameters() {
var request = new RestRequest($"/{Resource}/");
request.AddParameter("foo", "bar");
var expected = new Uri($"{Base}/{Resource}/?foo=bar");

using var client = new RestClient(Base);

var output = client.BuildUri(request);
Assert.Equal(expected, output);
}
}
Loading

0 comments on commit 40b9416

Please sign in to comment.