Skip to content

Commit

Permalink
Merge pull request #226 from hahmed/hahmed/search-api
Browse files Browse the repository at this point in the history
Search Api Implmentation
  • Loading branch information
shiftkey committed Dec 24, 2013
2 parents 1d37e01 + 3a85248 commit f495c70
Show file tree
Hide file tree
Showing 16 changed files with 1,388 additions and 0 deletions.
240 changes: 240 additions & 0 deletions Octokit.Tests/Clients/SearchClientTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
using System;
using System.Threading.Tasks;
using NSubstitute;
using Octokit.Tests.Helpers;
using Xunit;
using System.Collections.Generic;

namespace Octokit.Tests.Clients
{
/// <summary>
/// Client tests mostly just need to make sure they call the IApiConnection with the correct
/// relative Uri. No need to fake up the response. All *those* tests are in ApiConnectionTests.cs.
/// </summary>
public class SearchClientTests
{
public class TheConstructor
{
[Fact]
public void EnsuresNonNullArguments()
{
Assert.Throws<ArgumentNullException>(() => new SearchClient(null));
}
}

public class TheSearchUsersMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
client.SearchUsers(new SearchUsersRequest("something"));
connection.Received().GetAll<User>(Arg.Is<Uri>(u => u.ToString() == "search/users"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchUsers(null));
}
}

public class TheSearchRepoMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
client.SearchRepo(new SearchRepositoriesRequest("something"));
connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchRepo(null));
}

[Fact]
public void TestingTheSizeQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//check sizes for repos that are greater than 50 MB
var request = new SearchRepositoriesRequest("github");
request.Size = Range.GreaterThan(50);

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheStarsQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos whos stargazers are greater than 500
var request = new SearchRepositoriesRequest("github");
request.Stars = Range.GreaterThan(500);

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheForksQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos which has forks that are greater than 50
var request = new SearchRepositoriesRequest("github");
request.Forks = Range.GreaterThan(50);

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheForkQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//search repos that contains rails and forks are included in the search
var request = new SearchRepositoriesRequest("rails");
request.Fork = ForkQualifier.IncludeForks;

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheLangaugeQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos whos language is Ruby
var request = new SearchRepositoriesRequest("github");
request.Language = Language.Ruby;

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheInQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos where the Description contains the test 'github'
var request = new SearchRepositoriesRequest("github");
request.In = new[] { InQualifier.Description };
client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheCreatedQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos where the search contains 'github' and has been created after year jan 1 2011
var request = new SearchRepositoriesRequest("github");
request.Created = DateRange.GreaterThan(new DateTime(2011, 1, 1));

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheUpdatedQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos where the search contains 'github' and has been pushed before year jan 1 2013
var request = new SearchRepositoriesRequest("github");
request.Updated = DateRange.LessThan(new DateTime(2013, 1, 1));

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheUserQualifier()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos where the Description contains rails and user/org is 'github'
var request = new SearchRepositoriesRequest("rails");
request.User = "github";

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public void TestingTheSortParameter()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
//get repos where the Description contains rails and user/org is 'github'
var request = new SearchRepositoriesRequest("rails");
request.Sort = RepoSearchSort.Forks;

client.SearchRepo(request);

connection.Received().GetAll<Repository>(Arg.Is<Uri>(u => u.ToString() == "search/repositories"), Arg.Any<Dictionary<string, string>>());
}
}

public class TheSearchIssuesMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
client.SearchIssues(new SearchIssuesRequest("something"));
connection.Received().GetAll<Issue>(Arg.Is<Uri>(u => u.ToString() == "search/issues"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchIssues(null));
}
}

