diff --git a/Octokit.Tests/Clients/OauthClientTests.cs b/Octokit.Tests/Clients/OauthClientTests.cs index d009af68..8fdeebea 100644 --- a/Octokit.Tests/Clients/OauthClientTests.cs +++ b/Octokit.Tests/Clients/OauthClientTests.cs @@ -42,8 +42,7 @@ public class OauthClientTests var result = client.GetGitHubLoginUrl(request); - const string expected = "https://github.com/login/oauth/authorize?client_id=secret&redirect_uri=https://example.com/foo?foo=bar&scope=foo,bar&state=canARY"; - Assert.Equal(expected, result.ToString()); + Assert.Equal("/login/oauth/authorize", result.AbsolutePath); Assert.Equal("?client_id=secret&redirect_uri=https%3A%2F%2Fexample.com%2Ffoo%3Ffoo%3Dbar&scope=foo%2Cbar&state=canARY", result.Query); } } diff --git a/Octokit.Tests/Helpers/UriExtensionsTests.cs b/Octokit.Tests/Helpers/UriExtensionsTests.cs index 20bae54b..981ecd40 100644 --- a/Octokit.Tests/Helpers/UriExtensionsTests.cs +++ b/Octokit.Tests/Helpers/UriExtensionsTests.cs @@ -22,6 +22,19 @@ namespace Octokit.Tests.Helpers Assert.Equal(new Uri("https://example.com?foo=foo%20val&bar=barval"), uriWithParameters); } + [Fact] + public void ThrowsExceptionWhenNullValueProvided() + { + var uri = new Uri("https://example.com"); + + var parameters = new Dictionary + { + {"foo", null }, + }; + + Assert.Throws(() => uri.ApplyParameters(parameters)); + } + [Fact] public void AppendsParametersAsQueryStringToRelativeUri() { diff --git a/Octokit.Tests/Models/SearchCodeRequestTests.cs b/Octokit.Tests/Models/SearchCodeRequestTests.cs index 86587d57..831b6b3f 100644 --- a/Octokit.Tests/Models/SearchCodeRequestTests.cs +++ b/Octokit.Tests/Models/SearchCodeRequestTests.cs @@ -1,4 +1,5 @@ -using Octokit; +using System; +using Octokit; using Octokit.Tests.Helpers; using Xunit; @@ -16,5 +17,13 @@ public class SearchCodeRequestTests // If I can cast this to a writeable collection, then that defeats the purpose of a read only. AssertEx.IsReadOnlyCollection(result); } + + [Fact] + public void SortNotSpecifiedByDefault() + { + var request = new SearchCodeRequest("test"); + Assert.True(String.IsNullOrWhiteSpace(request.Sort)); + Assert.False(request.Parameters.ContainsKey("sort")); + } } } diff --git a/Octokit.Tests/Models/SearchIssuesRequestTests.cs b/Octokit.Tests/Models/SearchIssuesRequestTests.cs index 03a48514..9891dbdb 100644 --- a/Octokit.Tests/Models/SearchIssuesRequestTests.cs +++ b/Octokit.Tests/Models/SearchIssuesRequestTests.cs @@ -1,4 +1,5 @@ -using Octokit; +using System; +using Octokit; using Octokit.Tests.Helpers; using Xunit; @@ -16,5 +17,13 @@ internal class SearchIssuesRequestTests // If I can cast this to a writeable collection, then that defeats the purpose of a read only. AssertEx.IsReadOnlyCollection(result); } + + [Fact] + public void SortNotSpecifiedByDefault() + { + var request = new SearchIssuesRequest("test"); + Assert.True(String.IsNullOrWhiteSpace(request.Sort)); + Assert.False(request.Parameters.ContainsKey("sort")); + } } } diff --git a/Octokit.Tests/Models/SearchUsersRequestTests.cs b/Octokit.Tests/Models/SearchUsersRequestTests.cs index 110a3f60..b3746e87 100644 --- a/Octokit.Tests/Models/SearchUsersRequestTests.cs +++ b/Octokit.Tests/Models/SearchUsersRequestTests.cs @@ -1,4 +1,5 @@ -using Octokit; +using System; +using Octokit; using Octokit.Tests.Helpers; using Xunit; @@ -16,5 +17,13 @@ internal class SearchUsersRequestTests // If I can cast this to a writeable collection, then that defeats the purpose of a read only. AssertEx.IsReadOnlyCollection(result); } + + [Fact] + public void SortNotSpecifiedByDefault() + { + var request = new SearchUsersRequest("shiftkey"); + Assert.True(String.IsNullOrWhiteSpace(request.Sort)); + Assert.False(request.Parameters.ContainsKey("sort")); + } } } diff --git a/Octokit/Helpers/UriExtensions.cs b/Octokit/Helpers/UriExtensions.cs index 718cc795..d3f32af5 100644 --- a/Octokit/Helpers/UriExtensions.cs +++ b/Octokit/Helpers/UriExtensions.cs @@ -44,7 +44,13 @@ namespace Octokit } } - string query = String.Join("&", p.Select(kvp => kvp.Key + "=" + Uri.EscapeDataString(kvp.Value))); + Func mapValueFunc = (key, value) => + { + if (key == "q") return value; + return Uri.EscapeDataString(value); + }; + + string query = String.Join("&", p.Select(kvp => kvp.Key + "=" + mapValueFunc(kvp.Key, kvp.Value))); if (uri.IsAbsoluteUri) { var uriBuilder = new UriBuilder(uri) diff --git a/Octokit/Models/Request/BaseSearchRequest.cs b/Octokit/Models/Request/BaseSearchRequest.cs index cb7392f8..a5ac304c 100644 --- a/Octokit/Models/Request/BaseSearchRequest.cs +++ b/Octokit/Models/Request/BaseSearchRequest.cs @@ -83,7 +83,10 @@ namespace Octokit var d = new Dictionary(); d.Add("page", Page.ToString(CultureInfo.CurrentCulture)); d.Add("per_page", PerPage.ToString(CultureInfo.CurrentCulture)); - d.Add("sort", Sort); + if (!String.IsNullOrWhiteSpace(Sort)) + { + d.Add("sort", Sort); + } d.Add("order", SortOrder); d.Add("q", TermAndQualifiers); return d;