Skip to content

Commit 40b9416

Browse files
committed
Allow adding empty value for URL segments
1 parent ba2ebac commit 40b9416

17 files changed

+330
-322
lines changed

src/RestSharp/Parameters/UrlSegmentParameter.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
// limitations under the License.
1414

1515
using System.Text.RegularExpressions;
16+
using RestSharp.Extensions;
1617

1718
namespace RestSharp;
1819

@@ -30,7 +31,7 @@ public partial record UrlSegmentParameter : NamedParameter {
3031
public UrlSegmentParameter(string name, string value, bool encode = true, bool replaceEncodedSlash = true)
3132
: base(
3233
name,
33-
replaceEncodedSlash ? RegexPattern.Replace(Ensure.NotEmptyString(value, nameof(value)), "/") : value,
34+
value.IsEmpty() ? value : replaceEncodedSlash ? RegexPattern.Replace(value, "/") : value,
3435
ParameterType.UrlSegment,
3536
encode
3637
) { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
namespace RestSharp.Tests.Headers;
2+
3+
public class DefaultHeaderTests {
4+
const string BaseUrl = "http://localhost:8888/";
5+
6+
[Fact]
7+
public void AddDefaultHeadersUsingDictionary() {
8+
var headers = new Dictionary<string, string> {
9+
{ KnownHeaders.ContentType, ContentType.Json },
10+
{ KnownHeaders.Accept, ContentType.Json },
11+
{ KnownHeaders.ContentEncoding, "gzip, deflate" }
12+
};
13+
14+
var expected = headers.Select(x => new HeaderParameter(x.Key, x.Value));
15+
16+
using var client = new RestClient(BaseUrl);
17+
client.AddDefaultHeaders(headers);
18+
19+
var actual = client.DefaultParameters.Select(x => x as HeaderParameter);
20+
expected.Should().BeSubsetOf(actual);
21+
}
22+
23+
}

test/RestSharp.Tests/AddRangeTests.cs renamed to test/RestSharp.Tests/Headers/HeaderRangeTests.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
namespace RestSharp.Tests;
1+
namespace RestSharp.Tests.Parameters;
22

3-
public class AddRangeTests {
3+
public class HeaderRangeTests {
44
[Fact]
55
public async Task ShouldParseOutLongRangeSpecifier() {
66
using var restClient = new RestClient("http://localhost");

test/RestSharp.Tests/ObjectParameterTests.ArrayData.cs renamed to test/RestSharp.Tests/Parameters/ObjectParameterTests.ArrayData.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace RestSharp.Tests;
1+
namespace RestSharp.Tests.Parameters;
22

33
public partial class ObjectParameterTests {
44
sealed record ArrayData<TEnumerable>([property: RequestProperty(ArrayQueryType = RequestArrayQueryType.ArrayParameters)] TEnumerable Array) where TEnumerable : notnull;

test/RestSharp.Tests/ObjectParameterTests.CsvData.cs renamed to test/RestSharp.Tests/Parameters/ObjectParameterTests.CsvData.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace RestSharp.Tests;
1+
namespace RestSharp.Tests.Parameters;
22

33
public partial class ObjectParameterTests {
44
sealed record CsvData<TEnumerable>([property: RequestProperty(ArrayQueryType = RequestArrayQueryType.CommaSeparated)] TEnumerable Csv) where TEnumerable : notnull;

test/RestSharp.Tests/ObjectParameterTests.FormattedData.cs renamed to test/RestSharp.Tests/Parameters/ObjectParameterTests.FormattedData.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace RestSharp.Tests;
1+
namespace RestSharp.Tests.Parameters;
22

33
public partial class ObjectParameterTests {
44
sealed record FormattedData<TDateTime>([property: RequestProperty(Format = "hh:mm tt")] TDateTime FormattedParameter) where TDateTime : notnull;

test/RestSharp.Tests/ObjectParameterTests.NamedData.cs renamed to test/RestSharp.Tests/Parameters/ObjectParameterTests.NamedData.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace RestSharp.Tests;
1+
namespace RestSharp.Tests.Parameters;
22

33
public partial class ObjectParameterTests {
44
sealed record NamedData([property: RequestProperty(Name = "CustomName")] object NamedParameter);

test/RestSharp.Tests/ObjectParameterTests.cs renamed to test/RestSharp.Tests/Parameters/ObjectParameterTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using System.Collections;
22
using System.Globalization;
33

4-
namespace RestSharp.Tests;
4+
namespace RestSharp.Tests.Parameters;
55

66
public partial class ObjectParameterTests {
77
public ObjectParameterTests() => Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

test/RestSharp.Tests/ParameterValidationTests.cs renamed to test/RestSharp.Tests/Parameters/ParameterValidationTests.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace RestSharp.Tests;
1+
namespace RestSharp.Tests.Parameters;
22

33
public class ParameterValidationTests {
44
[Fact]

test/RestSharp.Tests/ParametersTests.cs renamed to test/RestSharp.Tests/Parameters/UrlSegmentTests.cs

+2-19
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,8 @@
1-
namespace RestSharp.Tests;
1+
namespace RestSharp.Tests.Parameters;
22

3-
public class ParametersTests {
3+
public class UrlSegmentTests {
44
const string BaseUrl = "http://localhost:8888/";
55

6-
[Fact]
7-
public void AddDefaultHeadersUsingDictionary() {
8-
var headers = new Dictionary<string, string> {
9-
{ KnownHeaders.ContentType, ContentType.Json },
10-
{ KnownHeaders.Accept, ContentType.Json },
11-
{ KnownHeaders.ContentEncoding, "gzip, deflate" }
12-
};
13-
14-
var expected = headers.Select(x => new HeaderParameter(x.Key, x.Value));
15-
16-
using var client = new RestClient(BaseUrl);
17-
client.AddDefaultHeaders(headers);
18-
19-
var actual = client.DefaultParameters.Select(x => x as HeaderParameter);
20-
expected.Should().BeSubsetOf(actual);
21-
}
22-
236
[Fact]
247
public void AddUrlSegmentWithInt() {
258
const string name = "foo";

test/RestSharp.Tests/RestClientTests.cs

-32
Original file line numberDiff line numberDiff line change
@@ -32,38 +32,6 @@ public async Task ConfigureHttp_will_set_proxy_to_null_with_no_exceptions_When_n
3232
await client.ExecuteAsync(req);
3333
}
3434

35-
[Fact]
36-
public void BuildUri_should_build_with_passing_link_as_Uri() {
37-
// arrange
38-
var relative = new Uri("/foo/bar/baz", UriKind.Relative);
39-
var absoluteUri = new Uri(new Uri(BaseUrl), relative);
40-
var req = new RestRequest(absoluteUri);
41-
42-
// act
43-
using var client = new RestClient();
44-
45-
var builtUri = client.BuildUri(req);
46-
47-
// assert
48-
absoluteUri.Should().Be(builtUri);
49-
}
50-
51-
[Fact]
52-
public void BuildUri_should_build_with_passing_link_as_Uri_with_set_BaseUrl() {
53-
// arrange
54-
var baseUrl = new Uri(BaseUrl);
55-
var relative = new Uri("/foo/bar/baz", UriKind.Relative);
56-
var req = new RestRequest(relative);
57-
58-
// act
59-
using var client = new RestClient(baseUrl);
60-
61-
var builtUri = client.BuildUri(req);
62-
63-
// assert
64-
new Uri(baseUrl, relative).Should().Be(builtUri);
65-
}
66-
6735
[Fact]
6836
public void UseJson_leaves_only_json_serializer() {
6937
// arrange

test/RestSharp.Tests/RestSharp.Tests.csproj

+4-10
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,11 @@
2929
<None Update="SampleData\underscore_prefix.json" CopyToOutputDirectory="PreserveNewest"/>
3030
</ItemGroup>
3131
<ItemGroup>
32-
<Compile Update="ObjectParameterTests.ArrayData.cs">
33-
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
32+
<Compile Update="UrlBuilderTests.Get.cs">
33+
<DependentUpon>UrlBuilderTests.cs</DependentUpon>
3434
</Compile>
35-
<Compile Update="ObjectParameterTests.CsvData.cs">
36-
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
37-
</Compile>
38-
<Compile Update="ObjectParameterTests.FormattedData.cs">
39-
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
40-
</Compile>
41-
<Compile Update="ObjectParameterTests.NamedData.cs">
42-
<DependentUpon>ObjectParameterTests.cs</DependentUpon>
35+
<Compile Update="UrlBuilderTests.Post.cs">
36+
<DependentUpon>UrlBuilderTests.cs</DependentUpon>
4337
</Compile>
4438
</ItemGroup>
4539
</Project>
+197
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
namespace RestSharp.Tests;
2+
3+
public partial class UrlBuilderTests {
4+
[Fact]
5+
public void GET_with_empty_base_and_query_parameters_without_encoding() {
6+
var request = new RestRequest($"{Base}/{Resource}?param1=value1")
7+
.AddQueryParameter("foo", "bar,baz", false);
8+
var expected = new Uri($"{Base}/{Resource}?param1=value1&foo=bar,baz");
9+
10+
using var client = new RestClient();
11+
12+
var output = client.BuildUri(request);
13+
Assert.Equal(expected, output);
14+
}
15+
16+
[Fact]
17+
public void GET_with_empty_base_and_resource_containing_tokens() {
18+
var request = new RestRequest($"{Base}/{Resource}/{{foo}}");
19+
request.AddUrlSegment("foo", "bar");
20+
21+
using var client = new RestClient();
22+
23+
var expected = new Uri($"{Base}/{Resource}/bar");
24+
var output = client.BuildUri(request);
25+
26+
Assert.Equal(expected, output);
27+
}
28+
29+
[Fact]
30+
public void GET_with_empty_request() {
31+
var request = new RestRequest();
32+
var expected = new Uri(Base);
33+
34+
using var client = new RestClient(new Uri(Base));
35+
36+
var output = client.BuildUri(request);
37+
Assert.Equal(expected, output);
38+
}
39+
40+
[Fact]
41+
public void GET_with_empty_request_and_bare_hostname() {
42+
var request = new RestRequest();
43+
var expected = new Uri(Base);
44+
45+
using var client = new RestClient(new Uri(Base));
46+
47+
var output = client.BuildUri(request);
48+
Assert.Equal(expected, output);
49+
}
50+
51+
[Fact]
52+
public void GET_with_empty_request_and_query_parameters_without_encoding() {
53+
var request = new RestRequest();
54+
request.AddQueryParameter("foo", "bar,baz", false);
55+
var expected = new Uri($"{Base}/{Resource}?param1=value1&foo=bar,baz");
56+
57+
using var client = new RestClient($"{Base}/{Resource}?param1=value1");
58+
59+
var output = client.BuildUri(request);
60+
Assert.Equal(expected, output);
61+
}
62+
63+
[Fact]
64+
public void GET_with_Invalid_Url_string_throws_exception()
65+
=> Assert.Throws<UriFormatException>(
66+
() => { _ = new RestClient("invalid url"); }
67+
);
68+
69+
[Fact]
70+
public void GET_with_leading_slash() {
71+
var request = new RestRequest($"/{Resource}");
72+
var expected = new Uri($"{Base}/{Resource}");
73+
74+
using var client = new RestClient(new Uri(Base));
75+
76+
var output = client.BuildUri(request);
77+
Assert.Equal(expected, output);
78+
}
79+
80+
[Fact]
81+
public void GET_with_leading_slash_and_baseurl_trailing_slash() {
82+
var request = new RestRequest($"/{Resource}");
83+
request.AddParameter("foo", "bar");
84+
var expected = new Uri($"{Base}/{Resource}?foo=bar");
85+
86+
using var client = new RestClient(new Uri(Base));
87+
88+
var output = client.BuildUri(request);
89+
Assert.Equal(expected, output);
90+
}
91+
92+
[Fact]
93+
public void GET_with_multiple_instances_of_same_key() {
94+
var request = new RestRequest("v1/people/~/network/updates");
95+
request.AddParameter("type", "STAT");
96+
request.AddParameter("type", "PICT");
97+
request.AddParameter("count", "50");
98+
request.AddParameter("start", "50");
99+
var expected = new Uri("https://api.linkedin.com/v1/people/~/network/updates?type=STAT&type=PICT&count=50&start=50");
100+
101+
using var client = new RestClient("https://api.linkedin.com");
102+
103+
var output = client.BuildUri(request);
104+
Assert.Equal(expected, output);
105+
}
106+
107+
[Fact]
108+
public void GET_with_resource_containing_null_token() {
109+
var request = new RestRequest($"/{Resource}/{{foo}}");
110+
Assert.Throws<ArgumentNullException>(() => request.AddUrlSegment("foo", null!));
111+
}
112+
113+
[Fact]
114+
public void GET_with_resource_containing_slashes() {
115+
var request = new RestRequest($"{Resource}/foo");
116+
var expected = new Uri($"{Base}/{Resource}/foo");
117+
118+
using var client = new RestClient(new Uri(Base));
119+
120+
var output = client.BuildUri(request);
121+
Assert.Equal(expected, output);
122+
}
123+
124+
[Fact]
125+
public void GET_with_resource_containing_tokens() {
126+
var request = new RestRequest($"{Resource}/{{foo}}");
127+
request.AddUrlSegment("foo", "bar");
128+
var expected = new Uri($"{Base}/{Resource}/bar");
129+
130+
using var client = new RestClient(new Uri(Base));
131+
132+
var output = client.BuildUri(request);
133+
Assert.Equal(expected, output);
134+
}
135+
136+
[Fact]
137+
public void GET_with_Uri_and_resource_containing_tokens() {
138+
var request = new RestRequest($"/{{foo}}/{Resource}/{{baz}}");
139+
request.AddUrlSegment("foo", "bar");
140+
request.AddUrlSegment("baz", "bat");
141+
var expected = new Uri($"{Base}/bar/{Resource}/bat");
142+
143+
using var client = new RestClient(Base);
144+
145+
var output = client.BuildUri(request);
146+
Assert.Equal(expected, output);
147+
}
148+
149+
[Fact]
150+
public void GET_with_Uri_containing_tokens() {
151+
var request = new RestRequest();
152+
request.AddUrlSegment("foo", "bar");
153+
var expected = new Uri(Base);
154+
155+
using var client = new RestClient(Base);
156+
157+
var output = client.BuildUri(request);
158+
Assert.Equal(expected, output);
159+
}
160+
161+
[Fact]
162+
public void GET_with_Url_string_and_resource_containing_tokens() {
163+
var request = new RestRequest($"{Resource}/{{baz}}");
164+
request.AddUrlSegment("foo", "bar");
165+
request.AddUrlSegment("baz", "bat");
166+
var expected = new Uri($"{Base}/bar/{Resource}/bat");
167+
168+
using var client = new RestClient($"{Base}/{{foo}}");
169+
170+
var output = client.BuildUri(request);
171+
Assert.Equal(expected, output);
172+
}
173+
174+
[Fact]
175+
public void GET_with_Url_string_containing_tokens() {
176+
var request = new RestRequest();
177+
request.AddUrlSegment("foo", "bar");
178+
var expected = new Uri($"{Base}/bar");
179+
180+
using var client = new RestClient($"{Base}/{{foo}}");
181+
182+
var output = client.BuildUri(request);
183+
Assert.Equal(expected, output);
184+
}
185+
186+
[Fact]
187+
public void GET_wth_trailing_slash_and_query_parameters() {
188+
var request = new RestRequest($"/{Resource}/");
189+
request.AddParameter("foo", "bar");
190+
var expected = new Uri($"{Base}/{Resource}/?foo=bar");
191+
192+
using var client = new RestClient(Base);
193+
194+
var output = client.BuildUri(request);
195+
Assert.Equal(expected, output);
196+
}
197+
}

0 commit comments

Comments
 (0)