public class TheSearchCodeMethod
{
[Fact]
public void RequestsTheCorrectUrl()
{
var connection = Substitute.For<IApiConnection>();
var client = new SearchClient(connection);
client.SearchCode(new SearchCodeRequest("something"));
connection.Received().GetAll<SearchCode>(Arg.Is<Uri>(u => u.ToString() == "search/code"), Arg.Any<Dictionary<string, string>>());
}

[Fact]
public async Task EnsuresNonNullArguments()
{
var client = new SearchClient(Substitute.For<IApiConnection>());
AssertEx.Throws<ArgumentNullException>(async () => await client.SearchCode(null));
}
}
}
}
1 change: 1 addition & 0 deletions Octokit.Tests/OctoKit.Tests-NetCore45.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
<Compile Include="SimpleJsonSerializerTests.cs" />
<Compile Include="Clients\UsersClientTests.cs" />
<Compile Include="Clients\TeamsClientTests.cs" />
<Compile Include="Clients\SearchClientTests.cs" />
<Compile Include="Clients\RepoCollaboratorsClientTests.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions Octokit.Tests/Octokit.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Authentication\CredentialsTests.cs" />
<Compile Include="Clients\SearchClientTests.cs" />
<Compile Include="Clients\GistCommentsClientTests.cs" />
<Compile Include="Clients\GistsClientTests.cs" />
<Compile Include="Clients\BlobClientTests.cs" />
Expand Down
45 changes: 45 additions & 0 deletions Octokit/Clients/ISearchClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#if NET_45
using System.Collections.Generic;
#endif
using System.Threading.Tasks;
namespace Octokit
{

/// <summary>
/// GitHub Search Api Client
/// </summary>
public interface ISearchClient
{
/// <summary>
/// search repos
/// http://developer.github.com/v3/search/#search-repositories
/// </summary>
/// <param name="search"></param>
/// <returns>List of repos</returns>
Task<IReadOnlyList<Repository>> SearchRepo(SearchRepositoriesRequest search);

/// <summary>
/// search users
/// http://developer.github.com/v3/search/#search-users
/// </summary>
/// <param name="search"></param>
/// <returns>List of users</returns>
Task<IReadOnlyList<User>> SearchUsers(SearchUsersRequest search);

/// <summary>
/// search issues
/// http://developer.github.com/v3/search/#search-issues
/// </summary>
/// <param name="search"></param>
/// <returns>List of issues</returns>
Task<IReadOnlyList<Issue>> SearchIssues(SearchIssuesRequest search);

/// <summary>
/// search code
/// http://developer.github.com/v3/search/#search-code
/// </summary>
/// <param name="search"></param>
/// <returns>List of files</returns>
Task<IReadOnlyList<SearchCode>> SearchCode(SearchCodeRequest search);
}
}
67 changes: 67 additions & 0 deletions Octokit/Clients/SearchClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#if NET_45
using System.Collections.Generic;
#endif
using System.Threading.Tasks;
namespace Octokit
{
public class SearchClient : ApiClient, ISearchClient
{
/// <summary>
/// Initializes a new GitHub Search API client.
/// </summary>
/// <param name="apiConnection">An API connection.</param>
public SearchClient(IApiConnection apiConnection)
: base(apiConnection)
{

}

/// <summary>
/// search repos
/// http://developer.github.com/v3/search/#search-repositories
/// </summary>
/// <param name="search"></param>
/// <returns>List of repos</returns>
public Task<IReadOnlyList<Repository>> SearchRepo(SearchRepositoriesRequest search)
{
Ensure.ArgumentNotNull(search, "search");
return ApiConnection.GetAll<Repository>("search/repositories".FormatUri(), search.Parameters);
}

/// <summary>
/// search users
/// http://developer.github.com/v3/search/#search-users
/// </summary>
/// <param name="search"></param>
/// <returns>List of users</returns>
public Task<IReadOnlyList<User>> SearchUsers(SearchUsersRequest search)
{
Ensure.ArgumentNotNull(search, "search");
return ApiConnection.GetAll<User>("search/users".FormatUri(), search.ToParametersDictionary());
}

/// <summary>
/// search issues
/// http://developer.github.com/v3/search/#search-issues
/// </summary>
/// <param name="search"></param>
/// <returns>List of issues</returns>
public Task<IReadOnlyList<Issue>> SearchIssues(SearchIssuesRequest search)
{
Ensure.ArgumentNotNull(search, "search");
return ApiConnection.GetAll<Issue>("search/issues".FormatUri(), search.ToParametersDictionary());
}

/// <summary>
/// search code
/// http://developer.github.com/v3/search/#search-code
/// </summary>
/// <param name="search"></param>
/// <returns>List of files</returns>
public Task<IReadOnlyList<SearchCode>> SearchCode(SearchCodeRequest search)
{
Ensure.ArgumentNotNull(search, "search");
return ApiConnection.GetAll<SearchCode>("search/code".FormatUri(), search.ToParametersDictionary());
}
}
}
Loading

0 comments on commit f495c70

Please sign in to comment.