define a custom Repos property when searching issues

This commit is contained in:
Brendan Forster
2015-07-12 20:59:31 -07:00
parent e202c61eda
commit cf1b99dd3d
3 changed files with 83 additions and 10 deletions
@@ -1,4 +1,6 @@
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Octokit;
using Octokit.Tests.Integration;
@@ -45,6 +47,11 @@ public class SearchClientTests
public async Task SearchForWordInCode()
{
var request = new SearchIssuesRequest("windows");
request.Repos = new Collection<string> {
"aspnet/dnx",
"aspnet/dnvm"
};
request.SortField = IssueSearchSort.Created;
request.Order = SortDirection.Descending;
+25 -4
View File
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using NSubstitute;
using Xunit;
using System.Threading.Tasks;
@@ -1150,13 +1151,13 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchIssuesRequest("something");
request.Repo = "octokit.net";
request.Repo = "octokit/octokit.net";
client.SearchIssues(request);
connection.Received().Get<SearchIssuesResult>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+repo:octokit.net"));
Arg.Is<Dictionary<string, string>>(d => d["q"] == "something+repo:octokit/octokit.net"));
}
[Fact]
@@ -1165,7 +1166,7 @@ namespace Octokit.Tests.Clients
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchIssuesRequest("something");
request.Repo = "octokit.net";
request.Repo = "octokit/octokit.net";
request.User = "alfhenrik";
request.Labels = new[] { "bug" };
@@ -1174,7 +1175,7 @@ namespace Octokit.Tests.Clients
connection.Received().Get<SearchIssuesResult>(
Arg.Is<Uri>(u => u.ToString() == "search/issues"),
Arg.Is<Dictionary<string, string>>(d => d["q"] ==
"something+label:bug+user:alfhenrik+repo:octokit.net"));
"something+label:bug+user:alfhenrik+repo:octokit/octokit.net"));
}
}
@@ -1487,6 +1488,26 @@ namespace Octokit.Tests.Clients
Arg.Is<Dictionary<string, string>>(d =>
d["q"] == "something+path:tools/FAKE.core+extension:fs+repo:octokit.net"));
}
[Fact]
public async Task ErrorOccursWhenSpecifyingInvalidFormatForRepos()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
var request = new SearchIssuesRequest("windows");
request.Repos = new Collection<string> {
"haha-business"
};
request.SortField = IssueSearchSort.Created;
request.Order = SortDirection.Descending;
await Assert.ThrowsAsync<ArgumentException>(
async () => await client.SearchIssues(request));
}
}
}
}
+50 -5
View File
@@ -6,6 +6,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
namespace Octokit
{
@@ -15,7 +16,10 @@ namespace Octokit
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public class SearchIssuesRequest : BaseSearchRequest
{
public SearchIssuesRequest(string term) : base(term) { }
public SearchIssuesRequest(string term) : base(term)
{
Repos = new Collection<string>();
}
public SearchIssuesRequest(string term, string owner, string name)
: this(term)
@@ -23,7 +27,9 @@ namespace Octokit
Ensure.ArgumentNotNullOrEmptyString(owner, "owner");
Ensure.ArgumentNotNullOrEmptyString(name, "name");
this.Repo = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", owner, name);
var repo = string.Format(CultureInfo.InvariantCulture, "{0}/{1}", owner, name);
Repos.Add(repo);
}
/// <summary>
@@ -183,7 +189,21 @@ namespace Octokit
/// <remarks>
/// https://help.github.com/articles/searching-issues#users-organizations-and-repositories
/// </remarks>
public string Repo { get; set; }
public string Repo
{
get
{
return Repos.FirstOrDefault();
}
set
{
Repos.Clear();
Repos.Add(value);
}
}
[SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public Collection<string> Repos { get; set; }
public override IReadOnlyList<string> MergedQualifiers()
{
@@ -264,14 +284,39 @@ namespace Octokit
parameters.Add(String.Format(CultureInfo.InvariantCulture, "user:{0}", User));
}
if (Repo.IsNotBlank())
if (Repos.Any())
{
parameters.Add(String.Format(CultureInfo.InvariantCulture, "repo:{0}", Repo));
var invalidFormatRepos = Repos.Where(x => !IsNameWithOwnerFormat(x));
if (invalidFormatRepos.Any())
{
var parameterList = string.Join(", ", invalidFormatRepos);
var message = string.Format(
CultureInfo.InvariantCulture,
"The list of repositories must be formatted as 'owner/name' - these values don't match this rule: {0}",
parameterList);
throw new ArgumentException(message);
}
parameters.Add(
string.Join("+", Repos.Select(x => "repo:" + x)));
}
return new ReadOnlyCollection<string>(parameters);
}
// what rules do we define here?
static Regex nameWithOwner = new Regex("[a-zA-Z.]{1,}/[a-zA-Z.]{1,}"
#if (!PORTABLE && !NETFX_CORE)
, RegexOptions.Compiled
#endif
);
static bool IsNameWithOwnerFormat(string input)
{
return nameWithOwner.IsMatch(input);
}
internal string DebuggerDisplay
{
get